~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to lib/hgfsServer/hgfsServer.c

  • Committer: Package Import Robot
  • Author(s): Nate Muench
  • Date: 2012-06-20 15:59:51 UTC
  • mfrom: (1.4.8)
  • Revision ID: package-import@ubuntu.com-20120620155951-6rupmpb0f70b52zr
Tags: 2012.05.21-724730-0ubuntu1
* Merging upstream version 2012.05.21-724730.
  - Fixes building against the current Quantal kernel. (LP: #1000344)
  - Fixes Quantal installation issues. (LP: #1019031)

* Sync with Debian
  - Updating to debhelper version 9.
  - Updating to standards version 3.9.3.
  - Updating copyright file machine-readable format version 1.0.
  - Building without multiarch paths for now

Show diffs side-by-side

added added

removed removed

Lines of Context:
287
287
                                  char **fileName,
288
288
                                  size_t *fileNameSize,
289
289
                                  HgfsSharedFolderHandle *folderHandle);
290
 
static void Hgfs_NotificationCallback(HgfsSharedFolderHandle sharedFolder,
291
 
                                      HgfsSubscriberHandle subscriber,
292
 
                                      char* fileName,
293
 
                                      uint32 mask,
294
 
                                      struct HgfsSessionInfo *session);
 
290
static void HgfsServerDirWatchEvent(HgfsSharedFolderHandle sharedFolder,
 
291
                                    HgfsSubscriberHandle subscriber,
 
292
                                    char* fileName,
 
293
                                    uint32 mask,
 
294
                                    struct HgfsSessionInfo *session);
295
295
static void HgfsFreeSearchDirents(HgfsSearch *search);
296
296
 
297
297
 
2966
2966
 
2967
2967
      ASSERT_DEVEL(reply && (replySize <= replyPacketSize));
2968
2968
      if (reply && (sizeof *reply <= replyPacketSize)) {
2969
 
         reply->id = input->id;
2970
 
         reply->status = HgfsConvertFromInternalStatus(status);
 
2969
         HgfsPackLegacyReplyHeader(status, input->id, reply);
2971
2970
      }
2972
2971
   }
2973
2972
   if (!HgfsPacketSend(input->packet, packetOut, replySize,
3331
3330
   HgfsSharedFolderHandle result = HGFS_INVALID_FOLDER_HANDLE;
3332
3331
 
3333
3332
   if (!gHgfsDirNotifyActive) {
3334
 
      return HGFS_INVALID_FOLDER_HANDLE;
 
3333
      LOG(8, ("%s: notification disabled\n", __FUNCTION__));
 
3334
      goto exit;
3335
3335
   }
3336
3336
 
3337
3337
   if (NULL == shareName) {
3341
3341
       * Need to delete all shared folders that were marked for deletion.
3342
3342
       */
3343
3343
      HgfsServerCleanupDeletedFolders();
3344
 
      return HGFS_INVALID_FOLDER_HANDLE;
 
3344
      goto exit;
3345
3345
   }
3346
3346
 
3347
3347
   MXUser_AcquireExclLock(gHgfsSharedFoldersLock);
3368
3368
      }
3369
3369
   }
3370
3370
   MXUser_ReleaseExclLock(gHgfsSharedFoldersLock);
 
3371
 
 
3372
exit:
 
3373
   LOG(8, ("%s: %s, %s, %s exit %#x\n",__FUNCTION__,
 
3374
           (shareName ? shareName : "NULL"), (sharePath ? sharePath : "NULL"),
 
3375
           (addFolder ? "add" : "remove"), result));
3371
3376
   return result;
3372
3377
}
3373
3378
 
3532
3537
      *callbackTable = &hgfsServerSessionCBTable;
3533
3538
      if (Config_GetBool(TRUE, "isolation.tools.hgfs.notify.enable")) {
3534
3539
         gHgfsDirNotifyActive = HgfsNotify_Init() == HGFS_STATUS_SUCCESS;
 
3540
         Log("%s: initialized notification %s.\n", __FUNCTION__,
 
3541
             (gHgfsDirNotifyActive ? "active" : "inactive"));
3535
3542
      }
3536
3543
      gHgfsInitialized = TRUE;
