[systemd-devel] [PATCH V2] service: Support environment variable substition for PIDFile=
harald at redhat.com
harald at redhat.com
Wed Apr 10 06:35:55 PDT 2013
From: Harald Hoyer <harald at redhat.com>
RFE: https://bugzilla.redhat.com/show_bug.cgi?id=840260
$ cat test.service
[Unit]
Description=test
[Service]
PIDFile=${PIDFILE}
EnvironmentFile=/etc/test-file
ExecStart=/bin/bash -c 'sleep 10000& jobs -p > $$PIDFILE; exit 0'
Type=forking
$ cat /etc/test-file
PIDFILE=/tmp/test.pid
$ systemctl status test.service
test.service - test
Loaded: loaded (/usr/lib/systemd/system/test.service; static)
Active: active (running) since Mi 2013-04-10 15:06:42 CEST; 2s ago
Process: 22407 ExecStart=/bin/bash -c sleep 10000& jobs -p > $$PIDFILE; exit 0 (code=exited, status=0/SUCCESS)
Main PID: 22408 (sleep)
CGroup: name=systemd:/system/test.service
└─22408 sleep 10000
Apr 10 15:06:42 lenovo systemd[1]: Started test.
---
man/systemd.service.xml | 3 +++
src/core/load-fragment-gperf.gperf.m4 | 2 +-
src/core/service.c | 27 ++++++++++++++++++++++-----
src/core/service.h | 1 +
4 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index b82a5c1..14ce395 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -276,6 +276,9 @@
the daemon after start-up of the
service. systemd will not write to the
file configured here.</para>
+ <para>Basic environment variable
+ substitution is supported like in
+ <varname>ExecStart=</varname>.</para>
</listitem>
</varlistentry>
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index d5e579f..4592f3d 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -140,7 +140,7 @@ Unit.ConditionHost, config_parse_unit_condition_string, CONDITION_H
Unit.ConditionACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, 0
Unit.ConditionNull, config_parse_unit_condition_null, 0, 0
m4_dnl
-Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file)
+Service.PIDFile, config_parse_unit_string_printf, 0, offsetof(Service, pid_file)
Service.ExecStartPre, config_parse_exec, SERVICE_EXEC_START_PRE, offsetof(Service, exec_command)
Service.ExecStart, config_parse_exec, SERVICE_EXEC_START, offsetof(Service, exec_command)
Service.ExecStartPost, config_parse_exec, SERVICE_EXEC_START_POST, offsetof(Service, exec_command)
diff --git a/src/core/service.c b/src/core/service.c
index a104b30..fd4c183 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -275,6 +275,9 @@ static void service_done(Unit *u) {
free(s->pid_file);
s->pid_file = NULL;
+ free(s->pid_file_env);
+ s->pid_file_env = NULL;
+
#ifdef HAVE_SYSV_COMPAT
free(s->sysv_runlevels);
s->sysv_runlevels = NULL;
@@ -703,7 +706,9 @@ static int service_load_sysv_path(Service *s, const char *path) {
}
free(s->pid_file);
+ free(s->pid_file_env);
s->pid_file = fn;
+ s->pid_file_env = NULL;
}
} else if (state == DESCRIPTION) {
@@ -1376,18 +1381,27 @@ static int service_load_pid_file(Service *s, bool may_warn) {
char _cleanup_free_ *k = NULL;
int r;
pid_t pid;
+ char _cleanup_strv_free_ **context_env = NULL;
+ char _cleanup_free_ *fe = NULL;
assert(s);
if (!s->pid_file)
return -ENOENT;
- r = read_one_line_file(s->pid_file, &k);
+ if (!s->pid_file_env)
+ if (!exec_context_load_environment(&s->exec_context, &context_env))
+ s->pid_file_env = replace_env(s->pid_file, context_env);
+
+ if (!s->pid_file_env)
+ s->pid_file_env = strdup(s->pid_file);
+
+ r = read_one_line_file(s->pid_file_env, &k);
if (r < 0) {
if (may_warn)
log_info_unit(UNIT(s)->id,
"PID file %s not readable (yet?) after %s.",
- s->pid_file, service_state_to_string(s->state));
+ s->pid_file_env, service_state_to_string(s->state));
return r;
}
@@ -1396,7 +1410,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
if (may_warn)
log_info_unit(UNIT(s)->id,
"Failed to read PID from file %s: %s",
- s->pid_file, strerror(-r));
+ s->pid_file_env, strerror(-r));
return r;
}
@@ -1404,7 +1418,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
if (may_warn)
log_info_unit(UNIT(s)->id,
"PID %lu read from file %s does not exist.",
- (unsigned long) pid, s->pid_file);
+ (unsigned long) pid, s->pid_file_env);
return -ESRCH;
}
@@ -2874,7 +2888,10 @@ static int service_demand_pid_file(Service *s) {
if (!ps)
return -ENOMEM;
- ps->path = strdup(s->pid_file);
+ if (s->pid_file_env)
+ ps->path = strdup(s->pid_file_env);
+ else
+ ps->path = strdup(s->pid_file);
if (!ps->path) {
free(ps);
return -ENOMEM;
diff --git a/src/core/service.h b/src/core/service.h
index d1e53bf..ae491a8 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -122,6 +122,7 @@ struct Service {
/* If set we'll read the main daemon PID from this file */
char *pid_file;
+ char *pid_file_env;
usec_t restart_usec;
usec_t timeout_start_usec;
--
1.8.2
More information about the systemd-devel
mailing list