diff --git a/man/ostree-prepare-root.xml b/man/ostree-prepare-root.xml index 8a682e7315..dfcac7109b 100644 --- a/man/ostree-prepare-root.xml +++ b/man/ostree-prepare-root.xml @@ -163,6 +163,11 @@ License along with this library. If not, see . This accepts the same values as composefs.enabled above, and overrides the config file (if present). For example, specifying ostree.prepare-root.composefs=0 will disable composefs, even if it is enabled by default in the initrd config. + + ostree.prepare-root.readonly + This accepts the same values as sysroot.readonly above, and overrides the config file (if present). + For example, specifying ostree.prepare-root.readonly=0 will disable mounting /sysroot read-only, even if it is enabled by default in the initrd config. + diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c index e0a1641a8f..963feaed50 100644 --- a/src/libotcore/otcore-prepare-root.c +++ b/src/libotcore/otcore-prepare-root.c @@ -26,6 +26,8 @@ #define BINDING_KEYPATH "/etc/ostree/initramfs-root-binding.key" // The kernel argument to configure composefs #define CMDLINE_KEY_COMPOSEFS "ostree.prepare-root.composefs" +// The kernel argument to configure sysroot.readonly +#define CMDLINE_KEY_READONLY "ostree.prepare-root.readonly" static bool proc_cmdline_has_key_starting_with (const char *cmdline, const char *key) @@ -239,3 +241,36 @@ otcore_load_composefs_config (const char *cmdline, GKeyFile *config, gboolean lo return g_steal_pointer (&ret); } + +gboolean +otcore_load_sysroot_readonly (const char *cmdline, GKeyFile *config, + const ComposefsConfig *composefs_config, + gboolean *sysroot_readonly, GError **error) +{ + g_assert (cmdline); + g_assert (config); + g_assert (composefs_config); + g_assert (sysroot_readonly); + + GLNX_AUTO_PREFIX_ERROR ("Loading sysroot readonly config", error); + + g_autofree char *readonly_cmdline = + otcore_find_proc_cmdline_key (cmdline, CMDLINE_KEY_READONLY); + if (readonly_cmdline) + { + if (!_ostree_parse_boolean(readonly_cmdline, sysroot_readonly, error)) + return glnx_prefix_error (error, "handling karg" CMDLINE_KEY_READONLY); + + return TRUE; + } + + // If composefs is enabled, that also implies sysroot.readonly=true because it's + // the new default we want to use (not because it's actually required) + const gboolean sysroot_readonly_default = composefs_config->enabled == OT_TRISTATE_YES; + if (!ot_keyfile_get_boolean_with_default (config, OTCORE_PREPARE_ROOT_SYSROOT_KEY, + OTCORE_PREPARE_ROOT_READONLY_KEY, + sysroot_readonly_default, sysroot_readonly, error)) + return FALSE; + + return TRUE; +} diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h index 6e1d510329..9a57913ebd 100644 --- a/src/libotcore/otcore.h +++ b/src/libotcore/otcore.h @@ -61,6 +61,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComposefsConfig, otcore_free_composefs_config) ComposefsConfig *otcore_load_composefs_config (const char *cmdline, GKeyFile *config, gboolean load_keys, GError **error); +gboolean otcore_load_sysroot_readonly (const char *cmdline, GKeyFile *config, + const ComposefsConfig *composefs_config, + gboolean *sysroot_readonly, GError **error); // Our directory with transient state (eventually /run/ostree-booted should be a link to // /run/ostree/booted) @@ -86,6 +89,9 @@ ComposefsConfig *otcore_load_composefs_config (const char *cmdline, GKeyFile *co // EROFS mount if we somehow leaked it (but it *should* be unmounted always). #define OSTREE_COMPOSEFS_LOWERMNT OTCORE_RUN_OSTREE_PRIVATE "/cfsroot-lower" +#define OTCORE_PREPARE_ROOT_SYSROOT_KEY "sysroot" +#define OTCORE_PREPARE_ROOT_READONLY_KEY "readonly" + #define OTCORE_PREPARE_ROOT_COMPOSEFS_KEY "composefs" #define OTCORE_PREPARE_ROOT_ENABLED_KEY "enabled" #define OTCORE_PREPARE_ROOT_KEYPATH_KEY "keypath" diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index 7754673eeb..37910e73d9 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -76,9 +76,6 @@ #include "ot-keyfile-utils.h" #include "otcore.h" -#define SYSROOT_KEY "sysroot" -#define READONLY_KEY "readonly" - /* This key configures the / mount in the deployment root */ #define ROOT_KEY "root" #define ETC_KEY "etc" @@ -109,7 +106,8 @@ sysroot_is_configured_ro (const char *sysroot) return false; } - return g_key_file_get_boolean (repo_config, SYSROOT_KEY, READONLY_KEY, NULL); + return g_key_file_get_boolean (repo_config, OTCORE_PREPARE_ROOT_SYSROOT_KEY, + OTCORE_PREPARE_ROOT_READONLY_KEY, NULL); } static char * @@ -280,7 +278,6 @@ main (int argc, char *argv[]) if (!config) errx (EXIT_FAILURE, "Failed to parse config: %s", error->message); - gboolean sysroot_readonly = FALSE; gboolean root_transient = FALSE; if (!ot_keyfile_get_boolean_with_default (config, ROOT_KEY, TRANSIENT_KEY, FALSE, &root_transient, @@ -294,12 +291,10 @@ main (int argc, char *argv[]) if (!composefs_config) errx (EXIT_FAILURE, "%s", error->message); - // If composefs is enabled, that also implies sysroot.readonly=true because it's - // the new default we want to use (not because it's actually required) - const bool sysroot_readonly_default = composefs_config->enabled == OT_TRISTATE_YES; - if (!ot_keyfile_get_boolean_with_default (config, SYSROOT_KEY, READONLY_KEY, - sysroot_readonly_default, &sysroot_readonly, &error)) - errx (EXIT_FAILURE, "Failed to parse sysroot.readonly value: %s", error->message); + gboolean sysroot_readonly; + if (!otcore_load_sysroot_readonly (kernel_cmdline, config, composefs_config, &sysroot_readonly, + &error)) + errx (EXIT_FAILURE, "%s", error->message); /* This is the final target where we should prepare the rootfs. The usual * case with systemd in the initramfs is that root_mountpoint = "/sysroot".