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;
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);
+ = (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
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;