3537
3544
   } else {
3568
3575
   gHgfsInitialized = FALSE;
3569
3576
 
3570
3577
   if (gHgfsDirNotifyActive) {
3571
 
      HgfsNotify_Shutdown();
 
3578
      HgfsNotify_Exit();
3572
3579
      gHgfsDirNotifyActive = FALSE;
 
3580
      Log("%s: exit notification - inactive.\n", __FUNCTION__);
3573
3581
   }
3574
3582
 
3575
3583
   if (NULL != gHgfsSharedFoldersLock) {
3796
3804
   int i;
3797
3805
   HgfsSessionInfo *session;
3798
3806
 
 
3807
   LOG(8, ("%s: entered\n", __FUNCTION__));
 
3808
 
3799
3809
   ASSERT(transportSession);
3800
3810
 
3801
3811
   session = Util_SafeCalloc(1, sizeof *session);
3907
3917
            HgfsServerSetSessionCapability(HGFS_OP_REMOVE_WATCH_V4,
3908
3918
                                           HGFS_REQUEST_NOT_SUPPORTED, session);
3909
3919
         }
 
3920
         LOG(8, ("%s: session notify capability is %s\n", __FUNCTION__,
 
3921
                 (session->activeNotification ? "enabled" : "disabled")));
3910
3922
      }
3911
3923
      HgfsServerSetSessionCapability(HGFS_OP_SEARCH_READ_V4,
3912
3924
                                     HGFS_REQUEST_SUPPORTED, session);
3914
3926
 
3915
3927
   *sessionData = session;
3916
3928
 
 
3929
   LOG(8, ("%s: exit TRUE\n", __FUNCTION__));
3917
3930
   return TRUE;
3918
3931
}
3919
3932
 
3946
3959
   ASSERT(session->nodeArray);
3947
3960
   ASSERT(session->searchArray);
3948
3961
   if (session->activeNotification) {
3949
 
      HgfsNotify_CleanupSession(session);
 
3962
      HgfsNotify_RemoveSessionSubscribers(session);
3950
3963
   }
3951
3964
}
3952
3965
 
3977
3990
   HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData;
3978
3991
   DblLnkLst_Links *curr, *next;
3979
3992
 
 
3993
   LOG(8, ("%s: entered\n", __FUNCTION__));
 
3994
 
3980
3995
   ASSERT(transportSession);
3981
3996
 
3982
3997
   MXUser_AcquireExclLock(transportSession->sessionArrayLock);
3990
4005
   MXUser_ReleaseExclLock(transportSession->sessionArrayLock);
3991
4006
 
3992
4007
   transportSession->state = HGFS_SESSION_STATE_CLOSED;
 
4008
   LOG(8, ("%s: exit\n", __FUNCTION__));
3993
4009
}
3994
4010
 
3995
4011
 
4216
4232
   if (freeze) {
4217
4233
      /* Suspend background activity. */
4218
4234
      if (gHgfsDirNotifyActive) {
4219
 
         HgfsNotify_Suspend();
 
4235
         HgfsNotify_Deactivate(HGFS_NOTIFY_REASON_SERVER_SYNC);
4220
4236
      }
4221
4237
      /* Wait for outstanding asynchronous requests to complete. */
4222
4238
      MXUser_AcquireExclLock(gHgfsAsyncLock);
4227
4243
   } else {
4228
4244
      /* Resume background activity. */
4229
4245
      if (gHgfsDirNotifyActive) {
4230
 
         HgfsNotify_Resume();
 
4246
         HgfsNotify_Activate(HGFS_NOTIFY_REASON_SERVER_SYNC);
4231
4247
      }
4232
4248
   }
4233
4249
}
6885
6901
   size_t fileNameSize;
6886
6902
   HgfsSharedFolderHandle sharedFolder = HGFS_INVALID_FOLDER_HANDLE;
6887
6903
 
 
6904
   LOG(8, ("%s: entered\n", __FUNCTION__));
 
6905
 
6888
6906
   ASSERT(watchId != NULL);
6889
6907
 
6890
6908
   if (HgfsHandle2NotifyInfo(dir, input->session, &fileName, &fileNameSize,
6891
6909
                             &sharedFolder)) {
6892
6910
      *watchId = HgfsNotify_AddSubscriber(sharedFolder, fileName, events, watchTree,
6893
 
                                          Hgfs_NotificationCallback, input->session);
 
6911
                                          HgfsServerDirWatchEvent, input->session);
6894
6912
      status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL :
6895
6913
                                                              HGFS_ERROR_SUCCESS;
6896
6914
   } else {
6897
6915
      status = HGFS_ERROR_INTERNAL;
6898
6916
   }
6899
6917
   free(fileName);
 
6918
   LOG(8, ("%s: exit %u\n", __FUNCTION__, status));
6900
6919
   return status;
6901
6920
}
6902
6921
 
6936
6955
   ASSERT(cpName != NULL);
6937
6956
   ASSERT(watchId != NULL);
6938
6957
 
 
6958
   LOG(8, ("%s: entered\n",__FUNCTION__));
 
6959
 
6939
6960
   nameStatus = HgfsServerGetShareInfo(cpName, cpNameSize, caseFlags, &shareInfo,
6940
6961
                                       &utf8Name, &utf8NameLen);
