diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h index 57ac6824ca..6baccfe6cc 100644 --- a/src/libostree/ostree-sysroot-private.h +++ b/src/libostree/ostree-sysroot-private.h @@ -64,9 +64,11 @@ struct OstreeSysroot { OstreeSysrootLoadState loadstate; gboolean mount_namespace_in_use; /* TRUE if caller has told us they used CLONE_NEWNS */ gboolean root_is_ostree_booted; /* TRUE if sysroot is / and we are booted via ostree */ - /* The device/inode for /, used to detect booted deployment */ + /* The device/inode for / and /etc, used to detect booted deployment */ dev_t root_device; ino_t root_inode; + dev_t etc_device; + ino_t etc_inode; gboolean is_physical; /* TRUE if we're pointed at physical storage root and not a deployment */ GPtrArray *deployments; diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index b8edcd64a9..e10a1a90ce 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -837,14 +837,26 @@ parse_deployment (OstreeSysroot *self, if (looking_for_booted_deployment) { struct stat stbuf; + struct stat etc_stbuf = {}; if (!glnx_fstat (deployment_dfd, &stbuf, error)) return FALSE; + + /* 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 + * dir is. + */ + + if (!glnx_fstatat_allow_noent (deployment_dfd, "etc", &etc_stbuf, 0, error)) + return FALSE; + /* A bit ugly, we're assigning to a sysroot-owned variable from deep in * this parsing code. But eh, if something fails the sysroot state can't * be relied on anyways. */ - is_booted_deployment = (stbuf.st_dev == self->root_device && - stbuf.st_ino == self->root_inode); + is_booted_deployment = + (stbuf.st_dev == self->root_device && stbuf.st_ino == self->root_inode) || + (etc_stbuf.st_dev == self->etc_device && etc_stbuf.st_ino == self->etc_inode); } g_autoptr(OstreeDeployment) ret_deployment @@ -1049,6 +1061,16 @@ ostree_sysroot_initialize (OstreeSysroot *self, self->root_inode = root_stbuf.st_ino; } + { struct stat etc_stbuf; + if (!glnx_fstatat_allow_noent (AT_FDCWD, "/etc", &etc_stbuf, 0, error)) + return FALSE; + if (errno != ENOENT) + { + self->etc_device = etc_stbuf.st_dev; + self->etc_inode = etc_stbuf.st_ino; + } + } + struct stat self_stbuf; if (!glnx_fstatat (AT_FDCWD, gs_file_get_path_cached (self->path), &self_stbuf, 0, error)) return FALSE;