All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] replace switch_root shell script with binary
@ 2009-03-04 12:54 Harald Hoyer
       [not found] ` <49AE7A1F.3040508-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 2+ messages in thread
From: Harald Hoyer @ 2009-03-04 12:54 UTC (permalink / raw)
  To: initramfs-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 368 bytes --]

The switch_root shell script did not work with bash-4.0-2, because
"exec" gets the real path of the executable which is then
"/sysroot/lib/ld-linux.so.2" instread of "./lib/ld-linux.so.2".

Also the required chroot binary might live in /usr/bin, which can
be mounted later.

Here is the switch_root code from nash, which can be stripped down
further, but which works.

[-- Attachment #2: 0002-replace-switch_root-shell-script-with-binary.patch --]
[-- Type: text/plain, Size: 20811 bytes --]

From f1b1e4f8694104f007e4483c36b0bf40a5760167 Mon Sep 17 00:00:00 2001
From: Harald Hoyer <harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date: Wed, 4 Mar 2009 13:41:07 +0100
Subject: [PATCH] replace switch_root shell script with binary

The switch_root shell script did not work with bash-4.0-2, because
"exec" gets the real path of the executable which is then
"/sysroot/lib/ld-linux.so.2" instead of "./lib/ld-linux.so.2".
Also the required chroot binary might live in /usr/bin, which can
be mounted later.

Here is the switch_root code from nash, which can be stripped down
further, but which works.
---
 Makefile      |   11 +-
 init          |    3 +
 switch_root   |  111 ------------
 switch_root.c |  556 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 566 insertions(+), 115 deletions(-)
 delete mode 100755 switch_root
 create mode 100644 switch_root.c

diff --git a/Makefile b/Makefile
index dbc2a7d..9441bbe 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
-all:
-	@echo "Nothing to do"
+switch_root: switch_root.c
+	gcc -o switch_root switch_root.c	
 
-install:
+all: switch_root
+
+install: all
 	mkdir -p $(DESTDIR)/usr/libexec/dracut
 	mkdir -p $(DESTDIR)/sbin
 	mkdir -p $(DESTDIR)/usr/libexec/dracut/hooks
@@ -16,6 +18,7 @@ install:
 	for module in modules/*.sh; do install -m 0755 $$module $(DESTDIR)/usr/libexec/dracut ; done
 clean:
 	rm -f *~
+	rm -f switch_root
 
-archive:
+archive: 
 	git archive --format=tar HEAD --prefix=dracut/ |bzip2 > dracut-$(shell git rev-list  --abbrev-commit  -n 1 HEAD  |cut -b 1-8).tar.bz2
diff --git a/init b/init
index 9605141..a0e83a7 100755
--- a/init
+++ b/init
@@ -103,6 +103,9 @@ INIT=$(getarg init); INIT=${INIT#init=}
 }
 	    
 source_all pre-pivot
+
+kill $(pidof udevd)
+
 echo "Switching to real root filesystem $root"
 exec switch_root "$NEWROOT" "$INIT"  $CMDLINE || {
     # davej doesn't like initrd bugs
diff --git a/switch_root b/switch_root
deleted file mode 100755
index d142e97..0000000
--- a/switch_root
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/bin/sh
-# Copyright (c) Victor Lowther <victor.lowther-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
-# Licensed under the terms of the GNU GPL v2 or later.
-
-# some utility functions first
-# this is so we can scroll back.
-
-die() { echo "${1}, dying horribly."; while :;do read line; done }
-
-# jsut enough to get the job done
-simple_find() {
-    # $1 = file to look for
-    # $rest = places to look for it
-    local file=$1
-    shift
-    for loc in "$@"; do
-	[ -f "$NEWROOT$loc/$file" ] && { echo "$loc/$file"; return 0; }
-    done
-    return 1
-}
-
-# We really should not be doing this from here, but...
-find_interp() {
-    local ldso=$("$NEWROOT$CHROOT" "$NEWROOT" "$LDD" "$1" |
-	while read interp rest; do
-	    [ -f "${NEWROOT}$interp" ] || continue
-	    echo "$interp"
-	    break
-	done);
-    [ "$ldso" ] && echo $ldso
-}
-
-# this makes it easier to run a command entirely from newroot
-# $1 = elf interpreter (must pass empty string if none)
-# $2 = command or "exec"
-# $3 = command if exec was passed
-run_from_newroot() {
-    local ldso="$1" cmd="$2"; shift; shift
-    if [ "$cmd" = "exec" ]; then
-	cmd="$1"; shift
-	if [ "$ldso" ]; then
-	    exec "$NEWROOT$ldso" --library-path "$LIBPATH" "$NEWROOT$cmd" "$@"
-	else
-	    exec "$NEWROOT$cmd" "$@"
-	fi
-    else
-	if [ "$ldso" ]; then
-	    "$NEWROOT$ldso" --library-path "$LIBPATH" "$NEWROOT$cmd" "$@"
-	else
-	    "$NEWROOT$cmd" "$@"
-	fi
-    fi
-}
-# update the path to find our dynamic libraries on newroot
-update_newroot_libpath() {
-    local x
-    LIBPATH=":"
-    LIBDIRS="$(echo $NEWROOT/lib* $NEWROOT/usr/lib*)"
-    for x in $LIBDIRS; do
-	[ -d "$x" ] && LIBPATH="${LIBPATH}${x}:"
-    done
-    LIBPATH="${LIBPATH%:}"; LIBPATH="${LIBPATH#:}"
-    [ "$LIBPATH" ] || die "Cannot find shared library diectories on $NEWROOT"
-}
-NEWROOT="$1"
-INIT="$2"
-[ -d "$NEWROOT" ] || die "$NEWROOT is not a directory"
-[ -x "$NEWROOT$INIT" ] || die "$NEWROOT/$INIT is not executable."
-shift; shift
-
-update_newroot_libpath
-
-# start looking for required binaries and bits of infrastructure
-BINDIRS="/bin /sbin /usr/bin /usr/sbin"
-RM=$(simple_find rm $BINDIRS) || die "Cannnot find rm on $NEWROOT"
-CHROOT=$(simple_find chroot $BINDIRS) || die "Cannot find chroot on $NEWROOT"
-LDD=$(simple_find ldd $BINDIRS) || die "Cannot find ldd on $NEWROOT"
-MOUNT=$(simple_find mount $BINDIRS) || die "Cannot find mount on $NEWROOT"
-
-# now, start the real process of switching the root
-cd /
-
-# kill udevd, move all our mounts over to the new root
-kill $(pidof udevd)
-mount --move /proc $NEWROOT/proc
-mount --move /sys $NEWROOT/sys
-mount --move /dev $NEWROOT/dev
-
-# Find the binary interpreter for our three required binaries.
-# We do it here so that ldd does not complain about a missing /dev/null.
-CHROOT_LDSO=$(find_interp "$CHROOT")
-RM_LDSO=$(find_interp "$RM")
-MOUNT_LDSO=$(find_interp "$MOUNT")
-
-# redirect to new console. Our old initramfs will not be freed otherwise
-CONSOLE=$NEWROOT/dev/console
-[ -c $CONSOLE ] && exec >$CONSOLE 2>&1 <$CONSOLE
-for x in *; do
-    [ "/$x" = "$NEWROOT" ] || run_from_newroot "$RM_LDSO" "$RM" -rf -- "$x"
-done
-# switch to our new root dir
-cd "$NEWROOT"
-# this moves rootfs to the actual root...
-run_from_newroot "$MOUNT_LDSO" "$MOUNT" -n --move . /
-# but does not update where / is in directory lookups.
-# Therefore, newroot is now ".".  Update things accordingly, then chroot and
-# exec init.
-NEWROOT="."
-update_newroot_libpath
-run_from_newroot "$CHROOT_LDSO" exec "$CHROOT" "$NEWROOT" "$INIT" "$@" || \
-    die "The chroot did not take for some reason"
diff --git a/switch_root.c b/switch_root.c
new file mode 100644
index 0000000..5e2f54f
--- /dev/null
+++ b/switch_root.c
@@ -0,0 +1,556 @@
+/*
+ * switch_root.c
+ *
+ * Code to switch from initramfs to system root.
+ * Based on nash.c from mkinitrd
+ *
+ * Copyright 2002-2009 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 <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *            Jeremy Katz <katzj-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *            Peter Jones <pjones-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *            Harald Hoyer <harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ */
+
+#define _GNU_SOURCE 1
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <alloca.h>
+#include <string.h>
+#include <errno.h>
+#include <mntent.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#include <linux/fs.h>
+
+#ifndef MNT_FORCE
+#define MNT_FORCE 0x1
+#endif
+
+#ifndef MNT_DETACH
+#define MNT_DETACH 0x2
+#endif
+
+
+#define asprintfa(str, fmt, ...) ({                 \
+        char *_tmp = NULL;                          \
+        int _rc;                                    \
+        _rc = asprintf((str), (fmt), __VA_ARGS__);  \
+        if (_rc != -1) {                            \
+            _tmp = strdupa(*(str));                 \
+            if (!_tmp) {                            \
+                _rc = -1;                           \
+            } else {                                \
+                free(*(str));                       \
+                *(str) = _tmp;                      \
+            }                                       \
+        }                                           \
+        _rc;                                        \
+    })
+
+
+
+static inline int
+setFdCoe(int fd, int enable)
+{
+    int rc;
+    long flags = 0;
+
+    rc = fcntl(fd, F_GETFD, &flags);
+    if (rc < 0)
+        return rc;
+
+    if (enable)
+        flags |= FD_CLOEXEC;
+    else
+        flags &= ~FD_CLOEXEC;
+
+    rc = fcntl(fd, F_SETFD, flags);
+    return rc;
+}
+
+static char *
+getArg(char * cmd, char * end, char ** arg)
+{
+    char quote = '\0';
+
+    if (!cmd || cmd >= end)
+        return NULL;
+
+    while (isspace(*cmd) && cmd < end)
+        cmd++;
+    if (cmd >= end)
+        return NULL;
+
+    if (*cmd == '"')
+        cmd++, quote = '"';
+    else if (*cmd == '\'')
+        cmd++, quote = '\'';
+
+    if (quote) {
+        *arg = cmd;
+
+        /* This doesn't support \ escapes */
+        while (cmd < end && *cmd != quote)
+            cmd++;
+
+        if (cmd == end) {
+            printf("error: quote mismatch for %s\n", *arg);
+            return NULL;
+        }
+
+        *cmd = '\0';
+        cmd++;
+    } else {
+        *arg = cmd;
+        while (!isspace(*cmd) && cmd < end)
+            cmd++;
+        *cmd = '\0';
+        if (**arg == '$')
+            *arg = getenv(*arg+1);
+        if (*arg == NULL)
+            *arg = "";
+    }
+
+    cmd++;
+
+    while (isspace(*cmd))
+        cmd++;
+
+    return cmd;
+}
+
+static int
+mountCommand(char * cmd, char * end)
+{
+    char * fsType = NULL;
+    char * device, *spec;
+    char * mntPoint;
+    char * opts = NULL;
+    int rc = 0;
+    int flags = MS_MGC_VAL;
+    char * newOpts;
+
+    if (!(cmd = getArg(cmd, end, &spec))) {
+        printf(
+            "usage: mount [--ro] [-o <opts>] -t <type> <device> <mntpoint>\n");
+        return 1;
+    }
+
+    while (cmd && *spec == '-') {
+        if (!strcmp(spec, "--ro")) {
+            flags |= MS_RDONLY;
+        } else if (!strcmp(spec, "--bind")) {
+            flags = MS_BIND;
+            fsType = "none";
+        } else if (!strcmp(spec, "--move")) {
+            flags = MS_MOVE;
+            fsType = "none";
+        } else if (!strcmp(spec, "-o")) {
+            cmd = getArg(cmd, end, &opts);
+            if (!cmd) {
+                printf("mount: -o requires arguments\n");
+                return 1;
+            }
+        } else if (!strcmp(spec, "-t")) {
+            if (!(cmd = getArg(cmd, end, &fsType))) {
+                printf("mount: missing filesystem type\n");
+                return 1;
+            }
+        }
+
+        cmd = getArg(cmd, end, &spec);
+    }
+
+    if (!cmd) {
+        printf("mount: missing device or mountpoint\n");
+        return 1;
+    }
+
+    if (!(cmd = getArg(cmd, end, &mntPoint))) {
+        struct mntent *mnt;
+        FILE *fstab;
+
+        fstab = fopen("/etc/fstab", "r");
+        if (!fstab) {
+            printf("mount: missing mount point\n");
+            return 1;
+        }
+        do {
+            if (!(mnt = getmntent(fstab))) {
+                printf("mount: missing mount point\n");
+                fclose(fstab);
+                return 1;
+            }
+            if (!strcmp(mnt->mnt_dir, spec)) {
+                spec = mnt->mnt_fsname;
+                mntPoint = mnt->mnt_dir;
+
+                if (!strcmp(mnt->mnt_type, "bind")) {
+                    flags |= MS_BIND;
+                    fsType = "none";
+                } else
+                    fsType = mnt->mnt_type;
+
+                opts = mnt->mnt_opts;
+                break;
+            }
+        } while(1);
+
+        fclose(fstab);
+    }
+
+    if (!fsType) {
+        printf("mount: filesystem type expected\n");
+        return 1;
+    }
+
+    if (cmd && cmd < end) {
+        printf("mount: unexpected arguments\n");
+        return 1;
+    }
+
+    /* need to deal with options */
+    if (opts) {
+        char * end;
+        char * start = opts;
+
+        newOpts = alloca(strlen(opts) + 1);
+        *newOpts = '\0';
+
+        while (*start) {
+            end = strchr(start, ',');
+            if (!end) {
+                end = start + strlen(start);
+            } else {
+                *end = '\0';
+                end++;
+            }
+
+            if (!strcmp(start, "ro"))
+                flags |= MS_RDONLY;
+            else if (!strcmp(start, "rw"))
+                flags &= ~MS_RDONLY;
+            else if (!strcmp(start, "nosuid"))
+                flags |= MS_NOSUID;
+            else if (!strcmp(start, "suid"))
+                flags &= ~MS_NOSUID;
+            else if (!strcmp(start, "nodev"))
+                flags |= MS_NODEV;
+            else if (!strcmp(start, "dev"))
+                flags &= ~MS_NODEV;
+            else if (!strcmp(start, "noexec"))
+                flags |= MS_NOEXEC;
+            else if (!strcmp(start, "exec"))
+                flags &= ~MS_NOEXEC;
+            else if (!strcmp(start, "sync"))
+                flags |= MS_SYNCHRONOUS;
+            else if (!strcmp(start, "async"))
+                flags &= ~MS_SYNCHRONOUS;
+            else if (!strcmp(start, "nodiratime"))
+                flags |= MS_NODIRATIME;
+            else if (!strcmp(start, "diratime"))
+                flags &= ~MS_NODIRATIME;
+            else if (!strcmp(start, "noatime"))
+                flags |= MS_NOATIME;
+            else if (!strcmp(start, "atime"))
+                flags &= ~MS_NOATIME;
+            else if (!strcmp(start, "relatime"))
+                flags |= MS_RELATIME;
+            else if (!strcmp(start, "norelatime"))
+                flags &= ~MS_RELATIME;
+            else if (!strcmp(start, "remount"))
+                flags |= MS_REMOUNT;
+            else if (!strcmp(start, "bind"))
+                flags |= MS_BIND;
+            else if (!strcmp(start, "defaults"))
+                ;
+            else {
+                if (*newOpts)
+                    strcat(newOpts, ",");
+                strcat(newOpts, start);
+            }
+
+            start = end;
+        }
+
+        opts = newOpts;
+    }
+
+    device = strdupa(spec);
+
+    if (!device) {
+        printf("mount: could not find filesystem '%s'\n", spec);
+        return 1;
+    }
+
+    {
+        char *mount_opts = NULL;
+	mount_opts = opts;
+        if (mount(device, mntPoint, fsType, flags, mount_opts) < 0) {
+            printf("mount: error mounting %s on %s as %s: %m\n",
+                    device, mntPoint, fsType);
+            rc = 1;
+        }
+    }
+
+    return rc;
+}
+
+/* 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 void
+mountMntEnt(const struct mntent *mnt)
+{
+    char *start = NULL, *end;
+    char *target = NULL;
+    struct stat sb;
+    
+    printf("mounting %s\n", mnt->mnt_dir);
+    if (asprintfa(&target, ".%s", mnt->mnt_dir) < 0) {
+        printf("setuproot: out of memory while mounting %s\n",
+                mnt->mnt_dir);
+        return;
+    }
+    
+    if (stat(target, &sb) < 0)
+        return;
+    
+    if (asprintf(&start, "-o %s -t %s %s .%s\n",
+            mnt->mnt_opts, mnt->mnt_type, mnt->mnt_fsname,
+            mnt->mnt_dir) < 0) {
+        printf("setuproot: out of memory while mounting %s\n",
+                mnt->mnt_dir);
+        return;
+    }
+    
+    end = start + 1;
+    while (*end && (*end != '\n'))
+        end++;
+    /* end points to the \n at the end of the command */
+    
+    if (mountCommand(start, end) != 0)
+        printf("setuproot: mount returned error\n");
+}
+
+static int
+setuprootCommand(char *new)
+{
+    FILE *fp;
+
+    printf("Setting up new root fs\n");
+
+    if (chdir(new)) {
+        printf("setuproot: chdir(%s) failed: %m\n", new);
+        return 1;
+    }
+
+    if (mount("/dev", "./dev", NULL, MS_BIND, NULL) < 0)
+        printf("setuproot: moving /dev failed: %m\n");
+
+        fp = setmntent("./etc/fstab.sys", "r");
+        if (fp)
+            printf("using fstab.sys from mounted FS\n");
+        else {
+            fp = setmntent("/etc/fstab.sys", "r");
+            if (fp)
+                printf("using fstab.sys from initrd\n");
+        }
+        if (fp) {
+            struct mntent *mnt;
+
+            while((mnt = getmntent(fp)))
+                mountMntEnt(mnt);
+            endmntent(fp);
+        } else {
+            struct {
+                char *source;
+                char *target;
+                char *type;
+                int flags;
+                void *data;
+                int raise;
+            } fstab[] = {
+                { "/proc", "./proc", "proc", 0, NULL },
+                { "/sys", "./sys", "sysfs", 0, NULL },
+#if 0
+                { "/dev/pts", "./dev/pts", "devpts", 0, "gid=5,mode=620" },
+                { "/dev/shm", "./dev/shm", "tmpfs", 0, NULL },
+                { "/selinux", "/selinux", "selinuxfs", 0, NULL },
+#endif
+                { NULL, }
+            };
+            int i = 0;
+
+            printf("no fstab.sys, mounting internal defaults\n");
+            for (; fstab[i].source != NULL; i++) {
+                if (mount(fstab[i].source, fstab[i].target, fstab[i].type,
+                            fstab[i].flags, fstab[i].data) < 0)
+                    printf("setuproot: error mounting %s: %m\n",
+                            fstab[i].source);
+            }
+        }
+
+    chdir("/");
+    return 0;
+}
+
+int main(int argc, char **argv) 
+{
+    /*  Don't try to unmount the old "/", there's no way to do it. */
+    const char *umounts[] = { "/dev", "/proc", "/sys", NULL };
+    char *new = NULL;
+    int fd, i = 0;
+
+    argv++;
+    new = argv[0];
+    argv++;
+    printf("Switching to root: %s", new);
+
+    setuprootCommand(new);
+
+    fd = open("/", O_RDONLY);
+    for (; umounts[i] != NULL; i++) {
+        printf("unmounting old %s\n", umounts[i]);
+        if (umount2(umounts[i], MNT_DETACH) < 0) {
+            printf("ERROR unmounting old %s: %m\n",umounts[i]);
+            printf("forcing unmount of %s\n", umounts[i]);
+            umount2(umounts[i], MNT_FORCE);
+        }
+    }
+    i=0;
+
+    chdir(new);
+
+    recursiveRemove("/");
+
+    if (mount(new, "/", NULL, MS_MOVE, NULL) < 0) {
+        printf("switchroot: mount failed: %m\n");
+        close(fd);
+        return 1;
+    }
+
+    if (chroot(".")) {
+        printf("switchroot: chroot() failed: %m\n");
+        close(fd);
+        return 1;
+    }
+
+    /* release the old "/" */
+    close(fd);
+
+    close(3);
+    if ((fd = open("/dev/console", O_RDWR)) < 0) {
+        printf("ERROR opening /dev/console: %m\n");
+        printf("Trying to use fd 0 instead.\n");
+        fd = dup2(0, 3);
+    } else {
+        setFdCoe(fd, 0);
+        if (fd != 3) {
+            dup2(fd, 3);
+            close(fd);
+            fd = 3;
+        }
+    }
+    close(0);
+    dup2(fd, 0);
+    close(1);
+    dup2(fd, 1);
+    close(2);
+    dup2(fd, 2);
+    close(fd);
+
+    if (access(argv[0], X_OK)) {
+        printf("WARNING: can't access %s\n", argv[0]);
+    }
+
+    execv(argv[0], argv);
+
+    printf("exec of init (%s) failed!!!: %m\n", argv[0]);
+    return 1;
+}
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] replace switch_root shell script with binary
       [not found] ` <49AE7A1F.3040508-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2009-03-04 22:50   ` Victor Lowther
  0 siblings, 0 replies; 2+ messages in thread
From: Victor Lowther @ 2009-03-04 22:50 UTC (permalink / raw)
  To: Harald Hoyer; +Cc: initramfs-u79uwXL29TY76Z2rM5mHXA

On Wed, 2009-03-04 at 13:54 +0100, Harald Hoyer wrote:
> The switch_root shell script did not work with bash-4.0-2, because
> "exec" gets the real path of the executable which is then
> "/sysroot/lib/ld-linux.so.2" instread of "./lib/ld-linux.so.2".

That is a little odd -- dash does not exhibit that behaviour.  

The only command that tries to use ./lib/ld-linux.so.2 is the final
chroot, and at that point /sysroot does not mean anything anymore
because of the move mount we did.  Is this a bug in bash we can work
around by setting $PWD?

> Also the required chroot binary might live in /usr/bin, which can
> be mounted later.

yeah, but /usr/sbin and /usr/bin are stupid places to have chroot, it is
a core utility anyways. :)

[ patch snipped ]

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-03-04 22:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-04 12:54 [PATCH] replace switch_root shell script with binary Harald Hoyer
     [not found] ` <49AE7A1F.3040508-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2009-03-04 22:50   ` Victor Lowther

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.