6941
6962
   if (HGFS_NAME_STATUS_COMPLETE == nameStatus) {
6970
6991
                                            &tempSize, &tempPtr);
6971
6992
            if (HGFS_NAME_STATUS_COMPLETE == nameStatus) {
6972
6993
               *watchId = HgfsNotify_AddSubscriber(sharedFolder, tempBuf, events,
6973
 
                                                   watchTree, Hgfs_NotificationCallback,
 
6994
                                                   watchTree, HgfsServerDirWatchEvent,
6974
6995
                                                   input->session);
6975
6996
                status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ?
6976
6997
                                              HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS;
6981
7002
            }
6982
7003
         } else {
6983
7004
            *watchId = HgfsNotify_AddSubscriber(sharedFolder, "", events, watchTree,
6984
 
                                                Hgfs_NotificationCallback,
 
7005
                                                HgfsServerDirWatchEvent,
6985
7006
                                                input->session);
6986
7007
            status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL :
6987
7008
                                                                    HGFS_ERROR_SUCCESS;
6999
7020
      status = HgfsPlatformConvertFromNameStatus(nameStatus);
7000
7021
   }
7001
7022
   free(utf8Name);
 
7023
   LOG(8, ("%s: exit %u\n",__FUNCTION__, status));
7002
7024
   return status;
7003
7025
}
7004
7026
 
7035
7057
 
7036
7058
   HGFS_ASSERT_INPUT(input);
7037
7059
 
 
7060
   LOG(8, ("%s: entered\n", __FUNCTION__));
 
7061
 
7038
7062
   /*
7039
7063
    * If the active session does not support directory change notification - bail out
7040
7064
    * with an error immediately. Otherwise setting watch may succeed but no notification
7066
7090
   }
7067
7091
 
7068
7092
   HgfsServerCompleteRequest(status, replyPayloadSize, input);
 
7093
   LOG(8, ("%s: exit %u\n", __FUNCTION__, status));
7069
7094
}
7070
7095
 
7071
7096
 
7092
7117
   HgfsInternalStatus status;
7093
7118
   size_t replyPayloadSize = 0;
7094
7119
 
 
7120
   LOG(8, ("%s: entered\n", __FUNCTION__));
7095
7121
   HGFS_ASSERT_INPUT(input);
7096
7122
 
7097
7123
   if (HgfsUnpackRemoveWatchRequest(input->payload, input->payloadSize, input->op,
7112
7138
   }
7113
7139
 
7114
7140
   HgfsServerCompleteRequest(status, replyPayloadSize, input);
 
7141
   LOG(8, ("%s: exit result %u\n", __FUNCTION__, status));
7115
7142
}
7116
7143
 
7117
7144
 
8369
8396
/*
8370
8397
 *-----------------------------------------------------------------------------
8371
8398
 *
8372
 
 * Hgfs_NotificationCallback --
 
8399
 * HgfsServerDirWatchEvent --
8373
8400
 *
8374
 
 *    Callback which is called by directory notification package when in response
8375
 
 *    to a event.
 
8401
 *    The callback is invoked by the file system change notification component
 
8402
 *    in response to a change event when the client has set at least one watch
 
8403
 *    on a directory.
8376
8404
 *
8377
8405
 *    The function builds directory notification packet and queues it to be sent
8378
 
 *    to the client. It processes one notification at a time. It relies on transport
8379
 
 *    to perform coalescing.
 
8406
 *    to the client. It processes one notification at a time. Any consolidation of
 
8407
 *    packets is expected to occur at the transport layer.
8380
8408
 *
8381
8409
 * Results:
8382
8410
 *    None.
8387
8415
 *-----------------------------------------------------------------------------
8388
8416
 */
8389
8417
 
8390
 
void
8391
 
Hgfs_NotificationCallback(HgfsSharedFolderHandle sharedFolder, // IN: shared folder
8392
 
                          HgfsSubscriberHandle subscriber,     // IN: subsciber
8393
 
                          char* fileName,                      // IN: name of the file
8394
 
                          uint32 mask,                         // IN: event type
8395
 
                          struct HgfsSessionInfo *session)     // IN: session info
 
8418
static void
 
8419
HgfsServerDirWatchEvent(HgfsSharedFolderHandle sharedFolder, // IN: shared folder
 
8420
                        HgfsSubscriberHandle subscriber,     // IN: subsciber
 
8421
                        char* fileName,                      // IN: name of the file
 
8422
                        uint32 mask,                         // IN: event type
 
8423
                        struct HgfsSessionInfo *session)     // IN: session info
