Skip to content

Commit

Permalink
Remove hard condition on ostree= karg
Browse files Browse the repository at this point in the history
Some kernel images are delivered in a signed kernel + cmdline +
initramfs + dtb blob. When this is added to the commit server side, only
after this do you know what the cmdline is, this creates a recursion
issue. To avoid this, in the case where we don't have an ostree= karg
boot from the latest symlink in /sysroot/ostree.
  • Loading branch information
ericcurtin committed Apr 5, 2023
1 parent c927142 commit bdc955c
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 5 deletions.
1 change: 0 additions & 1 deletion src/boot/ostree-prepare-root.service
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
Description=OSTree Prepare OS/
Documentation=man:ostree(1)
DefaultDependencies=no
ConditionKernelCommandLine=ostree
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
After=sysroot.mount
Expand Down
1 change: 0 additions & 1 deletion src/boot/ostree-remount.service
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
Description=OSTree Remount OS/ Bind Mounts
Documentation=man:ostree(1)
DefaultDependencies=no
ConditionKernelCommandLine=ostree
OnFailure=emergency.target
Conflicts=umount.target
# Run after core mounts
Expand Down
77 changes: 77 additions & 0 deletions src/switchroot/ostree-mount-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef __OSTREE_MOUNT_UTIL_H_
#define __OSTREE_MOUNT_UTIL_H_

#include <dirent.h>
#include <err.h>
#include <stdlib.h>
#include <sys/statvfs.h>
Expand Down Expand Up @@ -72,6 +73,19 @@ read_proc_cmdline (void)
return cmdline;
}

static inline void
free_char(char **to_free)
{
free(*to_free);
}

static inline void
close_dir(DIR **dir)
{
if (*dir)
closedir(*dir);
}

static inline char *
read_proc_cmdline_ostree (void)
{
Expand Down Expand Up @@ -106,6 +120,69 @@ read_proc_cmdline_ostree (void)
return ret;
}

static inline char*
gen_ostree_target (const char* prepend)
{
char dir_str[PATH_MAX];
int dir_str_len = snprintf(dir_str, sizeof(dir_str), "%s", prepend);
int dir_str_cap = PATH_MAX - dir_str_len;
int prepend_len = dir_str_len;
dir_str_len += snprintf(dir_str + prepend_len, sizeof(dir_str), "%s", "/ostree");
dir_str_cap = PATH_MAX - dir_str_len;
char* append_from = dir_str + dir_str_len;
int appended_len = 0;
DIR __attribute__ ((cleanup(close_dir))) *dir = opendir(dir_str);
if (!dir)
{
fprintf(stderr, "'%s' %d", strerror(errno), __LINE__);
return "";
}

struct dirent *ent = 0;
for (time_t latest = 0; (ent = readdir(dir)); )
{
if (ent->d_type == DT_LNK)
{
struct stat lsb;
lsb.st_mtime = 0;
lstat(ent->d_name, &lsb);
if (latest <= lsb.st_mtime)
{
appended_len = snprintf(append_from, dir_str_cap, "/%s", ent->d_name);
latest = lsb.st_mtime;
}
}
}

dir_str_len += appended_len;
dir_str_cap = PATH_MAX - dir_str_len;

for (int i = 0; i < 3; ++i)
{
DIR __attribute__ ((cleanup(close_dir))) *dir1 = opendir(dir_str);
if (!dir1)
{
fprintf(stderr, "%s:%d\n", strerror(errno), __LINE__);
return "";
}

while ((ent = readdir(dir1)))
{
if (ent->d_name[0] != '.')
{
dir_str_len += snprintf(dir_str + dir_str_len, dir_str_cap, "/%s", ent->d_name);
dir_str_cap = PATH_MAX - dir_str_len;
break;
}
}
}

/* We don't want the initial part included, we want to start at /ostree from
* the caller.
*/
return strdup(dir_str + prepend_len);
}

/* This is an API for other projects to determine whether or not the
* currently running system is ostree-controlled.
*/
Expand Down
10 changes: 8 additions & 2 deletions src/switchroot/ostree-prepare-root.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,17 @@ resolve_deploy_path (const char * root_mountpoint)
{
char destpath[PATH_MAX];
struct stat stbuf;
char *ostree_target, *deploy_path;
char __attribute__ ((cleanup(free_char))) *ostree_target;
char *deploy_path;

ostree_target = read_proc_cmdline_ostree ();
if (!ostree_target)
errx (EXIT_FAILURE, "No OSTree target; expected ostree=/ostree/boot.N/...");
{
ostree_target = gen_ostree_target (root_mountpoint);
}

if (!ostree_target)
errx (EXIT_FAILURE, "Could not find OSTree target either via ostree=/ostree/boot.N/ or searching,...");

if (snprintf (destpath, sizeof(destpath), "%s/%s", root_mountpoint, ostree_target) < 0)
err (EXIT_FAILURE, "failed to assemble ostree target path");
Expand Down
5 changes: 4 additions & 1 deletion src/switchroot/ostree-system-generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ main(int argc, char *argv[])
* exit so that we don't error, but at the same time work where switchroot
* is PID 1 (and so hasn't created /run/ostree-booted).
*/
char *ostree_cmdline = read_proc_cmdline_ostree ();
char __attribute__ ((cleanup(free_char))) *ostree_cmdline = read_proc_cmdline_ostree ();
if (!ostree_cmdline)
ostree_cmdline = gen_ostree_target("/sysroot");

if (!ostree_cmdline)
exit (EXIT_SUCCESS);

Expand Down

0 comments on commit bdc955c

Please sign in to comment.