Re: DiskArbitration, unmounting busy due to fseventsd?
site_archiver@lists.apple.com Delivered-To: Darwin-dev@lists.apple.com Hi Terry, Many thanks for your response. On Fri, 05 Sep 2008 12:01:58 -0700, Terry Lambert wrote:
Are you maybe using command line mounts and unmounts other than diskutil, which talks to DA? DA will run your command line tools under the covers after doing the right things. As long as you go through DA to do your mounts and unmount rather than explicit command line utilities or programs not going through DA, you should not need the nobrowse. As I said before, DA will notify fseventsd to stop looking.
All mounts and unmounts are performed via DADiskMountWithArguments and DADiskUnmount respectively. See below for a code snippet of the unmount function.
If Spolight and Time Machine are undesirable, you can explicitly disable them programattically by updating settings for "don't look here". Pretty sure this is well documented.
Yes - I'm aware that this is possible, but until I've fixed the busy unmount issue, I didn't see much point looking into this. So if I can get DADiskUnmount to succeed on mounts to specified locations, I'd be a super-happy-bunny. It seems though that others are also having issues: http://zfs.macosforge.org/trac/wiki/faq (search for fseventsd), although it looks like they're discussing command-line umount. Below is our unmount function (with some slight changes to make it more readable without having to add more definitions etc). If you can spot anything wrong with the way we're approving the unmount, please let me know! Note that the function is declared in a static class. Many thanks again for any help. Kind regards, Tim ---- /* Callback context struct. */ typedef struct { bool completed; int result; CFRunLoopRef runloop; bool mount; } MOUNT_RESULT; /* Generic callback function for mounts and unmounts. */ static void mount_disk_da_callback( DADiskRef /*disk*/, DADissenterRef dissenter, void* context ) { DAReturn rc; MOUNT_RESULT* result = static_cast<MOUNT_RESULT*>(context); if (NULL == result) { LOG_ERR("Failed to obtain context during DA callback."); goto out; // Should never happen. } if (NULL == dissenter) goto out; rc = DADissenterGetStatus(dissenter); switch (rc) { /* error handling that sets result.result */ } out: CFRunLoopStop(result->runloop); result->completed = true; } /* Unmount approval callback. We accept by returning NULL. */ static DADissenterRef approve_unmount_da_callback( DADiskRef /*disk*/, void* /*context*/ ) { LOG_DEBUG("approve_unmount_da_callback(): approving unmount."); return NULL; } /* Unmount function. */ int Mounter::unmount( const char* device_path, const bool& force ) { int result = 0; DADiskRef disk_ref = NULL; DASessionRef session_ref = NULL; DAApprovalSessionRef app_session_ref = NULL; MOUNT_RESULT unmount_result; unmount_result.completed = false; unmount_result.result = 0; unmount_result.mount = false; // Create DA session. session_ref = DASessionCreate(kCFAllocatorDefault); if (NULL == session_ref) { LOG_ERR("Failed to create DA session during unmount."); result = ERR_UNMOUNT; goto out; } // Create DA approval session. app_session_ref = DAApprovalSessionCreate(kCFAllocatorDefault); if (NULL == app_session_ref) { LOG_ERR("Failed to create DA approval session during unmount."); result = ERR_UMOUNT; goto out; } // Grab the current runloop and add it to the struct. unmount_result.runloop = CFRunLoopGetCurrent(); CFRetain(unmount_result.runloop); // Register our unmount approval callback. DARegisterDiskUnmountApprovalCallback( app_session_ref, kDADiskDescriptionMatchVolumeMountable, approve_unmount_da_callback, NULL); // Add our DA session to the runloop. DASessionScheduleWithRunLoop(session_ref, //CFRunLoopGetCurrent(), unmount_result.runloop, kCFRunLoopDefaultMode); // Add our DA approval session to the runloop. DAApprovalSessionScheduleWithRunLoop(app_session_ref, unmount_result.runloop, kCFRunLoopDefaultMode); // Get a reference to the disk, using the disk name. disk_ref = DADiskCreateFromBSDName(kCFAllocatorDefault, session_ref, device_path); if (NULL == disk_ref) { LOG_ERR("Failed to create DA disk reference during unmount."); result = ERR_UNMOUNT; goto out; } // Actually call the DA service to unmount the disk DADiskUnmountOptions options = force ? kDADiskUnmountOptionForce : kDADiskUnmountOptionDefault; DADiskUnmount(disk_ref, options, &mount_disk_da_callback, &unmount_result); LOG_DEBUG("Waiting for unmount callback from DA service..."); (void)CFRunLoopRun(); CFRelease(unmount_result.runloop); if (0 != (result = unmount_result.result)) { LOG_ERR("The DA service failed to unmount the device [%s].", error_str(unmount_result.result)); goto out; } LOG_DEBUG("unmount successful"); out: if (NULL != session_ref) { DASessionUnscheduleFromRunLoop(session_ref, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(session_ref); } if (NULL != app_session_ref) { DAUnregisterApprovalCallback(app_session_ref, (void*)approve_unmount_da_callback, NULL); DAApprovalSessionUnscheduleFromRunLoop(app_session_ref, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(app_session_ref); } if (NULL != disk_ref) CFRelease(disk_ref); return result; } ---- _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... This email sent to site_archiver@lists.apple.com
participants (1)
-
Tim Schooley