-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
generator: Fixes for Android Boot environment #3192
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -128,8 +128,8 @@ require_internal_units (const char *normal_dir, const char *early_dir, const cha | |||||||||||||||
|
||||||||||||||||
/* Generate var.mount */ | ||||||||||||||||
static gboolean | ||||||||||||||||
fstab_generator (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, | ||||||||||||||||
const char *late_dir, GError **error) | ||||||||||||||||
fstab_generator (const char *ostree_target, const bool is_aboot, const char *normal_dir, | ||||||||||||||||
const char *early_dir, const char *late_dir, GError **error) | ||||||||||||||||
{ | ||||||||||||||||
#ifdef HAVE_LIBMOUNT | ||||||||||||||||
/* Not currently cancellable, but define a var in case we care later */ | ||||||||||||||||
|
@@ -144,7 +144,8 @@ fstab_generator (const char *ostree_cmdline, const char *normal_dir, const char | |||||||||||||||
* mounted yet. | ||||||||||||||||
*/ | ||||||||||||||||
g_autofree char *stateroot = NULL; | ||||||||||||||||
if (!_ostree_sysroot_parse_bootlink (ostree_cmdline, NULL, &stateroot, NULL, NULL, error)) | ||||||||||||||||
if (!_ostree_sysroot_parse_bootlink (ostree_target, is_aboot, NULL, &stateroot, NULL, NULL, | ||||||||||||||||
error)) | ||||||||||||||||
return glnx_prefix_error (error, "Parsing stateroot"); | ||||||||||||||||
|
||||||||||||||||
/* Load /etc/fstab if it exists, and look for a /var mount */ | ||||||||||||||||
|
@@ -261,17 +262,19 @@ _ostree_impl_system_generator (const char *normal_dir, const char *early_dir, co | |||||||||||||||
if (!cmdline) | ||||||||||||||||
return glnx_throw (error, "Failed to read /proc/cmdline"); | ||||||||||||||||
|
||||||||||||||||
g_autofree char *ostree_cmdline = otcore_find_proc_cmdline_key (cmdline, "ostree"); | ||||||||||||||||
|
||||||||||||||||
g_autoptr (GError) otcore_get_ostree_target_error = NULL; | ||||||||||||||||
g_autofree char *ostree_target = NULL; | ||||||||||||||||
bool is_aboot = false; | ||||||||||||||||
/* This could happen in CoreOS live environments, where we hackily mock | ||||||||||||||||
* the `ostree=` karg for `ostree-prepare-root.service` specifically, but | ||||||||||||||||
* otherwise that karg doesn't exist on the real command-line. */ | ||||||||||||||||
Comment on lines
268
to
270
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think now that the conditional is more complex, let's tweak the comment slightly to make it clearer that we're referring to the "no
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you've identified generally this comment no longer makes a lot of sense, the only place the function fails is in the case where slot_suffix isn't right There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll rewrite the comment in this area, it's gonna be tomorrow morning, been online waaay too many hours this week |
||||||||||||||||
if (!ostree_cmdline) | ||||||||||||||||
if (!otcore_get_ostree_target (cmdline, &is_aboot, &ostree_target, | ||||||||||||||||
&otcore_get_ostree_target_error)) | ||||||||||||||||
return TRUE; | ||||||||||||||||
|
||||||||||||||||
if (!require_internal_units (normal_dir, early_dir, late_dir, error)) | ||||||||||||||||
return FALSE; | ||||||||||||||||
if (!fstab_generator (ostree_cmdline, normal_dir, early_dir, late_dir, error)) | ||||||||||||||||
if (!fstab_generator (ostree_target, is_aboot, normal_dir, early_dir, late_dir, error)) | ||||||||||||||||
return FALSE; | ||||||||||||||||
|
||||||||||||||||
return TRUE; | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ | |
|
||
#pragma once | ||
|
||
#include <stdbool.h> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: we do use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SGTM |
||
|
||
#include "libglnx.h" | ||
#include "ostree-bootloader.h" | ||
#include "ostree.h" | ||
|
@@ -177,8 +179,9 @@ gboolean _ostree_sysroot_parse_bootdir_name (const char *name, char **out_osname | |
gboolean _ostree_sysroot_list_all_boot_directories (OstreeSysroot *self, char ***out_bootdirs, | ||
GCancellable *cancellable, GError **error); | ||
|
||
gboolean _ostree_sysroot_parse_bootlink (const char *bootlink, int *out_entry_bootversion, | ||
char **out_osname, char **out_bootcsum, | ||
int *out_treebootserial, GError **error); | ||
gboolean _ostree_sysroot_parse_bootlink (const char *bootlink, const bool is_aboot, | ||
int *out_entry_bootversion, char **out_osname, | ||
char **out_bootcsum, int *out_treebootserial, | ||
GError **error); | ||
|
||
G_END_DECLS |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -724,24 +724,44 @@ load_origin (OstreeSysroot *self, OstreeDeployment *deployment, GCancellable *ca | |
|
||
// Parse the kernel argument ostree= | ||
gboolean | ||
_ostree_sysroot_parse_bootlink (const char *bootlink, int *out_entry_bootversion, char **out_osname, | ||
char **out_bootcsum, int *out_treebootserial, GError **error) | ||
_ostree_sysroot_parse_bootlink (const char *bootlink, const bool is_aboot, | ||
int *out_entry_bootversion, char **out_osname, char **out_bootcsum, | ||
int *out_treebootserial, GError **error) | ||
{ | ||
static gsize regex_initialized; | ||
static GRegex *regex; | ||
const char *to_parse = bootlink; | ||
g_autofree char *symlink_val = NULL; | ||
if (is_aboot) | ||
{ | ||
symlink_val = glnx_readlinkat_malloc (-1, bootlink, NULL, error); | ||
if (!symlink_val) | ||
return glnx_throw (error, "Failed to read '%s' symlink", bootlink); | ||
|
||
to_parse = symlink_val; | ||
} | ||
|
||
if (g_once_init_enter (®ex_initialized)) | ||
{ | ||
regex = g_regex_new ("^/ostree/boot.([01])/([^/]+)/([^/]+)/([0-9]+)$", 0, 0, NULL); | ||
regex = g_regex_new (is_aboot ? "^deploy/([^/]+)/" | ||
: "^/ostree/boot.([01])/([^/]+)/([^/]+)/([0-9]+)$", | ||
0, 0, NULL); | ||
Comment on lines
+746
to
+748
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having a conditional selector for the regex in a g_once looks highly suspect here. I think in practice it doesn't matter too much because you probably only have all aboot deployments or none. But the way the API for this function is structured leaves the door open. ISTM we probably want two static There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The thing is I'd end up doing:
so it wouldn't make a whole pile of difference. /proc/cmdline is an immutable file. Each process re-runs g_once_init_enter. We can do code like above (technically they are different regex strings), but it's not really gonna change much in reality. It's also gonna be more lines of duplicate code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll just write a _ostree_sysroot_parse_bootlink_aboot function altogether There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not that much duplicate code. Basically I'm saying something like: static GRegex *regex_aboot;
static GRegex *regex_ostree;
if (g_once_init_enter (...))
{
regex_aboot = ...
regex_ostree = ...
} and move the ternary down to The difference is that the function correctly handles There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wrote a _ostree_sysroot_parse_bootlink_aboot function instead in #3195, the only thing the aboot version had in common was that it was using a regex, it was starting to get messey. |
||
g_assert (regex); | ||
g_once_init_leave (®ex_initialized, 1); | ||
} | ||
|
||
g_autoptr (GMatchInfo) match = NULL; | ||
if (!g_regex_match (regex, bootlink, 0, &match)) | ||
if (!g_regex_match (regex, to_parse, 0, &match)) | ||
return glnx_throw (error, | ||
"Invalid ostree= argument '%s', expected " | ||
"ostree=/ostree/boot.BOOTVERSION/OSNAME/BOOTCSUM/TREESERIAL", | ||
bootlink); | ||
"ostree=/ostree/boot.BOOTVERSION/OSNAME/BOOTCSUM/TREESERIAL or aboot method", | ||
to_parse); | ||
|
||
if (is_aboot) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main difference of this PR, the systemd generator needs to parse the OSNAME from the directory structure which is a little different in the aboot case. |
||
{ | ||
*out_osname = g_match_info_fetch (match, 1); | ||
return TRUE; | ||
} | ||
|
||
g_autofree char *bootversion_str = g_match_info_fetch (match, 1); | ||
g_autofree char *treebootserial_str = g_match_info_fetch (match, 4); | ||
|
@@ -775,7 +795,10 @@ parse_deployment (OstreeSysroot *self, const char *boot_link, OstreeDeployment * | |
g_autofree char *osname = NULL; | ||
g_autofree char *bootcsum = NULL; | ||
int treebootserial = -1; | ||
if (!_ostree_sysroot_parse_bootlink (boot_link, &entry_boot_version, &osname, &bootcsum, | ||
|
||
// Note is_boot should always be false here, this boot_link is taken from BLS file, not | ||
// /proc/cmdline, BLS files are present in aboot images | ||
if (!_ostree_sysroot_parse_bootlink (boot_link, false, &entry_boot_version, &osname, &bootcsum, | ||
&treebootserial, error)) | ||
return FALSE; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,7 +75,7 @@ otcore_find_proc_cmdline_key (const char *cmdline, const char *key) | |
// | ||
// If invalid data is found, @error will be set. | ||
gboolean | ||
otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error) | ||
otcore_get_ostree_target (const char *cmdline, bool *is_aboot, char **out_target, GError **error) | ||
{ | ||
g_assert (cmdline); | ||
g_assert (out_target && *out_target == NULL); | ||
|
@@ -84,8 +84,10 @@ otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error | |
|
||
// First, handle the Android boot case | ||
g_autofree char *slot_suffix = otcore_find_proc_cmdline_key (cmdline, "androidboot.slot_suffix"); | ||
*is_aboot = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the callers, might as well make this argument optional so they can just pass There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are there examples of optional arguments in this codebase? I know we can't do that in C generally but maybe there's some extension to C etc. that does this we are using that I'm not aware of. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this context, optional means that the caller is allowed to pass
|
||
if (slot_suffix) | ||
{ | ||
*is_aboot = true; | ||
if (strcmp (slot_suffix, "_a") == 0) | ||
{ | ||
*out_target = g_strdup (slot_a); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't being checked. But anyway, why not pass
error
to the function? Looking at the code, not finding anostree=
karg isn't fatal.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually care so much if otcore_get_ostree_target fails but if there is no karg found for ostree selection we should return true for the CoreOS live environments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the androidboot karg doesn't exist all behavior is identical to what this code was like previous to this commit...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a "error" passed to this function, I deliberately didn't use it and used this one instead otcore_get_ostree_target_error, because we don't care so much about the otcore_get_ostree_target_error errors. But we do care about the "error" errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or are we saying:
should work? Didn't do this just in case of NULL ptr dereference or something, but if you are confident this works ok I trust you 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's totally OK to pass
NULL
for theGError**
. But I guess the question is, do we want to ignore the "androidboot.slot_suffix invalid: %s" error? I don't see why we would special-case that one. We're strict everywhere else in this function.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But actually, I think the issue is that the logic here is not correct. It should be e.g.