tree-wide: make specifier expansion --root= aware

This fixes repart's, systemctl's, sysusers' and tmpfiles' specifier
expansion to honour the root dir specified with --root=. This is
relevant for specifiers such as %m, %o, … which are directly sourced
from files on disk.

This doesn't try to be overly smart: specifiers referring to runtime
concepts (i.e. boot ID, architecture, hostname) rather than files on the
medium are left as is. There's certainly a point to be made that they
should fail in case --root= is specified, but I am not entirely convinced
about that, and it's certainly something we can look into later if
there's reason to.

I wondered for a while how to hook this up best, but given that quite a
large number of specifiers resolve to data from files on disks, and most
of our tools needs this, I ultimately decided to make the root dir a
first class parameter to specifier_printf().

Replaces: #16187
Fixes: #16183
This commit is contained in:
Lennart Poettering
2021-06-24 22:30:14 +02:00
committed by Zbigniew Jędrzejewski-Szmek
parent 0c651d32d4
commit de61a04b18
16 changed files with 181 additions and 136 deletions
+19 -9
View File
@@ -963,6 +963,7 @@ static void install_info_free(UnitFileInstallInfo *i) {
free(i->name);
free(i->path);
free(i->root);
strv_free(i->aliases);
strv_free(i->wanted_by);
strv_free(i->required_by);
@@ -1023,6 +1024,7 @@ static int install_info_add(
InstallContext *c,
const char *name,
const char *path,
const char *root,
bool auxiliary,
UnitFileInstallInfo **ret) {
@@ -1066,6 +1068,14 @@ static int install_info_add(
goto fail;
}
if (root) {
i->root = strdup(root);
if (!i->root) {
r = -ENOMEM;
goto fail;
}
}
if (path) {
i->path = strdup(path);
if (!i->path) {
@@ -1147,11 +1157,11 @@ static int config_parse_also(
if (r == 0)
break;
r = install_name_printf(info, word, &printed);
r = install_name_printf(info, word, info->root, &printed);
if (r < 0)
return r;
r = install_info_add(c, printed, NULL, true, NULL);
r = install_info_add(c, printed, NULL, info->root, /* auxiliary= */ true, NULL);
if (r < 0)
return r;
@@ -1194,7 +1204,7 @@ static int config_parse_default_instance(
return log_syntax(unit, LOG_WARNING, filename, line, 0,
"DefaultInstance= only makes sense for template units, ignoring.");
r = install_name_printf(i, rvalue, &printed);
r = install_name_printf(i, rvalue, i->root, &printed);
if (r < 0)
return r;
@@ -1637,7 +1647,7 @@ static int install_info_traverse(
bn = buffer;
}
r = install_info_add(c, bn, NULL, false, &i);
r = install_info_add(c, bn, NULL, paths->root_dir, /* auxiliary= */ false, &i);
if (r < 0)
return r;
@@ -1676,9 +1686,9 @@ static int install_info_add_auto(
pp = prefix_roota(paths->root_dir, name_or_path);
return install_info_add(c, NULL, pp, false, ret);
return install_info_add(c, NULL, pp, paths->root_dir, /* auxiliary= */ false, ret);
} else
return install_info_add(c, name_or_path, NULL, false, ret);
return install_info_add(c, name_or_path, NULL, paths->root_dir, /* auxiliary= */ false, ret);
}
static int install_info_discover(
@@ -1820,7 +1830,7 @@ static int install_info_symlink_alias(
STRV_FOREACH(s, i->aliases) {
_cleanup_free_ char *alias_path = NULL, *dst = NULL, *dst_updated = NULL;
q = install_path_printf(i, *s, &dst);
q = install_path_printf(i, *s, i->root, &dst);
if (q < 0)
return q;
@@ -1905,7 +1915,7 @@ static int install_info_symlink_wants(
STRV_FOREACH(s, list) {
_cleanup_free_ char *path = NULL, *dst = NULL;
q = install_name_printf(i, *s, &dst);
q = install_name_printf(i, *s, i->root, &dst);
if (q < 0)
return q;
@@ -2687,7 +2697,7 @@ int unit_file_disable(
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
return -EINVAL;
r = install_info_add(&c, *i, NULL, false, NULL);
r = install_info_add(&c, *i, NULL, paths.root_dir, /* auxiliary= */ false, NULL);
if (r < 0)
return r;
}