static bool do_format(const std::string &mountpoint) { if (mountpoint == SYSTEM || mountpoint == CACHE) { // Need to mount the partition if we're using an image file and it // hasn't been mounted int needs_mount = (mountpoint == SYSTEM) && (access("/mb/system.img", F_OK) == 0) && (access(STAMP_FILE, F_OK) != 0); if (needs_mount && !do_mount(mountpoint)) { LOGE(TAG "Failed to mount {}", mountpoint); return false; } if (!wipe_directory(mountpoint, true)) { LOGE(TAG "Failed to wipe {}", mountpoint); return false; } if (needs_mount && !do_unmount(mountpoint)) { LOGE(TAG "Failed to unmount {}", mountpoint); return false; } } else if (mountpoint == DATA) { if (!wipe_directory(mountpoint, false)) { LOGE(TAG "Failed to wipe {}", mountpoint); return false; } } LOGD(TAG "Formatted {}", mountpoint); return true; }
static int prepare_buffer(int argc, char * argv[]) { if (argc<2) { usage(); return -1; } if (strncmp(argv[1],"mount",5)==0) { return do_mount(argc,argv); } else if (strncmp(argv[1],"resume",6)==0) { return do_resume(argc,argv); } else if (strncmp(argv[1],"suspend",7)==0) { return do_suspend(argc,argv); } else if (strncmp(argv[1],"status",6)==0) { return do_status(argc,argv); } else if (strncmp(argv[1],"unmount",7)==0) { return do_unmount(argc,argv); } else if (strncmp(argv[1],"exit",4)==0) { return do_exit(argc,argv); } else { usage(); return -1; } return 0; }
static bool do_format(const char *mountpoint) { if (!get_paths(mountpoint, nullptr, nullptr)) { LOGE(TAG "%s: Invalid mountpoint", mountpoint); return false; } bool needs_mount = !util::is_mounted(mountpoint); if (needs_mount && !do_mount(mountpoint)) { LOGE(TAG "%s: Failed to mount path", mountpoint); return false; } std::vector<std::string> exclusions; if (strcmp(mountpoint, DATA) == 0) { exclusions.push_back("media"); } if (!wipe_directory(mountpoint, exclusions)) { LOGE(TAG "%s: Failed to wipe directory", mountpoint); return false; } if (needs_mount && !do_unmount(mountpoint)) { LOGE(TAG "%s: Failed to unmount path", mountpoint); return false; } LOGD(TAG "Successfully formatted %s", mountpoint); return true; }
/* * Unmount a single filesystem. */ static int unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags) { int error; error = do_unmount(mountpoint, flags); if (error != 0) { return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), mountpoint)); } return (0); }
int do_eject() { if (rip_status == STATUS_MOUNTED) do_unmount(); printf("Ejecting iPod at %s\n", RIP_MOUNTDEVICE); #ifdef IPOD /* This is a poor hack to deal with busybox's eject not working for SCSI devices */ if (vfork() == 0) { execl("/bin/rmmod", "/bin/rmmod", "sbp2", NULL); _exit(0); } pz_dialog("iPod Eject", "Please physically disconnect the iPods before pressing [OK]", 1, 0, "OK"); if (vfork() == 0) { execl("/bin/modprobe", "/bin/modprobe", "sbp2", NULL); _exit(0); } #else if (vfork() == 0) { execl("/usr/bin/eject", "/usr/bin/eject", RIP_MOUNTDEVICE, NULL); _exit(0); } #endif ipod_status_ejected(); return 1; }
static void autorun_dialog_response (GtkDialog *dialog, gint response, AutorunDialogData *data) { switch (response) { case AUTORUN_DIALOG_RESPONSE_EJECT: do_unmount (data->mount, data->should_eject, GTK_WINDOW (dialog)); break; case GTK_RESPONSE_NONE: /* window was closed */ break; case GTK_RESPONSE_CANCEL: break; case GTK_RESPONSE_OK: /* do the selected action */ if (data->remember) { /* make sure we don't ask again */ csd_autorun_set_preferences (data->x_content_type, TRUE, data->selected_ignore, data->selected_open_folder); if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) { g_app_info_set_as_default_for_type (data->selected_app, data->x_content_type, NULL); } } else { /* make sure we do ask again */ csd_autorun_set_preferences (data->x_content_type, FALSE, FALSE, FALSE); } if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) { csd_autorun_launch_for_mount (data->mount, data->selected_app); } else if (!data->selected_ignore && data->selected_open_folder) { if (data->open_window_func != NULL) data->open_window_func (data->mount, data->user_data); } break; } autorun_dialog_destroy (data); }
/* * Class: org_catacombae_jfuse_FUSE * Method: unmountNative * Signature: (Ljava/lang/String;Z)Z */ JNIEXPORT jboolean JNICALL Java_org_catacombae_jfuse_FUSE_unmountNative (JNIEnv *env, jclass clazz, jstring mountPoint, jboolean force) { #define _FNAME_ "Java_org_catacombae_jfuse_FUSE_unmountNative" CSLogTraceEnter("%s (%p, %p, %p, %d)", _FNAME_, env, clazz, mountPoint, force); jboolean res = JNI_FALSE; const char *mountPointChars = env->GetStringUTFChars(mountPoint, NULL); if(do_unmount(mountPointChars, (force == JNI_TRUE ? UNMOUNT_FORCE : 0)) == 0) res = JNI_TRUE; else CSLogError("Could not unmount \"%s\". errno=%d (%s)", mountPointChars, errno, strerror(errno)); env->ReleaseStringUTFChars(mountPoint, mountPointChars); CSLogTraceLeave("%s (%p, %p, %p, %d): %d", _FNAME_, env, clazz, mountPoint, force, res); return res; #undef _FNAME_ }
// The erase parameter in this routine is to control nested mount points. // We want to descend into a mount point to unmount anything that is // mounted under it, but we do not want to delete any files while doing // this traversal. In other words, we erase files until we cross the // first mount point, and after that point we only scan and unmount. static void cleanup_aux(const atf::fs::path& p, dev_t parent_device, bool erase) { try { atf::fs::file_info fi(p); if (fi.get_type() == atf::fs::file_info::dir_type) cleanup_aux_dir(p, fi, fi.get_device() == parent_device); if (fi.get_device() != parent_device) do_unmount(p); if (erase) { if (fi.get_type() == atf::fs::file_info::dir_type) atf::fs::rmdir(p); else atf::fs::remove(p); } } catch (const atf::system_error& e) { if (e.code() != ENOENT && e.code() != ENOTDIR) throw e; } }
int update_binary_tool_main(int argc, char *argv[]) { int opt; static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; int long_index = 0; while ((opt = getopt_long(argc, argv, "h", long_options, &long_index)) != -1) { switch (opt) { case 'h': update_binary_tool_usage(0); return EXIT_SUCCESS; default: update_binary_tool_usage(1); return EXIT_FAILURE; } } if (argc - optind != 2) { update_binary_tool_usage(1); return EXIT_FAILURE; } // Log to stderr, so the output is ordered correctly in /tmp/recovery.log util::log_set_logger(std::make_shared<util::StdioLogger>(stderr)); std::string action = argv[optind]; std::string mountpoint = argv[optind + 1]; if (action != ACTION_MOUNT && action != ACTION_UNMOUNT && action != ACTION_FORMAT) { update_binary_tool_usage(1); return EXIT_FAILURE; } if (mountpoint != SYSTEM && mountpoint != CACHE && mountpoint != DATA) { update_binary_tool_usage(1); return EXIT_FAILURE; } if (access("/.chroot", F_OK) < 0) { fprintf(stderr, "update-binary-tool must be run inside the chroot\n"); return EXIT_FAILURE; } bool ret = false; if (action == ACTION_MOUNT) { ret = do_mount(mountpoint); } else if (action == ACTION_UNMOUNT) { ret = do_unmount(mountpoint); } else if (action == ACTION_FORMAT) { ret = do_format(mountpoint); } return ret ? EXIT_SUCCESS : EXIT_FAILURE; }
PzWindow *new_dounmount_window() { do_unmount(); return TTK_MENU_DONOTHING; }
static int unmount_fuse(const char *mnt, int quiet, int lazy) { return do_unmount(mnt, quiet, lazy); }
static int unmount_fuse(const char *mnt, int quiet, int lazy) { int res; struct mntent *entp; FILE *fp; FILE *newfp = NULL; const char *user = NULL; char uidstr[32]; unsigned uidlen = 0; int found; int issymlink = 0; struct stat stbuf; const char *mtab = _PATH_MOUNTED; const char *mtab_new = _PATH_MOUNTED "~fuse~"; if (lstat(mtab, &stbuf) != -1 && S_ISLNK(stbuf.st_mode)) issymlink = 1; fp = setmntent(mtab, "r"); if (fp == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab, strerror(errno)); return -1; } if (!issymlink) { newfp = setmntent(mtab_new, "w"); if (newfp == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab_new, strerror(errno)); endmntent(fp); return -1; } } if (getuid() != 0) { user = get_user_name(); if (user == NULL) goto err_endmntent; uidlen = sprintf(uidstr, "%u", getuid()); } found = 0; while ((entp = getmntent(fp)) != NULL) { int removed = 0; if (!found && strcmp(entp->mnt_dir, mnt) == 0 && (strcmp(entp->mnt_type, "fuse") == 0 || strcmp(entp->mnt_type, "fuseblk") == 0)) { if (user == NULL) removed = 1; else { char *p = strstr(entp->mnt_opts, "user="******"user_id=")) && (p == entp->mnt_opts || *(p-1) == ',') && strncmp(p + 8, uidstr, uidlen) == 0 && (*(p+8+uidlen) == ',' || *(p+8+uidlen) == '\0')) removed = 1; } } if (removed) found = 1; else if (!issymlink) { res = addmntent(newfp, entp); if (res != 0) { fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname, mtab_new, strerror(errno)); } } } endmntent(fp); if (!issymlink) endmntent(newfp); if (!found) { if (!quiet) fprintf(stderr, "%s: entry for %s not found in %s\n", progname, mnt, mtab); goto err; } drop_privs(); res = do_unmount(mnt, quiet, lazy); restore_privs(); if (res == -1) goto err; if (!issymlink) { res = unmount_rename(mtab, mtab_new); if (res == -1) goto err; } return 0; err_endmntent: if (!issymlink) endmntent(newfp); endmntent(fp); err: if (!issymlink) unlink(mtab_new); return -1; }
int main(int argc, char *argv[]) { int ch; int fd; int res; char *origmnt; char *mnt; static int unmount = 0; static int lazy = 0; static int quiet = 0; char *commfd; int cfd; const char *opts = ""; static const struct option long_opts[] = { {"unmount", no_argument, NULL, 'u'}, {"lazy", no_argument, NULL, 'z'}, {"quiet", no_argument, NULL, 'q'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0}}; progname = strdup(argv[0]); if (progname == NULL) { fprintf(stderr, "%s: failed to allocate memory\n", argv[0]); exit(1); } while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts, NULL)) != -1) { switch (ch) { case 'h': usage(); break; case 'V': show_version(); break; case 'o': opts = optarg; break; case 'u': unmount = 1; break; case 'z': lazy = 1; break; case 'q': quiet = 1; break; default: exit(1); } } if (lazy && !unmount) { fprintf(stderr, "%s: -z can only be used with -u\n", progname); exit(1); } if (optind >= argc) { fprintf(stderr, "%s: missing mountpoint argument\n", progname); exit(1); } origmnt = argv[optind]; drop_privs(); mnt = resolve_path(origmnt); restore_privs(); if (mnt == NULL) exit(1); umask(033); if (unmount) { if (geteuid() == 0) { int mtablock = lock_mtab(); res = unmount_fuse(mnt, quiet, lazy); unlock_mtab(mtablock); } else res = do_unmount(mnt, quiet, lazy); if (res == -1) exit(1); return 0; } commfd = getenv(FUSE_COMMFD_ENV); if (commfd == NULL) { fprintf(stderr, "%s: old style mounting not supported\n", progname); exit(1); } fd = mount_fuse(mnt, opts); if (fd == -1) exit(1); cfd = atoi(commfd); res = send_fd(cfd, fd); if (res == -1) exit(1); return 0; }
/* * Mount the given filesystem. * * 'flags' appears pretty much always 0 here. */ 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; int remount; if (options == NULL) { mntopts[0] = '\0'; } else { (void) strlcpy(mntopts, options, sizeof (mntopts)); } if (strstr(mntopts, MNTOPT_REMOUNT) != NULL) remount = 1; /* * If the pool is imported read-only then all mounts must be read-only */ #ifdef __LINUX__ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts)); #else if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) flags |= MS_RDONLY; #endif /* __LINUX__ */ if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); #ifdef __LINUX__ /* * Append default mount options which apply to the mount point. * This is done because under Linux (unlike Solaris) multiple mount * points may reference a single super block. This means that just * given a super block there is no back reference to update the per * mount point options. */ rc = zfs_add_options(zhp, &flags); if (rc) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "default options unavailable")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* * Append zfsutil option so the mount helper allow the mount */ strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts)); #endif /* __LINUX__ */ /* Create the directory if it doesn't already exist */ #ifdef __APPLE__ if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT && lstat(mountpoint, &buf) != 0) { #else if (lstat(mountpoint, &buf) != 0) { #endif 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)); } } /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if 'remount' is * specified or if overlay option(-O) is given */ if ((flags & MS_OVERLAY) == 0 && !remount && !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)); } /* perform the mount */ #ifdef __LINUX__ rc = do_mount(zfs_get_name(zhp), mountpoint, mntopts); #elif defined(__APPLE__) || defined (__FREEBSD__) if (zmount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { #elif defined(__illumos__) if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { #endif /* __LINUX__*/ /* * 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 if (errno == ENOTSUP) { char buf[256]; int spa_version; VERIFY(zfs_spa_version(zhp, &spa_version) == 0); (void) snprintf(buf, sizeof (buf), dgettext(TEXT_DOMAIN, "Can't mount a version %lld " "file system on a version %d pool. Pool must be" " upgraded to mount this file system."), (u_longlong_t)zfs_prop_get_int(zhp, ZFS_PROP_VERSION), spa_version); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf)); #ifdef __APPLE__ } else if (((errno == ESRCH) || (errno == EINVAL) || (errno == ENOENT && lstat(mountpoint, &buf) != 0)) && zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "The parent file system must be mounted first.")); #endif } 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__ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) fprintf(stderr, "ZFS: snapshot mountpoint '%s'\n", mountpoint); if (!(flags & MS_RDONLY)) zfs_mount_seticon(mountpoint); #endif /* remove the mounted entry before re-adding on remount */ if (remount) libzfs_mnttab_remove(hdl, zhp->zfs_name); /* add the mounted entry into our cache */ libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts); return (0); } /* * Unmount a single filesystem. */ static int unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags) { int error; #if 0 error = unmount(mountpoint, flags); if (unmount(mountpoint, flags) != 0) { return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), mountpoint)); } #else error = do_unmount(mountpoint, flags); if (error != 0) { return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), mountpoint)); } #endif return (0); } /* * Unmount the given filesystem. */ int zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags) { libzfs_handle_t *hdl = zhp->zfs_hdl; #ifdef __LINUX__ struct mnttab search = { 0 }, entry; #else struct mnttab entry; #endif /* __LINUX__ */ char *mntpt = NULL; /* check to see if need to unmount the filesystem */ if (mountpoint != NULL || (((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) || (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)) && libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) { /* * mountpoint may have come from a call to * getmnt/getmntany if it isn't NULL. If it is NULL, * we know it comes from getmntany which can then get * overwritten later. We strdup it to play it safe. */ if (mountpoint == NULL) mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp); else mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint); /* * Unshare and unmount the filesystem */ #ifdef __illumos__ if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0) #else if (zfs_unshare_nfs(zhp, mntpt) != 0) #endif return (-1); if (unmount_one(hdl, mntpt, flags) != 0) { free(mntpt); #ifdef __illumos__ (void) zfs_shareall(zhp); #else (void) zfs_share_nfs(zhp); #endif return (-1); } libzfs_mnttab_remove(hdl, zhp->zfs_name); free(mntpt); } return (0); }
int update_binary_tool_main(int argc, char *argv[]) { int opt; static const char *short_options = "h"; static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; int long_index = 0; while ((opt = getopt_long(argc, argv, short_options, long_options, &long_index)) != -1) { switch (opt) { case 'h': update_binary_tool_usage(stdout); return EXIT_SUCCESS; default: update_binary_tool_usage(stderr); return EXIT_FAILURE; } } if (argc - optind != 2) { update_binary_tool_usage(stderr); return EXIT_FAILURE; } // Log to stderr, so the output is ordered correctly in /tmp/recovery.log log::log_set_logger(std::make_shared<log::StdioLogger>(stderr, false)); const char *action = argv[optind]; const char *mountpoint = argv[optind + 1]; bool is_valid_action = strcmp(action, ACTION_MOUNT) == 0 || strcmp(action, ACTION_UNMOUNT) == 0 || strcmp(action, ACTION_FORMAT) == 0; bool is_valid_mountpoint = strcmp(mountpoint, SYSTEM) == 0 || strcmp(mountpoint, CACHE) == 0 || strcmp(mountpoint, DATA) == 0; if (!is_valid_action || !is_valid_mountpoint) { update_binary_tool_usage(stderr); return EXIT_FAILURE; } if (access("/.chroot", F_OK) < 0) { fprintf(stderr, "update-binary-tool must be run inside the chroot\n"); return EXIT_FAILURE; } bool ret = false; if (strcmp(action, ACTION_MOUNT) == 0) { ret = do_mount(mountpoint); } else if (strcmp(action, ACTION_UNMOUNT) == 0) { ret = do_unmount(mountpoint); } else if (strcmp(action, ACTION_FORMAT) == 0) { ret = do_format(mountpoint); } return ret ? EXIT_SUCCESS : EXIT_FAILURE; }