There are 2 things missing from your code. As @Hanzaplastique mentioned, you need to wait for the callback to be executed. Secondly, you need to pass a valid queue to `DASessionSetDispatchQueue()`. If you pass `NULL` as in your code, you're telling it to unschedule the session. You can use a `dispatch_semaphore_t` to wait between threads. Putting it all together, I get this: #include <stdio.h> #import <CoreFoundation/CoreFoundation.h> #import <DiskArbitration/DiskArbitration.h> static dispatch_semaphore_t semaphore; void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context); int main(int argc, const char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <disk>\n", argv[0]); return EXIT_FAILURE; } const char *deviceName = argv[1]; // Create the semaphore we'll wait on. semaphore = dispatch_semaphore_create(0); DASessionRef session = DASessionCreate(kCFAllocatorDefault); DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, deviceName); // Pass NULL for a "standard" mount path. DADiskMount(disk, NULL, kDADiskMountOptionWhole, MountCallback, (void *)deviceName); // We'll pass the global concurrent queue here so it gets executed in the background DASessionSetDispatchQueue(session, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)); CFRelease(session); session = NULL; // Wait for the callback to signal that it's done dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // Clean up dispatch_release(semaphore); return EXIT_SUCCESS; } void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context) { const char *mountedDisk = context; fprintf(stderr, "Device mounted: %s\n", mountedDisk); fflush(stderr); // Tell the main thread that we've finished up. dispatch_semaphore_signal(semaphore); return; }