instances.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>SourcePath=</varname></term>
+ <listitem><para>A path to a
+ configuration file this unit has been
+ generated from. This is primarily
+ useful for implementation of generator
+ tools that convert configuration from
+ an external configuration file format
+ into native unit files. Thus
+ functionality should not be used in
+ normal units.</para></listitem>
+ </varlistentry>
</variablelist>
<para>Unit file may include a [Install] section, which
#ifdef HAVE_SYSV_COMPAT
#define BUS_SERVICE_SYSV_INTERFACE_FRAGMENT \
" <property name=\"SysVStartPriority\" type=\"i\" access=\"read\"/>\n" \
- " <property name=\"SysVRunLevels\" type=\"s\" access=\"read\"/>\n" \
- " <property name=\"SysVPath\" type=\"s\" access=\"read\"/>\n"
+ " <property name=\"SysVRunLevels\" type=\"s\" access=\"read\"/>\n"
#else
#define BUS_SERVICE_SYSV_INTERFACE_FRAGMENT ""
#endif
#ifdef HAVE_SYSV_COMPAT
{ "SysVRunLevels", bus_property_append_string, "s", offsetof(Service, sysv_runlevels), true },
{ "SysVStartPriority", bus_property_append_int, "i", offsetof(Service, sysv_start_priority) },
- { "SysVPath", bus_property_append_string, "s", offsetof(Service, sysv_path), true },
#endif
{ "FsckPassNo", bus_property_append_int, "i", offsetof(Service, fsck_passno) },
{ "Result", bus_service_append_service_result,"s", offsetof(Service, result) },
{ "ActiveState", bus_unit_append_active_state, "s", 0 },
{ "SubState", bus_unit_append_sub_state, "s", 0 },
{ "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true },
+ { "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true },
{ "UnitFileState", bus_unit_append_file_state, "s", 0 },
{ "InactiveExitTimestamp",bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) },
{ "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) },
" <property name=\"PropagateReloadFrom\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"SourcePath\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"Documentation\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
Unit.Names, config_parse_unit_names, 0, 0
Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description)
Unit.Documentation, config_parse_documentation, 0, offsetof(Unit, documentation)
+Unit.SourcePath, config_parse_path, 0, offsetof(Unit, source_path)
Unit.Requires, config_parse_unit_deps, UNIT_REQUIRES, 0
Unit.RequiresOverridable, config_parse_unit_deps, UNIT_REQUIRES_OVERRIDABLE, 0
Unit.Requisite, config_parse_unit_deps, UNIT_REQUISITE, 0
u->fragment_mtime = timespec_load(&st.st_mtim);
+ if (u->source_path) {
+ if (stat(u->source_path, &st) >= 0)
+ u->source_mtime = timespec_load(&st.st_mtim);
+ else
+ u->source_mtime = 0;
+ }
+
r = 0;
finish:
s->pid_file = NULL;
#ifdef HAVE_SYSV_COMPAT
- free(s->sysv_path);
- s->sysv_path = NULL;
-
free(s->sysv_runlevels);
s->sysv_runlevels = NULL;
#endif
ExecCommand *c;
assert(s);
- assert(s->sysv_path);
+ assert(s->is_sysv);
+ assert(UNIT(s)->source_path);
- if (!(c = exec_command_new(s->sysv_path, "start")))
+ c = exec_command_new(UNIT(s)->source_path, "start");
+ if (!c)
return -ENOMEM;
exec_command_append_list(s->exec_command+SERVICE_EXEC_START, c);
- if (!(c = exec_command_new(s->sysv_path, "stop")))
+ c = exec_command_new(UNIT(s)->source_path, "stop");
+ if (!c)
return -ENOMEM;
exec_command_append_list(s->exec_command+SERVICE_EXEC_STOP, c);
- if (!(c = exec_command_new(s->sysv_path, "reload")))
+ c = exec_command_new(UNIT(s)->source_path, "reload");
+ if (!c)
return -ENOMEM;
exec_command_append_list(s->exec_command+SERVICE_EXEC_RELOAD, c);
u = UNIT(s);
- if (!(f = fopen(path, "re"))) {
+ f = fopen(path, "re");
+ if (!f) {
r = errno == ENOENT ? 0 : -errno;
goto finish;
}
goto finish;
}
- free(s->sysv_path);
- if (!(s->sysv_path = strdup(path))) {
+ free(u->source_path);
+ u->source_path = strdup(path);
+ if (!u->source_path) {
r = -ENOMEM;
goto finish;
}
-
- s->sysv_mtime = timespec_load(&st.st_mtim);
+ u->source_mtime = timespec_load(&st.st_mtim);
if (null_or_empty(&st)) {
u->load_state = UNIT_MASKED;
goto finish;
}
+ s->is_sysv = true;
+
while (!feof(f)) {
char l[LINE_MAX], *t;
}
#ifdef HAVE_SYSV_COMPAT
- if (s->sysv_path)
+ if (s->is_sysv)
fprintf(f,
- "%sSysV Init Script Path: %s\n"
"%sSysV Init Script has LSB Header: %s\n"
"%sSysVEnabled: %s\n",
- prefix, s->sysv_path,
prefix, yes_no(s->sysv_has_lsb),
prefix, yes_no(s->sysv_enabled));
return true;
#ifdef HAVE_SYSV_COMPAT
- if (s->sysv_path)
+ if (s->is_sysv)
return true;
#endif
s->reload_result = SERVICE_SUCCESS;
}
-static bool service_need_daemon_reload(Unit *u) {
- Service *s = SERVICE(u);
-
- assert(s);
-
-#ifdef HAVE_SYSV_COMPAT
- if (s->sysv_path) {
- struct stat st;
-
- zero(st);
- if (stat(s->sysv_path, &st) < 0)
- /* What, cannot access this anymore? */
- return true;
-
- if (s->sysv_mtime > 0 &&
- timespec_load(&st.st_mtim) != s->sysv_mtime)
- return true;
- }
-#endif
-
- return false;
-}
-
static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) {
Service *s = SERVICE(u);
int r = 0;
.reset_failed = service_reset_failed,
- .need_daemon_reload = service_need_daemon_reload,
-
.cgroup_notify_empty = service_cgroup_notify_event,
.notify_message = service_notify_message,
bool forbid_restart:1;
bool got_socket_fd:1;
#ifdef HAVE_SYSV_COMPAT
+ bool is_sysv:1;
bool sysv_has_lsb:1;
bool sysv_enabled:1;
int sysv_start_priority_from_rcnd;
int sysv_start_priority;
- char *sysv_path;
char *sysv_runlevels;
- usec_t sysv_mtime;
#endif
char *bus_name;
RateLimit start_limit;
StartLimitAction start_limit_action;
-
UnitRef accept_socket;
Watch timer_watch;
return r;
#ifdef HAVE_SYSV_COMPAT
- if (SERVICE(u)->sysv_path) {
+ if (SERVICE(u)->is_sysv) {
log_error("Using SysV services for socket activation is not supported. Refusing.");
return -ENOENT;
}
}
#ifdef HAVE_SYSV_COMPAT
- if (service->sysv_path) {
+ if (service->is_sysv) {
log_error("Using SysV services for socket activation is not supported. Refusing.");
return -ENOENT;
}
free(u->description);
strv_free(u->documentation);
free(u->fragment_path);
+ free(u->source_path);
free(u->instance);
set_free_free(u->names);
if (u->fragment_path)
fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
+ if (u->source_path)
+ fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
+
if (u->job_timeout > 0)
fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout));
}
bool unit_need_daemon_reload(Unit *u) {
+ struct stat st;
+
assert(u);
if (u->fragment_path) {
- struct stat st;
-
zero(st);
if (stat(u->fragment_path, &st) < 0)
/* What, cannot access this anymore? */
return true;
}
- if (UNIT_VTABLE(u)->need_daemon_reload)
- return UNIT_VTABLE(u)->need_daemon_reload(u);
+ if (u->source_path) {
+ zero(st);
+ if (stat(u->source_path, &st) < 0)
+ return true;
+
+ if (u->source_mtime > 0 &&
+ timespec_load(&st.st_mtim) != u->source_mtime)
+ return true;
+ }
return false;
}
char **documentation;
char *fragment_path; /* if loaded from a config file this is the primary path to it */
+ char *source_path; /* if converted, the source file */
usec_t fragment_mtime;
+ usec_t source_mtime;
/* If there is something to do with this unit, then this is the installed job for it */
Job *job;
void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w);
- /* Check whether unit needs a daemon reload */
- bool (*need_daemon_reload)(Unit *u);
-
/* Reset failed state if we are in failed state */
void (*reset_failed)(Unit *u);
"# Automatically generated by systemd-cryptsetup-generator\n\n"
"[Unit]\n"
"Description=Cryptography Setup for %%I\n"
+ "SourcePath=/etc/crypttab\n"
"Conflicts=umount.target\n"
"DefaultDependencies=no\n"
"BindTo=%s dev-mapper-%%i.device\n"
if (password && (streq(password, "/dev/urandom") ||
streq(password, "/dev/random") ||
streq(password, "/dev/hw_random")))
- fprintf(f,
- "After=systemd-random-seed-load.service\n");
+ fputs("After=systemd-random-seed-load.service\n", f);
else
- fprintf(f,
- "Before=local-fs.target\n");
+ fputs("Before=local-fs.target\n", f);
fprintf(f,
"\n[Service]\n"
fputs("# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
+ "SourcePath=/etc/fstab\n"
"DefaultDependencies=no\n"
"Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
"Before=" SPECIAL_UMOUNT_TARGET "\n", f);
fputs("# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
+ "SourcePath=/etc/fstab\n"
"DefaultDependencies=no\n", f);
if (!path_equal(where, "/"))
fprintf(f,
"# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
+ "SourcePath=/etc/fstab\n"
"DefaultDependencies=no\n"
"Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
"Before=" SPECIAL_UMOUNT_TARGET " %s\n"
char **documentation;
- const char *path;
+ const char *fragment_path;
+ const char *source_path;
const char *default_control_group;
const char *load_error;
pid_t control_pid;
const char *status_text;
bool running:1;
-#ifdef HAVE_SYSV_COMPAT
- bool is_sysv:1;
-#endif
usec_t start_timestamp;
usec_t exit_timestamp;
usec_t timestamp;
char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
+ const char *path;
assert(i);
} else
on = off = "";
+ path = i->source_path ? i->source_path : i->fragment_path;
+
if (i->load_error)
printf("\t Loaded: %s%s%s (Reason: %s)\n", on, strna(i->load_state), off, i->load_error);
- else if (i->path && i->unit_file_state)
- printf("\t Loaded: %s%s%s (%s; %s)\n", on, strna(i->load_state), off, i->path, i->unit_file_state);
- else if (i->path)
- printf("\t Loaded: %s%s%s (%s)\n", on, strna(i->load_state), off, i->path);
+ else if (path && i->unit_file_state)
+ printf("\t Loaded: %s%s%s (%s; %s)\n", on, strna(i->load_state), off, path, i->unit_file_state);
+ else if (path)
+ printf("\t Loaded: %s%s%s (%s)\n", on, strna(i->load_state), off, path);
else
printf("\t Loaded: %s%s%s\n", on, strna(i->load_state), off);
printf("\t Process: %u %s=%s ", p->pid, p->name, strna(t));
free(t);
-#ifdef HAVE_SYSV_COMPAT
- if (i->is_sysv)
- good = is_clean_exit_lsb(p->code, p->status);
- else
-#endif
- good = is_clean_exit(p->code, p->status);
-
+ good = is_clean_exit_lsb(p->code, p->status);
if (!good) {
on = ansi_highlight_red(true);
off = ansi_highlight_red(false);
printf("status=%i", p->status);
-#ifdef HAVE_SYSV_COMPAT
- if ((c = exit_status_to_string(p->status, i->is_sysv ? EXIT_STATUS_LSB : EXIT_STATUS_SYSTEMD)))
-#else
- if ((c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD)))
-#endif
+ c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
+ if (c)
printf("/%s", c);
} else
printf("status=%i", i->exit_status);
-#ifdef HAVE_SYSV_COMPAT
- if ((c = exit_status_to_string(i->exit_status, i->is_sysv ? EXIT_STATUS_LSB : EXIT_STATUS_SYSTEMD)))
-#else
- if ((c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD)))
-#endif
+ c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
+ if (c)
printf("/%s", c);
} else
else if (streq(name, "Description"))
i->description = s;
else if (streq(name, "FragmentPath"))
- i->path = s;
-#ifdef HAVE_SYSV_COMPAT
- else if (streq(name, "SysVPath")) {
- i->is_sysv = true;
- i->path = s;
- }
-#endif
+ i->fragment_path = s;
+ else if (streq(name, "SourcePath"))
+ i->source_path = s;
else if (streq(name, "DefaultControlGroup"))
i->default_control_group = s;
else if (streq(name, "StatusText"))