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
This commit is contained in:
parent
a0a4052365
commit
47e7afab27
|
|
@ -191,7 +191,6 @@ main(int argc, char *argv[])
|
||||||
char *deploy_path = NULL;
|
char *deploy_path = NULL;
|
||||||
char srcpath[PATH_MAX];
|
char srcpath[PATH_MAX];
|
||||||
char destpath[PATH_MAX];
|
char destpath[PATH_MAX];
|
||||||
char newroot[PATH_MAX];
|
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
int orig_cwd_dfd;
|
int orig_cwd_dfd;
|
||||||
|
|
||||||
|
|
@ -202,16 +201,6 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
deploy_path = resolve_deploy_path (root_mountpoint);
|
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
|
/* 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
|
||||||
|
|
@ -225,7 +214,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make deploy_path a bind mount, so we can move it later */
|
/* 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);
|
perrorv ("failed to initial bind mount %s", deploy_path);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
|
|
@ -233,7 +222,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
/* Link to the deployment's /var */
|
/* Link to the deployment's /var */
|
||||||
snprintf (srcpath, sizeof(srcpath), "%s/../../var", deploy_path);
|
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)
|
if (mount (srcpath, destpath, NULL, MS_MGC_VAL|MS_BIND, NULL) < 0)
|
||||||
{
|
{
|
||||||
perrorv ("failed to bind mount %s to %s", srcpath, destpath);
|
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);
|
snprintf (srcpath, sizeof(srcpath), "%s/boot/loader", root_mountpoint);
|
||||||
if (lstat (srcpath, &stbuf) == 0 && S_ISLNK (stbuf.st_mode))
|
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))
|
if (lstat (destpath, &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
|
||||||
{
|
{
|
||||||
snprintf (srcpath, sizeof(srcpath), "%s/boot", root_mountpoint);
|
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
|
* the potential overlayfs mount points not look ugly. However...I
|
||||||
* think we could do this a lot earlier and make all of the mounts
|
* think we could do this a lot earlier and make all of the mounts
|
||||||
* here just be relative.
|
* here just be relative.
|
||||||
|
|
@ -269,9 +258,9 @@ main(int argc, char *argv[])
|
||||||
exit (EXIT_FAILURE);
|
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);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,19 +313,39 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
touch_run_ostree ();
|
touch_run_ostree ();
|
||||||
|
|
||||||
/* Move physical root to $deployment/sysroot */
|
/* In this instance typically we have our ready made-up up root at
|
||||||
snprintf (destpath, sizeof(destpath), "%s/sysroot", newroot);
|
* /sysroot/ostree/deploy/.../ (deploy_path) and the real rootfs at
|
||||||
if (mount (root_mountpoint, destpath, NULL, MS_MOVE, NULL) < 0)
|
* /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);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we've set up all the bind mounts in /sysroot.tmp which
|
if (mount (deploy_path, "/sysroot.tmp", NULL, MS_MOVE, NULL) < 0)
|
||||||
* points to the deployment, move it /sysroot. From there,
|
{
|
||||||
* systemd's initrd-switch-root.target will take over.
|
perrorv ("failed to MS_MOVE '%s' to '/sysroot.tmp'", deploy_path);
|
||||||
*/
|
exit (EXIT_FAILURE);
|
||||||
if (mount (newroot, root_mountpoint, NULL, MS_MOVE, NULL) < 0)
|
}
|
||||||
|
|
||||||
|
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);
|
perrorv ("failed to MS_MOVE %s to %s", deploy_path, root_mountpoint);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue