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;
    }