From: Alexander Larsson Date: Tue, 16 May 2023 08:17:32 +0000 (+0200) Subject: sysroot: Ensure deployment detection works when using composefs X-Git-Tag: archive/raspbian/2023.7-3+rpi1~1^2~9^2~1^2~29^2~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d47a90347ba4e72ae223d4eb59287a42d32a5df0;p=ostree.git sysroot: Ensure deployment detection works when using composefs In the case of composefs, we cannot compare the devino of the rootfs and the deploy dir, because the root is the composefs mount, not a bind mount. Instead we check the devino of the etc subdir of the deploy, because this is a bind mount even when using composefs. --- diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h index 6c1c5d3e..78e736fc 100644 --- a/src/libostree/ostree-sysroot-private.h +++ b/src/libostree/ostree-sysroot-private.h @@ -70,9 +70,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 ca8b3277..946bd353 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -799,14 +799,26 @@ parse_deployment (OstreeSysroot *self, const char *boot_link, OstreeDeployment * 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 @@ -1003,6 +1015,17 @@ ostree_sysroot_initialize (OstreeSysroot *self, GError **error) 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;