Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
cgwalters committed Dec 7, 2023
1 parent 7f9d6c3 commit 9887658
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/libostree/ostree-sysroot-cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ gboolean
_ostree_sysroot_rmrf_deployment (OstreeSysroot *self, OstreeDeployment *deployment,
GCancellable *cancellable, GError **error)
{
g_autofree char *backing_relpath =_ostree_sysroot_get_deployment_backing_relpath (deployment);
g_autofree char *origin_relpath = ostree_deployment_get_origin_relpath (deployment);
g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment);
struct stat stbuf;
Expand All @@ -238,6 +239,12 @@ _ostree_sysroot_rmrf_deployment (OstreeSysroot *self, OstreeDeployment *deployme
/* This deployment wasn't referenced, so delete it */
if (!_ostree_linuxfs_fd_alter_immutable_flag (deployment_fd, FALSE, cancellable, error))
return FALSE;
/* Note we must delete the origin and backing directories first, as the "source of truth"
* is the deployment path. We don't currently have code that detects "orphaned"
* origin files or work directories.
*/
if (!glnx_shutil_rm_rf_at (self->sysroot_fd, backing_relpath, cancellable, error))
return FALSE;
if (!glnx_shutil_rm_rf_at (self->sysroot_fd, origin_relpath, cancellable, error))
return FALSE;
if (!glnx_shutil_rm_rf_at (self->sysroot_fd, deployment_path, cancellable, error))
Expand Down
2 changes: 2 additions & 0 deletions src/libostree/ostree-sysroot-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ gboolean _ostree_sysroot_boot_complete (OstreeSysroot *self, GCancellable *cance

OstreeDeployment *_ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, GError **error);

char *_ostree_sysroot_get_deployment_backing_relpath (OstreeDeployment *deployment);

gboolean _ostree_sysroot_rmrf_deployment (OstreeSysroot *sysroot, OstreeDeployment *deployment,
GCancellable *cancellable, GError **error);

Expand Down
15 changes: 14 additions & 1 deletion src/libostree/ostree-sysroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include "ostree-repo-private.h"
#include "ostree-sepolicy-private.h"
#include "ostree-sysroot-private.h"
#include "ostree.h"
#include "otcore.h"

/**
* SECTION:ostree-sysroot
Expand Down Expand Up @@ -1965,6 +1965,19 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, const char *osna
return TRUE;
}

/* Return the sysroot-relative path to the "backing" directory of a deployment
* which can hold additional data.
*/
char *
_ostree_sysroot_get_deployment_backing_relpath (OstreeDeployment *deployment)
{
return g_strdup_printf ("ostree/deploy/%s/deploy/%s.%d%s",
ostree_deployment_get_osname (deployment), ostree_deployment_get_csum (deployment),
ostree_deployment_get_deployserial (deployment),
OSTREE_DEPLOYMENT_BACKING_EXT);
}


/* Deploy a copy of @target_deployment */
static gboolean
clone_deployment (OstreeSysroot *sysroot, OstreeDeployment *target_deployment,
Expand Down
3 changes: 3 additions & 0 deletions src/libotcore/otcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error);
// we make it with mode 0 (which requires CAP_DAC_OVERRIDE to pass through).
#define OTCORE_RUN_OSTREE_PRIVATE "/run/ostree/.private"

// The directory holding extra/backing data for a deployment, such as overlayfs workdirs
#define OSTREE_DEPLOYMENT_BACKING_EXT ".backing"

// The name of the composefs metadata root
#define OSTREE_COMPOSEFS_NAME ".ostree.cfs"
// The temporary directory used for the EROFS mount; it's in the .private directory
Expand Down
38 changes: 37 additions & 1 deletion src/switchroot/ostree-prepare-root.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@
#define SYSROOT_KEY "sysroot"
#define READONLY_KEY "readonly"

/* This key configures the / mount in the deployment root */
#define ROOT_KEY "root"
#define ETC_KEY "etc"
#define TRANSIENT_KEY "transient"

Expand Down Expand Up @@ -352,6 +354,11 @@ main (int argc, char *argv[])
errx (EXIT_FAILURE, "Failed to parse config: %s", error->message);

gboolean sysroot_readonly = FALSE;
gboolean root_transient = FALSE;

if (!ot_keyfile_get_boolean_with_default (config, ROOT_KEY, TRANSIENT_KEY,
FALSE, &root_transient, &error))
return FALSE;

// We always parse the composefs config, because we want to detect and error
// out if it's enabled, but not supported at compile time.
Expand All @@ -375,6 +382,11 @@ main (int argc, char *argv[])
if (root_mountpoint == NULL)
err (EXIT_FAILURE, "realpath(\"%s\")", root_arg);
g_autofree char *deploy_path = resolve_deploy_path (root_mountpoint);
const char *deploy_directory_name = glnx_basename (deploy_path);
// Note that realpath() should have stripped any trailing `/` which shouldn't
// be in the karg to start with, but we assert here to be sure we have a non-empty
// filename.
g_assert (deploy_directory_name && *deploy_directory_name);

if (mkdirat (AT_FDCWD, OTCORE_RUN_OSTREE, 0755) < 0)
err (EXIT_FAILURE, "Failed to create %s", OTCORE_RUN_OSTREE);
Expand Down Expand Up @@ -517,6 +529,30 @@ main (int argc, char *argv[])
err (EXIT_FAILURE, "failed to make initial bind mount %s", deploy_path);
}

