Commit 1b64d026 authored by Lennart Poettering's avatar Lennart Poettering
Browse files

units: remove service sysv_path variable and replace it by generic unit_path

UnitPath= is also writable via native units and may be used by generators
to clarify from which file a unit is generated. This patch also hooks up
the cryptsetup and fstab generators to set UnitPath= accordingly.
parent a6903061
......@@ -897,6 +897,19 @@
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
......
......@@ -29,8 +29,7 @@
#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
......@@ -148,7 +147,6 @@ static const BusProperty bus_service_properties[] = {
#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) },
......
......@@ -814,6 +814,7 @@ const BusProperty bus_unit_properties[] = {
{ "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) },
......
......@@ -87,6 +87,7 @@
" <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" \
......
......@@ -93,6 +93,7 @@ $1.ControlGroupPersistent, config_parse_tristate, 0,
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
......
......@@ -2320,6 +2320,13 @@ static int load_from_path(Unit *u, const char *path) {
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:
......
......@@ -264,9 +264,6 @@ static void service_done(Unit *u) {
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
......@@ -504,17 +501,21 @@ static int sysv_exec_commands(Service *s) {
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);
......@@ -540,7 +541,8 @@ static int service_load_sysv_path(Service *s, const char *path) {
u = UNIT(s);
if (!(f = fopen(path, "re"))) {
f = fopen(path, "re");
if (!f) {
r = errno == ENOENT ? 0 : -errno;
goto finish;
}
......@@ -551,13 +553,13 @@ static int service_load_sysv_path(Service *s, const char *path) {
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;
......@@ -565,6 +567,8 @@ static int service_load_sysv_path(Service *s, const char *path) {
goto finish;
}
s->is_sysv = true;
while (!feof(f)) {
char l[LINE_MAX], *t;
......@@ -1337,12 +1341,10 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
}
#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));
......@@ -2716,7 +2718,7 @@ static bool service_check_gc(Unit *u) {
return true;
#ifdef HAVE_SYSV_COMPAT
if (s->sysv_path)
if (s->is_sysv)
return true;
#endif
......@@ -3626,29 +3628,6 @@ static void service_reset_failed(Unit *u) {
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;
......@@ -3826,8 +3805,6 @@ const UnitVTable service_vtable = {
.reset_failed = service_reset_failed,
.need_daemon_reload = service_need_daemon_reload,
.cgroup_notify_empty = service_cgroup_notify_event,
.notify_message = service_notify_message,
......
......@@ -165,14 +165,13 @@ struct Service {
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;
......@@ -182,7 +181,6 @@ struct Service {
RateLimit start_limit;
StartLimitAction start_limit_action;
UnitRef accept_socket;
Watch timer_watch;
......
......@@ -165,7 +165,7 @@ static int socket_instantiate_service(Socket *s) {
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;
}
......@@ -1575,7 +1575,7 @@ static int socket_start(Unit *u) {
}
#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;
}
......
......@@ -399,6 +399,7 @@ void unit_free(Unit *u) {
free(u->description);
strv_free(u->documentation);
free(u->fragment_path);
free(u->source_path);
free(u->instance);
set_free_free(u->names);
......@@ -682,6 +683,9 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
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));
......@@ -2575,11 +2579,11 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
}
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? */
......@@ -2590,8 +2594,15 @@ bool unit_need_daemon_reload(Unit *u) {
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;
}
......
......@@ -160,7 +160,9 @@ struct Unit {
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;
......@@ -353,9 +355,6 @@ struct UnitVTable {
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);
......
......@@ -115,6 +115,7 @@ static int create_disk(
"# 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"
......@@ -129,11 +130,9 @@ static int create_disk(
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"
......
......@@ -117,6 +117,7 @@ static int add_swap(const char *what, struct mntent *me) {
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);
......@@ -274,6 +275,7 @@ static int add_mount(const char *what, const char *where, struct mntent *me) {
fputs("# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
"SourcePath=/etc/fstab\n"
"DefaultDependencies=no\n", f);
if (!path_equal(where, "/"))
......@@ -386,6 +388,7 @@ static int add_mount(const char *what, const char *where, struct mntent *me) {
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"
......
......@@ -2160,7 +2160,8 @@ typedef struct UnitStatusInfo {
char **documentation;
const char *path;
const char *fragment_path;
const char *source_path;
const char *default_control_group;
const char *load_error;
......@@ -2179,9 +2180,6 @@ typedef struct UnitStatusInfo {
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;
......@@ -2214,6 +2212,7 @@ static void print_status_info(UnitStatusInfo *i) {
usec_t timestamp;
char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
const char *path;
assert(i);
......@@ -2236,12 +2235,14 @@ static void print_status_info(UnitStatusInfo *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);
......@@ -2333,13 +2334,7 @@ static void print_status_info(UnitStatusInfo *i) {
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);
......@@ -2353,11 +2348,8 @@ static void print_status_info(UnitStatusInfo *i) {
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
......@@ -2396,11 +2388,8 @@ static void print_status_info(UnitStatusInfo *i) {
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
......@@ -2492,13 +2481,9 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
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"))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment