mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-05 13:18:17 +03:00
sysroot: Add an API to initialize with mountns
This lowers down into the C library some logic we have in the binary/app logic, in prep for having more Rust-native CLI code in https://github.com/ostreedev/ostree-rs-ext/pull/412 Basically we want to *ensure* a mount namespace by invoking `unshare()` if necessary, instead of requiring our callers to do this dance. This also helps fix e.g. Closes: https://github.com/ostreedev/ostree/issues/2769
This commit is contained in:
parent
9d652be3b1
commit
599ffefe7f
@ -548,6 +548,7 @@ OstreeSysroot
|
|||||||
ostree_sysroot_new
|
ostree_sysroot_new
|
||||||
ostree_sysroot_new_default
|
ostree_sysroot_new_default
|
||||||
ostree_sysroot_initialize
|
ostree_sysroot_initialize
|
||||||
|
ostree_sysroot_initialize_with_mount_namespace
|
||||||
ostree_sysroot_get_path
|
ostree_sysroot_get_path
|
||||||
ostree_sysroot_load
|
ostree_sysroot_load
|
||||||
ostree_sysroot_load_if_changed
|
ostree_sysroot_load_if_changed
|
||||||
|
@ -24,6 +24,7 @@ LIBOSTREE_2022.7 {
|
|||||||
global:
|
global:
|
||||||
ostree_kernel_args_contains;
|
ostree_kernel_args_contains;
|
||||||
ostree_kernel_args_delete_if_present;
|
ostree_kernel_args_delete_if_present;
|
||||||
|
ostree_sysroot_initialize_with_mount_namespace;
|
||||||
} LIBOSTREE_2022.5;
|
} LIBOSTREE_2022.5;
|
||||||
|
|
||||||
/* Stub section for the stable release *after* this development one; don't
|
/* Stub section for the stable release *after* this development one; don't
|
||||||
|
@ -259,6 +259,63 @@ ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self)
|
|||||||
self->mount_namespace_in_use = TRUE;
|
self->mount_namespace_in_use = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_sysroot_initialize_with_mount_namespace:
|
||||||
|
*
|
||||||
|
* Prepare the current process for modifying a booted sysroot, if applicable.
|
||||||
|
* This function subsumes the functionality of `ostree_sysroot_initialize`
|
||||||
|
* and may be invoked wherever that function is.
|
||||||
|
*
|
||||||
|
* If the sysroot does not appear to be booted, or where the current process is not uid 0,
|
||||||
|
* this function returns successfully.
|
||||||
|
*
|
||||||
|
* Otherwise, if the process is in the same mount namespace as pid 1, create
|
||||||
|
* a new namespace.
|
||||||
|
*
|
||||||
|
* If you invoke this function, it must be before ostree_sysroot_load(); it may
|
||||||
|
* be invoked before or after ostree_sysroot_initialize().
|
||||||
|
*
|
||||||
|
* Since: 2022.7
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
ostree_sysroot_initialize_with_mount_namespace (OstreeSysroot *self, GCancellable *cancellable, GError **error)
|
||||||
|
{
|
||||||
|
GLNX_AUTO_PREFIX_ERROR ("Initializing with mountns", error);
|
||||||
|
/* Must be before we're loaded, as otherwise we'd have to close/reopen all our
|
||||||
|
fds, e.g. the repo */
|
||||||
|
g_assert (self->loadstate < OSTREE_SYSROOT_LOAD_STATE_LOADED);
|
||||||
|
|
||||||
|
if (!ostree_sysroot_initialize (self, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Do nothing if we're not privileged */
|
||||||
|
if (getuid () != 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* We also assume operating on non-booted roots won't have a readonly sysroot */
|
||||||
|
if (!self->root_is_ostree_booted)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
g_autofree char *mntns_pid1 =
|
||||||
|
glnx_readlinkat_malloc (AT_FDCWD, "/proc/1/ns/mnt", cancellable, error);
|
||||||
|
if (!mntns_pid1)
|
||||||
|
return glnx_prefix_error (error, "Reading /proc/1/ns/mnt");
|
||||||
|
g_autofree char *mntns_self =
|
||||||
|
glnx_readlinkat_malloc (AT_FDCWD, "/proc/self/ns/mnt", cancellable, error);
|
||||||
|
if (!mntns_self)
|
||||||
|
return glnx_prefix_error (error, "Reading /proc/self/ns/mnt");
|
||||||
|
|
||||||
|
// If the mount namespaces are the same, we need to unshare().
|
||||||
|
if (strcmp (mntns_pid1, mntns_self) == 0)
|
||||||
|
{
|
||||||
|
if (unshare (CLONE_NEWNS) < 0)
|
||||||
|
return glnx_throw_errno_prefix (error, "Failed to invoke unshare(CLONE_NEWNS)");
|
||||||
|
}
|
||||||
|
|
||||||
|
ostree_sysroot_set_mount_namespace_in_use (self);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ostree_sysroot_get_path:
|
* ostree_sysroot_get_path:
|
||||||
* @self: Sysroot
|
* @self: Sysroot
|
||||||
|
@ -50,6 +50,9 @@ OstreeSysroot* ostree_sysroot_new_default (void);
|
|||||||
_OSTREE_PUBLIC
|
_OSTREE_PUBLIC
|
||||||
void ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self);
|
void ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self);
|
||||||
|
|
||||||
|
_OSTREE_PUBLIC
|
||||||
|
gboolean ostree_sysroot_initialize_with_mount_namespace (OstreeSysroot *self, GCancellable *cancellable, GError **error);
|
||||||
|
|
||||||
_OSTREE_PUBLIC
|
_OSTREE_PUBLIC
|
||||||
GFile *ostree_sysroot_get_path (OstreeSysroot *self);
|
GFile *ostree_sysroot_get_path (OstreeSysroot *self);
|
||||||
|
|
||||||
|
@ -586,23 +586,9 @@ ostree_admin_sysroot_load (OstreeSysroot *sysroot,
|
|||||||
{
|
{
|
||||||
if ((flags & OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED) == 0)
|
if ((flags & OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED) == 0)
|
||||||
{
|
{
|
||||||
/* If we're requested to lock the sysroot, first check if we're operating
|
/* Set up the mount namespace, if applicable */
|
||||||
* on a booted (not physical) sysroot. Then find out if the /sysroot
|
if (!ostree_sysroot_initialize_with_mount_namespace (sysroot, cancellable, error))
|
||||||
* subdir is a read-only mount point, and if so, create a new mount
|
return FALSE;
|
||||||
* namespace and tell the sysroot that we've done so. See the docs for
|
|
||||||
* ostree_sysroot_set_mount_namespace_in_use().
|
|
||||||
*
|
|
||||||
* This is a conservative approach; we could just always
|
|
||||||
* unshare() too.
|
|
||||||
*/
|
|
||||||
if (ostree_sysroot_is_booted (sysroot))
|
|
||||||
{
|
|
||||||
gboolean setup_ns = FALSE;
|
|
||||||
if (!maybe_setup_mount_namespace (&setup_ns, error))
|
|
||||||
return FALSE;
|
|
||||||
if (setup_ns)
|
|
||||||
ostree_sysroot_set_mount_namespace_in_use (sysroot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Released when sysroot is finalized, or on process exit */
|
/* Released when sysroot is finalized, or on process exit */
|
||||||
if (!ot_admin_sysroot_lock (sysroot, error))
|
if (!ot_admin_sysroot_lock (sysroot, error))
|
||||||
|
Loading…
Reference in New Issue
Block a user