if (root_transient)
{
const char *root_transient_dirname = "root-transient";
// Create the "backing" directory with additional data */
g_autofree char *backingdir = g_strdup_printf ("../%s%s", deploy_directory_name, OSTREE_DEPLOYMENT_BACKING_EXT);
if (!glnx_ensure_dir (AT_FDCWD, backingdir, 0700, &error))
err (EXIT_FAILURE, "%s", error->message);
// The root-transient holds overlayfs directories for the root
g_autofree char *rootovldir = g_build_filename (backingdir, root_transient_dirname, NULL);
if (!glnx_ensure_dir (AT_FDCWD, rootovldir, 0700, &error))
err (EXIT_FAILURE, "%s", error->message);
// Create the overlayfs upper
g_autofree char *upperdir = g_build_filename (backingdir, root_transient_dirname, "upper", NULL);
if (!glnx_ensure_dir (AT_FDCWD, upperdir, 0700, &error))
err (EXIT_FAILURE, "%s", error->message);
// And the overlayfs work
g_autofree char *workdir = g_build_filename (backingdir, root_transient_dirname, "work", NULL);
if (!glnx_ensure_dir (AT_FDCWD, workdir, 0700, &error))
err (EXIT_FAILURE, "%s", error->message);
g_autofree char *ovl_options = g_strdup_printf ("lowerdir=" TMP_SYSROOT ",upperdir=%s,workdir=%s", upperdir, workdir);
if (mount ("overlay", ".", "overlay", MS_SILENT, ovl_options) < 0)
err (EXIT_FAILURE, "failed to mount transient root overlayfs");
}

/* This will result in a system with /sysroot read-only. Thus, two additional
* writable bind-mounts (for /etc and /var) are required later on. */
if (sysroot_readonly)
Expand Down Expand Up @@ -548,7 +584,7 @@ main (int argc, char *argv[])
/* Prepare /etc.
* No action required if sysroot is writable. Otherwise, a bind-mount for
* the deployment needs to be created and remounted as read/write. */
if (sysroot_readonly || using_composefs)
if (sysroot_readonly || using_composefs || root_transient)
{
gboolean etc_transient = FALSE;
if (!ot_keyfile_get_boolean_with_default (config, ETC_KEY, TRANSIENT_KEY, FALSE,
Expand Down

0 comments on commit 9887658

Please sign in to comment.