8396
8424
{
8397
 
   HgfsPacket *packet;
 
8425
   HgfsPacket *packet = NULL;
 
8426
   HgfsHeader *packetHeader = NULL;
 
8427
   char *shareName = NULL;
 
8428
   size_t shareNameLen;
8398
8429
   size_t sizeNeeded;
8399
 
   char *shareName;
8400
 
   size_t shareNameLen;
8401
 
   HgfsHeader *packetHeader;
8402
8430
   uint32 flags;
8403
8431
 
8404
 
   if (HgfsServerGetShareName(sharedFolder, &shareNameLen, &shareName)) {
8405
 
 
8406
 
      sizeNeeded = HgfsPackCalculateNotificationSize(shareName, fileName);
8407
 
 
8408
 
      packetHeader = Util_SafeCalloc(1, sizeNeeded);
8409
 
      packet = Util_SafeCalloc(1, sizeof *packet);
8410
 
      packet->guestInitiated = FALSE;
8411
 
      packet->metaPacketSize = sizeNeeded;
8412
 
      packet->metaPacket = packetHeader;
8413
 
      packet->dataPacketIsAllocated = TRUE;
8414
 
      flags = 0;
8415
 
      if (mask & HGFS_NOTIFY_EVENTS_DROPPED) {
8416
 
         flags |= HGFS_NOTIFY_FLAG_OVERFLOW;
8417
 
      }
8418
 
 
8419
 
      HgfsPackChangeNotificationRequest(packetHeader, subscriber, shareName, fileName, mask,
8420
 
                                        flags, session, &sizeNeeded);
8421
 
      if (!HgfsPacketSend(packet, (char *)packetHeader,  sizeNeeded, session->transportSession, 0)) {
8422
 
         LOG(4, ("%s: failed to send notification to the host\n", __FUNCTION__));
8423
 
      }
8424
 
 
8425
 
      LOG(4, ("%s: notification for folder: %d index: %d file name %s "
8426
 
              " mask %x\n", __FUNCTION__, sharedFolder,
8427
 
              (int)subscriber, fileName, mask));
8428
 
      free(shareName);
8429
 
   } else {
 
8432
   LOG(4, ("%s:Entered shr hnd %u hnd %"FMT64"x file %s mask %u\n",
 
8433
         __FUNCTION__, sharedFolder, subscriber, fileName, mask));
 
8434
 
 
8435
   if (!HgfsServerGetShareName(sharedFolder, &shareNameLen, &shareName)) {
8430
8436
      LOG(4, ("%s: failed to find shared folder for a handle %x\n",
8431
8437
              __FUNCTION__, sharedFolder));
 
8438
      goto exit;
 
8439
   }
 
8440
 
 
8441
   sizeNeeded = HgfsPackCalculateNotificationSize(shareName, fileName);
 
8442
 
 
8443
   packetHeader = Util_SafeCalloc(1, sizeNeeded);
 
8444
   packet = Util_SafeCalloc(1, sizeof *packet);
 
8445
   packet->guestInitiated = FALSE;
 
8446
   packet->metaPacketSize = sizeNeeded;
 
8447
   packet->metaPacket = packetHeader;
 
8448
   packet->dataPacketIsAllocated = TRUE;
 
8449
   flags = 0;
 
8450
   if (mask & HGFS_NOTIFY_EVENTS_DROPPED) {
 
8451
      flags |= HGFS_NOTIFY_FLAG_OVERFLOW;
 
8452
   }
 
8453
 
 
8454
   if (!HgfsPackChangeNotificationRequest(packetHeader, subscriber, shareName, fileName, mask,
 
8455
                                          flags, session, &sizeNeeded)) {
 
8456
      LOG(4, ("%s: failed to pack notification request\n", __FUNCTION__));
 
8457
      goto exit;
 
8458
   }
 
8459
 
 
8460
   if (!HgfsPacketSend(packet, (char *)packetHeader,  sizeNeeded, session->transportSession, 0)) {
 
8461
      LOG(4, ("%s: failed to send notification to the host\n", __FUNCTION__));
 
8462
      goto exit;
 
8463
   }
 
8464
 
 
8465
   /* The transport will call the server send complete callback to release the packets. */
 
8466
   packet = NULL;
 
8467
   packetHeader = NULL;
 
8468
 
 
8469
   LOG(4, ("%s: Sent notify for: %u index: %"FMT64"u file name %s mask %x\n",
 
8470
           __FUNCTION__, sharedFolder, subscriber, fileName, mask));
 
8471
 
 
8472
exit:
 
8473
   if (shareName) {
 
8474
      free(shareName);
 
8475
   }
 
8476
   if (packet) {
 
8477
      free(packet);
 
8478
   }
 
8479
   if (packetHeader) {
 
8480
      free(packetHeader);
8432
8481
   }
8433
8482
}
8434
8483