X Tutup
Skip to content

Commit de61a04

Browse files
poetteringkeszybz
authored andcommitted
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: systemd#16187 Fixes: systemd#16183
1 parent 0c651d3 commit de61a04

File tree

16 files changed

+181
-136
lines changed

16 files changed

+181
-136
lines changed

src/core/load-fragment.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2660,7 +2660,7 @@ int config_parse_environ(
26602660
if (u)
26612661
r = unit_env_printf(u, word, &resolved);
26622662
else
2663-
r = specifier_printf(word, sc_arg_max(), system_and_tmp_specifier_table, NULL, &resolved);
2663+
r = specifier_printf(word, sc_arg_max(), system_and_tmp_specifier_table, NULL, NULL, &resolved);
26642664
if (r < 0) {
26652665
log_syntax(unit, LOG_WARNING, filename, line, r,
26662666
"Failed to resolve specifiers in %s, ignoring: %m", word);

src/core/unit-printf.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@
1212
#include "unit.h"
1313
#include "user-util.h"
1414

15-
static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) {
15+
static int specifier_prefix_and_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
1616
const Unit *u = userdata;
1717

1818
assert(u);
1919

2020
return unit_name_to_prefix_and_instance(u->id, ret);
2121
}
2222

23-
static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) {
23+
static int specifier_prefix(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
2424
const Unit *u = userdata;
2525

2626
assert(u);
2727

2828
return unit_name_to_prefix(u->id, ret);
2929
}
3030

31-
static int specifier_prefix_unescaped(char specifier, const void *data, const void *userdata, char **ret) {
31+
static int specifier_prefix_unescaped(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
3232
_cleanup_free_ char *p = NULL;
3333
const Unit *u = userdata;
3434
int r;
@@ -42,15 +42,15 @@ static int specifier_prefix_unescaped(char specifier, const void *data, const vo
4242
return unit_name_unescape(p, ret);
4343
}
4444

45-
static int specifier_instance_unescaped(char specifier, const void *data, const void *userdata, char **ret) {
45+
static int specifier_instance_unescaped(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
4646
const Unit *u = userdata;
4747

4848
assert(u);
4949

5050
return unit_name_unescape(strempty(u->instance), ret);
5151
}
5252

53-
static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) {
53+
static int specifier_last_component(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
5454
const Unit *u = userdata;
5555
_cleanup_free_ char *prefix = NULL;
5656
char *dash;
@@ -64,24 +64,24 @@ static int specifier_last_component(char specifier, const void *data, const void
6464

6565
dash = strrchr(prefix, '-');
6666
if (dash)
67-
return specifier_string(specifier, dash + 1, userdata, ret);
67+
return specifier_string(specifier, dash + 1, root, userdata, ret);
6868

6969
*ret = TAKE_PTR(prefix);
7070
return 0;
7171
}
7272

73-
static int specifier_last_component_unescaped(char specifier, const void *data, const void *userdata, char **ret) {
73+
static int specifier_last_component_unescaped(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
7474
_cleanup_free_ char *p = NULL;
7575
int r;
7676

77-
r = specifier_last_component(specifier, data, userdata, &p);
77+
r = specifier_last_component(specifier, data, root, userdata, &p);
7878
if (r < 0)
7979
return r;
8080

8181
return unit_name_unescape(p, ret);
8282
}
8383

84-
static int specifier_filename(char specifier, const void *data, const void *userdata, char **ret) {
84+
static int specifier_filename(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
8585
const Unit *u = userdata;
8686

8787
assert(u);
@@ -96,7 +96,7 @@ static void bad_specifier(const Unit *u, char specifier) {
9696
log_unit_warning(u, "Specifier '%%%c' used in unit configuration, which is deprecated. Please update your unit file, as it does not work as intended.", specifier);
9797
}
9898

99-
static int specifier_cgroup(char specifier, const void *data, const void *userdata, char **ret) {
99+
static int specifier_cgroup(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
100100
const Unit *u = userdata;
101101
char *n;
102102

@@ -115,7 +115,7 @@ static int specifier_cgroup(char specifier, const void *data, const void *userda
115115
return 0;
116116
}
117117

118-
static int specifier_cgroup_root(char specifier, const void *data, const void *userdata, char **ret) {
118+
static int specifier_cgroup_root(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
119119
const Unit *u = userdata;
120120
char *n;
121121

@@ -131,7 +131,7 @@ static int specifier_cgroup_root(char specifier, const void *data, const void *u
131131
return 0;
132132
}
133133

134-
static int specifier_cgroup_slice(char specifier, const void *data, const void *userdata, char **ret) {
134+
static int specifier_cgroup_slice(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
135135
const Unit *u = userdata, *slice;
136136
char *n;
137137

@@ -154,7 +154,7 @@ static int specifier_cgroup_slice(char specifier, const void *data, const void *
154154
return 0;
155155
}
156156

157-
static int specifier_special_directory(char specifier, const void *data, const void *userdata, char **ret) {
157+
static int specifier_special_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
158158
const Unit *u = userdata;
159159
char *n = NULL;
160160

@@ -198,7 +198,7 @@ int unit_name_printf(const Unit *u, const char* format, char **ret) {
198198
assert(format);
199199
assert(ret);
200200

201-
return specifier_printf(format, UNIT_NAME_MAX, table, u, ret);
201+
return specifier_printf(format, UNIT_NAME_MAX, table, NULL, u, ret);
202202
}
203203

204204
int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, char **ret) {
@@ -262,5 +262,5 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
262262
{}
263263
};
264264

265-
return specifier_printf(format, max_length, table, u, ret);
265+
return specifier_printf(format, max_length, table, NULL, u, ret);
266266
}

src/partition/repart.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ static int config_parse_label(
973973
/* Nota bene: the empty label is a totally valid one. Let's hence not follow our usual rule of
974974
* assigning the empty string to reset to default here, but really accept it as label to set. */
975975

976-
r = specifier_printf(rvalue, GPT_LABEL_MAX, system_and_tmp_specifier_table, NULL, &resolved);
976+
r = specifier_printf(rvalue, GPT_LABEL_MAX, system_and_tmp_specifier_table, arg_root, NULL, &resolved);
977977
if (r < 0) {
978978
log_syntax(unit, LOG_WARNING, filename, line, r,
979979
"Failed to expand specifiers in Label=, ignoring: %s", rvalue);
@@ -1138,7 +1138,7 @@ static int config_parse_copy_files(
11381138
if (!isempty(p))
11391139
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue);
11401140

1141-
r = specifier_printf(source, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_source);
1141+
r = specifier_printf(source, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_source);
11421142
if (r < 0) {
11431143
log_syntax(unit, LOG_WARNING, filename, line, r,
11441144
"Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue);
@@ -1149,7 +1149,7 @@ static int config_parse_copy_files(
11491149
if (r < 0)
11501150
return 0;
11511151

1152-
r = specifier_printf(target, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_target);
1152+
r = specifier_printf(target, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_target);
11531153
if (r < 0) {
11541154
log_syntax(unit, LOG_WARNING, filename, line, r,
11551155
"Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target);
@@ -1198,7 +1198,7 @@ static int config_parse_copy_blocks(
11981198
return 0;
11991199
}
12001200

1201-
r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &d);
1201+
r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &d);
12021202
if (r < 0) {
12031203
log_syntax(unit, LOG_WARNING, filename, line, r,
12041204
"Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue);
@@ -1246,7 +1246,7 @@ static int config_parse_make_dirs(
12461246
if (r == 0)
12471247
return 0;
12481248

1249-
r = specifier_printf(word, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &d);
1249+
r = specifier_printf(word, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &d);
12501250
if (r < 0) {
12511251
log_syntax(unit, LOG_WARNING, filename, line, r,
12521252
"Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word);

src/resolve/resolved-conf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ int config_parse_dnssd_service_name(
255255
return 0;
256256
}
257257

258-
r = specifier_printf(rvalue, DNS_LABEL_MAX, specifier_table, NULL, &name);
258+
r = specifier_printf(rvalue, DNS_LABEL_MAX, specifier_table, NULL, NULL, &name);
259259
if (r < 0) {
260260
log_syntax(unit, LOG_WARNING, filename, line, r,
261261
"Invalid service instance name template '%s', ignoring assignment: %m", rvalue);

src/resolve/resolved-dnssd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
135135
return 0;
136136
}
137137

138-
static int specifier_dnssd_host_name(char specifier, const void *data, const void *userdata, char **ret) {
138+
static int specifier_dnssd_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
139139
DnssdService *s = (DnssdService *) userdata;
140140
char *n;
141141

@@ -170,7 +170,7 @@ int dnssd_render_instance_name(DnssdService *s, char **ret_name) {
170170
assert(s);
171171
assert(s->name_template);
172172

173-
r = specifier_printf(s->name_template, DNS_LABEL_MAX, specifier_table, s, &name);
173+
r = specifier_printf(s->name_template, DNS_LABEL_MAX, specifier_table, NULL, s, &name);
174174
if (r < 0)
175175
return log_debug_errno(r, "Failed to replace specifiers: %m");
176176

src/shared/install-printf.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "unit-name.h"
1414
#include "user-util.h"
1515

16-
static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) {
16+
static int specifier_prefix_and_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
1717
const UnitFileInstallInfo *i = userdata;
1818
_cleanup_free_ char *prefix = NULL;
1919
int r;
@@ -37,7 +37,7 @@ static int specifier_prefix_and_instance(char specifier, const void *data, const
3737
return 0;
3838
}
3939

40-
static int specifier_name(char specifier, const void *data, const void *userdata, char **ret) {
40+
static int specifier_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
4141
const UnitFileInstallInfo *i = userdata;
4242
char *ans;
4343

@@ -53,15 +53,15 @@ static int specifier_name(char specifier, const void *data, const void *userdata
5353
return 0;
5454
}
5555

56-
static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) {
56+
static int specifier_prefix(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
5757
const UnitFileInstallInfo *i = userdata;
5858

5959
assert(i);
6060

6161
return unit_name_to_prefix(i->name, ret);
6262
}
6363

64-
static int specifier_instance(char specifier, const void *data, const void *userdata, char **ret) {
64+
static int specifier_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
6565
const UnitFileInstallInfo *i = userdata;
6666
char *instance;
6767
int r;
@@ -82,12 +82,12 @@ static int specifier_instance(char specifier, const void *data, const void *user
8282
return 0;
8383
}
8484

85-
static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) {
85+
static int specifier_last_component(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
8686
_cleanup_free_ char *prefix = NULL;
8787
char *dash;
8888
int r;
8989

90-
r = specifier_prefix(specifier, data, userdata, &prefix);
90+
r = specifier_prefix(specifier, data, root, userdata, &prefix);
9191
if (r < 0)
9292
return r;
9393

@@ -103,7 +103,7 @@ static int specifier_last_component(char specifier, const void *data, const void
103103
return 0;
104104
}
105105

106-
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, char **ret) {
106+
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, const char *root, char **ret) {
107107
/* This is similar to unit_name_printf() */
108108

109109
const Specifier table[] = {
@@ -123,5 +123,5 @@ int install_full_printf_internal(const UnitFileInstallInfo *i, const char *forma
123123
assert(format);
124124
assert(ret);
125125

126-
return specifier_printf(format, max_length, table, i, ret);
126+
return specifier_printf(format, max_length, table, root, i, ret);
127127
}

src/shared/install-printf.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
#include "install.h"
55
#include "unit-name.h"
66

7-
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, char **ret);
8-
static inline int install_name_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
9-
return install_full_printf_internal(i, format, UNIT_NAME_MAX, ret);
7+
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, const char *root, char **ret);
8+
9+
static inline int install_name_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
10+
return install_full_printf_internal(i, format, UNIT_NAME_MAX, root, ret);
1011
}
11-
static inline int install_path_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
12-
return install_full_printf_internal(i, format, PATH_MAX-1, ret);
12+
static inline int install_path_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
13+
return install_full_printf_internal(i, format, PATH_MAX-1, root, ret);
1314
}

src/shared/install.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,7 @@ static void install_info_free(UnitFileInstallInfo *i) {
963963

964964
free(i->name);
965965
free(i->path);
966+
free(i->root);
966967
strv_free(i->aliases);
967968
strv_free(i->wanted_by);
968969
strv_free(i->required_by);
@@ -1023,6 +1024,7 @@ static int install_info_add(
10231024
InstallContext *c,
10241025
const char *name,
10251026
const char *path,
1027+
const char *root,
10261028
bool auxiliary,
10271029
UnitFileInstallInfo **ret) {
10281030

@@ -1066,6 +1068,14 @@ static int install_info_add(
10661068
goto fail;
10671069
}
10681070

1071+
if (root) {
1072+
i->root = strdup(root);
1073+
if (!i->root) {
1074+
r = -ENOMEM;
1075+
goto fail;
1076+
}
1077+
}
1078+
10691079
if (path) {
10701080
i->path = strdup(path);
10711081
if (!i->path) {
@@ -1147,11 +1157,11 @@ static int config_parse_also(
11471157
if (r == 0)
11481158
break;
11491159

1150-
r = install_name_printf(info, word, &printed);
1160+
r = install_name_printf(info, word, info->root, &printed);
11511161
if (r < 0)
11521162
return r;
11531163

1154-
r = install_info_add(c, printed, NULL, true, NULL);
1164+
r = install_info_add(c, printed, NULL, info->root, /* auxiliary= */ true, NULL);
11551165
if (r < 0)
11561166
return r;
11571167

@@ -1194,7 +1204,7 @@ static int config_parse_default_instance(
11941204
return log_syntax(unit, LOG_WARNING, filename, line, 0,
11951205
"DefaultInstance= only makes sense for template units, ignoring.");
11961206

1197-
r = install_name_printf(i, rvalue, &printed);
1207+
r = install_name_printf(i, rvalue, i->root, &printed);
11981208
if (r < 0)
11991209
return r;
12001210

@@ -1637,7 +1647,7 @@ static int install_info_traverse(
16371647
bn = buffer;
16381648
}
16391649

1640-
r = install_info_add(c, bn, NULL, false, &i);
1650+
r = install_info_add(c, bn, NULL, paths->root_dir, /* auxiliary= */ false, &i);
16411651
if (r < 0)
16421652
return r;
16431653

@@ -1676,9 +1686,9 @@ static int install_info_add_auto(
16761686

16771687
pp = prefix_roota(paths->root_dir, name_or_path);
16781688

1679-
return install_info_add(c, NULL, pp, false, ret);
1689+
return install_info_add(c, NULL, pp, paths->root_dir, /* auxiliary= */ false, ret);
16801690
} else
1681-
return install_info_add(c, name_or_path, NULL, false, ret);
1691+
return install_info_add(c, name_or_path, NULL, paths->root_dir, /* auxiliary= */ false, ret);
16821692
}
16831693

16841694
static int install_info_discover(
@@ -1820,7 +1830,7 @@ static int install_info_symlink_alias(
18201830
STRV_FOREACH(s, i->aliases) {
18211831
_cleanup_free_ char *alias_path = NULL, *dst = NULL, *dst_updated = NULL;
18221832

1823-
q = install_path_printf(i, *s, &dst);
1833+
q = install_path_printf(i, *s, i->root, &dst);
18241834
if (q < 0)
18251835
return q;
18261836

@@ -1905,7 +1915,7 @@ static int install_info_symlink_wants(
19051915
STRV_FOREACH(s, list) {
19061916
_cleanup_free_ char *path = NULL, *dst = NULL;
19071917

1908-
q = install_name_printf(i, *s, &dst);
1918+
q = install_name_printf(i, *s, i->root, &dst);
19091919
if (q < 0)
19101920
return q;
19111921

@@ -2687,7 +2697,7 @@ int unit_file_disable(
26872697
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
26882698
return -EINVAL;
26892699

2690-
r = install_info_add(&c, *i, NULL, false, NULL);
2700+
r = install_info_add(&c, *i, NULL, paths.root_dir, /* auxiliary= */ false, NULL);
26912701
if (r < 0)
26922702
return r;
26932703
}

0 commit comments

Comments
 (0)
X Tutup