static int set_ct_root(struct container *ct) { char put_root[] = "libct-root.XXXXXX"; if (!(ct->nsmask & CLONE_NEWNS)) return set_current_root(ct->root_path); /* * We're in new mount namespace. No need in * just going into chroot, do pivot root, that * gives us the ability to umount old tree. */ if (mount(ct->root_path, ct->root_path, NULL, MS_BIND | MS_REC, NULL) == -1) return -1; if (chdir(ct->root_path)) return -1; if (mkdtemp(put_root) == NULL) return -1; if (pivot_root(".", put_root)) { rmdir(put_root); return -1; } if (umount2(put_root, MNT_DETACH)) return -1; rmdir(put_root); return 0; }
CFSMounter::UMountRes CFSMounter::umount(const char * const dir) { UMountRes res = UMRES_OK; if (dir != NULL) { if (umount2(dir, MNT_FORCE) != 0) { return UMRES_ERR; } } else { MountInfo mi; std::ifstream in("/proc/mounts", std::ifstream::in); while(in.good()) { in >> mi.device >> mi.mountPoint >> mi.type; in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); if(strcmp(mi.type.c_str(),"nfs")==0 && strcmp(mi.mountPoint.c_str(),"/")==0) { if (umount2(mi.mountPoint.c_str(),MNT_FORCE) != 0) { printf("[CFSMounter] Error umounting %s\n",mi.device.c_str()); res = UMRES_ERR; } } } } if (nfs_mounted_once) remove_modules(CFSMounter::NFS); return res; }
void procd_coldplug(void) { char *argv[] = { "udevtrigger", NULL }; umount2("/dev/pts", MNT_DETACH); umount2("/dev/", MNT_DETACH); mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755,size=512K"); mkdir("/dev/shm", 0755); mkdir("/dev/pts", 0755); mount("devpts", "/dev/pts", "devpts", 0, 0); udevtrigger.cb = udevtrigger_complete; udevtrigger.pid = fork(); if (!udevtrigger.pid) { execvp(argv[0], argv); ERROR("Failed to start coldplug\n"); exit(-1); } if (udevtrigger.pid <= 0) { ERROR("Failed to start new coldplug instance\n"); return; } uloop_process_add(&udevtrigger); DEBUG(4, "Launched coldplug instance, pid=%d\n", (int) udevtrigger.pid); }
static void cleanup_dev (void) { if (!access (MOVE_DEV_PATH "/kmsg", W_OK)) { umount2 (MOVE_DEV_PATH PROC_PATH, MNT_DETACH); umount2 (MOVE_DEV_PATH, MNT_DETACH); rmdir (MOVE_DEV_PATH); } }
static void umount_api (const char *path) { verbose_do ("Unmounting ", path); if (umount2 (path, 0) < 0 && umount2 (path, MNT_DETACH) < 0) verbose_fail (errno); else if (level > 0) aa_put_title (0, "Unmounted", path, 1); }
/* Check whether the kernel supports UMOUNT_NOFOLLOW flag */ static int umount_nofollow_support(void) { int res = umount2("", UMOUNT_UNUSED); if (res != -1 || errno != EINVAL) return 0; res = umount2("", UMOUNT_NOFOLLOW); if (res != -1 || errno != ENOENT) return 0; return 1; }
static int lxc_attach_remount_sys_proc(void) { int ret; ret = unshare(CLONE_NEWNS); if (ret < 0) { SYSERROR("failed to unshare mount namespace"); return -1; } if (detect_shared_rootfs()) { if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) { SYSERROR("Failed to make / rslave"); ERROR("Continuing..."); } } /* assume /proc is always mounted, so remount it */ ret = umount2("/proc", MNT_DETACH); if (ret < 0) { SYSERROR("failed to unmount /proc"); return -1; } ret = mount("none", "/proc", "proc", 0, NULL); if (ret < 0) { SYSERROR("failed to remount /proc"); return -1; } /* try to umount /sys - if it's not a mount point, * we'll get EINVAL, then we ignore it because it * may not have been mounted in the first place */ ret = umount2("/sys", MNT_DETACH); if (ret < 0 && errno != EINVAL) { SYSERROR("failed to unmount /sys"); return -1; } else if (ret == 0) { /* remount it */ ret = mount("none", "/sys", "sysfs", 0, NULL); if (ret < 0) { SYSERROR("failed to remount /sys"); return -1; } } return 0; }
int unlink_fundamental_devices(const char* chroot_path) { unlink_fundamental_device(chroot_path,"/dev/null"); unlink_fundamental_device(chroot_path,"/dev/zero"); unlink_fundamental_device(chroot_path,"/dev/random"); unlink_fundamental_device(chroot_path,"/dev/urandom"); // unmount /dev/shm for linux only #ifdef __linux__ char *fullpath = (char *) malloc(strlen(chroot_path) + strlen("/dev/shm") + 1); sprintf(fullpath, "%s/dev/shm", chroot_path); if (umount2(fullpath, MNT_FORCE) < 0) { fprintf(stderr, "Could not unmount %s (%s). Aborting.\n", fullpath, strerror(errno)); exit(ERR_EXIT_CODE); } if (rmdir(fullpath) < 0) { fprintf(stderr, "Could not rmdir %s (%s). Aborting.\n", fullpath, strerror(errno)); exit(ERR_EXIT_CODE); } free(fullpath); #endif return 0; }
int create_fundamental_devices(const char* chroot_path) { // we need to let the devices be created with the appropriate // modes. However, since the file will be group-owned by // the user creating the device, we make sure the umask prevent // the user from having any permission granted just by the group. mode_t original_mask = umask(0070); create_fundamental_device(chroot_path,"/dev/null"); create_fundamental_device(chroot_path,"/dev/zero"); create_fundamental_device(chroot_path,"/dev/random"); create_fundamental_device(chroot_path,"/dev/urandom"); // add a mount for /dev/shm for linux only #ifdef __linux__ char *fullpath = (char *) malloc(strlen(chroot_path) + strlen("/dev/shm") + 1); sprintf(fullpath, "%s/dev/shm", chroot_path); struct stat statbuf; mode_t perms = (0777 | S_ISVTX); // clean up from a previous run and set up for this one umount2(fullpath, MNT_FORCE); rmdir(fullpath); mkdir(fullpath, perms); if (chown(fullpath, 0, 0) < 0) { fprintf(stderr, "Could not chown %s to root. Aborting.\n", fullpath); exit(ERR_EXIT_CODE); } if (chmod(fullpath, perms) < 0) { fprintf(stderr, "Could not chmod %s to 777+sticky. Aborting.\n", fullpath); exit(ERR_EXIT_CODE); } if (stat(fullpath, &statbuf) < 0) { fprintf(stderr, "Could not stat %s. Aborting.\n", fullpath); exit(ERR_EXIT_CODE); } if (!S_ISDIR(statbuf.st_mode)) { fprintf(stderr, "%s not a directory. Aborting.\n", fullpath); exit(ERR_EXIT_CODE); } if ((statbuf.st_mode & perms) != perms) { fprintf(stderr, "Wrong perms on %s. Aborting.\n", fullpath); exit(ERR_EXIT_CODE); } if (mount("tmpfs", fullpath, "tmpfs", MS_MGC_VAL, "size=128m") < 0) { fprintf(stderr, "Could not mount %s. Aborting.\n", fullpath); exit(ERR_EXIT_CODE); } free(fullpath); #endif umask(original_mask); return 0; }
void UndoBindMounts(char *DirList, int Flags) { char *UmountList=NULL, *Token=NULL, *Tempstr=NULL, *ptr, *dptr; //Reverse dir list so we unmount in reverse order //to the mounts ptr=GetToken(DirList,",",&Token,0); while (ptr) { dptr=Token; Tempstr=MCopyStr(Tempstr,dptr,",",UmountList,NULL); UmountList=CopyStr(UmountList,Tempstr); ptr=GetToken(ptr,",",&Token,0); } ptr=GetToken(UmountList,",",&Token,0); while (ptr) { dptr=strrchr(Token,':'); if (dptr) dptr++; else dptr=Token; while (*dptr=='/') dptr++; umount2(dptr, MNT_DETACH); RmDirPath(dptr); ptr=GetToken(ptr,",",&Token,0); } DestroyString(Token); }
int CNFSSmallMenu::exec( CMenuTarget* parent, const std::string & actionKey ) { if (actionKey.empty()) { CMenuWidget menu(LOCALE_NETWORKMENU_MOUNT, NEUTRINO_ICON_STREAMING); CNFSMountGui mountGui; CNFSUmountGui umountGui; CMenuForwarder *remount_fwd = new CMenuForwarder(LOCALE_NFS_REMOUNT, true, NULL, this, "remount"); remount_fwd->setItemButton(NEUTRINO_ICON_BUTTON_OKAY, true); menu.addIntroItems(); menu.addItem(remount_fwd); menu.addItem(new CMenuForwarder(LOCALE_NFS_MOUNT , true, NULL, & mountGui)); menu.addItem(new CMenuForwarder(LOCALE_NFS_UMOUNT, true, NULL, &umountGui)); return menu.exec(parent, actionKey); } else if(actionKey.substr(0,7) == "remount") { //umount automount dirs for(int i = 0; i < NETWORK_NFS_NR_OF_ENTRIES; i++) { if(g_settings.network_nfs_automount[i]) umount2(g_settings.network_nfs_local_dir[i],MNT_FORCE); } CFSMounter::automount(); return menu_return::RETURN_REPAINT; } return menu_return::RETURN_REPAINT; }
static int do_unmount(const char* mountpoint, int flags) { #if defined(__linux__) || defined(__sun__) return umount2(mountpoint, flags); #else return unmount(mountpoint, flags); #endif }
void sc_do_umount(const char *target, int flags) { char buf[10000] = { 0 }; const char *umount_cmd = NULL; if (sc_is_debug_enabled()) { #ifdef SNAP_CONFINE_DEBUG_BUILD umount_cmd = sc_umount_cmd(buf, sizeof(buf), target, flags); #else umount_cmd = use_debug_build; #endif debug("performing operation: %s", umount_cmd); } if (sc_faulty("umount", NULL) || umount2(target, flags) < 0) { // Save errno as ensure can clobber it. int saved_errno = errno; // Drop privileges so that we can compute our nice error message // without risking an attack on one of the string functions there. sc_privs_drop(); // Compute the equivalent umount command. umount_cmd = sc_umount_cmd(buf, sizeof(buf), target, flags); // Restore errno and die. errno = saved_errno; die("cannot perform operation: %s", umount_cmd); } }
static int umount_and_exec(char **argv) { char *mountpoint = argv[0]; char *cmd = argv[1]; if (unshare(CLONE_NEWNS) == -1) { if(!(flags&QUIET)) fprintf(stderr, "Cannot unshare(CLONE_NEWNS): %s (errno: %i)\n", strerror(errno), errno); return errno; } if(mountpoint == NULL) return EINVAL; if(umount2(mountpoint, MNT_DETACH)) { if(!(flags&QUIET)) fprintf(stderr, "Cannot umount2(\"%s\", MNT_DETACH) in the new namespace: %s (errno: %i)\n", mountpoint, strerror(errno), errno); return errno; } if(cmd == NULL) { char *argv_exec[2] = { NULL }; cmd = getenv("SHELL"); argv_exec[1] = cmd; return my_execvp(cmd, argv_exec); } char **argv_exec = &argv[1]; return my_execvp(cmd, argv_exec); }
int umount_if_needed(char *sourcedir) { FILE *fp; char line[PATH_MAX]; char *dev = NULL; char *realdir; int i; realdir = g_strdup_printf("%s/%s", TARGETDIR, sourcedir); if ((fp = fopen("/proc/mounts", "r")) == NULL) { perror(_("Could not open output file for writing")); return(1); } while(!feof(fp)) { if(fgets(line, PATH_MAX, fp) == NULL) break; if(strstr(line, realdir)) { for(i=0;i<strlen(line);i++) if(line[i]==' ') line[i]='\0'; dev = strdup(line); } } fclose(fp); if(dev != NULL) return (umount2(dev,0)); return(0); }
int main(int argc, char **argv) { int fd, ret = 1; char buf[1024], fname[PATH_MAX]; test_init(argc, argv); mkdir(dirname, 0700); if (mount("none", dirname, "tmpfs", MS_RDONLY, "") < 0) { fail("Can't mount tmpfs"); return 1; } snprintf(fname, sizeof(buf), "%s/test.file", dirname); test_daemon(); test_waitsig(); fd = open(fname, O_RDWR | O_CREAT, 0777); if (fd >= 0 || errno != EROFS) { pr_perror("open failed -> %d", fd); goto err; } pass(); ret = 0; err: umount2(dirname, MNT_DETACH); rmdir(dirname); return ret; }
int __pumount(char *mntdir, int mntflags, char *looped_file) { int my_mntflags = 0; if ((mntflags & PUMOUNT_FORCE) != 0) my_mntflags |= MNT_FORCE; if (umount2(mntdir, my_mntflags) == -1) return -1; #ifdef USE_LOOP if (looped_file != NULL) { verbose("%s: pumount claims the loop is %s\n", __func__, looped_file); if (__clrloop(looped_file) == -1) return -1; } else { verbose("%s: pumount claims there is no such loop.\n", __func__); } #endif errno = 0; return 0; }
void stop_jffs2(int stop) { struct statfs sf; #if defined(RTCONFIG_PSISTLOG) || defined(RTCONFIG_JFFS2LOG) int restart_syslogd = 0; #endif if (!wait_action_idle(10)) return; if ((statfs("/jffs", &sf) == 0) && (sf.f_type != 0x73717368) && (sf.f_type != 0x71736873)) { // is mounted run_userfile("/jffs", ".autostop", "/jffs", 5); run_nvscript("script_autostop", "/jffs", 5); } #if defined(RTCONFIG_PSISTLOG) || defined(RTCONFIG_JFFS2LOG) if (!stop && !strncmp(get_syslog_fname(0), "/jffs/", 6)) { restart_syslogd = 1; stop_syslogd(); eval("cp", "/jffs/syslog.log", "/jffs/syslog.log-1", "/tmp"); } #endif notice_set("jffs", "Stopped"); if (umount("/jffs")) umount2("/jffs", MNT_DETACH); else modprobe_r(JFFS_NAME); #if defined(RTCONFIG_PSISTLOG) || defined(RTCONFIG_JFFS2LOG) if (restart_syslogd) start_syslogd(); #endif }
static void term_handler (int sig) { int ret = 0; if (unlink (TMPFS_PATH "/kmsg") < 0) ret = 1; if (umount2 (PROC_PATH, MNT_DETACH) < 0) ret = 1; if (umount2 (TMPFS_PATH, MNT_DETACH) < 0) ret = 1; _exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }
static void container_unmount_oldroot(char *path) { FILE *mtab; struct mntent *mnt; char *mntlist[128]; int i; int n = 0; char *filesys; mtab = setmntent("/proc/mounts", "r"); if (mtab == NULL) { fprintf(stderr, "cannot open /proc/mount"); return; } while (n < 128 && (mnt = getmntent(mtab))) { if (strncmp(mnt->mnt_dir, path, strlen(path))) continue; mntlist[n++] = strdup(mnt->mnt_dir); } endmntent(mtab); for (i = n - 1; i >= 0; i--) { filesys = mntlist[i]; fprintf(stdout, "umount %s\n", filesys); if (umount(mntlist[i]) < 0 && umount2(mntlist[i], MNT_DETACH) < 0) { fprintf(stdout, "umount %s: %s failed\n", filesys, strerror(errno)); } } }
/** * This function is called whenever the process wants to override it's default resolv.conf with a custom one. * @param[in] A new resolv.conf file to override the existing resolv.conf in this process * @return 0 if success * @return errno if failed */ int rwnetns_mount_bind_resolv_conf(const char *new_resolv_conf_path) { int fd = open(new_resolv_conf_path, O_RDONLY, 0); int ret = 0; if (fd < 0) { return errno; } close(fd); // Make sure any future mounts do not affect any other process. if (unshare(CLONE_NEWNS) < 0) { return errno; } // Make sure the resolv.conf mount does not propogate upwards if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL) < 0) { return errno; } if (mount(new_resolv_conf_path, RESOLV_CONF_PATH, "none", MS_BIND, NULL) < 0) { ret = errno; umount2(RESOLV_CONF_PATH, MNT_DETACH); return ret; } return 0; }
static int netns_exec(int argc, char **argv) { /* Setup the proper environment for apps that are not netns * aware, and execute a program in that environment. */ const char *name, *cmd; char net_path[MAXPATHLEN]; int netns; if (argc < 1) { fprintf(stderr, "No netns name specified\n"); return EXIT_FAILURE; } if (argc < 2) { fprintf(stderr, "No command specified\n"); return EXIT_FAILURE; } name = argv[0]; cmd = argv[1]; snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name); netns = open(net_path, O_RDONLY); if (netns < 0) { fprintf(stderr, "Cannot open network namespace \"%s\": %s\n", name, strerror(errno)); return EXIT_FAILURE; } if (setns(netns, CLONE_NEWNET) < 0) { fprintf(stderr, "seting the network namespace \"%s\" failed: %s\n", name, strerror(errno)); return EXIT_FAILURE; } if (unshare(CLONE_NEWNS) < 0) { fprintf(stderr, "unshare failed: %s\n", strerror(errno)); return EXIT_FAILURE; } /* Don't let any mounts propogate back to the parent */ if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) { fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n", strerror(errno)); return EXIT_FAILURE; } /* Mount a version of /sys that describes the network namespace */ if (umount2("/sys", MNT_DETACH) < 0) { fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno)); return EXIT_FAILURE; } if (mount(name, "/sys", "sysfs", 0, NULL) < 0) { fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno)); return EXIT_FAILURE; } /* Setup bind mounts for config files in /etc */ bind_etc(name); if (execvp(cmd, argv + 1) < 0) fprintf(stderr, "exec of \"%s\" failed: %s\n", cmd, strerror(errno)); return EXIT_FAILURE; }
static int fuse_setup(struct fuse* fuse, gid_t gid, mode_t mask) { char opts[256]; fuse->fd = TEMP_FAILURE_RETRY(open("/dev/fuse", O_RDWR | O_CLOEXEC)); if (fuse->fd == -1) { PLOG(ERROR) << "failed to open fuse device"; return -1; } umount2(fuse->dest_path, MNT_DETACH); snprintf(opts, sizeof(opts), "fd=%i,rootmode=40000,default_permissions,allow_other,user_id=%d,group_id=%d", fuse->fd, fuse->global->uid, fuse->global->gid); if (mount("/dev/fuse", fuse->dest_path, "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts) == -1) { PLOG(ERROR) << "failed to mount fuse filesystem"; return -1; } fuse->gid = gid; fuse->mask = mask; return 0; }
static void unmount_and_fsck(const struct mntent *entry) { if (strcmp(entry->mnt_type, "f2fs") && strcmp(entry->mnt_type, "ext4")) return; /* First, lazily unmount the directory. This unmount request finishes when * all processes that open a file or directory in |entry->mnt_dir| exit. */ TEMP_FAILURE_RETRY(umount2(entry->mnt_dir, MNT_DETACH)); /* Next, kill all processes except init, kthreadd, and kthreadd's * children to finish the lazy unmount. Killing all processes here is okay * because this callback function is only called right before reboot(). * It might be cleaner to selectively kill processes that actually use * |entry->mnt_dir| rather than killing all, probably by reusing a function * like killProcessesWithOpenFiles() in vold/, but the selinux policy does * not allow init to scan /proc/<pid> files which the utility function * heavily relies on. The policy does not allow the process to execute * killall/pkill binaries either. Note that some processes might * automatically restart after kill(), but that is not really a problem * because |entry->mnt_dir| is no longer visible to such new processes. */ ServiceManager::GetInstance().ForEachService([] (Service* s) { s->Stop(); }); TEMP_FAILURE_RETRY(kill(-1, SIGKILL)); int count = 0; while (count++ < UNMOUNT_CHECK_TIMES) { int fd = TEMP_FAILURE_RETRY(open(entry->mnt_fsname, O_RDONLY | O_EXCL)); if (fd >= 0) { /* |entry->mnt_dir| has sucessfully been unmounted. */ close(fd); break; } else if (errno == EBUSY) { /* Some processes using |entry->mnt_dir| are still alive. Wait for a * while then retry. */ TEMP_FAILURE_RETRY( usleep(UNMOUNT_CHECK_MS * 1000 / UNMOUNT_CHECK_TIMES)); continue; } else { /* Cannot open the device. Give up. */ return; } } int st; if (!strcmp(entry->mnt_type, "f2fs")) { const char *f2fs_argv[] = { "/system/bin/fsck.f2fs", "-f", entry->mnt_fsname, }; android_fork_execvp_ext(ARRAY_SIZE(f2fs_argv), (char **)f2fs_argv, &st, true, LOG_KLOG, true, NULL, NULL, 0); } else if (!strcmp(entry->mnt_type, "ext4")) { const char *ext4_argv[] = { "/system/bin/e2fsck", "-f", "-y", entry->mnt_fsname, }; android_fork_execvp_ext(ARRAY_SIZE(ext4_argv), (char **)ext4_argv, &st, true, LOG_KLOG, true, NULL, NULL, 0); } }
int generic_umount(char *mntbuf) { if (!mntbuf) { errprintf("invalid param: mntbuf is null\n"); return -1; } msgprintf(MSG_DEBUG1, "unmount_partition(%s)\n", mntbuf); return umount2(mntbuf, 0); }
static bool umount_if_mounted(void) { if (umount2(basedir, MNT_DETACH) < 0 && errno != EINVAL) { fprintf(stderr, "failed to umount %s: %s\n", basedir, strerror(errno)); return false; } return true; }
static int do_unmount(const char *mnt, int quiet, int lazy) { int res = umount2(mnt, lazy ? 2 : 0); if (res == -1) { if (!quiet) fprintf(stderr, "%s: failed to unmount %s: %s\n", progname, mnt, strerror(errno)); } return res; }
int ui_umount(const char * mnt) { int rc; if((rc = umount2(mnt, MNT_DETACH)) != 0) { fprintf(stderr, "Failed to unmount %s.\n", mnt); fprintf(stderr, "Error (%d) %s\n", errno, strerror(errno)); } return rc; }
static int netns_exec(int argc, char **argv) { /* Setup the proper environment for apps that are not netns * aware, and execute a program in that environment. */ const char *name, *cmd; char net_path[MAXPATHLEN]; int netns; if (argc < 1) { fprintf(stderr, "No netns name specified\n"); return -1; } if (argc < 2) { fprintf(stderr, "No cmd specified\n"); return -1; } name = argv[0]; cmd = argv[1]; snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name); netns = open(net_path, O_RDONLY); if (netns < 0) { fprintf(stderr, "Cannot open network namespace: %s\n", strerror(errno)); return -1; } if (setns(netns, CLONE_NEWNET) < 0) { fprintf(stderr, "seting the network namespace failed: %s\n", strerror(errno)); return -1; } /* if (unshare(CLONE_NEWNS) < 0) { fprintf(stderr, "unshare failed: %s\n", strerror(errno)); return -1; } */ /* Mount a version of /sys that describes the network namespace */ if (umount2("/sys", MNT_DETACH) < 0) { fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno)); return -1; } if (mount(name, "/sys", "sysfs", 0, NULL) < 0) { fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno)); return -1; } /* Setup bind mounts for config files in /etc */ bind_etc(name); if (execvp(cmd, argv + 1) < 0) fprintf(stderr, "exec of %s failed: %s\n", cmd, strerror(errno)); exit(-1); }
int lxc_attach_remount_sys_proc() { int ret; ret = unshare(CLONE_NEWNS); if (ret < 0) { SYSERROR("failed to unshare mount namespace"); return -1; } /* assume /proc is always mounted, so remount it */ ret = umount2("/proc", MNT_DETACH); if (ret < 0) { SYSERROR("failed to unmount /proc"); return -1; } ret = mount("none", "/proc", "proc", 0, NULL); if (ret < 0) { SYSERROR("failed to remount /proc"); return -1; } /* try to umount /sys - if it's not a mount point, * we'll get EINVAL, then we ignore it because it * may not have been mounted in the first place */ ret = umount2("/sys", MNT_DETACH); if (ret < 0 && errno != EINVAL) { SYSERROR("failed to unmount /sys"); return -1; } else if (ret == 0) { /* remount it */ ret = mount("none", "/sys", "sysfs", 0, NULL); if (ret < 0) { SYSERROR("failed to remount /sys"); return -1; } } return 0; }