diff options
author | William Manley <will@williammanley.net> | 2016-07-18 18:02:12 +0100 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2016-08-02 19:07:25 +0000 |
commit | 47e7afab272721fdfa046aa22ee5260ce64d5541 (patch) | |
tree | 4f3c00bb0aec3062671d4df0d2de2cf202ad4ba2 /src/switchroot | |
parent | a0a4052365288d32c682baa7b6477645130c265e (diff) | |
download | ostree-47e7afab272721fdfa046aa22ee5260ce64d5541.tar.gz |
ostree-prepare-root: Refactor: Create /sysroot.tmp much later
Typically we have our ready made-up up root at
`/sysroot/ostree/deploy/.../` (`deploy_path`) and the real rootfs at
`/sysroot` (`root_mountpoint`). We want to end up with our made-up root
at `/sysroot/` and the real rootfs under `/sysroot/sysroot` as systemd
will be responsible for moving `/sysroot` to `/`.
We need to do this in 3 moves to avoid trying to move `/sysroot` under
itself:
1. `/sysroot/ostree/deploy/...` -> `/sysroot.tmp`
2. `/sysroot` -> `/sysroot.tmp/sysroot`
3. `/sysroot.tmp` -> `/sysroot`
This is a refactoring to group all these operations together so I can
implement an alternative in terms of `pivot_root`.
Closes: #403
Approved by: cgwalters
Diffstat (limited to 'src/switchroot')
-rw-r--r-- | src/switchroot/ostree-prepare-root.c | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index 77a084ad..114bd672 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -191,7 +191,6 @@ main(int argc, char *argv[]) char *deploy_path = NULL; char srcpath[PATH_MAX]; char destpath[PATH_MAX]; - char newroot[PATH_MAX]; struct stat stbuf; int orig_cwd_dfd; @@ -202,16 +201,6 @@ main(int argc, char *argv[]) deploy_path = resolve_deploy_path (root_mountpoint); - /* Create a temporary target for our mounts in the initramfs; this will - * be moved to the new system root below. - */ - snprintf (newroot, sizeof(newroot), "%s.tmp", root_mountpoint); - if (mkdir (newroot, 0755) < 0) - { - perrorv ("Couldn't create temporary sysroot '%s': ", newroot); - exit (EXIT_FAILURE); - } - /* Work-around for a kernel bug: for some reason the kernel * refuses switching root if any file systems are mounted * MS_SHARED. Hence remount them MS_PRIVATE here as a @@ -225,7 +214,7 @@ main(int argc, char *argv[]) } /* Make deploy_path a bind mount, so we can move it later */ - if (mount (deploy_path, newroot, NULL, MS_BIND, NULL) < 0) + if (mount (deploy_path, deploy_path, NULL, MS_BIND, NULL) < 0) { perrorv ("failed to initial bind mount %s", deploy_path); exit (EXIT_FAILURE); @@ -233,7 +222,7 @@ main(int argc, char *argv[]) /* Link to the deployment's /var */ snprintf (srcpath, sizeof(srcpath), "%s/../../var", deploy_path); - snprintf (destpath, sizeof(destpath), "%s/var", newroot); + snprintf (destpath, sizeof(destpath), "%s/var", deploy_path); if (mount (srcpath, destpath, NULL, MS_MGC_VAL|MS_BIND, NULL) < 0) { perrorv ("failed to bind mount %s to %s", srcpath, destpath); @@ -245,7 +234,7 @@ main(int argc, char *argv[]) snprintf (srcpath, sizeof(srcpath), "%s/boot/loader", root_mountpoint); if (lstat (srcpath, &stbuf) == 0 && S_ISLNK (stbuf.st_mode)) { - snprintf (destpath, sizeof(destpath), "%s/boot", newroot); + snprintf (destpath, sizeof(destpath), "%s/boot", deploy_path); if (lstat (destpath, &stbuf) == 0 && S_ISDIR (stbuf.st_mode)) { snprintf (srcpath, sizeof(srcpath), "%s/boot", root_mountpoint); @@ -257,7 +246,7 @@ main(int argc, char *argv[]) } } - /* Here we do a dance to chdir to the newroot so that we can have + /* Here we do a dance to chdir to the deploy_path so that we can have * the potential overlayfs mount points not look ugly. However...I * think we could do this a lot earlier and make all of the mounts * here just be relative. @@ -269,9 +258,9 @@ main(int argc, char *argv[]) exit (EXIT_FAILURE); } - if (chdir (newroot) < 0) + if (chdir (deploy_path) < 0) { - perrorv ("failed to chdir to newroot"); + perrorv ("failed to chdir to deploy_path"); exit (EXIT_FAILURE); } @@ -324,19 +313,39 @@ main(int argc, char *argv[]) touch_run_ostree (); - /* Move physical root to $deployment/sysroot */ - snprintf (destpath, sizeof(destpath), "%s/sysroot", newroot); - if (mount (root_mountpoint, destpath, NULL, MS_MOVE, NULL) < 0) + /* In this instance typically we have our ready made-up up root at + * /sysroot/ostree/deploy/.../ (deploy_path) and the real rootfs at + * /sysroot (root_mountpoint). We want to end up with our made-up root at + * /sysroot/ and the real rootfs under /sysroot/sysroot as systemd will be + * responsible for moving /sysroot to /. + * + * We need to do this in 3 moves to avoid trying to move /sysroot under + * itself: + * + * 1. /sysroot/ostree/deploy/... -> /sysroot.tmp + * 2. /sysroot -> /sysroot.tmp/sysroot + * 3. /sysroot.tmp -> /sysroot + */ + if (mkdir ("/sysroot.tmp", 0755) < 0) { - perrorv ("Failed to MS_MOVE %s to '%s'", root_mountpoint, destpath); + perrorv ("couldn't create temporary sysroot /sysroot.tmp: "); exit (EXIT_FAILURE); } - /* Now that we've set up all the bind mounts in /sysroot.tmp which - * points to the deployment, move it /sysroot. From there, - * systemd's initrd-switch-root.target will take over. - */ - if (mount (newroot, root_mountpoint, NULL, MS_MOVE, NULL) < 0) + if (mount (deploy_path, "/sysroot.tmp", NULL, MS_MOVE, NULL) < 0) + { + perrorv ("failed to MS_MOVE '%s' to '/sysroot.tmp'", deploy_path); + exit (EXIT_FAILURE); + } + + if (mount (root_mountpoint, "/sysroot.tmp/sysroot", NULL, MS_MOVE, NULL) < 0) + { + perrorv ("failed to MS_MOVE '%s' to '/sysroot.tmp/sysroot'", + root_mountpoint); + exit (EXIT_FAILURE); + } + + if (mount ("/sysroot.tmp", root_mountpoint, NULL, MS_MOVE, NULL) < 0) { perrorv ("failed to MS_MOVE %s to %s", deploy_path, root_mountpoint); exit (EXIT_FAILURE); |