mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #21807 from keszybz/bootcls-no-autodetect
Use KERNEL_INSTALL_MACHINE_ID and KERNEL_INSTALL_LAYOUT with bootctl install
This commit is contained in:
commit
3e6357de9d
@ -258,14 +258,11 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--make-machine-id-directory=yes|no|auto</option></term>
|
||||
<term><option>--make-machine-id-directory=yes|no</option></term>
|
||||
<listitem><para>Control creation and deletion of the top-level machine ID directory on the file
|
||||
system containing boot loader entries (i.e. beneath the file system returned by the
|
||||
<option>--print-boot-path</option> option, see above) during <option>install</option> and
|
||||
<option>remove</option>, respectively. <literal>auto</literal> is equivalent to
|
||||
<literal>yes</literal> if <filename>/etc/machine-id</filename> resides on a filesystem other than
|
||||
tmpfs and <literal>no</literal> otherwise (in the latter case the machine ID is likely transient and
|
||||
hence should not be used persistently in the ESP). Defaults to <literal>auto</literal>. See
|
||||
<option>remove</option>, respectively. Defaults to <literal>no</literal>. See
|
||||
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
|
||||
details about the machine ID concept and file.</para>
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "dirent-util.h"
|
||||
#include "efi-loader.h"
|
||||
#include "efivars.h"
|
||||
#include "env-file.h"
|
||||
#include "env-util.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
@ -40,6 +41,7 @@
|
||||
#include "sync-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "tmpfile-util.h"
|
||||
#include "tmpfile-util-label.h"
|
||||
#include "umask-util.h"
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
@ -53,10 +55,13 @@ static bool arg_print_dollar_boot_path = false;
|
||||
static bool arg_touch_variables = true;
|
||||
static PagerFlags arg_pager_flags = 0;
|
||||
static bool arg_graceful = false;
|
||||
static int arg_make_machine_id_directory = -1;
|
||||
static int arg_make_machine_id_directory = 0;
|
||||
static sd_id128_t arg_machine_id = SD_ID128_NULL;
|
||||
static char *arg_install_layout = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_install_layout, freep);
|
||||
|
||||
static const char *arg_dollar_boot_path(void) {
|
||||
/* $BOOT shall be the XBOOTLDR partition if it exists, and otherwise the ESP */
|
||||
@ -119,17 +124,68 @@ static int acquire_xbootldr(bool unprivileged_mode, sd_id128_t *ret_uuid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void settle_make_machine_id_directory(void) {
|
||||
static int load_install_machine_id_and_layout(void) {
|
||||
/* Figure out the right machine-id for operations. If KERNEL_INSTALL_MACHINE_ID is configured in
|
||||
* /etc/machine-info, let's use that. Otherwise, just use the real machine-id.
|
||||
*
|
||||
* Also load KERNEL_INSTALL_LAYOUT.
|
||||
*/
|
||||
_cleanup_free_ char *s = NULL, *layout = NULL;
|
||||
int r;
|
||||
|
||||
if (arg_make_machine_id_directory >= 0)
|
||||
return;
|
||||
r = parse_env_file(NULL, "/etc/machine-info",
|
||||
"KERNEL_INSTALL_LAYOUT", &layout,
|
||||
"KERNEL_INSTALL_MACHINE_ID", &s);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return log_error_errno(r, "Failed to parse /etc/machine-info: %m");
|
||||
|
||||
r = path_is_temporary_fs("/etc/machine-id");
|
||||
if (isempty(s)) {
|
||||
r = sd_id128_get_machine(&arg_machine_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get machine-id: %m");
|
||||
} else {
|
||||
r = sd_id128_from_string(s, &arg_machine_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse KERNEL_INSTALL_MACHINE_ID=%s in /etc/machine-info: %m", s);
|
||||
|
||||
}
|
||||
log_debug("Using KERNEL_INSTALL_MACHINE_ID=%s from %s.",
|
||||
SD_ID128_TO_STRING(arg_machine_id),
|
||||
isempty(s) ? "/etc/machine_id" : "KERNEL_INSTALL_MACHINE_ID in /etc/machine-info");
|
||||
|
||||
if (!isempty(layout)) {
|
||||
log_debug("KERNEL_INSTALL_LAYOUT=%s is specified in /etc/machine-info.", layout);
|
||||
arg_install_layout = TAKE_PTR(layout);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int settle_install_machine_id(void) {
|
||||
int r;
|
||||
|
||||
r = load_install_machine_id_and_layout();
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Couldn't determine whether /etc/machine-id is on a temporary file system, assuming so.");
|
||||
return r;
|
||||
|
||||
arg_make_machine_id_directory = r == 0;
|
||||
bool layout_non_bls = arg_install_layout && !streq(arg_install_layout, "bls");
|
||||
if (arg_make_machine_id_directory < 0) {
|
||||
if (layout_non_bls)
|
||||
arg_make_machine_id_directory = 0;
|
||||
else {
|
||||
r = path_is_temporary_fs("/etc/machine-id");
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Couldn't determine whether /etc/machine-id is on a temporary file system: %m");
|
||||
arg_make_machine_id_directory = r == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_make_machine_id_directory > 0 && layout_non_bls)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"KERNEL_INSTALL_LAYOUT=%s is configured, but bls directory creation was requested.",
|
||||
arg_install_layout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* search for "#### LoaderInfo: systemd-boot 218 ####" string inside the binary */
|
||||
@ -924,20 +980,14 @@ static int remove_subdirs(const char *root, const char *const *subdirs) {
|
||||
}
|
||||
|
||||
static int remove_machine_id_directory(const char *root) {
|
||||
sd_id128_t machine_id;
|
||||
int r;
|
||||
|
||||
assert(root);
|
||||
assert(arg_make_machine_id_directory >= 0);
|
||||
assert(!sd_id128_is_null(arg_machine_id));
|
||||
|
||||
if (!arg_make_machine_id_directory)
|
||||
return 0;
|
||||
|
||||
r = sd_id128_get_machine(&machine_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get machine id: %m");
|
||||
|
||||
return rmdir_one(root, SD_ID128_TO_STRING(machine_id));
|
||||
return rmdir_one(root, SD_ID128_TO_STRING(arg_machine_id));
|
||||
}
|
||||
|
||||
static int remove_binaries(const char *esp_path) {
|
||||
@ -1047,13 +1097,8 @@ static int install_loader_config(const char *esp_path) {
|
||||
"#console-mode keep\n");
|
||||
|
||||
if (arg_make_machine_id_directory) {
|
||||
sd_id128_t machine_id;
|
||||
|
||||
r = sd_id128_get_machine(&machine_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get machine id: %m");
|
||||
|
||||
fprintf(f, "default %s-*\n", SD_ID128_TO_STRING(machine_id));
|
||||
assert(!sd_id128_is_null(arg_machine_id));
|
||||
fprintf(f, "default %s-*\n", SD_ID128_TO_STRING(arg_machine_id));
|
||||
}
|
||||
|
||||
r = fflush_sync_and_check(f);
|
||||
@ -1071,20 +1116,100 @@ static int install_loader_config(const char *esp_path) {
|
||||
}
|
||||
|
||||
static int install_machine_id_directory(const char *root) {
|
||||
sd_id128_t machine_id;
|
||||
int r;
|
||||
|
||||
assert(root);
|
||||
assert(arg_make_machine_id_directory >= 0);
|
||||
|
||||
if (!arg_make_machine_id_directory)
|
||||
return 0;
|
||||
|
||||
r = sd_id128_get_machine(&machine_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get machine id: %m");
|
||||
assert(!sd_id128_is_null(arg_machine_id));
|
||||
return mkdir_one(root, SD_ID128_TO_STRING(arg_machine_id));
|
||||
}
|
||||
|
||||
return mkdir_one(root, SD_ID128_TO_STRING(machine_id));
|
||||
static int install_machine_info_config(void) {
|
||||
_cleanup_free_ char *contents = NULL;
|
||||
size_t length;
|
||||
bool need_install_layout = true, need_machine_id;
|
||||
int r;
|
||||
|
||||
assert(arg_make_machine_id_directory >= 0);
|
||||
|
||||
/* We only want to save the machine-id if we created any directories using it. */
|
||||
need_machine_id = arg_make_machine_id_directory;
|
||||
|
||||
_cleanup_fclose_ FILE *orig = fopen("/etc/machine-info", "re");
|
||||
if (!orig && errno != ENOENT)
|
||||
return log_error_errno(errno, "Failed to open /etc/machine-info: %m");
|
||||
|
||||
if (orig) {
|
||||
_cleanup_free_ char *install_layout = NULL, *machine_id = NULL;
|
||||
|
||||
r = parse_env_file(orig, "/etc/machine-info",
|
||||
"KERNEL_INSTALL_LAYOUT", &install_layout,
|
||||
"KERNEL_INSTALL_MACHINE_ID", &machine_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse /etc/machine-info: %m");
|
||||
|
||||
rewind(orig);
|
||||
|
||||
if (!isempty(install_layout))
|
||||
need_install_layout = false;
|
||||
|
||||
if (!isempty(machine_id))
|
||||
need_machine_id = false;
|
||||
|
||||
if (!need_install_layout && !need_machine_id) {
|
||||
log_debug("/etc/machine-info already has KERNEL_INSTALL_MACHINE_ID=%s and KERNEL_INSTALL_LAYOUT=%s.",
|
||||
machine_id, install_layout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = read_full_stream(orig, &contents, &length);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read /etc/machine-info: %m");
|
||||
}
|
||||
|
||||
_cleanup_(unlink_and_freep) char *dst_tmp = NULL;
|
||||
_cleanup_fclose_ FILE *dst = NULL;
|
||||
r = fopen_temporary_label("/etc/machine-info", /* The path for which to the look up the label */
|
||||
"/etc/machine-info", /* Where we want the file actually to end up */
|
||||
&dst, /* The temporary file we write to */
|
||||
&dst_tmp);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to open temporary copy of /etc/machine-info: %m");
|
||||
|
||||
if (contents)
|
||||
fwrite_unlocked(contents, 1, length, dst);
|
||||
|
||||
bool no_newline = !contents || contents[length - 1] == '\n';
|
||||
|
||||
if (need_install_layout) {
|
||||
const char *line = "\nKERNEL_INSTALL_LAYOUT=bls\n" + no_newline;
|
||||
fwrite_unlocked(line, 1, strlen(line), dst);
|
||||
no_newline = false;
|
||||
}
|
||||
|
||||
const char *mid_string = SD_ID128_TO_STRING(arg_machine_id);
|
||||
if (need_machine_id)
|
||||
fprintf(dst, "%sKERNEL_INSTALL_MACHINE_ID=%s\n",
|
||||
no_newline ? "" : "\n",
|
||||
mid_string);
|
||||
|
||||
r = fflush_and_check(dst);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write temporary copy of /etc/machine-info: %m");
|
||||
if (fchmod(fileno(dst), 0644) < 0)
|
||||
return log_debug_errno(errno, "Failed to fchmod %s: %m", dst_tmp);
|
||||
|
||||
if (rename(dst_tmp, "/etc/machine-info") < 0)
|
||||
return log_error_errno(errno, "Failed to replace /etc/machine-info: %m");
|
||||
|
||||
log_info("%s /etc/machine-info with%s%s%s",
|
||||
orig ? "Updated" : "Created",
|
||||
need_install_layout ? " KERNEL_INSTALL_LAYOUT=bls" : "",
|
||||
need_machine_id ? " KERNEL_INSTALL_MACHINE_ID=" : "",
|
||||
need_machine_id ? mid_string : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int help(int argc, char *argv[], void *userdata) {
|
||||
@ -1222,8 +1347,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case ARG_MAKE_MACHINE_ID_DIRECTORY:
|
||||
if (streq(optarg, "auto"))
|
||||
arg_make_machine_id_directory = -1; /* default */
|
||||
if (streq(optarg, "auto")) /* retained for backwards compatibility */
|
||||
arg_make_machine_id_directory = -1; /* yes if machine-id is permanent */
|
||||
else {
|
||||
r = parse_boolean_argument("--make-machine-id-directory=", optarg, &b);
|
||||
if (r < 0)
|
||||
@ -1637,7 +1762,9 @@ static int verb_install(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
settle_make_machine_id_directory();
|
||||
r = settle_install_machine_id();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
RUN_WITH_UMASK(0002) {
|
||||
if (install) {
|
||||
@ -1666,6 +1793,10 @@ static int verb_install(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = install_machine_info_config();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = install_random_seed(arg_esp_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1695,7 +1826,9 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
settle_make_machine_id_directory();
|
||||
r = settle_install_machine_id();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = remove_binaries(arg_esp_path);
|
||||
|
||||
|
@ -269,10 +269,10 @@ static int make_backup(const char *target, const char *x) {
|
||||
return -errno;
|
||||
|
||||
r = fopen_temporary_label(
|
||||
target, /* The path for which to the lookup the label */
|
||||
target, /* The path for which to the look up the label */
|
||||
x, /* Where we want the file actually to end up */
|
||||
&dst,
|
||||
&dst_tmp /* The temporary file we write to */);
|
||||
&dst, /* The temporary file we write to */
|
||||
&dst_tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user