Skip to content

Commit

Permalink
otcore: add debug logging capability for ostree-prepare-root
Browse files Browse the repository at this point in the history
This commit introduces a new function, proc_cmdline_has_key, to check for
specific keys in the kernel command line. Additionally, it adds a debug
logging mechanism in ostree-prepare-root.c, which is controlled by the
presence of the "ostree-prepare-root.debug" key in the kernel command line.

These changes provide enhanced visibility into the mounting process,
aiding in troubleshooting.

Signed-off-by: Eric Curtin <[email protected]>
  • Loading branch information
ericcurtin committed May 28, 2024
1 parent b605230 commit de33c7f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 21 deletions.
18 changes: 18 additions & 0 deletions src/libotcore/otcore-prepare-root.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@
// which can be used to fully verify the target filesystem tree.
#define BINDING_KEYPATH "/etc/ostree/initramfs-root-binding.key"

bool
proc_cmdline_has_key (const char *cmdline, const char *key)
{
for (const char *iter = cmdline; iter;)
{
if (g_str_equal (iter, key))
return true;

iter = strchr (iter, ' ');
if (iter == NULL)
return false;

iter += strspn (iter, " ");
}

return false;
}

static bool
proc_cmdline_has_key_starting_with (const char *cmdline, const char *key)
{
Expand Down
1 change: 1 addition & 0 deletions src/libotcore/otcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ bool otcore_ed25519_init (void);
gboolean otcore_validate_ed25519_signature (GBytes *data, GBytes *pubkey, GBytes *signature,
bool *out_valid, GError **error);

bool proc_cmdline_has_key (const char *cmdline, const char *key);
char *otcore_find_proc_cmdline_key (const char *cmdline, const char *key);
gboolean otcore_get_ostree_target (const char *cmdline, gboolean *is_aboot, char **out_target,
GError **error);
Expand Down
69 changes: 48 additions & 21 deletions src/switchroot/ostree-prepare-root.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@

#include "ostree-mount-util.h"

static bool enable_debug = false;

__attribute__ ((__format__ (printf, 1, 2))) static void
dbg (const char *format, ...)
{
if (enable_debug)
{
va_list args;
va_start (args, format);
vprintf (format, args);
va_end (args);
}
}

static int
ostree_mount (const char *source, const char *target, const char *filesystemtype,
const unsigned long mountflags, const char *options)
{
dbg ("ostree_mount(\"%s\", \"%s\", \"%s\", %lu, \"%s\")\n", source, target, filesystemtype,
mountflags, options);
return mount (source, target, filesystemtype, mountflags, options);
}

static bool
sysroot_is_configured_ro (const char *sysroot)
{
Expand Down Expand Up @@ -124,6 +147,7 @@ resolve_deploy_path (const char *root_mountpoint)

g_autoptr (GError) error = NULL;
g_autofree char *ostree_target = NULL;
enable_debug = proc_cmdline_has_key (kernel_cmdline, "ostree-prepare-root.debug");
if (!otcore_get_ostree_target (kernel_cmdline, NULL, &ostree_target, &error))
errx (EXIT_FAILURE, "Failed to determine ostree target: %s", error->message);
if (!ostree_target)
Expand Down Expand Up @@ -344,7 +368,7 @@ main (int argc, char *argv[])
*
* Kernel docs: Documentation/filesystems/sharedsubtree.txt
*/
if (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE | MS_SILENT, NULL) < 0)
if (ostree_mount (NULL, "/", NULL, MS_REC | MS_PRIVATE | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to make \"/\" private mount");

if (mkdir (TMP_SYSROOT, 0755) < 0)
Expand Down Expand Up @@ -492,7 +516,7 @@ main (int argc, char *argv[])
}
g_print ("Using legacy ostree bind mount for /\n");
/* The deploy root starts out bind mounted to sysroot.tmp */
if (mount (deploy_path, TMP_SYSROOT, NULL, MS_BIND | MS_SILENT, NULL) < 0)
if (ostree_mount (deploy_path, TMP_SYSROOT, NULL, MS_BIND | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to make initial bind mount %s", deploy_path);
}

Expand Down Expand Up @@ -522,7 +546,7 @@ main (int argc, char *argv[])
{
if (snprintf (srcpath, sizeof (srcpath), "%s/boot", root_mountpoint) < 0)
err (EXIT_FAILURE, "failed to assemble /boot path");
if (mount (srcpath, TMP_SYSROOT "/boot", NULL, MS_BIND | MS_SILENT, NULL) < 0)
if (ostree_mount (srcpath, TMP_SYSROOT "/boot", NULL, MS_BIND | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to bind mount %s to boot", srcpath);
}
}
Expand Down Expand Up @@ -564,16 +588,16 @@ main (int argc, char *argv[])

g_autofree char *ovl_options
= g_strdup_printf ("lowerdir=%s,upperdir=%s,workdir=%s", lowerdir, upperdir, workdir);
if (mount ("overlay", TMP_SYSROOT "/etc", "overlay", MS_SILENT, ovl_options) < 0)
if (ostree_mount ("overlay", TMP_SYSROOT "/etc", "overlay", MS_SILENT, ovl_options) < 0)
err (EXIT_FAILURE, "failed to mount transient etc overlayfs");
}
else
{
/* Bind-mount /etc (at deploy path), and remount as writable. */
if (mount ("etc", TMP_SYSROOT "/etc", NULL, MS_BIND | MS_SILENT, NULL) < 0)
if (ostree_mount ("etc", TMP_SYSROOT "/etc", NULL, MS_BIND | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to prepare /etc bind-mount at /sysroot.tmp/etc");
if (mount (TMP_SYSROOT "/etc", TMP_SYSROOT "/etc", NULL, MS_BIND | MS_REMOUNT | MS_SILENT,
NULL)
if (ostree_mount (TMP_SYSROOT "/etc", TMP_SYSROOT "/etc", NULL,
MS_BIND | MS_REMOUNT | MS_SILENT, NULL)
< 0)
err (EXIT_FAILURE, "failed to make writable /etc bind-mount at /sysroot.tmp/etc");
}
Expand All @@ -598,29 +622,31 @@ main (int argc, char *argv[])
// Propagate readonly state
if (!sysroot_currently_writable)
mflags |= MS_RDONLY;
if (mount ("overlay", TMP_SYSROOT "/usr", "overlay", mflags, usr_ovl_options) < 0)

if (ostree_mount ("overlay", TMP_SYSROOT "/usr", "overlay", mflags, usr_ovl_options) < 0)
err (EXIT_FAILURE, "failed to mount /usr overlayfs");
}
else if (!using_composefs)
{
/* Otherwise, a read-only bind mount for /usr. (Not needed for composefs) */
if (mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL, MS_BIND | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr");
if (mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL,
MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL)
if (ostree_mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL, MS_BIND | MS_SILENT, NULL)
< 0)
err (EXIT_FAILURE, "failed to bind ostree_mount(class:readonly) /usr");
if (ostree_mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL,
MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL)
< 0)
err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr");
err (EXIT_FAILURE, "failed to bind ostree_mount(class:readonly) /usr");
}

/* Prepare /var.
* When a read-only sysroot is configured, this adds a dedicated bind-mount (to itself)
* When a read-only sysroot is configured, this adds a dedicated bind-ostree_mount(to itself)
* so that the stateroot location stays writable. */
if (sysroot_readonly)
{
/* Bind-mount /var (at stateroot path), and remount as writable. */
if (mount ("../../var", "../../var", NULL, MS_BIND | MS_SILENT, NULL) < 0)
if (ostree_mount ("../../var", "../../var", NULL, MS_BIND | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to prepare /var bind-mount at %s", srcpath);
if (mount ("../../var", "../../var", NULL, MS_BIND | MS_REMOUNT | MS_SILENT, NULL) < 0)
if (ostree_mount ("../../var", "../../var", NULL, MS_BIND | MS_REMOUNT | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to make writable /var bind-mount at %s", srcpath);
}

Expand All @@ -641,7 +667,7 @@ main (int argc, char *argv[])
*/
if (mount_var)
{
if (mount ("../../var", TMP_SYSROOT "/var", NULL, MS_BIND | MS_SILENT, NULL) < 0)
if (ostree_mount ("../../var", TMP_SYSROOT "/var", NULL, MS_BIND | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to bind mount ../../var to var");
}

Expand All @@ -663,10 +689,10 @@ main (int argc, char *argv[])
* root under /sysroot/sysroot as systemd will be responsible for
* moving /sysroot to /.
*/
if (mount (root_mountpoint, "sysroot", NULL, MS_MOVE | MS_SILENT, NULL) < 0)
if (ostree_mount (root_mountpoint, "sysroot", NULL, MS_MOVE | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to MS_MOVE '%s' to 'sysroot'", root_mountpoint);

if (mount (".", root_mountpoint, NULL, MS_MOVE | MS_SILENT, NULL) < 0)
if (ostree_mount (".", root_mountpoint, NULL, MS_MOVE | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to MS_MOVE %s to %s", ".", root_mountpoint);

if (chdir (root_mountpoint) < 0)
Expand All @@ -681,7 +707,8 @@ main (int argc, char *argv[])
*/
if (sysroot_readonly)
{
if (mount ("sysroot", "sysroot", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL)
if (ostree_mount ("sysroot", "sysroot", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT,
NULL)
< 0)
err (EXIT_FAILURE, "failed to make /sysroot read-only");
}
Expand All @@ -694,7 +721,7 @@ main (int argc, char *argv[])
* at the very start (perhaps down the line systemd will have compile/runtime option
* to say that the initramfs environment did everything right from the start).
*/
if (mount ("none", "sysroot", NULL, MS_PRIVATE | MS_SILENT, NULL) < 0)
if (ostree_mount ("none", "sysroot", NULL, MS_PRIVATE | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "remounting 'sysroot' private");

exit (EXIT_SUCCESS);
Expand Down

0 comments on commit de33c7f

Please sign in to comment.