Skip to content

Commit

Permalink
WIP: Track deployment root/inode from prepare root
Browse files Browse the repository at this point in the history
  • Loading branch information
cgwalters committed Feb 8, 2024
1 parent da89214 commit 0b16f02
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/libostree/ostree-sysroot-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ struct OstreeSysroot
dev_t etc_device;
ino_t etc_inode;

// The parsed data from /run/ostree
GVariantDict *run_ostree_metadata;

gboolean is_physical; /* TRUE if we're pointed at physical storage root and not a deployment */
GPtrArray *deployments;
int bootversion;
Expand Down
32 changes: 29 additions & 3 deletions src/libostree/ostree-sysroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ ostree_sysroot_finalize (GObject *object)

g_clear_object (&self->path);
g_clear_object (&self->repo);
g_clear_pointer (&self->run_ostree_metadata, g_variant_dict_unref);
g_clear_pointer (&self->deployments, g_ptr_array_unref);
g_clear_object (&self->booted_deployment);
g_clear_object (&self->staged_deployment);
Expand Down Expand Up @@ -812,6 +813,19 @@ parse_deployment (OstreeSysroot *self, const char *boot_link, OstreeDeployment *
if (!glnx_fstat (deployment_dfd, &stbuf, error))
return FALSE;

g_assert (self->run_ostree_metadata);
guint64 expected_root_dev = 0;
guint64 expected_root_inode = 0;
if (!g_variant_dict_lookup (self->run_ostree_metadata, OTCORE_RUN_BOOTED_KEY_ROOTDEV, "(tt)",
&expected_root_dev, &expected_root_inode))
{
g_debug ("Missing %s", OTCORE_RUN_BOOTED_KEY_ROOTDEV);
expected_root_dev = (guint64)self->root_device;
expected_root_inode = (guint64)self->root_inode;
}
else
g_debug ("Target rootdev key %s found", OTCORE_RUN_BOOTED_KEY_ROOTDEV);

/* We look for either the root or the etc subdir of the
* deployment. We need to do this, because when using composefs,
* the root is not a bind mount of the deploy dir, but the etc
Expand All @@ -826,7 +840,7 @@ parse_deployment (OstreeSysroot *self, const char *boot_link, OstreeDeployment *
* be relied on anyways.
*/
is_booted_deployment
= (stbuf.st_dev == self->root_device && stbuf.st_ino == self->root_inode)
= (stbuf.st_dev == expected_root_dev && stbuf.st_ino == expected_root_inode)
|| (etc_stbuf.st_dev == self->etc_device && etc_stbuf.st_ino == self->etc_inode);
}

Expand Down Expand Up @@ -1016,10 +1030,21 @@ ostree_sysroot_initialize (OstreeSysroot *self, GError **error)
* we'll use it to sanity check that we found a booted deployment for example.
* Second, we also find out whether sysroot == /.
*/
if (!glnx_fstatat_allow_noent (AT_FDCWD, OSTREE_PATH_BOOTED, NULL, 0, error))
glnx_autofd int booted_state_fd = -1;
if (!ot_openat_ignore_enoent (AT_FDCWD, OSTREE_PATH_BOOTED, &booted_state_fd, error))
return FALSE;
const gboolean ostree_booted = (errno == 0);
const gboolean ostree_booted = booted_state_fd != -1;

if (booted_state_fd != -1)
{
g_autoptr (GVariant) ostree_run_metadata_v = NULL;
if (!ot_variant_read_fd (booted_state_fd, 0, G_VARIANT_TYPE_VARDICT, TRUE,
&ostree_run_metadata_v, error))
return glnx_prefix_error (error, "failed to read %s", OTCORE_RUN_BOOTED);
self->run_ostree_metadata = g_variant_dict_new (ostree_run_metadata_v);
}

// Gather the root device/inode
{
struct stat root_stbuf;
if (!glnx_fstatat (AT_FDCWD, "/", &root_stbuf, 0, error))
Expand Down Expand Up @@ -1047,6 +1072,7 @@ ostree_sysroot_initialize (OstreeSysroot *self, GError **error)
= (self->root_device == self_stbuf.st_dev && self->root_inode == self_stbuf.st_ino);

self->root_is_ostree_booted = (ostree_booted && root_is_sysroot);
g_debug ("root_is_ostree_booted: %d", self->root_is_ostree_booted);
self->loadstate = OSTREE_SYSROOT_LOAD_STATE_INIT;
}

Expand Down
2 changes: 2 additions & 0 deletions src/libotcore/otcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,7 @@ GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error);
#define OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT "root.transient"
// This key will be present if the sysroot-ro flag was found
#define OTCORE_RUN_BOOTED_KEY_SYSROOT_RO "sysroot-ro"
// Always holds the (device, inode) pair of the booted deployment
#define OTCORE_RUN_BOOTED_KEY_ROOTDEV "root-device-inode"

#define OTCORE_RUN_BOOTED_KEY_TRANSIENT_ETC "transient-etc"
5 changes: 5 additions & 0 deletions src/switchroot/ostree-prepare-root.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,11 @@ main (int argc, char *argv[])
GVariantBuilder metadata_builder;
g_variant_builder_init (&metadata_builder, G_VARIANT_TYPE ("a{sv}"));

if (lstat (".", &stbuf) < 0)
err (EXIT_FAILURE, "lstat deploy_root");
g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_ROOTDEV,
g_variant_new ("(tt)", (guint64)stbuf.st_dev, (guint64)stbuf.st_ino));

// Tracks if we did successfully enable it at runtime
bool using_composefs = false;

Expand Down

0 comments on commit 0b16f02

Please sign in to comment.