static void disk_op_done_cb(DADiskRef disk, DADissenterRef dissenter, void *c) { (void) disk; struct disk_op_context *context = (struct disk_op_context *) c; if (dissenter) { CFStringRef what = DADissenterGetStatusString(dissenter); fwup_warnx("%s failed: 0x%x (%d) %s)", context->operation, DADissenterGetStatus(dissenter), DADissenterGetStatus(dissenter), CFStringGetCStringPtr(what, kCFStringEncodingMacRoman)); context->succeeded = false; } else { context->succeeded = true; } CFRunLoopStop(CFRunLoopGetCurrent()); }
static void __DAStageMountApprovalCallback( CFTypeRef response, void * context ) { DADiskRef disk = context; DADissenterRef dissenter = response; if ( dissenter ) { /* * The mount was disapproved. */ ///w:start if ( DADissenterGetStatus( dissenter ) == 0xF8DAFF01 ) { DADiskSetState( disk, _kDADiskStateRequireAuthorize, TRUE ); } else if ( DADissenterGetStatus( dissenter ) == 0xF8DAFF02 ) { DADiskSetState( disk, _kDADiskStateMountPreferenceNoWrite, TRUE ); } else if ( DADissenterGetStatus( dissenter ) == 0xF8DAFF03 ) { DADiskSetState( disk, _kDADiskStateRequireAuthorize, TRUE ); DADiskSetState( disk, _kDADiskStateMountPreferenceNoWrite, TRUE ); } else ///w:stop DADiskSetState( disk, kDADiskStateStagedMount, TRUE ); } DADiskSetState( disk, kDADiskStateCommandActive, FALSE ); DAStageSignal( ); CFRelease( disk ); }
/* * Mount the given filesystem. */ int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; #ifdef __APPLE__ struct zfs_mount_args mnt_args = {0}; char devpath[MAXPATHLEN]; #endif if (options == NULL) mntopts[0] = '\0'; else (void) strlcpy(mntopts, options, sizeof (mntopts)); if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); #ifdef __APPLE__ /* * Check for optional paths */ if (hasoptionalpath(mntopts, "mountdev=", devpath, sizeof (devpath))) mnt_args.mountdev = devpath; if (hasoptionalpath(mntopts, "mountpoint=", mountpoint, sizeof (mountpoint))) goto callmount; #endif /* Create the directory if it doesn't already exist */ if (lstat(mountpoint, &buf) != 0) { if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } } #ifndef __APPLE__ /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if MS_OVERLAY is specified, which * would defeat the point. We also avoid this check if 'remount' is * specified. */ if ((flags & MS_OVERLAY) == 0 && strstr(mntopts, MNTOPT_REMOUNT) == NULL && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } #endif /*!__APPLE__*/ /* perform the mount */ #ifdef __APPLE__ callmount: mnt_args.dataset = zfs_get_name(zhp); mnt_args.flags = 0; if (mount(MNTTYPE_ZFS, mountpoint, flags, &mnt_args) != 0) { #else if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { #endif #ifdef __APPLE__ /* * If this was a top-level filesystem, then IOKit * probing may have already mounted it, causing * our call to mount() to fail. */ if (zfs_is_mounted(zhp, NULL)) { goto success; } #endif /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ if (errno == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); } else if (errno == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else { zfs_error_aux(hdl, strerror(errno)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), zhp->zfs_name)); } #ifdef __APPLE__ success: /* * Remove any legacy custom volume icons. */ { char path[MAXPATHLEN]; struct stat sbuf; snprintf(path, MAXPATHLEN, "%s/%s", mountpoint, MOUNT_POINT_CUSTOM_ICON); if (stat(path, &sbuf) == 0 && sbuf.st_size == 35014 && sbuf.st_uid == 0) { /* Clear "has custom icon" flag */ (void) removexattr(mountpoint, XATTR_FINDERINFO_NAME, 0); /* Clear custom icon file */ (void) unlink(path); } } #endif return (0); } #ifdef __APPLE__ /* * When unmounting, we first talk to diskarb and attempt to unmount via that * route. This allows diskarb to tell fsevents, mds, etc. to stop using the * filesystem. * * This code was borrowed from umount(8). */ #include <CoreFoundation/CoreFoundation.h> #include <TargetConditionals.h> #if !TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE #include <DiskArbitration/DiskArbitrationPrivate.h> static void __diskarb_unmount( DADiskRef disk, DADissenterRef dissenter, void * context ) { *( ( int * ) context ) = dissenter ? DADissenterGetStatus( dissenter ) : 0; CFRunLoopStop( CFRunLoopGetCurrent( ) ); }