mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
Merge pull request #4835 from poettering/unit-name-printf
Various specifier resolution fixes.
This commit is contained in:
commit
1ac7a93574
2
TODO
2
TODO
@ -116,8 +116,6 @@ Features:
|
||||
* journald: sigbus API via a signal-handler safe function that people may call
|
||||
from the SIGBUS handler
|
||||
|
||||
* move specifier expansion from service_spawn() into load-fragment.c
|
||||
|
||||
* optionally, also require WATCHDOG=1 notifications during service start-up and shutdown
|
||||
|
||||
* resolved: when routing queries, make sure only look for the *longest* suffix...
|
||||
|
@ -1246,21 +1246,6 @@
|
||||
<entry>This is either the unescaped instance name (if applicable) with <filename>/</filename> prepended (if applicable), or the unescaped prefix name prepended with <filename>/</filename>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>%c</literal></entry>
|
||||
<entry>Control group path of the unit</entry>
|
||||
<entry>This path does not include the <filename>/sys/fs/cgroup/systemd/</filename> prefix.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>%r</literal></entry>
|
||||
<entry>Control group path of the slice the unit is placed in</entry>
|
||||
<entry>This usually maps to the parent control group path of <literal>%c</literal>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>%R</literal></entry>
|
||||
<entry>Root control group path below which slices and units are placed</entry>
|
||||
<entry>For system instances, this resolves to <filename>/</filename>, except in containers, where this maps to the container's root control group path.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>%t</literal></entry>
|
||||
<entry>Runtime directory</entry>
|
||||
<entry>This is either <filename>/run</filename> (for the system manager) or the path <literal>$XDG_RUNTIME_DIR</literal> resolves to (for user managers).</entry>
|
||||
@ -1314,13 +1299,6 @@
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>Please note that specifiers <literal>%U</literal>,
|
||||
<literal>%h</literal>, <literal>%s</literal> are mostly useless
|
||||
when systemd is running in system mode. PID 1 cannot query the
|
||||
user account database for information, so the specifiers only work
|
||||
as shortcuts for things which are already specified in a different
|
||||
way in the unit file. They are fully functional when systemd is
|
||||
running in <option>--user</option> mode.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
@ -191,13 +191,13 @@ Unit.IgnoreOnIsolate, config_parse_bool, 0,
|
||||
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
|
||||
Unit.JobTimeoutAction, config_parse_emergency_action, 0, offsetof(Unit, job_timeout_action)
|
||||
Unit.JobTimeoutRebootArgument, config_parse_string, 0, offsetof(Unit, job_timeout_reboot_arg)
|
||||
Unit.JobTimeoutRebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, job_timeout_reboot_arg)
|
||||
Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
|
||||
m4_dnl The following is a legacy alias name for compatibility
|
||||
Unit.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
|
||||
Unit.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
|
||||
Unit.StartLimitAction, config_parse_emergency_action, 0, offsetof(Unit, start_limit_action)
|
||||
Unit.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
|
||||
Unit.RebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, reboot_arg)
|
||||
Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, conditions)
|
||||
Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, conditions)
|
||||
Unit.ConditionPathIsDirectory, config_parse_unit_condition_path, CONDITION_PATH_IS_DIRECTORY, offsetof(Unit, conditions)
|
||||
@ -254,7 +254,7 @@ m4_dnl The following three only exist for compatibility, they moved into Unit, s
|
||||
Service.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
|
||||
Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
|
||||
Service.StartLimitAction, config_parse_emergency_action, 0, offsetof(Unit, start_limit_action)
|
||||
Service.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
|
||||
Service.RebootArgument, config_parse_unit_path_printf, 0, offsetof(Unit, reboot_arg)
|
||||
Service.FailureAction, config_parse_emergency_action, 0, offsetof(Service, emergency_action)
|
||||
Service.Type, config_parse_service_type, 0, offsetof(Service, type)
|
||||
Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart)
|
||||
@ -272,8 +272,8 @@ Service.FileDescriptorStoreMax, config_parse_unsigned, 0,
|
||||
Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access)
|
||||
Service.Sockets, config_parse_service_sockets, 0, 0
|
||||
Service.BusPolicy, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
Service.USBFunctionDescriptors, config_parse_path, 0, offsetof(Service, usb_function_descriptors)
|
||||
Service.USBFunctionStrings, config_parse_path, 0, offsetof(Service, usb_function_strings)
|
||||
Service.USBFunctionDescriptors, config_parse_unit_path_printf, 0, offsetof(Service, usb_function_descriptors)
|
||||
Service.USBFunctionStrings, config_parse_unit_path_printf, 0, offsetof(Service, usb_function_strings)
|
||||
EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
|
||||
CGROUP_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
|
||||
KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
|
||||
@ -332,9 +332,9 @@ Socket.Service, config_parse_socket_service, 0,
|
||||
Socket.TriggerLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, trigger_limit.interval)
|
||||
Socket.TriggerLimitBurst, config_parse_unsigned, 0, offsetof(Socket, trigger_limit.burst)
|
||||
m4_ifdef(`HAVE_SMACK',
|
||||
`Socket.SmackLabel, config_parse_string, 0, offsetof(Socket, smack)
|
||||
Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in)
|
||||
Socket.SmackLabelIPOut, config_parse_string, 0, offsetof(Socket, smack_ip_out)',
|
||||
`Socket.SmackLabel, config_parse_unit_string_printf, 0, offsetof(Socket, smack)
|
||||
Socket.SmackLabelIPIn, config_parse_unit_string_printf, 0, offsetof(Socket, smack_ip_in)
|
||||
Socket.SmackLabelIPOut, config_parse_unit_string_printf, 0, offsetof(Socket, smack_ip_out)',
|
||||
`Socket.SmackLabel, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
|
||||
Socket.SmackLabelIPIn, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
|
||||
Socket.SmackLabelIPOut, config_parse_warn_compat, DISABLED_CONFIGURATION, 0')
|
||||
@ -354,9 +354,9 @@ BusName.AllowWorld, config_parse_bus_policy_world, 0,
|
||||
BusName.SELinuxContext, config_parse_exec_selinux_context, 0, 0
|
||||
BusName.AcceptFileDescriptors, config_parse_bool, 0, offsetof(BusName, accept_fd)
|
||||
m4_dnl
|
||||
Mount.What, config_parse_string, 0, offsetof(Mount, parameters_fragment.what)
|
||||
Mount.What, config_parse_unit_string_printf, 0, offsetof(Mount, parameters_fragment.what)
|
||||
Mount.Where, config_parse_path, 0, offsetof(Mount, where)
|
||||
Mount.Options, config_parse_string, 0, offsetof(Mount, parameters_fragment.options)
|
||||
Mount.Options, config_parse_unit_string_printf, 0, offsetof(Mount, parameters_fragment.options)
|
||||
Mount.Type, config_parse_string, 0, offsetof(Mount, parameters_fragment.fstype)
|
||||
Mount.TimeoutSec, config_parse_sec, 0, offsetof(Mount, timeout_usec)
|
||||
Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode)
|
||||
@ -373,7 +373,7 @@ Automount.TimeoutIdleSec, config_parse_sec, 0,
|
||||
m4_dnl
|
||||
Swap.What, config_parse_path, 0, offsetof(Swap, parameters_fragment.what)
|
||||
Swap.Priority, config_parse_int, 0, offsetof(Swap, parameters_fragment.priority)
|
||||
Swap.Options, config_parse_string, 0, offsetof(Swap, parameters_fragment.options)
|
||||
Swap.Options, config_parse_unit_string_printf, 0, offsetof(Swap, parameters_fragment.options)
|
||||
Swap.TimeoutSec, config_parse_sec, 0, offsetof(Swap, timeout_usec)
|
||||
EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
|
||||
CGROUP_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
|
||||
|
@ -579,6 +579,7 @@ int config_parse_exec(
|
||||
void *userdata) {
|
||||
|
||||
ExecCommand **e = data;
|
||||
Unit *u = userdata;
|
||||
const char *p;
|
||||
bool semicolon;
|
||||
int r;
|
||||
@ -604,7 +605,7 @@ int config_parse_exec(
|
||||
_cleanup_free_ ExecCommand *nce = NULL;
|
||||
_cleanup_strv_free_ char **n = NULL;
|
||||
size_t nlen = 0, nbufsize = 0;
|
||||
char *f;
|
||||
const char *f;
|
||||
int i;
|
||||
|
||||
semicolon = false;
|
||||
@ -631,47 +632,47 @@ int config_parse_exec(
|
||||
f++;
|
||||
}
|
||||
|
||||
if (isempty(f)) {
|
||||
r = unit_full_printf(u, f, &path);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isempty(path)) {
|
||||
/* First word is either "-" or "@" with no command. */
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (!string_is_safe(f)) {
|
||||
if (!string_is_safe(path)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (!path_is_absolute(f)) {
|
||||
if (!path_is_absolute(path)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (endswith(f, "/")) {
|
||||
if (endswith(path, "/")) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (f == firstword) {
|
||||
path = firstword;
|
||||
firstword = NULL;
|
||||
} else {
|
||||
path = strdup(f);
|
||||
if (!path)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (!separate_argv0) {
|
||||
char *w = NULL;
|
||||
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
f = strdup(path);
|
||||
if (!f)
|
||||
|
||||
w = strdup(path);
|
||||
if (!w)
|
||||
return log_oom();
|
||||
n[nlen++] = f;
|
||||
n[nlen++] = w;
|
||||
n[nlen] = NULL;
|
||||
}
|
||||
|
||||
path_kill_slashes(path);
|
||||
|
||||
while (!isempty(p)) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
_cleanup_free_ char *word = NULL, *resolved = NULL;
|
||||
|
||||
/* Check explicitly for an unquoted semicolon as
|
||||
* command separator token. */
|
||||
@ -682,18 +683,21 @@ int config_parse_exec(
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for \; explicitly, to not confuse it with \\;
|
||||
* or "\;" or "\\;" etc. extract_first_word would
|
||||
* return the same for all of those. */
|
||||
/* Check for \; explicitly, to not confuse it with \\; or "\;" or "\\;" etc.
|
||||
* extract_first_word() would return the same for all of those. */
|
||||
if (p[0] == '\\' && p[1] == ';' && (!p[2] || strchr(WHITESPACE, p[2]))) {
|
||||
char *w;
|
||||
|
||||
p += 2;
|
||||
p += strspn(p, WHITESPACE);
|
||||
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
f = strdup(";");
|
||||
if (!f)
|
||||
|
||||
w = strdup(";");
|
||||
if (!w)
|
||||
return log_oom();
|
||||
n[nlen++] = f;
|
||||
n[nlen++] = w;
|
||||
n[nlen] = NULL;
|
||||
continue;
|
||||
}
|
||||
@ -701,14 +705,20 @@ int config_parse_exec(
|
||||
r = extract_first_word_and_warn(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
|
||||
if (r == 0)
|
||||
break;
|
||||
else if (r < 0)
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
r = unit_full_printf(u, word, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to resolve unit specifiers on %s, ignoring: %m", word);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
|
||||
return log_oom();
|
||||
n[nlen++] = word;
|
||||
n[nlen++] = resolved;
|
||||
n[nlen] = NULL;
|
||||
word = NULL;
|
||||
resolved = NULL;
|
||||
}
|
||||
|
||||
if (!n || !n[0]) {
|
||||
@ -1326,7 +1336,7 @@ int config_parse_exec_selinux_context(
|
||||
} else
|
||||
ignore = false;
|
||||
|
||||
r = unit_name_printf(u, rvalue, &k);
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
|
||||
return 0;
|
||||
@ -1374,7 +1384,7 @@ int config_parse_exec_apparmor_profile(
|
||||
} else
|
||||
ignore = false;
|
||||
|
||||
r = unit_name_printf(u, rvalue, &k);
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
|
||||
return 0;
|
||||
@ -1422,7 +1432,7 @@ int config_parse_exec_smack_process_label(
|
||||
} else
|
||||
ignore = false;
|
||||
|
||||
r = unit_name_printf(u, rvalue, &k);
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
|
||||
return 0;
|
||||
@ -1689,7 +1699,7 @@ int config_parse_fdname(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_name_printf(UNIT(s), rvalue, &p);
|
||||
r = unit_full_printf(UNIT(s), rvalue, &p);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
@ -2555,7 +2565,7 @@ int config_parse_unit_requires_mounts_for(
|
||||
assert(data);
|
||||
|
||||
for (p = rvalue;; ) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
_cleanup_free_ char *word = NULL, *resolved = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
|
||||
if (r == 0)
|
||||
@ -2573,9 +2583,15 @@ int config_parse_unit_requires_mounts_for(
|
||||
continue;
|
||||
}
|
||||
|
||||
r = unit_require_mounts_for(u, word);
|
||||
r = unit_full_printf(u, word, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount \"%s\", ignoring: %m", word);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit name \"%s\", ignoring: %m", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = unit_require_mounts_for(u, resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount \"%s\", ignoring: %m", resolved);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -3710,7 +3726,7 @@ int config_parse_runtime_directory(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_name_printf(u, word, &k);
|
||||
r = unit_full_printf(u, word, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to resolve specifiers in \"%s\", ignoring: %m", word);
|
||||
@ -3812,8 +3828,8 @@ int config_parse_namespace_path_strv(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Unit *u = userdata;
|
||||
char*** sv = data;
|
||||
const char *prev;
|
||||
const char *cur;
|
||||
int r;
|
||||
|
||||
@ -3828,10 +3844,10 @@ int config_parse_namespace_path_strv(
|
||||
return 0;
|
||||
}
|
||||
|
||||
prev = cur = rvalue;
|
||||
cur = rvalue;
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
int offset;
|
||||
_cleanup_free_ char *word = NULL, *resolved = NULL, *joined = NULL;
|
||||
bool ignore_enoent;
|
||||
|
||||
r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES);
|
||||
if (r == 0)
|
||||
@ -3839,31 +3855,37 @@ int config_parse_namespace_path_strv(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage, ignoring: %s", prev);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract first word, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!utf8_is_valid(word)) {
|
||||
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word);
|
||||
prev = cur;
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = word[0] == '-';
|
||||
if (!path_is_absolute(word + offset)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", word);
|
||||
prev = cur;
|
||||
ignore_enoent = word[0] == '-';
|
||||
|
||||
r = unit_full_printf(u, word + ignore_enoent, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers in %s: %m", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
path_kill_slashes(word + offset);
|
||||
if (!path_is_absolute(resolved)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", resolved);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = strv_push(sv, word);
|
||||
path_kill_slashes(resolved);
|
||||
|
||||
joined = strjoin(ignore_enoent ? "-" : "", resolved);
|
||||
|
||||
r = strv_push(sv, joined);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
prev = cur;
|
||||
word = NULL;
|
||||
joined = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "unit-printf.h"
|
||||
#include "unit.h"
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
@ -1205,7 +1204,7 @@ static int service_spawn(
|
||||
ExecFlags flags,
|
||||
pid_t *_pid) {
|
||||
|
||||
_cleanup_strv_free_ char **argv = NULL, **final_env = NULL, **our_env = NULL, **fd_names = NULL;
|
||||
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
|
||||
_cleanup_free_ int *fds = NULL;
|
||||
unsigned n_fds = 0, n_env = 0;
|
||||
const char *path;
|
||||
@ -1263,10 +1262,6 @@ static int service_spawn(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
our_env = new0(char*, 9);
|
||||
if (!our_env)
|
||||
return -ENOMEM;
|
||||
@ -1349,7 +1344,7 @@ static int service_spawn(
|
||||
} else
|
||||
path = UNIT(s)->cgroup_path;
|
||||
|
||||
exec_params.argv = argv;
|
||||
exec_params.argv = c->argv;
|
||||
exec_params.environment = final_env;
|
||||
exec_params.fds = fds;
|
||||
exec_params.fd_names = fd_names;
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "unit-printf.h"
|
||||
#include "unit.h"
|
||||
#include "user-util.h"
|
||||
#include "in-addr-util.h"
|
||||
@ -1740,7 +1739,6 @@ static int socket_coldplug(Unit *u) {
|
||||
}
|
||||
|
||||
static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
|
||||
_cleanup_free_ char **argv = NULL;
|
||||
pid_t pid;
|
||||
int r;
|
||||
ExecParameters exec_params = {
|
||||
@ -1772,11 +1770,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
exec_params.argv = argv;
|
||||
exec_params.argv = c->argv;
|
||||
exec_params.environment = UNIT(s)->manager->environment;
|
||||
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
|
||||
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
|
||||
|
@ -78,12 +78,18 @@ static int specifier_filename(char specifier, void *data, void *userdata, char *
|
||||
return unit_name_to_path(u->id, ret);
|
||||
}
|
||||
|
||||
static void bad_specifier(Unit *u, char specifier) {
|
||||
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);
|
||||
}
|
||||
|
||||
static int specifier_cgroup(char specifier, void *data, void *userdata, char **ret) {
|
||||
Unit *u = userdata;
|
||||
char *n;
|
||||
|
||||
assert(u);
|
||||
|
||||
bad_specifier(u, specifier);
|
||||
|
||||
if (u->cgroup_path)
|
||||
n = strdup(u->cgroup_path);
|
||||
else
|
||||
@ -101,6 +107,8 @@ static int specifier_cgroup_root(char specifier, void *data, void *userdata, cha
|
||||
|
||||
assert(u);
|
||||
|
||||
bad_specifier(u, specifier);
|
||||
|
||||
n = strdup(u->manager->cgroup_root);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
@ -115,6 +123,8 @@ static int specifier_cgroup_slice(char specifier, void *data, void *userdata, ch
|
||||
|
||||
assert(u);
|
||||
|
||||
bad_specifier(u, specifier);
|
||||
|
||||
if (UNIT_ISSET(u->slice)) {
|
||||
Unit *slice;
|
||||
|
||||
@ -194,13 +204,20 @@ static int specifier_user_shell(char specifier, void *data, void *userdata, char
|
||||
int unit_name_printf(Unit *u, const char* format, char **ret) {
|
||||
|
||||
/*
|
||||
* This will use the passed string as format string and
|
||||
* replace the following specifiers:
|
||||
* This will use the passed string as format string and replace the following specifiers (which should all be
|
||||
* safe for inclusion in unit names):
|
||||
*
|
||||
* %n: the full id of the unit (foo@bar.waldo)
|
||||
* %N: the id of the unit without the suffix (foo@bar)
|
||||
* %p: the prefix (foo)
|
||||
* %i: the instance (bar)
|
||||
*
|
||||
* %U: the UID of the running user
|
||||
* %u: the username of the running user
|
||||
*
|
||||
* %m: the machine ID of the running system
|
||||
* %H: the host name of the running system
|
||||
* %b: the boot ID of the running system
|
||||
*/
|
||||
|
||||
const Specifier table[] = {
|
||||
@ -208,7 +225,14 @@ int unit_name_printf(Unit *u, const char* format, char **ret) {
|
||||
{ 'N', specifier_prefix_and_instance, NULL },
|
||||
{ 'p', specifier_prefix, NULL },
|
||||
{ 'i', specifier_string, u->instance },
|
||||
{ 0, NULL, NULL }
|
||||
|
||||
{ 'U', specifier_user_id, NULL },
|
||||
{ 'u', specifier_user_name, NULL },
|
||||
|
||||
{ 'm', specifier_machine_id, NULL },
|
||||
{ 'H', specifier_host_name, NULL },
|
||||
{ 'b', specifier_boot_id, NULL },
|
||||
{}
|
||||
};
|
||||
|
||||
assert(u);
|
||||
@ -220,22 +244,23 @@ int unit_name_printf(Unit *u, const char* format, char **ret) {
|
||||
|
||||
int unit_full_printf(Unit *u, const char *format, char **ret) {
|
||||
|
||||
/* This is similar to unit_name_printf() but also supports
|
||||
* unescaping. Also, adds a couple of additional codes:
|
||||
/* This is similar to unit_name_printf() but also supports unescaping. Also, adds a couple of additional codes
|
||||
* (which are likely not suitable for unescaped inclusion in unit names):
|
||||
*
|
||||
* %f the instance if set, otherwise the id
|
||||
* %c cgroup path of unit
|
||||
* %r where units in this slice are placed in the cgroup tree
|
||||
* %R the root of this systemd's instance tree
|
||||
* %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
|
||||
* %U the UID of the running user
|
||||
* %u the username of the running user
|
||||
* %h the homedir of the running user
|
||||
* %s the shell of the running user
|
||||
* %m the machine ID of the running system
|
||||
* %H the host name of the running system
|
||||
* %b the boot ID of the running system
|
||||
* %v `uname -r` of the running system
|
||||
* %f: the unescaped instance if set, otherwise the id unescaped as path
|
||||
* %c: cgroup path of unit (deprecated)
|
||||
* %r: where units in this slice are placed in the cgroup tree (deprecated)
|
||||
* %R: the root of this systemd's instance tree (deprecated)
|
||||
* %t: the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
|
||||
*
|
||||
* %h: the homedir of the running user
|
||||
* %s: the shell of the running user
|
||||
*
|
||||
* %v: `uname -r` of the running system
|
||||
*
|
||||
* NOTICE: When you add new entries here, please be careful: specifiers which depend on settings of the unit
|
||||
* file itself are broken by design, as they would resolve differently depending on whether they are used
|
||||
* before or after the relevant configuration setting. Hence: don't add them.
|
||||
*/
|
||||
|
||||
const Specifier table[] = {
|
||||
|
@ -409,8 +409,8 @@ static void test_exec_spec_interpolation(Manager *m) {
|
||||
test(m, "exec-spec-interpolation.service", 0, CLD_EXITED);
|
||||
}
|
||||
|
||||
static int run_tests(UnitFileScope scope, test_function_t *tests) {
|
||||
test_function_t *test = NULL;
|
||||
static int run_tests(UnitFileScope scope, const test_function_t *tests) {
|
||||
const test_function_t *test = NULL;
|
||||
Manager *m = NULL;
|
||||
int r;
|
||||
|
||||
@ -433,7 +433,7 @@ static int run_tests(UnitFileScope scope, test_function_t *tests) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_function_t user_tests[] = {
|
||||
static const test_function_t user_tests[] = {
|
||||
test_exec_workingdirectory,
|
||||
test_exec_personality,
|
||||
test_exec_ignoresigpipe,
|
||||
@ -464,7 +464,7 @@ int main(int argc, char *argv[]) {
|
||||
test_exec_spec_interpolation,
|
||||
NULL,
|
||||
};
|
||||
test_function_t system_tests[] = {
|
||||
static const test_function_t system_tests[] = {
|
||||
test_exec_systemcall_system_mode_with_user,
|
||||
NULL,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user