ostree-prepare-root: Fix running with musl
musl libc's implementation of `realpath` works by opening the path and then doing a lookup in `/proc/self/fd` to find the canonical path. This fails if `/proc` is not mounted. This causes problems for us if `ostree-prepare-root` is `init` as `/proc` won't be mounted. We have to mount `/proc` anyway for `/proc/cmdline` so this fix just expands the scope over which `/proc` is mounted to include both our `realpath` calls. See also: * http://www.openwall.com/lists/musl/2016/06/08/2 and * http://git.musl-libc.org/cgit/musl/tree/src/misc/realpath.c?id=e738b8cbe64b6dd3ed9f47b6d4cd7eb2c422b38d Closes: #485 Approved by: cgwalters
This commit is contained in:
parent
5424404813
commit
2aacc6912b
|
|
@ -80,26 +80,10 @@ parse_ostree_cmdline (void)
|
||||||
char *cmdline = NULL;
|
char *cmdline = NULL;
|
||||||
const char *iter;
|
const char *iter;
|
||||||
char *ret = NULL;
|
char *ret = NULL;
|
||||||
int tmp_errno;
|
|
||||||
|
|
||||||
cmdline = read_proc_cmdline ();
|
cmdline = read_proc_cmdline ();
|
||||||
if (!cmdline)
|
|
||||||
{
|
|
||||||
// Mount proc
|
|
||||||
if (mount ("proc", "/proc", "proc", 0, NULL) < 0)
|
|
||||||
err (EXIT_FAILURE, "failed to mount proc on /proc");
|
|
||||||
|
|
||||||
cmdline = read_proc_cmdline ();
|
|
||||||
tmp_errno = errno;
|
|
||||||
|
|
||||||
/* Leave the filesystem in the state that we found it: */
|
|
||||||
if (umount ("/proc"))
|
|
||||||
err (EXIT_FAILURE, "failed to umount proc from /proc");
|
|
||||||
|
|
||||||
errno = tmp_errno;
|
|
||||||
if (!cmdline)
|
if (!cmdline)
|
||||||
err (EXIT_FAILURE, "failed to read /proc/cmdline");
|
err (EXIT_FAILURE, "failed to read /proc/cmdline");
|
||||||
}
|
|
||||||
|
|
||||||
iter = cmdline;
|
iter = cmdline;
|
||||||
while (iter != NULL)
|
while (iter != NULL)
|
||||||
|
|
@ -178,17 +162,36 @@ main(int argc, char *argv[])
|
||||||
char *deploy_path = NULL;
|
char *deploy_path = NULL;
|
||||||
char srcpath[PATH_MAX];
|
char srcpath[PATH_MAX];
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
int we_mounted_proc = 0;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
root_arg = "/";
|
root_arg = "/";
|
||||||
else
|
else
|
||||||
root_arg = argv[1];
|
root_arg = argv[1];
|
||||||
|
|
||||||
|
if (stat ("/proc/cmdline", &stbuf) < 0)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
err (EXIT_FAILURE, "stat(\"/proc/cmdline\") failed");
|
||||||
|
/* We need /proc mounted for /proc/cmdline and realpath (on musl) to
|
||||||
|
* work: */
|
||||||
|
if (mount ("proc", "/proc", "proc", 0, NULL) < 0)
|
||||||
|
err (EXIT_FAILURE, "failed to mount proc on /proc");
|
||||||
|
we_mounted_proc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
root_mountpoint = realpath (root_arg, NULL);
|
root_mountpoint = realpath (root_arg, NULL);
|
||||||
if (root_mountpoint == NULL)
|
if (root_mountpoint == NULL)
|
||||||
err (EXIT_FAILURE, "realpath(\"%s\")", root_arg);
|
err (EXIT_FAILURE, "realpath(\"%s\")", root_arg);
|
||||||
deploy_path = resolve_deploy_path (root_mountpoint);
|
deploy_path = resolve_deploy_path (root_mountpoint);
|
||||||
|
|
||||||
|
if (we_mounted_proc)
|
||||||
|
{
|
||||||
|
/* Leave the filesystem in the state that we found it: */
|
||||||
|
if (umount ("/proc"))
|
||||||
|
err (EXIT_FAILURE, "failed to umount proc from /proc");
|
||||||
|
}
|
||||||
|
|
||||||
/* Work-around for a kernel bug: for some reason the kernel
|
/* Work-around for a kernel bug: for some reason the kernel
|
||||||
* refuses switching root if any file systems are mounted
|
* refuses switching root if any file systems are mounted
|
||||||
* MS_SHARED. Hence remount them MS_PRIVATE here as a
|
* MS_SHARED. Hence remount them MS_PRIVATE here as a
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,14 @@ this_script="${BASH_SOURCE:-$(readlink -f "$0")}"
|
||||||
|
|
||||||
setup_bootfs() {
|
setup_bootfs() {
|
||||||
mkdir -p "$1/proc" "$1/bin"
|
mkdir -p "$1/proc" "$1/bin"
|
||||||
echo "quiet ostree=/ostree/boot.0 ro" >"$1/proc/cmdline"
|
|
||||||
|
# We need the real /proc mounted here so musl's realpath will work, but we
|
||||||
|
# want to be able to override /proc/cmdline, so bind mount.
|
||||||
|
mount -t proc proc "$1/proc"
|
||||||
|
|
||||||
|
echo "quiet ostree=/ostree/boot.0 ro" >"$1/override_cmdline"
|
||||||
|
mount --bind "$1/override_cmdline" "$1/proc/cmdline"
|
||||||
|
|
||||||
touch "$1/this_is_bootfs"
|
touch "$1/this_is_bootfs"
|
||||||
cp "$(dirname "$this_script")/../ostree-prepare-root" "$1/bin"
|
cp "$(dirname "$this_script")/../ostree-prepare-root" "$1/bin"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue