X-Git-Url: http://git.ipfire.org/?p=people%2Fpmueller%2Fipfire-2.x.git;a=blobdiff_plain;f=src%2Fdracut%2Fswitch_root.c;fp=src%2Fdracut%2Fswitch_root.c;h=0000000000000000000000000000000000000000;hp=1520387239e1d8d0ac797f57ae08d474be4a7e8d;hb=fd3b60d89e24a60d89cfd9153ceedaac0d959f6c;hpb=a4d36b4a3f3f8cdab5f83c91114091721d9e050b diff --git a/src/dracut/switch_root.c b/src/dracut/switch_root.c deleted file mode 100644 index 1520387239..0000000000 --- a/src/dracut/switch_root.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * switchroot.c - switch to new root directory and start init. - * - * Copyright 2002-2008 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Authors: - * Peter Jones - * Jeremy Katz - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef MS_MOVE -#define MS_MOVE 8192 -#endif - -enum { - ok, - err_no_directory, - err_usage, -}; - -/* remove all files/directories below dirName -- don't cross mountpoints */ -static int -recursiveRemove(char * dirName) -{ - struct stat sb,rb; - DIR * dir; - struct dirent * d; - char * strBuf = alloca(strlen(dirName) + 1024); - - if (!(dir = opendir(dirName))) { - printf("error opening %s: %m\n", dirName); - return 0; - } - - if (fstat(dirfd(dir),&rb)) { - printf("unable to stat %s: %m\n", dirName); - closedir(dir); - return 0; - } - - errno = 0; - - while ((d = readdir(dir))) { - errno = 0; - - if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) { - errno = 0; - continue; - } - - strcpy(strBuf, dirName); - strcat(strBuf, "/"); - strcat(strBuf, d->d_name); - - if (lstat(strBuf, &sb)) { - printf("failed to stat %s: %m\n", strBuf); - errno = 0; - continue; - } - - /* only descend into subdirectories if device is same as dir */ - if (S_ISDIR(sb.st_mode)) { - if (sb.st_dev == rb.st_dev) { - recursiveRemove(strBuf); - if (rmdir(strBuf)) - printf("failed to rmdir %s: %m\n", strBuf); - } - errno = 0; - continue; - } - if (unlink(strBuf)) { - printf("failed to remove %s: %m\n", strBuf); - errno = 0; - continue; - } - } - - if (errno) { - closedir(dir); - printf("error reading from %s: %m\n", dirName); - return 1; - } - - closedir(dir); - return 0; -} - -static int switchroot(const char *newroot) -{ - /* Don't try to unmount the old "/", there's no way to do it. */ - const char *umounts[] = { "/dev", "/proc", "/sys", NULL }; - int errnum; - int i; - - for (i = 0; umounts[i] != NULL; i++) { - char newmount[PATH_MAX]; - strcpy(newmount, newroot); - strcat(newmount, umounts[i]); - if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) { - fprintf(stderr, "Error mount moving old %s %s %m\n", - umounts[i], newmount); - fprintf(stderr, "Forcing unmount of %s\n", umounts[i]); - umount2(umounts[i], MNT_FORCE); - } - } - - if (chdir(newroot) < 0) { - errnum=errno; - fprintf(stderr, "switchroot: chdir failed: %m\n"); - errno=errnum; - return -1; - } - recursiveRemove("/"); - if (mount(newroot, "/", NULL, MS_MOVE, NULL) < 0) { - errnum = errno; - fprintf(stderr, "switchroot: mount failed: %m\n"); - errno = errnum; - return -1; - } - - if (chroot(".")) { - errnum = errno; - fprintf(stderr, "switchroot: chroot failed: %m\n"); - errno = errnum; - return -2; - } - return 1; -} - -static void usage(FILE *output) -{ - fprintf(output, "usage: switchroot \n"); - if (output == stderr) - exit(err_usage); - exit(ok); -} - -int main(int argc, char *argv[]) -{ - char *newroot = argv[1]; - char *init = argv[2]; - char **initargs = &argv[2]; - - if (newroot == NULL || newroot[0] == '\0' || - init == NULL || init[0] == '\0' ) { - usage(stderr); - } - - if (switchroot(newroot) < 0) { - fprintf(stderr, "switchroot has failed. Sorry.\n"); - return 1; - } - if (access(initargs[0], X_OK)) - fprintf(stderr, "WARNING: can't access %s\n", initargs[0]); - - /* get session leader */ - setsid(); - /* set controlling terminal */ - ioctl (0, TIOCSCTTY, 1); - - execv(initargs[0], initargs); -} -