bootctl: Add --force option to enable chroot install/remove of sd-boot

This change enables the force-installation, removal, and update of the
systemd EFI boot binaries and supporting assets, without requiring verification
of the ESP.

Prior to this change it is assumed the target path is an ESP that can be probed,
however this requires several virtual filesystems to be present and mounted,
which may not be possible during filesystem image generation, or even for use
within eltorito alt sections of an ISO.

Given that an image invocation of bootctl may involve a host that has older,
or even absent files required by bootctl (such as EFI files), it is not always
safe to assume one can use the --path option. This change ensures that the
utility can be used in a consistent manner, in a bare chroot (no virtual
filesystems), without the need for custom systemd-boot installation routines
currently seen in many places; i.e bootctl both sets and enforces the standard
for its installation, configuration and layout.
This commit is contained in:
Ikey Doherty
2015-09-23 03:36:36 +01:00
committed by Dimitri John Ledkov
parent 5900c132c1
commit 1bd4f581e8
+12 -3
View File
@@ -937,12 +937,14 @@ static int help(void) {
static const char *arg_path = "/boot";
static bool arg_touch_variables = true;
static bool arg_force = false;
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_PATH = 0x100,
ARG_VERSION,
ARG_NO_VARIABLES,
ARG_FORCE,
};
static const struct option options[] = {
@@ -950,6 +952,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "path", required_argument, NULL, ARG_PATH },
{ "no-variables", no_argument, NULL, ARG_NO_VARIABLES },
{ "force", no_argument, NULL, ARG_FORCE },
{ NULL, 0, NULL, 0 }
};
@@ -975,6 +978,9 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_NO_VARIABLES:
arg_touch_variables = false;
break;
case ARG_FORCE:
arg_force = true;
break;
case '?':
return -EINVAL;
@@ -1034,10 +1040,13 @@ static int bootctl_main(int argc, char*argv[]) {
if (geteuid() != 0)
return log_error_errno(EPERM, "Need to be root.");
if (arg_force && arg_action < ACTION_INSTALL)
return log_error_errno(EINVAL, "Can only force install, update or remove operations");
r = verify_esp(arg_path, &part, &pstart, &psize, &uuid);
if (r == -ENODEV && !arg_path)
log_notice("You might want to use --path= to indicate the path to your ESP, in case it is not mounted on /boot.");
if (r < 0)
if (r < 0 && !arg_force)
return r;
switch (arg_action) {
@@ -1110,7 +1119,7 @@ static int bootctl_main(int argc, char*argv[]) {
return r;
}
if (arg_touch_variables)
if (arg_touch_variables && !arg_force)
r = install_variables(arg_path,
part, pstart, psize, uuid,
"/EFI/systemd/systemd-boot" EFI_MACHINE_TYPE_NAME ".efi",
@@ -1120,7 +1129,7 @@ static int bootctl_main(int argc, char*argv[]) {
case ACTION_REMOVE:
r = remove_binaries(arg_path);
if (arg_touch_variables) {
if (arg_touch_variables && !arg_force) {
q = remove_variables(uuid, "/EFI/systemd/systemd-boot" EFI_MACHINE_TYPE_NAME ".efi", true);
if (q < 0 && r == 0)
r = q;