static int do_swapon(const char *orig_special, int prio, int canonic) { int status; const char *special = orig_special; int flags = 0; if (verbose) printf(_("%s on %s\n"), progname, orig_special); if (!canonic) { special = fsprobe_get_devname_by_spec(orig_special); if (!special) return cannot_find(orig_special); } if (swapon_checks(special)) return -1; #ifdef SWAP_FLAG_PREFER if (prio >= 0) { if (prio > SWAP_FLAG_PRIO_MASK) prio = SWAP_FLAG_PRIO_MASK; flags = SWAP_FLAG_PREFER | ((prio & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT); } #endif status = swapon(special, flags); if (status < 0) warn(_("%s: swapon failed"), orig_special); return status; }
const char * spec_to_devname(const char *spec) { if (!spec) return NULL; if (nocanonicalize || is_pseudo_fs(spec)) return xstrdup(spec); return fsprobe_get_devname_by_spec(spec); }
static int swapon_all(void) { FILE *fp; struct mntent *fstab; int status = 0; read_proc_swaps(); fp = setmntent(_PATH_MNTTAB, "r"); if (fp == NULL) err(2, _("%s: open failed"), _PATH_MNTTAB); while ((fstab = getmntent(fp)) != NULL) { const char *special; int skip = 0, nofail = ifexists; int pri = priority, dsc = discard; char *opt, *opts; if (!streq(fstab->mnt_type, MNTTYPE_SWAP)) continue; opts = strdup(fstab->mnt_opts); for (opt = strtok(opts, ","); opt != NULL; opt = strtok(NULL, ",")) { if (strncmp(opt, "pri=", 4) == 0) pri = atoi(opt+4); if (strcmp(opt, "discard") == 0) dsc = 1; if (strcmp(opt, "noauto") == 0) skip = 1; if (strcmp(opt, "nofail") == 0) nofail = 1; } free(opts); if (skip) continue; special = fsprobe_get_devname_by_spec(fstab->mnt_fsname); if (!special) { if (!nofail) status |= cannot_find(fstab->mnt_fsname); continue; } if (!is_in_proc_swaps(special) && (!nofail || !access(special, R_OK))) status |= do_swapon(special, pri, dsc, CANONIC); free((void *) special); } fclose(fp); return status; }
static int do_swapoff(const char *orig_special, int quiet, int canonic) { const char *special = orig_special; if (verbose) printf(_("%s on %s\n"), progname, orig_special); if (!canonic) { special = fsprobe_get_devname_by_spec(orig_special); if (!special) return cannot_find(orig_special); } if (swapoff(special) == 0) return 0; /* success */ if (errno == EPERM) errx(EXIT_FAILURE, _("Not superuser.")); if (!quiet || errno == ENOMEM) warn(_("%s: swapoff failed"), orig_special); return -1; }
int main(int argc, char **argv, char **envp) { int fd_stdin=-1, fd_stdout=-1; pid_t pid; int guess = 0; /* char *argv[] = { "/sbin/init", NULL }; char *envp[] = { "PATH=/bin:/sbin:/usr/bin:/usr/sbin", NULL }; */ char *rootdev = NULL; open_console(); /* create mountpoints /dev and /proc /rootfs */ mkmountpoint("/dev"); mkmountpoint("/proc"); mkmountpoint("/rootfs"); open_console(); /* make sure /dev is mounted */ if(mount("devtmpfs", "/dev", "devtmpfs", 0, "")) { if(fstdout) { if(fstdout) { fprintf(fstdout, "INIT: could not mount devtmpfs on /dev: %s\n", strerror(errno)); fprintf(fstdout, "INIT: waiting 10 seconds ..\n"); sleep(5); sleep(5); } } } open_console(); /* mount /proc */ if(mount("proc", "/proc", "proc", 0, "")) { if(fstdout) { fprintf(fstdout, "INIT: could not mount proc on /proc: %s\n", strerror(errno)); fprintf(fstdout, "INIT: waiting 10 seconds ..\n"); sleep(5); sleep(5); } } rootdev = fsprobe_get_devname_by_spec(ROOTFSLABEL); if(!rootdev) { if(fstdout) { fprintf(fstdout, "INIT: could not find rootdevice\n"); fprintf(fstdout, "INIT: waiting 10 seconds ..\n"); sleep(5); sleep(5); fprintf(fstdout, "INIT: guessing that rootdev is /dev/sda1\n\n"); } rootdev="/dev/sda1"; guess = 1; } else { if(fstdout) fprintf(fstdout, "INIT: probed rootdev is %s\n", rootdev); } sleep(1); /* e2fsck -y rootdev */ /* fork + exec("/e2fsck", "/e2fsck"-y", rootdev) */ if(!guess) { if((pid=fork())==0) { execl("/e2fsck", "/e2fsck", "-y", rootdev, NULL); exit(0); } if(pid != -1) wait(NULL); } /* unlink /e2sck to save some memory */ if(unlink("/e2fsck")) { fprintf(fstdout, "INIT: unlink(\"/e2fsck\") failed: %s\n", strerror(errno)); } /* mount /rootfs, try ext4, ext3, ext2 */ if(mount(rootdev, "/rootfs", "ext4", MS_NOATIME, "")) { if(mount(rootdev, "/rootfs", "ext3", MS_NOATIME, "")) { if(mount(rootdev, "/rootfs", "ext2", MS_NOATIME, "")) { if(fstdout) fprintf(fstdout, "INIT: failed to mount %s: %s\n", rootdev, strerror(errno)); goto forever; } } } if(fstdout) fprintf(fstdout, "INIT: %s mounted.\n", rootdev); sleep(1); if (mount("/dev", "/rootfs/dev", NULL, MS_MOVE, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to mount moving /dev to /rootfs/dev"); sleep(1); } if (mount("/proc", "/rootfs/proc", NULL, MS_MOVE, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to mount moving /proc to /rootfs/proc"); sleep(1); } if(chdir("/rootfs")) { if(fstdout) fprintf(fstdout, "INIT: chdir(\"/rootfs\") failed: %s\n", strerror(errno)); goto forever; } if (mount("/rootfs", "/", NULL, MS_MOVE, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to mount moving /rootfs to /"); goto forever; } /* Now, the init process may still access the old root via its executable, shared libraries, standard input/output/error, and its current root directory. All these references are dropped by the following command: # exec chroot . /sbin/init <dev/console >dev/console 2>&1 */ if(chroot(".")) { if(fstdout) { fprintf(fstdout, "INIT: chroot(\".\") failed: %s\n", strerror(errno)); sleep(5); sleep(5); } } fd_stdin = open("/dev/console", O_RDONLY|O_NOCTTY); if(fd_stdin == -1) { if(fstdout) fprintf(fstdout, "INIT: open(\"/dev/console\", O_RDONLY) failed: %s\n", strerror(errno)); } else { if(fd_stdin != 0) { dup2(fd_stdin, 0); close(fd_stdin); } } fd_stdout = open("/dev/console", O_WRONLY|O_NOCTTY); if(fd_stdout == -1) { if(fstdout) fprintf(fstdout, "INIT: open(\"/dev/console\", O_WRONLY) failed: %s\n", strerror(errno)); } else { if(fd_stdout != 1) { dup2(fd_stdout, 1); dup2(fd_stdout, 2); close(fd_stdout); } } if(fstdout) fprintf(fstdout, "INIT: now execing \"/sbin/init\"\n"); sleep(1); if(fstdout) { fclose(fstdout); fstdout = NULL; } argv[0] = "/sbin/init"; execve("/sbin/init", argv, envp); open_console(); if(fstdout) { fprintf(fstdout, "INIT: execve(\"/sbin/init\") failed: %s\n", strerror(errno)); } forever: if(fstdout) { fprintf(fstdout, "INIT: pid is %u", getpid()); fprintf(fstdout, "INIT: boot cannot proceed from here.\n"); fprintf(fstdout, "INIT: turn off the computer.\n"); } while(1) sleep(1000); return 2; }
static int main_swapoff(int argc, char *argv[]) { FILE *fp; struct mntent *fstab; int status = 0; int c, i; while ((c = getopt_long(argc, argv, "ahvVL:U:", longswapoffopts, NULL)) != -1) { switch (c) { case 'a': /* all */ ++all; break; case 'h': /* help */ swapoff_usage(stdout, 0); break; case 'v': /* be chatty */ ++verbose; break; case 'V': /* version */ printf(_("%s (%s)\n"), progname, PACKAGE_STRING); exit(EXIT_SUCCESS); case 'L': addl(optarg); break; case 'U': addu(optarg); break; case 0: break; case '?': default: swapoff_usage(stderr, 1); } } argv += optind; if (!all && !llct && !ulct && *argv == NULL) swapoff_usage(stderr, 2); /* * swapoff any explicitly given arguments. * Complain in case the swapoff call fails. */ for (i = 0; i < llct; i++) status |= swapoff_by_label(llist[i], !QUIET); for (i = 0; i < ulct; i++) status |= swapoff_by_uuid(ulist[i], !QUIET); while (*argv != NULL) status |= do_swapoff(*argv++, !QUIET, !CANONIC); if (all) { /* * In case /proc/swaps exists, unswap stuff listed there. * We are quiet but report errors in status. * Errors might mean that /proc/swaps * exists as ordinary file, not in procfs. * do_swapoff() exits immediately on EPERM. */ read_proc_swaps(); for(i=0; i<numSwaps; i++) status |= do_swapoff(swapFiles[i], QUIET, CANONIC); /* * Unswap stuff mentioned in /etc/fstab. * Probably it was unmounted already, so errors are not bad. * Doing swapoff -a twice should not give error messages. */ fp = setmntent(_PATH_MNTTAB, "r"); if (fp == NULL) err(2, _("%s: open failed"), _PATH_MNTTAB); while ((fstab = getmntent(fp)) != NULL) { const char *special; if (!streq(fstab->mnt_type, MNTTYPE_SWAP)) continue; special = fsprobe_get_devname_by_spec(fstab->mnt_fsname); if (!special) continue; if (!is_in_proc_swaps(special)) do_swapoff(special, QUIET, CANONIC); } fclose(fp); } return status; }
int main(int argc, char **argv, char **envp) { int fd_stdin=-1, fd_stdout=-1; pid_t pid; int retries = 0; int rootmounted = 0; char *rootdev = NULL; char *rootfstype = "unknown"; char *rootfslabel = ROOTFSLABEL; char *initprg = "/sbin/init"; conf.mountflags = MS_SYNCHRONOUS; open_console(); /* create mountpoints /dev and /proc /rootfs */ mkmountpoint("/dev"); mkmountpoint("/proc"); mkmountpoint("/rootfs"); open_console(); /* make sure /dev is mounted */ if(mount("devtmpfs", "/dev", "devtmpfs", 0, "")) { if(fstdout) { if(fstdout) { fprintf(fstdout, "INIT: could not mount devtmpfs on /dev: %s\n", strerror(errno)); fprintf(fstdout, "INIT: waiting 10 seconds ..\n"); sleep(5); sleep(5); } } } open_console(); /* mount /proc */ if(mount("proc", "/proc", "proc", 0, "")) { if(fstdout) { fprintf(fstdout, "INIT: could not mount proc on /proc: %s\n", strerror(errno)); fprintf(fstdout, "INIT: waiting 10 seconds ..\n"); sleep(5); sleep(5); } } /* parse kernel commandline options */ cmdline.autoresize = 1; cmdline_parse(); if(cmdline.init) { initprg = cmdline.init; } if(cmdline.async) { conf.mountflags ^= MS_SYNCHRONOUS; } if(cmdline.usbreset) { usbreset(); sleep(1); } if(cmdline.rootdelay > 0) { if(fstdout) fprintf(fstdout, "INIT: rootdelay, waiting %d seconds\n", cmdline.rootdelay); sleep(cmdline.rootdelay); } if(cmdline.rootdev) { struct stat statb; if(fstdout) fprintf(fstdout, "INIT: rootdev %s given on commandline\n", cmdline.rootdev); rootdev = cmdline.rootdev; if(stat(rootdev, &statb)) { if(fstdout) fprintf(fstdout, "INIT: rootdev %s not found!\n", rootdev); rootdev = NULL; } } if(!rootdev) { if(cmdline.rootfslabel) { if(strncmp(cmdline.rootfslabel, "LABEL=", 6)) { rootfslabel = malloc(strlen("LABEL=") + strlen(cmdline.rootfslabel) + 1); strcpy(rootfslabel, "LABEL="); strcat(rootfslabel, cmdline.rootfslabel); } else { rootfslabel = cmdline.rootfslabel; } } if(fstdout) fprintf(fstdout, "INIT: probing for rootdev labeled '%s'\n", rootfslabel); fsprobe_init(); while( (rootdev = fsprobe_get_devname_by_spec(rootfslabel)) == NULL ) { retries++; if(retries == 15) usbreset(); if(retries > 25) break; if(fstdout) fprintf(fstdout, "INIT: waiting for rootdevice to be available\n"); sleep(2); fsprobe_init(); } } if(!rootdev) { if(fstdout) { fprintf(fstdout, "INIT: could not find rootdevice\n"); listdevices(); fprintf(fstdout, "INIT: waiting 10 seconds ..\n"); sleep(5); sleep(5); fprintf(fstdout, "INIT: guessing that rootdev is /dev/sda1\n\n"); } rootdev="/dev/sda1"; } else { if(fstdout) fprintf(fstdout, "INIT: using rootdev %s\n", rootdev); } sleep(1); /* if filesystem is of the ext family */ if((!cmdline.rootfstype) || (!strncmp(cmdline.rootfstype, "ext", 3))) { int status = 0; int fsckok = 0; /* e2fsck -y rootdev */ /* fork + exec("/e2fsck", "/e2fsck"-y", rootdev) */ if((pid=fork())==0) { execl("/e2fsck", "/e2fsck", "-y", rootdev, NULL); exit(0); } if(pid != -1) { wait(&status); if(WIFEXITED(status)) { fprintf(fstdout, "INIT: e2fsck exited normally with exit code: %d\n", WEXITSTATUS(status)); if(WEXITSTATUS(status)==0) fsckok=1; } else { fprintf(fstdout, "INIT: e2fsck exited abnormally\n"); } } if(fsckok) { if(cmdline.autoresize) { sync(); if((pid=fork())==0) { execl("/resize2fs", "/resize2fs", "-f", rootdev, NULL); exit(0); } if(pid != -1) wait(NULL); sync(); } } } /* unlink /e2sck and /resize2fs to save some memory */ if(unlink("/e2fsck")) { fprintf(fstdout, "INIT: unlink(\"/e2fsck\") failed: %s\n", strerror(errno)); } if(unlink("/resize2fs")) { fprintf(fstdout, "INIT: unlink(\"/resize2fs\") failed: %s\n", strerror(errno)); } if(cmdline.rootfstype) { /* mount /rootfs, try fstype supplied on kernel commandline */ if(mount(rootdev, "/rootfs", cmdline.rootfstype, MS_NOATIME|MS_RDONLY|conf.mountflags, "")) { if(fstdout) fprintf(fstdout, "INIT: failed to mount (%s) %s: %s\n", cmdline.rootfstype, rootdev, strerror(errno)); } else { rootmounted = 1; rootfstype = cmdline.rootfstype; } } if(!rootmounted) { /* mount /rootfs, try ext2 */ if(mount(rootdev, "/rootfs", "ext2", MS_NOATIME|MS_RDONLY|conf.mountflags, "")) { if(fstdout) fprintf(fstdout, "INIT: failed to mount (ext2) %s: %s\n", rootdev, strerror(errno)); goto forever; } rootfstype = "ext2"; } if(fstdout) fprintf(fstdout, "INIT: (%s) %s mounted.\n", rootfstype, rootdev); sleep(1); if(cmdline.install) { if(fstdout) { fprintf(fstdout, "INIT: INSTALL INVOKED!\nINSTALL: PROCEEDING IN 5 SECONDS!\n"); sleep(5); } /* unpack install archive in initramfs root */ { int fd; fd = open("/rootfs/install.tar", O_RDONLY); if(fd == -1) { if(fstdout) fprintf(fstdout, "INSTALL: failed to open '/rootfs/install.tar'\n"); } else { if(fstdout) fprintf(fstdout, "INSTALL: '/rootfs/install.tar' opened ok\n"); tar_extract(fd); close(fd); } } /* Be nice and prepare stdin and stdout for the install program */ fd_stdin = open("/dev/console", O_RDONLY|O_NOCTTY); if(fd_stdin == -1) { if(fstdout) fprintf(fstdout, "INSTALL: open(\"/dev/console\", O_RDONLY) failed: %s\n", strerror(errno)); } else { if(fd_stdin != 0) { dup2(fd_stdin, 0); close(fd_stdin); } } fd_stdout = open("/dev/console", O_WRONLY|O_NOCTTY); if(fd_stdout == -1) { if(fstdout) fprintf(fstdout, "INSTALL: open(\"/dev/console\", O_WRONLY) failed: %s\n", strerror(errno)); } else { if(fd_stdout != 1) { dup2(fd_stdout, 1); dup2(fd_stdout, 2); close(fd_stdout); } } /* exec "/install" */ { char *iv[2]; iv[0] = "/install"; iv[1] = NULL; if(fstdout) fprintf(fstdout, "INSTALL: exec(\"/install\")\n"); execve(iv[0], iv, envp); if(fstdout) fprintf(fstdout, "INSTALL: exec(\"/install\") failed\n"); sleep(10); } } if (mount("/dev", "/rootfs/dev", NULL, MS_MOVE, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to mount moving /dev to /rootfs/dev\n"); sleep(1); } if (mount("/proc", "/rootfs/proc", NULL, MS_MOVE, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to mount moving /proc to /rootfs/proc\n"); sleep(1); } /* * mkdir /sbin * copy /rootfs/sbin/init to /sbin/init * mount --bind /rootfs/sbin/init /sbin/init */ if(mkdir("/sbin", 0755)) { if(fstdout) fprintf(fstdout, "INIT: mkdir(\"/sbin\") failed: %s\n", strerror(errno)); sleep(1); } else { int fd, ofd; ssize_t siz; struct stat statb; if(stat("/rootfs/sbin/init", &statb)) { if(fstdout) fprintf(fstdout, "INIT: stat(\"/rootfs/sbin/init\") failed: %s\n", strerror(errno)); sleep(1); goto noinitcopy; } siz = statb.st_size; if(mount("tmpfs", "/sbin","tmpfs", 0,"")) { if(fstdout) fprintf(fstdout, "INIT: mount(\"tmpfs\", \"/sbin\") failed: %s\n", strerror(errno)); } if( (fd = open("/rootfs/sbin/init", O_RDONLY)) == -1) { if(fstdout) fprintf(fstdout, "INIT: open(\"/rootfs/sbin/init\", O_RDONLY) failed: %s\n", strerror(errno)); sleep(1); goto noinitcopy; } if( (ofd = open("/sbin/init", O_WRONLY|O_CREAT|O_TRUNC, 0755)) == -1) { if(fstdout) fprintf(fstdout, "INIT: open(\"/sbin/init\", O_WRONLY|O_CREAT|O_TRUNC) failed: %s\n", strerror(errno)); sleep(1); close(fd); goto noinitcopy; } if(data(fd, siz, ofd)) { if(fstdout) fprintf(fstdout, "INIT: datacopy of /sbin/init failed: %s\n", strerror(errno)); sleep(1); close(fd); close(ofd); goto noinitcopy; } close(fd); if(close(ofd)) { if(fstdout) fprintf(fstdout, "INIT: close(\"/sbin/init\") failed: %s\n", strerror(errno)); sleep(1); goto noinitcopy; } if (mount("rootfs", "/", NULL, MS_REMOUNT|MS_NOATIME|MS_RDONLY, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to remount initramfs as read-only\n"); sleep(1); } if (mount("tmpfs", "/sbin", NULL, MS_REMOUNT|MS_NOATIME|MS_RDONLY, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to remount \"/sbin\" as read-only\n"); sleep(1); } if(mount("/sbin/init", "/rootfs/sbin/init", "tmpfs", MS_BIND|MS_RDONLY, NULL)) { if(mount("/sbin/init", "/rootfs/sbin/init", "tmpfs", MS_BIND, NULL)) { if(fstdout) fprintf(fstdout, "INIT: bind mount(\"/sbin/init\", \"/rootfs/sbin/init\") failed: %s\n", strerror(errno)); sleep(1); } } } noinitcopy: if(chdir("/rootfs")) { if(fstdout) fprintf(fstdout, "INIT: chdir(\"/rootfs\") failed: %s\n", strerror(errno)); goto forever; } if (mount("/rootfs", "/", NULL, MS_MOVE, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to mount moving /rootfs to /\n"); goto forever; } /* Now, the init process may still access the old root via its executable, shared libraries, standard input/output/error, and its current root directory. All these references are dropped by the following command: # exec chroot . /sbin/init <dev/console >dev/console 2>&1 */ if(chroot(".")) { if(fstdout) { fprintf(fstdout, "INIT: chroot(\".\") failed: %s\n", strerror(errno)); sleep(5); sleep(5); } } /* check if we need to copy default versions of some config files */ { int remounted=0; chk_cfg_file(&remounted, "ssh/ssh_config"); chk_cfg_file(&remounted, "ssh/sshd_config"); chk_cfg_file(&remounted, "inetd.conf"); chk_cfg_file(&remounted, "inittab"); chk_cfg_file(&remounted, "login.defs"); chk_cfg_file(&remounted, "limits"); chk_cfg_file(&remounted, "login.access"); if(remounted) if (mount("rootfs", "/", NULL, MS_REMOUNT|MS_NOATIME|MS_RDONLY|conf.mountflags, NULL) < 0) { if(fstdout) fprintf(fstdout, "INIT: failed to remount rootfs as read-only\n"); sleep(1); } } fd_stdin = open("/dev/console", O_RDONLY|O_NOCTTY); if(fd_stdin == -1) { if(fstdout) fprintf(fstdout, "INIT: open(\"/dev/console\", O_RDONLY) failed: %s\n", strerror(errno)); } else { if(fd_stdin != 0) { dup2(fd_stdin, 0); close(fd_stdin); } } fd_stdout = open("/dev/console", O_WRONLY|O_NOCTTY); if(fd_stdout == -1) { if(fstdout) fprintf(fstdout, "INIT: open(\"/dev/console\", O_WRONLY) failed: %s\n", strerror(errno)); } else { if(fd_stdout != 1) { dup2(fd_stdout, 1); dup2(fd_stdout, 2); close(fd_stdout); } } if(fstdout) fprintf(fstdout, "INIT: now execing \"%s\"\n", initprg); sleep(1); if(fstdout) { fclose(fstdout); fstdout = NULL; } argv[0] = initprg; execve(initprg, argv, envp); open_console(); if(fstdout) { fprintf(fstdout, "INIT: execve(\"%s\") failed: %s\n", initprg, strerror(errno)); } forever: if(fstdout) { fprintf(fstdout, "INIT: pid is %u\n", getpid()); fprintf(fstdout, "INIT: boot cannot proceed from here.\n"); fprintf(fstdout, "INIT: turn off the computer.\n"); } while(1) sleep(1000); return 2; }