---
LICENSE | 1 +
Makefile | 1 +
switch_root.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++=
++++
3 files changed, 138 insertions(+)
create mode 100644 switch_root.c
diff --git a/LICENSE b/LICENSE
index a1078df..91107e6 100644
--- a/LICENSE
+++ b/LICENSE
_AT_@ -6,6 +6,7 @@ MIT/X Consortium License
=C2=A9 2013 Jakob Kramer <jakob.kramer_AT_gmx.de>
=C2=A9 2014 Carlos J. Torres <vlaadbrain_AT_gmail.com>
=C2=A9 2014 Hiltjo Posthuma <hiltjo_AT_codemadness.org>
+=C2=A9 2014 Laslo Hunhold <dev_AT_frign.de>
=20
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/Makefile b/Makefile
index c139777..0e9d26e 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -45,6 +45,7 @@ SRC =3D \
su.c \
swapoff.c \
swapon.c \
+ switch_root.c \
truncate.c \
umount.c \
unshare.c \
diff --git a/switch_root.c b/switch_root.c
new file mode 100644
index 0000000..cfa37e9
--- /dev/null
+++ b/switch_root.c
_AT_@ -0,0 +1,136 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/magic.h>
+#include <linux/limits.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include "util.h"
+
+static void
+delete_content(const char *dir, dev_t curdevice){
+ char path[PATH_MAX];
+ DIR *d;
+ struct stat st;
+ struct dirent *dent;
+=09
+ /* don't dive into other filesystems */
+ if (lstat(dir, &st) || st.st_dev !=3D curdevice){
+ return;
+ }
+ /* delete contents recursively */
+ if (S_ISDIR(st.st_mode)) {
+ d =3D opendir(dir);
+ if (d) {
+ for(; (dent =3D readdir(d)) ;) {
+ /* skip ".." and "." */
+ if (dent->d_name[0] =3D=3D '.'
+ && ((dent->d_name[1] =3D=3D '.' && dent->d_name[2] =3D=3D 0)
+ || (dent->d_name[1] =3D=3D 0)))
+ {
+ continue;
+ }
+ =09
+ /* build path and dive deeper */
+ strlcat(path, dir, sizeof(path));
+ strlcat(path, dent->d_name, sizeof(path));
+
+ delete_content(path, curdevice);
+ path[0] =3D 0;
+ }
+ closedir(d);
+ =09
+ /* remove now empty dir */
+ rmdir(dir);
+ }
+ } else {
+ /* unlink non-directory */
+ unlink(dir);
+ }
+}
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [-c console] [newroot] [init] (PID 1)\n", argv0);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *console =3D NULL;
+ dev_t curdev;
+ struct stat st;
+ struct statfs stfs;
+
+ ARGBEGIN {
+ case 'c':
+ console =3D EARGF(usage());
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ /* check number of args and if we are PID 1 */
+ if (argc !=3D 2 || getpid() !=3D 1){
+ usage();
+ }
+=09
+ /* chdir to newroot and make sure it's a different fs */
+ if (chdir(argv[0])) {
+ eprintf("chdir %s:", argv[0]);
+ }
+ if (stat("/", &st)) {
+ eprintf("stat %s:", "/");
+ }
+ curdev =3D st.st_dev;
+ if (stat(".", &st)) {
+ eprintf("stat %s:", ".");
+ }
+ if (st.st_dev =3D=3D curdev) {
+ usage();
+ }
+
+ /* further checks */
+ if (stat("/init", &st) || !S_ISREG(st.st_mode)) {
+ /* avoids trouble with real filesystems */
+ eprintf("/init is not a regular file\n");
+ }
+ statfs("/", &stfs);
+ if ((unsigned)stfs.f_type !=3D RAMFS_MAGIC && (unsigned)stfs.f_type !=3D =
TMPFS_MAGIC){
+ eprintf("current filesystem is not a RAMFS or TMPFS\n");
+ }
+=09
+ /* wipe / */
+ delete_content("/", curdev);
+=09
+ /* overmount / with newroot and chroot into it */
+ if (mount(".", "/", NULL, MS_MOVE, NULL)) {
+ eprintf("mount %s:", ".");
+ }
+ if (chroot(".")) {
+ eprintf("chroot failed\n");
+ }
+
+ /* if -c is set, redirect stdin/stdout/stderr to console */
+ if (console) {
+ close(0);
+ if(open(console, O_RDWR) =3D=3D -1){
+ eprintf("open %s:", console);
+ }
+ if (dup2(0,1) =3D=3D -1){
+ eprintf("dup2 %s:", "0,1");
+ }
+ if (dup2(0,2) =3D=3D -1){
+ eprintf("dup2 %s:", "0,2");
+ }
+ }
+
+ /* execute init */
+ execv(argv[1], argv);
+ eprintf("can't execute '%s'\n", argv[1]);
+}
--=20
1.8.3.2
--Multipart=_Mon__14_Apr_2014_00_15_12_+0200_PFbmMdwa_u.7YJDY--
Received on Mon Sep 17 2001 - 00:00:00 CEST
This archive was generated by hypermail 2.3.0 : Mon Apr 14 2014 - 01:36:03 CEST