-
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
generator: Fixes for Android Boot environment #3192
Conversation
Will "undraft" this PR pending testing... |
Re-pushing something shortly hold tight. |
fadec22
to
81b94ab
Compare
c3813e3
to
a8f8ca8
Compare
In Android Boot environment we do not parse ostree= karg to determine what directory to boot into, alternatively we do this based on the androidboot.slot_suffix= karg. But we do set ostree=true karg to denote that we are indeed booting an ostree environment (required for some systemd unit files). This change accounts for this approach in the systemd generator. In this case androidboot.slot_suffix= points you to /ostree/root.[a|b] and then that points you to the directory to boot into in /ostree/deploy... Here is what a cmdline may look like in this type of environment: androidboot.slot_suffix=_a androidboot.bootdevice=*.ufshc root=PARTLABEL=system_a root=UUID=76a22bf4-f153-4541-b6c7-0332c0dfaeac rw ostree=true loglevel=4 acpi=off console=ttyAMA0 systemd.show_status=auto libahci.ignore_sss=1 slub_debug=FPZ fsck.mode=skip rcupdate.rcu_normal_after_boot=0 rcupdate.rcu_expedited=1 Signed-off-by: Eric Curtin <[email protected]>
a8f8ca8
to
4a71845
Compare
/ok-to-test |
"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 comment
The 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.
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.
lgtm
@@ -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; |
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 an ostree=
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:
if (!otcore_get_ostree_target (cmdline, &is_aboot, &ostree_target,
NULL)
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 the GError**
. 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.
if (!otcore_get_ostree_target (cmdline, &is_aboot, &ostree_target, error))
return FALSE;
/* This could happen ... */
if (!ostree_target)
return TRUE;
@@ -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 comment
The 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 NULL
if they're not interested.
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.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
In this context, optional means that the caller is allowed to pass NULL
. So then in this function we'd do e.g.
if (is_aboot)
*is_aboot = ...
/* 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. */ |
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.
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 ostree=
karg exists". E.g.
/* 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. */ | |
/* If no `ostree=` karg exists, gracefully no-op. | |
* 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. */ |
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.
Will add
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.
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 comment
The 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 comment
The 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
@@ -19,6 +19,8 @@ | |||
|
|||
#pragma once | |||
|
|||
#include <stdbool.h> |
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.
Minor: we do use bool
in a few places already but not really in function signatures. Let's just keep using gboolean
for consistency?
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.
SGTM
regex = g_regex_new (is_aboot ? "^deploy/([^/]+)/" | ||
: "^/ostree/boot.([01])/([^/]+)/([^/]+)/([0-9]+)$", | ||
0, 0, NULL); |
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.
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 GRegex
s instead.
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.
The thing is I'd end up doing:
if (!g_regex_match (is_aboot ? aboot_regex : non_aboot_regex, to_parse, 0, &match))
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 comment
The 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 comment
The 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 g_regex_match
.
The difference is that the function correctly handles is_aboot
actually being different on multiple calls in the same invocation. If we're saying that's never gonna happen, then I would refactor things to lift is_aboot
to e.g. the OstreeSysroot
level or so to say "this is an aboot-managed machine". Short-term, just handling this here correctly makes the code more obviously right when reading the 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.
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.
@ericcurtin can you address the @jlebon comments before I do the release? |
I'll open another PR |
In Android Boot environment we do not parse ostree= karg to determine
what directory to boot into, alternatively we do this based on the
androidboot.slot_suffix= karg. But we do set ostree=true karg to denote
that we are indeed booting an ostree environment (required for some
systemd unit files). This change accounts for this approach in the
systemd generator. In this case androidboot.slot_suffix= points you to
/ostree/root.[a|b] and then that points you to the directory to boot
into in /ostree/deploy... Here is what a cmdline may look like in this
type of environment:
androidboot.slot_suffix=_a androidboot.bootdevice=*.ufshc root=PARTLABEL=system_a root=UUID=76a22bf4-f153-4541-b6c7-0332c0dfaeac rw ostree=true loglevel=4 acpi=off console=ttyAMA0 systemd.show_status=auto libahci.ignore_sss=1 slub_debug=FPZ fsck.mode=skip rcupdate.rcu_normal_after_boot=0 rcupdate.rcu_expedited=1