summaryrefslogtreecommitdiff
path: root/src/switchroot
diff options
context:
space:
mode:
authorWilliam Manley <will@williammanley.net>2016-07-18 18:02:12 +0100
committerAtomic Bot <atomic-devel@projectatomic.io>2016-08-02 19:07:25 +0000
commit47e7afab272721fdfa046aa22ee5260ce64d5541 (patch)
tree4f3c00bb0aec3062671d4df0d2de2cf202ad4ba2 /src/switchroot
parenta0a4052365288d32c682baa7b6477645130c265e (diff)
downloadostree-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.c61
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);