[systemd-commits] 24 commits - fixme man/systemctl.xml man/systemd.exec.xml man/systemd.timer.xml src/dbus-automount.c src/dbus.c src/dbus-execute.c src/dbus-execute.h src/dbus.h src/dbus-job.c src/dbus-manager.c src/dbus-mount.c src/dbus-path.c src/dbus-service.c src/dbus-socket.c src/dbus-target.c src/dbus-timer.c src/dbus-unit.c src/dbus-unit.h src/execute.c src/execute.h src/job.c src/job.h src/load-fragment.c src/log.c src/manager.c src/manager.h src/missing.h src/mount.c src/service.c src/socket.c src/systemctl.c src/timer.c src/unit.c src/util.c src/util.h
Lennart Poettering
lennart at kemper.freedesktop.org
Mon Jul 5 05:40:50 PDT 2010
fixme | 2
man/systemctl.xml | 134 +++++---
man/systemd.exec.xml | 24 -
man/systemd.timer.xml | 32 -
src/dbus-automount.c | 4
src/dbus-execute.c | 271 ++++++++++++++++
src/dbus-execute.h | 105 +++++-
src/dbus-job.c | 34 +-
src/dbus-manager.c | 53 ++-
src/dbus-mount.c | 23 -
src/dbus-path.c | 43 ++
src/dbus-service.c | 49 ++-
src/dbus-socket.c | 51 +--
src/dbus-target.c | 25 +
src/dbus-timer.c | 57 +++
src/dbus-unit.c | 4
src/dbus-unit.h | 4
src/dbus.c | 112 +++++-
src/dbus.h | 7
src/execute.c | 43 +-
src/execute.h | 15
src/job.c | 8
src/job.h | 4
src/load-fragment.c | 30 -
src/log.c | 4
src/manager.c | 2
src/manager.h | 4
src/missing.h | 1
src/mount.c | 4
src/service.c | 6
src/socket.c | 2
src/systemctl.c | 810 +++++++++++++++++++++++++++++++++++++++++++++++---
src/timer.c | 10
src/unit.c | 3
src/util.c | 87 +++++
src/util.h | 7
36 files changed, 1785 insertions(+), 289 deletions(-)
New commits:
commit c59760eedae9d9de3be1572b9b612dfd8cc37547
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Jul 5 03:06:02 2010 +0200
systemctl: show cgroup contents in status
diff --git a/src/systemctl.c b/src/systemctl.c
index d32a688..76f6b84 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -959,6 +959,43 @@ finish:
return r;
}
+static void show_cgroup(const char *name) {
+ char *fn, *pids;
+ int r;
+ char *p;
+
+ if (!startswith(name, "name=systemd:"))
+ return;
+
+ if (asprintf(&fn, "/cgroup/systemd/%s/tasks", name + 13) < 0)
+ return;
+
+ r = read_one_line_file(fn, &pids);
+ free(fn);
+
+ if (r < 0)
+ return;
+
+ p = pids;
+ while (p[0]) {
+ unsigned long ul;
+ char *t = NULL;
+
+ p += strspn(p, WHITESPACE);
+
+ errno = 0;
+ ul = strtoul(p, &p, 0);
+ if (errno != 0 || ul <= 0)
+ break;
+
+ get_process_cmdline((pid_t) ul, 60, &t);
+ printf("\t\t%lu %s\n", ul, strna(t));
+ free(t);
+ }
+
+ free(pids);
+}
+
typedef struct UnitStatusInfo {
const char *id;
const char *load_state;
@@ -1079,8 +1116,10 @@ static void print_status_info(UnitStatusInfo *i) {
printf("\n");
}
- if (i->default_control_group)
+ if (i->default_control_group) {
printf("\t CGroup: %s\n", i->default_control_group);
+ show_cgroup(i->default_control_group);
+ }
}
static int status_property(const char *name, DBusMessageIter *iter, UnitStatusInfo *i) {
diff --git a/src/util.c b/src/util.c
index ea8bfc1..8c22dbe 100644
--- a/src/util.c
+++ b/src/util.c
@@ -566,6 +566,65 @@ int get_process_name(pid_t pid, char **name) {
return 0;
}
+int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
+ char *p, *r, *k;
+ int c;
+ bool space = false;
+ size_t left;
+ FILE *f;
+
+ assert(pid >= 1);
+ assert(max_length > 0);
+ assert(line);
+
+ if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
+ return -ENOMEM;
+
+ f = fopen(p, "r");
+ free(p);
+
+ if (!f)
+ return -errno;
+
+ if (!(r = new(char, max_length))) {
+ fclose(f);
+ return -ENOMEM;
+ }
+
+ k = r;
+ left = max_length;
+ while ((c = getc(f)) != EOF) {
+
+ if (isprint(c)) {
+ if (space) {
+ if (left <= 4)
+ break;
+
+ *(k++) = ' ';
+ space = false;
+ }
+
+ if (left <= 4)
+ break;
+
+ *(k++) = (char) c;
+ } else
+ space = true;
+ }
+
+ if (left <= 4) {
+ size_t n = MIN(left-1, 3U);
+ memcpy(k, "...", n);
+ k[n] = 0;
+ } else
+ *k = 0;
+
+ fclose(f);
+
+ *line = r;
+ return 0;
+}
+
char *strappend(const char *s, const char *suffix) {
size_t a, b;
char *r;
diff --git a/src/util.h b/src/util.h
index 8c91714..cb47c7a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -183,6 +183,7 @@ int mkdir_p(const char *path, mode_t mode);
int rmdir_parents(const char *path, const char *stop);
int get_process_name(pid_t pid, char **name);
+int get_process_cmdline(pid_t pid, size_t max_length, char **line);
char hexchar(int x);
int unhexchar(char c);
commit 61cbdc4b307718d74e8aa04875475aac2f8617ab
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Jul 5 02:40:39 2010 +0200
systemctl: implement 'status' command
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 1bd08da..c0b8d79 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -247,16 +247,25 @@
state to STDOUT.</para></listitem>
</varlistentry>
<varlistentry>
+ <term><command>status [NAME...]</command></term>
+
+ <listitem><para>Show short status
+ information about one or more
+ units. This shows terse runtime
+ information about
+ units.</para></listitem>
+ </varlistentry>
+ <varlistentry>
<term><command>show [NAME...|JOB...]</command></term>
- <listitem><para>Show information about
+ <listitem><para>Show properties of
one or more units, jobs or the manager
itself. If no argument is specified
- information about the manager will be
+ properties of the manager will be
shown. If a unit name is specified
- information about the unit is shown,
+ properties of the unit is shown,
and if a job id is specified
- information about the job is
+ properties of the job is
shown.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/log.c b/src/log.c
index a47285c..e67a5b3 100644
--- a/src/log.c
+++ b/src/log.c
@@ -227,10 +227,10 @@ static int write_to_console(
if (show_location)
IOVEC_SET_STRING(iovec[n++], location);
if (highlight)
- IOVEC_SET_STRING(iovec[n++], "\x1B[1;31m");
+ IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_ON);
IOVEC_SET_STRING(iovec[n++], buffer);
if (highlight)
- IOVEC_SET_STRING(iovec[n++], "\x1B[0m");
+ IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
IOVEC_SET_STRING(iovec[n++], "\n");
if (writev(console_fd, iovec, n) < 0)
diff --git a/src/systemctl.c b/src/systemctl.c
index 1ad0c48..d32a688 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -959,10 +959,227 @@ finish:
return r;
}
+typedef struct UnitStatusInfo {
+ const char *id;
+ const char *load_state;
+ const char *active_state;
+ const char *sub_state;
+
+ const char *description;
+
+ const char *fragment_path;
+ const char *default_control_group;
+
+ /* Service */
+ pid_t main_pid;
+ pid_t control_pid;
+ const char *status_text;
+ bool running;
+
+ usec_t start_timestamp;
+ usec_t exit_timestamp;
+
+ int exit_code, exit_status;
+
+ /* Socket */
+ unsigned n_accepted;
+ unsigned n_connections;
+
+ /* Device */
+ const char *sysfs_path;
+
+ /* Mount, Automount */
+ const char *where;
+
+ /* Swap */
+ const char *what;
+} UnitStatusInfo;
+
+static void print_status_info(UnitStatusInfo *i) {
+ assert(i);
+
+ /* This shows pretty information about a unit. See
+ * print_property() for a low-level property printer */
+
+ printf("%s", strna(i->id));
+
+ if (i->description && !streq_ptr(i->id, i->description))
+ printf(" - %s", i->description);
+
+ printf("\n");
+
+ if (i->fragment_path)
+ printf("\t Loaded: %s (%s)\n", strna(i->load_state), i->fragment_path);
+ else if (streq_ptr(i->load_state, "failed"))
+ printf("\t Loaded: " ANSI_HIGHLIGHT_ON "%s" ANSI_HIGHLIGHT_OFF "\n", strna(i->load_state));
+ else
+ printf("\t Loaded: %s\n", strna(i->load_state));
+
+ if (streq_ptr(i->active_state, "maintenance"))
+ printf("\t Active: " ANSI_HIGHLIGHT_ON "%s (%s)" ANSI_HIGHLIGHT_OFF "\n",
+ strna(i->active_state),
+ strna(i->sub_state));
+ else
+ printf("\t Active: %s (%s)\n",
+ strna(i->active_state),
+ strna(i->sub_state));
+
+ if (i->sysfs_path)
+ printf("\t Device: %s\n", i->sysfs_path);
+ else if (i->where)
+ printf("\t Where: %s\n", i->where);
+ else if (i->what)
+ printf("\t What: %s\n", i->what);
+
+ if (i->status_text)
+ printf("\t Status: \"%s\"\n", i->status_text);
+
+ if (i->id && endswith(i->id, ".socket"))
+ printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
+
+ if (i->main_pid > 0 || i->control_pid > 0) {
+ printf("\t");
+
+ if (i->main_pid > 0) {
+ printf(" Process: %u", (unsigned) i->main_pid);
+
+ if (i->running) {
+ char *t = NULL;
+ get_process_name(i->main_pid, &t);
+ if (t) {
+ printf(" (%s)", t);
+ free(t);
+ }
+ } else {
+ printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
+
+ if (i->exit_code == CLD_EXITED)
+ printf("status=%i", i->exit_status);
+ else
+ printf("signal=%s", strsignal(i->exit_status));
+ printf(")");
+ }
+ }
+
+ if (i->main_pid > 0 && i->control_pid > 0)
+ printf(";");
+
+ if (i->control_pid > 0) {
+ char *t = NULL;
+
+ printf(" Control: %u", (unsigned) i->control_pid);
+
+ get_process_name(i->control_pid, &t);
+ if (t) {
+ printf(" (%s)", t);
+ free(t);
+ }
+ }
+
+ printf("\n");
+ }
+
+ if (i->default_control_group)
+ printf("\t CGroup: %s\n", i->default_control_group);
+}
+
+static int status_property(const char *name, DBusMessageIter *iter, UnitStatusInfo *i) {
+
+ switch (dbus_message_iter_get_arg_type(iter)) {
+
+ case DBUS_TYPE_STRING: {
+ const char *s;
+
+ dbus_message_iter_get_basic(iter, &s);
+
+ if (s[0]) {
+ if (streq(name, "Id"))
+ i->id = s;
+ else if (streq(name, "LoadState"))
+ i->load_state = s;
+ else if (streq(name, "ActiveState"))
+ i->active_state = s;
+ else if (streq(name, "SubState"))
+ i->sub_state = s;
+ else if (streq(name, "Description"))
+ i->description = s;
+ else if (streq(name, "FragmentPath"))
+ i->fragment_path = s;
+ else if (streq(name, "DefaultControlGroup"))
+ i->default_control_group = s;
+ else if (streq(name, "StatusText"))
+ i->status_text = s;
+ else if (streq(name, "SysFSPath"))
+ i->sysfs_path = s;
+ else if (streq(name, "Where"))
+ i->where = s;
+ else if (streq(name, "What"))
+ i->what = s;
+ }
+
+ break;
+ }
+
+ case DBUS_TYPE_UINT32: {
+ uint32_t u;
+
+ dbus_message_iter_get_basic(iter, &u);
+
+ if (streq(name, "MainPID")) {
+ if (u > 0) {
+ i->main_pid = (pid_t) u;
+ i->running = true;
+ }
+ } else if (streq(name, "ControlPID"))
+ i->control_pid = (pid_t) u;
+ else if (streq(name, "ExecMainPID")) {
+ if (u > 0)
+ i->main_pid = (pid_t) u;
+ } else if (streq(name, "NAccepted"))
+ i->n_accepted = u;
+ else if (streq(name, "NConnections"))
+ i->n_connections = u;
+
+ break;
+ }
+
+ case DBUS_TYPE_INT32: {
+ int32_t j;
+
+ dbus_message_iter_get_basic(iter, &j);
+
+ if (streq(name, "ExecMainCode"))
+ i->exit_code = (int) j;
+ else if (streq(name, "ExecMainStatus"))
+ i->exit_status = (int) j;
+
+ break;
+ }
+
+ case DBUS_TYPE_UINT64: {
+ uint64_t u;
+
+ dbus_message_iter_get_basic(iter, &u);
+
+ if (streq(name, "ExecMainStartTimestamp"))
+ i->start_timestamp = (usec_t) u;
+ else if (streq(name, "ExecMainExitTimestamp"))
+ i->exit_timestamp = (usec_t) u;
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
static int print_property(const char *name, DBusMessageIter *iter) {
assert(name);
assert(iter);
+ /* This is a low-level property printer, see
+ * print_status_info() for the nicer output */
+
if (arg_property && !streq(name, arg_property))
return 0;
@@ -1200,7 +1417,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
(unsigned) pid,
sigchld_code_to_string(code),
status,
- strna(code == CLD_EXITED ? NULL : strsignal(status)));
+ strempty(code == CLD_EXITED ? NULL : strsignal(status)));
}
printf(" }\n");
@@ -1220,16 +1437,19 @@ static int print_property(const char *name, DBusMessageIter *iter) {
return 0;
}
-static int show_one(DBusConnection *bus, const char *path) {
+static int show_one(DBusConnection *bus, const char *path, bool show_properties, bool *new_line) {
DBusMessage *m = NULL, *reply = NULL;
const char *interface = "";
int r;
DBusError error;
DBusMessageIter iter, sub, sub2, sub3;
+ UnitStatusInfo info;
assert(bus);
assert(path);
+ assert(new_line);
+ zero(info);
dbus_error_init(&error);
if (!(m = dbus_message_new_method_call(
@@ -1266,6 +1486,11 @@ static int show_one(DBusConnection *bus, const char *path) {
dbus_message_iter_recurse(&iter, &sub);
+ if (*new_line)
+ printf("\n");
+
+ *new_line = true;
+
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
const char *name;
@@ -1291,7 +1516,12 @@ static int show_one(DBusConnection *bus, const char *path) {
dbus_message_iter_recurse(&sub2, &sub3);
- if (print_property(name, &sub3) < 0) {
+ if (show_properties)
+ r = print_property(name, &sub3);
+ else
+ r = status_property(name, &sub3, &info);
+
+ if (r < 0) {
log_error("Failed to parse reply.");
r = -EIO;
goto finish;
@@ -1300,6 +1530,9 @@ static int show_one(DBusConnection *bus, const char *path) {
dbus_message_iter_next(&sub);
}
+ if (!show_properties)
+ print_status_info(&info);
+
r = 0;
finish:
@@ -1319,17 +1552,20 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
int r;
DBusError error;
unsigned i;
+ bool show_properties, new_line = false;
assert(bus);
assert(args);
dbus_error_init(&error);
- if (n <= 1) {
+ show_properties = !streq(args[0], "status");
+
+ if (show_properties && n <= 1) {
/* If not argument is specified inspect the manager
* itself */
- r = show_one(bus, "/org/freedesktop/systemd1");
+ r = show_one(bus, "/org/freedesktop/systemd1", show_properties, &new_line);
goto finish;
}
@@ -1337,7 +1573,7 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
const char *path = NULL;
uint32_t id;
- if (safe_atou32(args[i], &id) < 0) {
+ if (!show_properties || safe_atou32(args[i], &id) < 0) {
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
@@ -1392,7 +1628,7 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
goto finish;
}
- if ((r = show_one(bus, path)) < 0)
+ if ((r = show_one(bus, path, show_properties, &new_line)) < 0)
goto finish;
dbus_message_unref(m);
@@ -2098,7 +2334,8 @@ static int systemctl_help(void) {
" reload [NAME...] Reload one or more units\n"
" isolate [NAME] Start one unit and stop all others\n"
" check [NAME...] Check whether any of the passed units are active\n"
- " show [NAME...|JOB...] Show information about one or more units/jobs/manager\n"
+ " status [NAME...] Show status of one or more units\n"
+ " show [NAME...|JOB...] Show properties of one or more units/jobs/manager\n"
" load [NAME...] Load one or more units\n"
" list-jobs List jobs\n"
" cancel [JOB...] Cancel one or more jobs\n"
@@ -2780,6 +3017,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[]) {
{ "isolate", EQUAL, 2, start_unit },
{ "check", MORE, 2, check_unit },
{ "show", MORE, 1, show },
+ { "status", MORE, 2, show },
{ "monitor", EQUAL, 1, monitor },
{ "dump", EQUAL, 1, dump },
{ "snapshot", LESS, 2, snapshot },
diff --git a/src/util.h b/src/util.h
index 50bac6e..8c91714 100644
--- a/src/util.h
+++ b/src/util.h
@@ -59,6 +59,9 @@ typedef struct dual_timestamp {
#define FORMAT_TIMESTAMP_MAX 64
#define FORMAT_TIMESPAN_MAX 64
+#define ANSI_HIGHLIGHT_ON "\x1B[1;31m"
+#define ANSI_HIGHLIGHT_OFF "\x1B[0m"
+
usec_t now(clockid_t clock);
dual_timestamp* dual_timestamp_get(dual_timestamp *ts);
commit 74922904348e53a992af63c581d4ccd3317ccce0
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Jul 5 01:08:13 2010 +0200
turn negative options into positive options
diff --git a/fixme b/fixme
index 2f133d4..1e27844 100644
--- a/fixme
+++ b/fixme
@@ -39,8 +39,6 @@
* systemctl daemon-reload is kaputt
-* Turn around negative options
-
* Add missing man pages: update systemd.1, finish daemon.7
External:
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 83eef32..6502d87 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -468,7 +468,7 @@
the default log level specified
here. The interpretation of these
prefixes may be disabled with
- <varname>SyslogNoPrefix=</varname>,
+ <varname>SyslogLevelPrefix=</varname>,
see below. For details see
<citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
@@ -477,9 +477,9 @@
</varlistentry>
<varlistentry>
- <term><varname>SyslogNoPrefix=</varname></term>
+ <term><varname>SyslogLevelPrefix=</varname></term>
<listitem><para>Takes a boolean
- argument. If false and
+ argument. If true and
<varname>StandardOutput=</varname> or
<varname>StandardError=</varname> are
set to <option>syslog</option> or
@@ -488,12 +488,12 @@
are prefixed with a log level will be
passed on to syslog with this log
level set but the prefix removed. If
- set to true, the interpretation of
+ set to false, the interpretation of
these prefixes is disabled and the
logged lines are passed on as-is. For
details about this prefixing see
<citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
- Defaults to false.</para></listitem>
+ Defaults to true.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/dbus-execute.h b/src/dbus-execute.h
index 5208159..32d58d6 100644
--- a/src/dbus-execute.h
+++ b/src/dbus-execute.h
@@ -69,7 +69,7 @@
" <property name=\"TTYPath\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"SyslogPriority\" type=\"i\" access=\"read\"/>\n" \
" <property name=\"SyslogIdentifier\" type=\"s\" access=\"read\"/>\n" \
- " <property name=\"SyslogNoPrefix\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"SyslogLevelPrefix\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"Capabilities\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"SecureBits\" type=\"i\" access=\"read\"/>\n" \
" <property name=\"CapabilityBoundingSetDrop\" type=\"t\" access=\"read\"/>\n" \
@@ -83,7 +83,7 @@
" <property name=\"InaccessibleDirectories\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"MountFlags\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"PrivateTmp\" type=\"b\" access=\"read\"/>\n" \
- " <property name=\"NoSetSID\" type=\"b\" access=\"read\"/>\n"
+ " <property name=\"SameProcessGroup\" type=\"b\" access=\"read\"/>\n"
#define BUS_EXEC_COMMAND_INTERFACE(name) \
" <property name=\"" name "\" type=\"a(sasttuii)\" access=\"read\"/>\n"
@@ -115,7 +115,7 @@
{ interface, "CPUSchedulingPolicy", bus_execute_append_cpu_sched_policy, "i", &(context) }, \
{ interface, "CPUSchedulingPriority", bus_execute_append_cpu_sched_priority, "i", &(context) }, \
{ interface, "CPUAffinity", bus_execute_append_affinity,"ay", &(context) }, \
- { interface, "TimerSlackNSec", bus_execute_append_timer_slack_nsec, "t", &(context) }, \
+ { interface, "TimerSlackNSec", bus_execute_append_timer_slack_nsec, "t", &(context) }, \
{ interface, "CPUSchedulingResetOnFork", bus_property_append_bool, "b", &(context).cpu_sched_reset_on_fork }, \
{ interface, "NonBlocking", bus_property_append_bool, "b", &(context).non_blocking }, \
{ interface, "StandardInput", bus_execute_append_input, "s", &(context).std_input }, \
@@ -124,7 +124,7 @@
{ interface, "TTYPath", bus_property_append_string, "s", (context).tty_path }, \
{ interface, "SyslogPriority", bus_property_append_int, "i", &(context).syslog_priority }, \
{ interface, "SyslogIdentifier", bus_property_append_string, "s", (context).syslog_identifier }, \
- { interface, "SyslogNoPrefix", bus_property_append_bool, "b", &(context).syslog_no_prefix }, \
+ { interface, "SyslogLevelPrefix", bus_property_append_bool, "b", &(context).syslog_level_prefix }, \
{ interface, "Capabilities", bus_property_append_string, "s", (context).capabilities }, \
{ interface, "SecureBits", bus_property_append_int, "i", &(context).secure_bits }, \
{ interface, "CapabilityBoundingSetDrop", bus_property_append_uint64, "t", &(context).capability_bounding_set_drop }, \
@@ -138,7 +138,7 @@
{ interface, "InaccessibleDirectories", bus_property_append_strv, "as", (context).inaccessible_dirs }, \
{ interface, "MountFlags", bus_property_append_ul, "t", &(context).mount_flags }, \
{ interface, "PrivateTmp", bus_property_append_bool, "b", &(context).private_tmp }, \
- { interface, "NoSetSID", bus_property_append_bool, "b", &(context).no_setsid }
+ { interface, "SameProcessGroup", bus_property_append_bool, "b", &(context).same_pgrp }
#define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix) \
{ interface, prefix "StartTimestamp", bus_property_append_usec, "t", &(estatus).start_timestamp.realtime }, \
@@ -147,7 +147,7 @@
{ interface, prefix "Code", bus_property_append_int, "i", &(estatus).code }, \
{ interface, prefix "Status", bus_property_append_int, "i", &(estatus).status }
-#define BUS_EXEC_COMMAND_PROPERTY(interface, command, name) \
+#define BUS_EXEC_COMMAND_PROPERTY(interface, command, name) \
{ interface, name, bus_execute_append_command, "a(sasttuii)", (command) }
int bus_execute_append_output(Manager *m, DBusMessageIter *i, const char *property, void *data);
diff --git a/src/execute.c b/src/execute.c
index 982b7d1..2acb111 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -197,7 +197,7 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons
output == EXEC_OUTPUT_KMSG ? "kmsg" : "syslog",
context->syslog_priority,
context->syslog_identifier ? context->syslog_identifier : ident,
- !context->syslog_no_prefix);
+ context->syslog_level_prefix);
if (fd != nfd) {
r = dup2(fd, nfd) < 0 ? -errno : nfd;
@@ -964,7 +964,7 @@ int exec_spawn(ExecCommand *command,
goto fail;
}
- if (!context->no_setsid)
+ if (!context->same_pgrp)
if (setsid() < 0) {
r = EXIT_SETSID;
goto fail;
@@ -1294,6 +1294,7 @@ void exec_context_init(ExecContext *c) {
c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
c->cpu_sched_policy = SCHED_OTHER;
c->syslog_priority = LOG_DAEMON|LOG_INFO;
+ c->syslog_level_prefix = true;
c->mount_flags = MS_SHARED;
}
diff --git a/src/execute.h b/src/execute.h
index 1ab6a24..2e0e6cc 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -103,7 +103,7 @@ struct ExecContext {
int syslog_priority;
char *syslog_identifier;
- bool syslog_no_prefix;
+ bool syslog_level_prefix;
char *tcpwrap_name;
@@ -142,7 +142,7 @@ struct ExecContext {
* /bin/mount it is run in the same process group as us so
* that the autofs logic detects that it belongs to us and we
* don't enter a trigger loop. */
- bool no_setsid;
+ bool same_pgrp;
};
typedef enum ExitStatus {
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 8e777fd..3c0cccf 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1464,7 +1464,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "SyslogIdentifier", config_parse_string_printf, &(context).syslog_identifier, section }, \
{ "SyslogFacility", config_parse_facility, &(context).syslog_priority, section }, \
{ "SyslogLevel", config_parse_level, &(context).syslog_priority, section }, \
- { "SyslogNoPrefix", config_parse_bool, &(context).syslog_no_prefix, section }, \
+ { "SyslogLevelPrefix", config_parse_bool, &(context).syslog_level_prefix, section }, \
{ "Capabilities", config_parse_capabilities, &(context), section }, \
{ "SecureBits", config_parse_secure_bits, &(context), section }, \
{ "CapabilityBoundingSetDrop", config_parse_bounding_set, &(context), section }, \
diff --git a/src/mount.c b/src/mount.c
index b99e5ff..6da880e 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -68,7 +68,7 @@ static void mount_init(Unit *u) {
* the same process group as us, so that the autofs kernel
* side doesn't send us another mount request while we are
* already trying to comply its last one. */
- m->exec_context.no_setsid = true;
+ m->exec_context.same_pgrp = true;
m->timer_watch.type = WATCH_INVALID;
commit a567261a29b4e19c0c195240411b7562063d99f8
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Jul 5 00:58:07 2010 +0200
dbus: send signals about jobs to the clients having created them unconditionally, and thus get rid of broadcast signals in most cases
diff --git a/fixme b/fixme
index 49b69a6..2f133d4 100644
--- a/fixme
+++ b/fixme
@@ -39,8 +39,6 @@
* systemctl daemon-reload is kaputt
-* get rid of Subscribe() in systemctl
-
* Turn around negative options
* Add missing man pages: update systemd.1, finish daemon.7
diff --git a/src/dbus-job.c b/src/dbus-job.c
index 48b1588..0956dcf 100644
--- a/src/dbus-job.c
+++ b/src/dbus-job.c
@@ -146,6 +146,32 @@ const DBusObjectPathVTable bus_job_vtable = {
.message_function = bus_job_message_handler
};
+static int job_send_message(Job *j, DBusMessage *m) {
+ int r;
+
+ assert(j);
+ assert(m);
+
+ if (bus_has_subscriber(j->manager)) {
+ if ((r = bus_broadcast(j->manager, m)) < 0)
+ return r;
+
+ } else if (j->bus_client) {
+ /* If nobody is subscribed, we just send the message
+ * to the client which created the job */
+
+ assert(j->bus);
+
+ if (!dbus_message_set_destination(m, j->bus_client))
+ return -ENOMEM;
+
+ if (!dbus_connection_send(j->bus, m, NULL))
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
void bus_job_send_change_signal(Job *j) {
char *p = NULL;
DBusMessage *m = NULL;
@@ -156,7 +182,7 @@ void bus_job_send_change_signal(Job *j) {
LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
j->in_dbus_queue = false;
- if (set_isempty(j->manager->subscribed)) {
+ if (!bus_has_subscriber(j->manager) && !j->bus_client) {
j->sent_dbus_new_signal = true;
return;
}
@@ -182,7 +208,7 @@ void bus_job_send_change_signal(Job *j) {
goto oom;
}
- if (bus_broadcast(j->manager, m) < 0)
+ if (job_send_message(j, m) < 0)
goto oom;
free(p);
@@ -208,7 +234,7 @@ void bus_job_send_removed_signal(Job *j, bool success) {
assert(j);
- if (set_isempty(j->manager->subscribed))
+ if (!bus_has_subscriber(j->manager) && !j->bus_client)
return;
if (!j->sent_dbus_new_signal)
@@ -227,7 +253,7 @@ void bus_job_send_removed_signal(Job *j, bool success) {
DBUS_TYPE_INVALID))
goto oom;
- if (bus_broadcast(j->manager, m) < 0)
+ if (job_send_message(j, m) < 0)
goto oom;
free(p);
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index 705a4dc..704e5fa 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -452,14 +452,25 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Subscribe")) {
char *client;
+ Set *s;
+
+ if (!(s = BUS_CONNECTION_SUBSCRIBED(m, connection))) {
+ if (!(s = set_new(string_hash_func, string_compare_func)))
+ goto oom;
+
+ if (!(dbus_connection_set_data(connection, m->subscribed_data_slot, s, NULL))) {
+ set_free(s);
+ goto oom;
+ }
+ }
if (!(client = strdup(dbus_message_get_sender(message))))
goto oom;
- r = set_put(m->subscribed, client);
-
- if (r < 0)
+ if ((r = set_put(s, client)) < 0) {
+ free(client);
return bus_send_error_reply(m, connection, message, NULL, r);
+ }
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
@@ -467,7 +478,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Unsubscribe")) {
char *client;
- if (!(client = set_remove(m->subscribed, (char*) dbus_message_get_sender(message))))
+ if (!(client = set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) dbus_message_get_sender(message))))
return bus_send_error_reply(m, connection, message, NULL, -ENOENT);
free(client);
@@ -702,6 +713,11 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
if ((r = manager_add_job(m, job_type, u, mode, true, &j)) < 0)
return bus_send_error_reply(m, connection, message, NULL, r);
+ if (!(j->bus_client = strdup(dbus_message_get_sender(message))))
+ goto oom;
+
+ j->bus = connection;
+
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
@@ -713,6 +729,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
goto oom;
+
}
free(path);
diff --git a/src/dbus-unit.c b/src/dbus-unit.c
index 17ca7bd..1f74a2a 100644
--- a/src/dbus-unit.c
+++ b/src/dbus-unit.c
@@ -376,7 +376,7 @@ void bus_unit_send_change_signal(Unit *u) {
LIST_REMOVE(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta);
u->meta.in_dbus_queue = false;
- if (set_isempty(u->meta.manager->subscribed)) {
+ if (!bus_has_subscriber(u->meta.manager)) {
u->meta.sent_dbus_new_signal = true;
return;
}
@@ -427,7 +427,7 @@ void bus_unit_send_removed_signal(Unit *u) {
assert(u);
- if (set_isempty(u->meta.manager->subscribed))
+ if (!bus_has_subscriber(u->meta.manager))
return;
if (!u->meta.sent_dbus_new_signal)
diff --git a/src/dbus.c b/src/dbus.c
index 385bf6a..6660cf0 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -355,8 +355,8 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus
DBUS_TYPE_INVALID))
log_error("Failed to parse NameOwnerChanged message: %s", error.message);
else {
- if (set_remove(m->subscribed, (char*) name))
- log_debug("Subscription client vanished: %s (left: %u)", name, set_size(m->subscribed));
+ if (set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) name))
+ log_debug("Subscription client vanished: %s (left: %u)", name, set_size(BUS_CONNECTION_SUBSCRIBED(m, connection)));
if (old_owner[0] == 0)
old_owner = NULL;
@@ -882,13 +882,6 @@ static int bus_init_api(Manager *m) {
strnull(dbus_bus_get_unique_name(m->api_bus)));
dbus_free(id);
- if (!m->subscribed)
- if (!(m->subscribed = set_new(string_hash_func, string_compare_func))) {
- log_error("Not enough memory");
- r = -ENOMEM;
- goto fail;
- }
-
return 0;
fail:
@@ -959,6 +952,12 @@ int bus_init(Manager *m) {
return -ENOMEM;
}
+ if (m->subscribed_data_slot < 0)
+ if (!dbus_pending_call_allocate_data_slot(&m->subscribed_data_slot)) {
+ log_error("Not enough memory");
+ return -ENOMEM;
+ }
+
if ((r = bus_init_system(m)) < 0 ||
(r = bus_init_api(m)) < 0 ||
(r = bus_init_private(m)) < 0)
@@ -968,9 +967,30 @@ int bus_init(Manager *m) {
}
static void shutdown_connection(Manager *m, DBusConnection *c) {
+ Set *s;
+ Job *j;
+ Iterator i;
+
+ HASHMAP_FOREACH(j, m->jobs, i)
+ if (j->bus == c) {
+ free(j->bus_client);
+ j->bus_client = NULL;
+
+ j->bus = NULL;
+ }
+
set_remove(m->bus_connections, c);
set_remove(m->bus_connections_for_dispatch, c);
+ if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) {
+ char *t;
+
+ while ((t = set_steal_first(s)))
+ free(t);
+
+ set_free(s);
+ }
+
dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL);
dbus_connection_flush(c);
dbus_connection_close(c);
@@ -988,15 +1008,6 @@ static void bus_done_api(Manager *m) {
m->api_bus = NULL;
}
- if (m->subscribed) {
- char *c;
-
- while ((c = set_steal_first(m->subscribed)))
- free(c);
-
- set_free(m->subscribed);
- m->subscribed = NULL;
- }
if (m->queued_message) {
dbus_message_unref(m->queued_message);
@@ -1043,6 +1054,9 @@ void bus_done(Manager *m) {
if (m->name_data_slot >= 0)
dbus_pending_call_free_data_slot(&m->name_data_slot);
+
+ if (m->subscribed_data_slot >= 0)
+ dbus_pending_call_free_data_slot(&m->subscribed_data_slot);
}
static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) {
@@ -1053,7 +1067,7 @@ static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) {
dbus_error_init(&error);
- assert_se(name = dbus_pending_call_get_data(pending, m->name_data_slot));
+ assert_se(name = BUS_PENDING_CALL_NAME(m, pending));
assert_se(reply = dbus_pending_call_steal_reply(pending));
switch (dbus_message_get_type(reply)) {
@@ -1538,3 +1552,27 @@ int bus_parse_strv(DBusMessage *m, char ***_l) {
return 0;
}
+
+bool bus_has_subscriber(Manager *m) {
+ Iterator i;
+ DBusConnection *c;
+
+ assert(m);
+
+ SET_FOREACH(c, m->bus_connections_for_dispatch, i)
+ if (bus_connection_has_subscriber(m, c))
+ return true;
+
+ SET_FOREACH(c, m->bus_connections, i)
+ if (bus_connection_has_subscriber(m, c))
+ return true;
+
+ return false;
+}
+
+bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) {
+ assert(m);
+ assert(c);
+
+ return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c));
+}
diff --git a/src/dbus.h b/src/dbus.h
index ccee74f..01ab2fc 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -105,6 +105,12 @@ int bus_property_append_ul(Manager *m, DBusMessageIter *i, const char *property,
int bus_parse_strv(DBusMessage *m, char ***_l);
+bool bus_has_subscriber(Manager *m);
+bool bus_connection_has_subscriber(Manager *m, DBusConnection *c);
+
+#define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot)
+#define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot)
+
extern const char * const bus_interface_table[];
#endif
diff --git a/src/job.c b/src/job.c
index 31e9cfe..a090ec9 100644
--- a/src/job.c
+++ b/src/job.c
@@ -76,6 +76,7 @@ void job_free(Job *j) {
if (j->in_dbus_queue)
LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
+ free(j->bus_client);
free(j);
}
@@ -544,10 +545,9 @@ void job_add_to_dbus_queue(Job *j) {
if (j->in_dbus_queue)
return;
- if (set_isempty(j->manager->subscribed)) {
- j->sent_dbus_new_signal = true;
- return;
- }
+ /* We don't check if anybody is subscribed here, since this
+ * job might just have been created and not yet assigned to a
+ * connection/client. */
LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
j->in_dbus_queue = true;
diff --git a/src/job.h b/src/job.h
index 054aa53..9c685f1 100644
--- a/src/job.h
+++ b/src/job.h
@@ -102,6 +102,10 @@ struct Job {
JobType type;
JobState state;
+ /* Note that this bus object is not ref counted here. */
+ DBusConnection *bus;
+ char *bus_client;
+
bool installed:1;
bool in_run_queue:1;
bool matters_to_anchor:1;
diff --git a/src/manager.c b/src/manager.c
index 74a414a..6e571ea 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -198,7 +198,7 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
m->running_as = running_as;
m->confirm_spawn = confirm_spawn;
- m->name_data_slot = -1;
+ m->name_data_slot = m->subscribed_data_slot = -1;
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->pin_cgroupfs_fd = -1;
diff --git a/src/manager.h b/src/manager.h
index e856f53..aff4cb8 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -156,7 +156,6 @@ struct Manager {
DBusServer *private_bus;
Set *bus_connections, *bus_connections_for_dispatch;
- Set *subscribed;
DBusMessage *queued_message; /* This is used during reloading:
* before the reload we queue the
* reply message here, and
@@ -164,6 +163,7 @@ struct Manager {
Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */
int32_t name_data_slot;
+ int32_t subscribed_data_slot;
/* Data specific to the Automount subsystem */
int dev_autofs_fd;
diff --git a/src/systemctl.c b/src/systemctl.c
index 226ecee..1ad0c48 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -583,13 +583,10 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me
static int enable_wait_for_jobs(DBusConnection *bus) {
DBusError error;
- DBusMessage *m = NULL, *reply = NULL;
- int r;
assert(bus);
dbus_error_init(&error);
-
dbus_bus_add_match(bus,
"type='signal',"
"sender='org.freedesktop.systemd1',"
@@ -600,40 +597,12 @@ static int enable_wait_for_jobs(DBusConnection *bus) {
if (dbus_error_is_set(&error)) {
log_error("Failed to add match: %s", error.message);
- r = -EIO;
- goto finish;
- }
-
- if (!(m = dbus_message_new_method_call(
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "Subscribe"))) {
- log_error("Could not allocate message.");
- r = -ENOMEM;
- goto finish;
- }
-
- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
- r = -EIO;
- goto finish;
+ dbus_error_free(&error);
+ return -EIO;
}
- r = 0;
-
-finish:
/* This is slightly dirty, since we don't undo the match registrations. */
-
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
- dbus_error_free(&error);
-
- return r;
+ return 0;
}
static int wait_for_jobs(DBusConnection *bus, Set *s) {
diff --git a/src/unit.c b/src/unit.c
index 8f5ae8a..8b57148 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -282,7 +282,8 @@ void unit_add_to_dbus_queue(Unit *u) {
if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue)
return;
- if (set_isempty(u->meta.manager->subscribed)) {
+ /* Shortcut things if nobody cares */
+ if (!bus_has_subscriber(u->meta.manager)) {
u->meta.sent_dbus_new_signal = true;
return;
}
commit 552e4331bf165290eb02596355d9570c1ef9af47
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 21:18:06 2010 +0200
systemctl: use format_timespan() where applicable
diff --git a/fixme b/fixme
index 8143f01..49b69a6 100644
--- a/fixme
+++ b/fixme
@@ -41,8 +41,6 @@
* get rid of Subscribe() in systemctl
-* use format_timespan where applicable
-
* Turn around negative options
* Add missing man pages: update systemd.1, finish daemon.7
diff --git a/src/systemctl.c b/src/systemctl.c
index 72bb7d8..226ecee 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1029,6 +1029,10 @@ static int print_property(const char *name, DBusMessageIter *iter) {
if ((t = format_timestamp(timestamp, sizeof(timestamp), u)) || arg_all)
printf("%s=%s\n", name, strempty(t));
+ } else if (strstr(name, "USec")) {
+ char timespan[FORMAT_TIMESPAN_MAX];
+
+ printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u));
} else
printf("%s=%llu\n", name, (unsigned long long) u);
@@ -1165,11 +1169,14 @@ static int print_property(const char *name, DBusMessageIter *iter) {
if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 &&
bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 &&
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0)
- printf("%s={ value=%llu ; next_elapse=%llu }\n",
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0) {
+ char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
+
+ printf("%s={ value=%s ; next_elapse=%s }\n",
base,
- (unsigned long long) value,
- (unsigned long long) next_elapse);
+ format_timespan(timespan1, sizeof(timespan1), value),
+ format_timespan(timespan2, sizeof(timespan2), next_elapse));
+ }
dbus_message_iter_next(&sub);
}
commit fae20b110fe8734440ebfbcb676838dffda60b1b
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 21:17:40 2010 +0200
dbus: fix unclean shut-down
diff --git a/src/dbus.c b/src/dbus.c
index 405ea46..385bf6a 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -967,7 +967,10 @@ int bus_init(Manager *m) {
return 0;
}
-static void shutdown_connection(DBusConnection *c) {
+static void shutdown_connection(Manager *m, DBusConnection *c) {
+ set_remove(m->bus_connections, c);
+ set_remove(m->bus_connections_for_dispatch, c);
+
dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL);
dbus_connection_flush(c);
dbus_connection_close(c);
@@ -981,8 +984,7 @@ static void bus_done_api(Manager *m) {
if (m->system_bus == m->api_bus)
m->system_bus = NULL;
- set_remove(m->bus_connections, m->api_bus);
- shutdown_connection(m->api_bus);
+ shutdown_connection(m, m->api_bus);
m->api_bus = NULL;
}
@@ -1009,8 +1011,7 @@ static void bus_done_system(Manager *m) {
bus_done_api(m);
if (m->system_bus) {
- set_remove(m->bus_connections, m->system_bus);
- shutdown_connection(m->system_bus);
+ shutdown_connection(m, m->system_bus);
m->system_bus = NULL;
}
}
@@ -1032,10 +1033,10 @@ void bus_done(Manager *m) {
bus_done_private(m);
while ((c = set_steal_first(m->bus_connections)))
- shutdown_connection(c);
+ shutdown_connection(m, c);
while ((c = set_steal_first(m->bus_connections_for_dispatch)))
- shutdown_connection(c);
+ shutdown_connection(m, c);
set_free(m->bus_connections);
set_free(m->bus_connections_for_dispatch);
commit 03fae01822b5275a2940458f65644796283a8a23
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 21:12:10 2010 +0200
uniformly suffix time span properties with their unit
diff --git a/fixme b/fixme
index 55e47d7..8143f01 100644
--- a/fixme
+++ b/fixme
@@ -41,10 +41,12 @@
* get rid of Subscribe() in systemctl
-* Unify NS, USec, NSec, Sec suffixes in properties, use format_timespan
+* use format_timespan where applicable
* Turn around negative options
+* Add missing man pages: update systemd.1, finish daemon.7
+
External:
* patch /etc/init.d/functions with:
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 6e9051d..83eef32 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -497,13 +497,19 @@
</varlistentry>
<varlistentry>
- <term><varname>TimerSlackNS=</varname></term>
+ <term><varname>TimerSlackNSec=</varname></term>
<listitem><para>Sets the timer slack
in nanoseconds for the executed
- processes The timer slack controls the accuracy
- of wake-ups triggered by timers. See
+ processes The timer slack controls the
+ accuracy of wake-ups triggered by
+ timers. See
<citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- for more information.</para></listitem>
+ for more information. Note that in
+ contrast to most other time span
+ definitions this value is takes a
+ nano-seconds integer and does not
+ understand any other
+ units.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
index ef89693..557a45e 100644
--- a/man/systemd.timer.xml
+++ b/man/systemd.timer.xml
@@ -99,27 +99,27 @@
<variablelist>
<varlistentry>
- <term><varname>OnActive=</varname></term>
- <term><varname>OnBootup=</varname></term>
- <term><varname>OnStartup=</varname></term>
- <term><varname>OnUnitActive=</varname></term>
- <term><varname>OnUnitInactive=</varname></term>
+ <term><varname>OnActiveSec=</varname></term>
+ <term><varname>OnBootSec=</varname></term>
+ <term><varname>OnStartupSec=</varname></term>
+ <term><varname>OnUnitActiveSec=</varname></term>
+ <term><varname>OnUnitInactiveSec=</varname></term>
<listitem><para>Defines timers
relative to different starting points:
- <varname>OnActive=</varname> defines a
+ <varname>OnActiveSec=</varname> defines a
timer relative to the moment the timer
itself is
- activated. <varname>OnBootup=</varname>
+ activated. <varname>OnBootSec=</varname>
defines a timer relative to when the
machine was booted
- up. <varname>OnStartup=</varname>
+ up. <varname>OnStartupSec=</varname>
defines a timer relative to when
systemd was
- started. <varname>OnUnitActive=</varname>
+ started. <varname>OnUnitActiveSec=</varname>
defines a timer relative to when the
unit the timer is activating was last
- activated. <varname>OnUnitInactive=</varname>
+ activated. <varname>OnUnitInactiveSec=</varname>
defines a timer relative to when the
unit the timer is activating was last
deactivated.</para>
@@ -127,8 +127,8 @@
<para>Multiple directives may be
combined of the same and of different
types. For example, by combining
- <varname>OnBoot=</varname> and
- <varname>OnUnitActive=</varname> it is
+ <varname>OnBootSec=</varname> and
+ <varname>OnUnitActiveSec=</varname> it is
possible to define a timer that
elapses in regular intervals and
activates a specific service each
@@ -136,17 +136,17 @@
<para>The arguments to the directives
are time spans configured in
- seconds. Example: "OnBoot=50" means
+ seconds. Example: "OnBootSec=50" means
50s after boot-up. The argument may
also include time units. Example:
- "OnBoot=5h 30min" means 5 hours and 30
+ "OnBootSec=5h 30min" means 5 hours and 30
minutes after boot-up. For details
about the syntax of time spans see
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para>If a timer configured with
- <varname>OnBootup=</varname> or
- <varname>OnStartup=</varname> is
+ <varname>OnBootSec=</varname> or
+ <varname>OnStartupSec=</varname> is
already in the past when the timer
unit is activated, it will immediately
elapse and the configured unit is
diff --git a/src/dbus-execute.c b/src/dbus-execute.c
index 529f72d..d37bd55 100644
--- a/src/dbus-execute.c
+++ b/src/dbus-execute.c
@@ -171,7 +171,7 @@ int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *prop
return 0;
}
-int bus_execute_append_timer_slack_ns(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const char *property, void *data) {
ExecContext *c = data;
uint64_t u;
@@ -180,8 +180,8 @@ int bus_execute_append_timer_slack_ns(Manager *m, DBusMessageIter *i, const char
assert(property);
assert(c);
- if (c->timer_slack_ns_set)
- u = (uint64_t) c->timer_slack_ns_set;
+ if (c->timer_slack_nsec_set)
+ u = (uint64_t) c->timer_slack_nsec;
else
u = (uint64_t) prctl(PR_GET_TIMERSLACK);
diff --git a/src/dbus-execute.h b/src/dbus-execute.h
index 95d400d..5208159 100644
--- a/src/dbus-execute.h
+++ b/src/dbus-execute.h
@@ -115,7 +115,7 @@
{ interface, "CPUSchedulingPolicy", bus_execute_append_cpu_sched_policy, "i", &(context) }, \
{ interface, "CPUSchedulingPriority", bus_execute_append_cpu_sched_priority, "i", &(context) }, \
{ interface, "CPUAffinity", bus_execute_append_affinity,"ay", &(context) }, \
- { interface, "TimerSlackNS", bus_execute_append_timer_slack_ns, "t", &(context) }, \
+ { interface, "TimerSlackNSec", bus_execute_append_timer_slack_nsec, "t", &(context) }, \
{ interface, "CPUSchedulingResetOnFork", bus_property_append_bool, "b", &(context).cpu_sched_reset_on_fork }, \
{ interface, "NonBlocking", bus_property_append_bool, "b", &(context).non_blocking }, \
{ interface, "StandardInput", bus_execute_append_input, "s", &(context).std_input }, \
@@ -158,7 +158,7 @@ int bus_execute_append_ioprio(Manager *m, DBusMessageIter *i, const char *proper
int bus_execute_append_cpu_sched_policy(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data);
-int bus_execute_append_timer_slack_ns(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_command(Manager *m, DBusMessageIter *u, const char *property, void *data);
diff --git a/src/dbus-timer.c b/src/dbus-timer.c
index d548227..0cd37d9 100644
--- a/src/dbus-timer.c
+++ b/src/dbus-timer.c
@@ -29,7 +29,7 @@
" <interface name=\"org.freedesktop.systemd1.Timer\">\n" \
" <property name=\"Unit\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"Timers\" type=\"a(stt)\" access=\"read\"/>\n" \
- " <property name=\"NextElapse\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"NextElapseUSec\" type=\"t\" access=\"read\"/>\n" \
" </interface>\n"
#define INTROSPECTION \
@@ -57,13 +57,30 @@ static int bus_timer_append_timers(Manager *m, DBusMessageIter *i, const char *p
return -ENOMEM;
LIST_FOREACH(value, k, p->values) {
- const char *t = timer_base_to_string(k->base);
+ char *buf;
+ const char *t;
+ size_t l;
+ bool b;
- if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &t) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->value) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) ||
- !dbus_message_iter_close_container(&sub, &sub2))
+ t = timer_base_to_string(k->base);
+ assert(endswith(t, "Sec"));
+
+ /* s/Sec/USec/ */
+ l = strlen(t);
+ if (!(buf = new(char, l+2)))
+ return -ENOMEM;
+
+ memcpy(buf, t, l-3);
+ memcpy(buf+l-3, "USec", 5);
+
+ b = dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) &&
+ dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &buf) &&
+ dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->value) &&
+ dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) &&
+ dbus_message_iter_close_container(&sub, &sub2);
+
+ free(buf);
+ if (!b)
return -ENOMEM;
}
@@ -76,9 +93,9 @@ static int bus_timer_append_timers(Manager *m, DBusMessageIter *i, const char *p
DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Timer", "Unit", bus_property_append_string, "s", u->timer.unit->meta.id },
- { "org.freedesktop.systemd1.Timer", "Timers", bus_timer_append_timers, "a(stt)", u },
- { "org.freedesktop.systemd1.Timer", "NextElapse", bus_property_append_usec, "t", &u->timer.next_elapse },
+ { "org.freedesktop.systemd1.Timer", "Unit", bus_property_append_string, "s", u->timer.unit->meta.id },
+ { "org.freedesktop.systemd1.Timer", "Timers", bus_timer_append_timers, "a(stt)", u },
+ { "org.freedesktop.systemd1.Timer", "NextElapseUSec", bus_property_append_usec, "t", &u->timer.next_elapse },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/execute.c b/src/execute.c
index f3f95ff..982b7d1 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1083,8 +1083,8 @@ int exec_spawn(ExecCommand *command,
goto fail;
}
- if (context->timer_slack_ns_set)
- if (prctl(PR_SET_TIMERSLACK, context->timer_slack_ns_set) < 0) {
+ if (context->timer_slack_nsec_set)
+ if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
r = EXIT_TIMERSLACK;
goto fail;
}
@@ -1468,8 +1468,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
fputs("\n", f);
}
- if (c->timer_slack_ns_set)
- fprintf(f, "%sTimerSlackNS: %lu\n", prefix, c->timer_slack_ns);
+ if (c->timer_slack_nsec_set)
+ fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, c->timer_slack_nsec);
fprintf(f,
"%sStandardInput: %s\n"
diff --git a/src/execute.h b/src/execute.h
index aa5f566..1ab6a24 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -95,7 +95,7 @@ struct ExecContext {
cpu_set_t *cpuset;
unsigned cpuset_ncpus;
- unsigned long timer_slack_ns;
+ unsigned long timer_slack_nsec;
ExecInput std_input;
ExecOutput std_output;
@@ -135,7 +135,7 @@ struct ExecContext {
bool nice_set:1;
bool ioprio_set:1;
bool cpu_sched_set:1;
- bool timer_slack_ns_set:1;
+ bool timer_slack_nsec_set:1;
/* This is not exposed to the user but available
* internally. We need it to make sure that whenever we spawn
diff --git a/src/load-fragment.c b/src/load-fragment.c
index a5ea0e4..8e777fd 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -857,7 +857,7 @@ static int config_parse_bounding_set(
return 0;
}
-static int config_parse_timer_slack_ns(
+static int config_parse_timer_slack_nsec(
const char *filename,
unsigned line,
const char *section,
@@ -880,7 +880,7 @@ static int config_parse_timer_slack_ns(
return r;
}
- c->timer_slack_ns = u;
+ c->timer_slack_nsec = u;
return 0;
}
@@ -1373,7 +1373,7 @@ static void dump_items(FILE *f, const ConfigItem *items) {
{ config_parse_capabilities, "CAPABILITIES" },
{ config_parse_secure_bits, "SECUREBITS" },
{ config_parse_bounding_set, "BOUNDINGSET" },
- { config_parse_timer_slack_ns, "TIMERSLACK" },
+ { config_parse_timer_slack_nsec, "TIMERSLACK" },
{ config_parse_limit, "LIMIT" },
{ config_parse_cgroup, "CGROUP [...]" },
{ config_parse_deps, "UNIT [...]" },
@@ -1468,7 +1468,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "Capabilities", config_parse_capabilities, &(context), section }, \
{ "SecureBits", config_parse_secure_bits, &(context), section }, \
{ "CapabilityBoundingSetDrop", config_parse_bounding_set, &(context), section }, \
- { "TimerSlackNS", config_parse_timer_slack_ns, &(context), section }, \
+ { "TimerSlackNSec", config_parse_timer_slack_nsec,&(context), section }, \
{ "LimitCPU", config_parse_limit, &(context).rlimit[RLIMIT_CPU], section }, \
{ "LimitFSIZE", config_parse_limit, &(context).rlimit[RLIMIT_FSIZE], section }, \
{ "LimitDATA", config_parse_limit, &(context).rlimit[RLIMIT_DATA], section }, \
@@ -1574,11 +1574,11 @@ static int load_from_path(Unit *u, const char *path) {
{ "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" },
{ "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" },
- { "OnActive", config_parse_timer, &u->timer, "Timer" },
- { "OnBoot", config_parse_timer, &u->timer, "Timer" },
- { "OnStartup", config_parse_timer, &u->timer, "Timer" },
- { "OnUnitActive", config_parse_timer, &u->timer, "Timer" },
- { "OnUnitInactive", config_parse_timer, &u->timer, "Timer" },
+ { "OnActiveSec", config_parse_timer, &u->timer, "Timer" },
+ { "OnBootSec", config_parse_timer, &u->timer, "Timer" },
+ { "OnStartupSec", config_parse_timer, &u->timer, "Timer" },
+ { "OnUnitActiveSec", config_parse_timer, &u->timer, "Timer" },
+ { "OnUnitInactiveSec", config_parse_timer, &u->timer, "Timer" },
{ "Unit", config_parse_timer_unit, &u->timer, "Timer" },
{ "PathExists", config_parse_path_spec, &u->path, "Path" },
diff --git a/src/timer.c b/src/timer.c
index e3c916b..b4521e6 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -440,11 +440,11 @@ static const char* const timer_state_table[_TIMER_STATE_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
- [TIMER_ACTIVE] = "OnActive",
- [TIMER_BOOT] = "OnBoot",
- [TIMER_STARTUP] = "OnStartup",
- [TIMER_UNIT_ACTIVE] = "OnUnitActive",
- [TIMER_UNIT_INACTIVE] = "OnUnitInactive"
+ [TIMER_ACTIVE] = "OnActiveSec",
+ [TIMER_BOOT] = "OnBootSec",
+ [TIMER_STARTUP] = "OnStartupSec",
+ [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec",
+ [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec"
};
DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
commit 393a2f9be167f4147e117fd2fc912292899b6b33
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 20:46:12 2010 +0200
man: update systemctl man page
diff --git a/man/systemctl.xml b/man/systemctl.xml
index e3a07d5..1bd08da 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -91,13 +91,28 @@
</varlistentry>
<varlistentry>
+ <term><option>--property=</option></term>
+ <term><option>-p</option></term>
+
+ <listitem><para>When showing
+ unit/job/manager information, limit
+ display to certain property names. If
+ not specified all set properties are
+ shown. The argument should be a
+ property name, such as
+ <literal>MainPID</literal>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--all</option></term>
<term><option>-a</option></term>
<listitem><para>When listing units,
show all units, regardless of their
- state, including inactive
- units.</para></listitem>
+ state, including inactive units. When
+ showing unit/job/manager information,
+ show all properties regardless whether
+ they are set or not.</para></listitem>
</varlistentry>
<varlistentry>
@@ -165,53 +180,6 @@
<listitem><para>List known units.</para></listitem>
</varlistentry>
<varlistentry>
- <term><command>list-jobs</command></term>
-
- <listitem><para>List jobs that are in progress.</para></listitem>
- </varlistentry>
- <varlistentry>
- <term><command>clear-jobs</command></term>
-
- <listitem><para>Cancel all jobs that are in progress.</para></listitem>
- </varlistentry>
- <varlistentry>
- <term><command>load [NAME...]</command></term>
-
- <listitem><para>Load one or more units
- specified on the command line. This
- will simply load their configuration
- from disk, but not start them. To
- start them you need to use the
- <command>start</command> command which
- will implicitly load a unit that has
- not been loaded yet. Note that systemd
- garbage collects loaded units that are
- not active or referenced by an active
- unit. This means that units loaded
- this way will usually not stay loaded
- for long. Also note that this command
- cannot be used to reload unit
- configuration. Use the
- <command>daemon-reload</command>
- command for that. All in all, this
- command is of little use except for
- debugging.</para>
- <para>This command should not be
- confused with the
- <command>daemon-reload</command> or
- <command>reload</command>
- commands.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><command>cancel [JOB...]</command></term>
-
- <listitem><para>Cancel one or more
- jobs specified on the command line by
- their numeric job
- IDs.</para></listitem>
- </varlistentry>
- <varlistentry>
<term><command>start [NAME...]</command></term>
<listitem><para>Start one or more
@@ -279,6 +247,65 @@
state to STDOUT.</para></listitem>
</varlistentry>
<varlistentry>
+ <term><command>show [NAME...|JOB...]</command></term>
+
+ <listitem><para>Show information about
+ one or more units, jobs or the manager
+ itself. If no argument is specified
+ information about the manager will be
+ shown. If a unit name is specified
+ information about the unit is shown,
+ and if a job id is specified
+ information about the job is
+ shown.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><command>load [NAME...]</command></term>
+
+ <listitem><para>Load one or more units
+ specified on the command line. This
+ will simply load their configuration
+ from disk, but not start them. To
+ start them you need to use the
+ <command>start</command> command which
+ will implicitly load a unit that has
+ not been loaded yet. Note that systemd
+ garbage collects loaded units that are
+ not active or referenced by an active
+ unit. This means that units loaded
+ this way will usually not stay loaded
+ for long. Also note that this command
+ cannot be used to reload unit
+ configuration. Use the
+ <command>daemon-reload</command>
+ command for that. All in all, this
+ command is of little use except for
+ debugging.</para>
+ <para>This command should not be
+ confused with the
+ <command>daemon-reload</command> or
+ <command>reload</command>
+ commands.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><command>list-jobs</command></term>
+
+ <listitem><para>List jobs that are in progress.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><command>cancel [JOB...]</command></term>
+
+ <listitem><para>Cancel one or more
+ jobs specified on the command line by
+ their numeric job
+ IDs.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><command>clear-jobs</command></term>
+
+ <listitem><para>Cancel all jobs that are in progress.</para></listitem>
+ </varlistentry>
+ <varlistentry>
<term><command>monitor</command></term>
<listitem><para>Monitor unit/job
diff --git a/src/systemctl.c b/src/systemctl.c
index 12ddae8..72bb7d8 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -2106,7 +2106,7 @@ static int systemctl_help(void) {
"Send control commands to the systemd manager.\n\n"
" -h --help Show this help\n"
" -t --type=TYPE List only units of a particular type\n"
- " -p --property=NAME Show only property by this name\n"
+ " -p --property=NAME Show only properties by this name\n"
" -a --all Show all units/properties, including dead/empty ones\n"
" --replace When installing a new job, replace existing conflicting ones\n"
" --system Connect to system bus\n"
@@ -2122,7 +2122,7 @@ static int systemctl_help(void) {
" reload [NAME...] Reload one or more units\n"
" isolate [NAME] Start one unit and stop all others\n"
" check [NAME...] Check whether any of the passed units are active\n"
- " show [NAME...|JOB...] Show information about one or more units\n"
+ " show [NAME...|JOB...] Show information about one or more units/jobs/manager\n"
" load [NAME...] Load one or more units\n"
" list-jobs List jobs\n"
" cancel [JOB...] Cancel one or more jobs\n"
commit fe68089df69f3580ebc9bbaf2483bdcda40a6933
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 20:38:14 2010 +0200
dbus: complete exec command coverage
diff --git a/src/dbus-execute.c b/src/dbus-execute.c
index a41b639..529f72d 100644
--- a/src/dbus-execute.c
+++ b/src/dbus-execute.c
@@ -26,6 +26,7 @@
#include "dbus-execute.h"
#include "missing.h"
#include "ioprio.h"
+#include "strv.h"
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput);
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput);
@@ -153,7 +154,7 @@ int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *prop
assert(property);
assert(c);
- if (!(dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub)))
+ if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub))
return -ENOMEM;
if (c->cpuset)
@@ -246,3 +247,53 @@ int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *prope
return 0;
}
+
+int bus_execute_append_command(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecCommand *c = data;
+ DBusMessageIter sub, sub2, sub3;
+
+ assert(m);
+ assert(i);
+ assert(property);
+
+ if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sasttuii)", &sub))
+ return -ENOMEM;
+
+ LIST_FOREACH(command, c, c) {
+ char **l;
+ uint32_t pid;
+ int32_t code, status;
+
+ if (!c->path)
+ continue;
+
+ if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &c->path) ||
+ !dbus_message_iter_open_container(&sub2, DBUS_TYPE_ARRAY, "s", &sub3))
+ return -ENOMEM;
+
+ STRV_FOREACH(l, c->argv)
+ if (!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, l))
+ return -ENOMEM;
+
+ pid = (uint32_t) c->exec_status.pid;
+ code = (int32_t) c->exec_status.code;
+ status = (int32_t) c->exec_status.status;
+
+ if (!dbus_message_iter_close_container(&sub2, &sub3) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.realtime) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.realtime) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &c->exec_status.pid) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &c->exec_status.code) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &c->exec_status.status))
+ return -ENOMEM;
+
+ if (!dbus_message_iter_close_container(&sub, &sub2))
+ return -ENOMEM;
+ }
+
+ if (!dbus_message_iter_close_container(i, &sub))
+ return -ENOMEM;
+
+ return 0;
+}
diff --git a/src/dbus-execute.h b/src/dbus-execute.h
index 1ab196f..95d400d 100644
--- a/src/dbus-execute.h
+++ b/src/dbus-execute.h
@@ -83,7 +83,10 @@
" <property name=\"InaccessibleDirectories\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"MountFlags\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"PrivateTmp\" type=\"b\" access=\"read\"/>\n" \
- " <property name=\"NoSetSID\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"NoSetSID\" type=\"b\" access=\"read\"/>\n"
+
+#define BUS_EXEC_COMMAND_INTERFACE(name) \
+ " <property name=\"" name "\" type=\"a(sasttuii)\" access=\"read\"/>\n"
#define BUS_EXEC_CONTEXT_PROPERTIES(interface, context) \
{ interface, "Environment", bus_property_append_strv, "as", (context).environment }, \
@@ -144,6 +147,9 @@
{ interface, prefix "Code", bus_property_append_int, "i", &(estatus).code }, \
{ interface, prefix "Status", bus_property_append_int, "i", &(estatus).status }
+#define BUS_EXEC_COMMAND_PROPERTY(interface, command, name) \
+ { interface, name, bus_execute_append_command, "a(sasttuii)", (command) }
+
int bus_execute_append_output(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_input(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_oom_adjust(Manager *m, DBusMessageIter *i, const char *property, void *data);
@@ -155,5 +161,6 @@ int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *prop
int bus_execute_append_timer_slack_ns(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_command(Manager *m, DBusMessageIter *u, const char *property, void *data);
#endif
diff --git a/src/dbus-mount.c b/src/dbus-mount.c
index 5e17ec2..76a010b 100644
--- a/src/dbus-mount.c
+++ b/src/dbus-mount.c
@@ -32,6 +32,9 @@
" <property name=\"Options\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"Type\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+ BUS_EXEC_COMMAND_INTERFACE("ExecMount") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecUnmount") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecRemount") \
BUS_EXEC_CONTEXT_INTERFACE \
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
@@ -129,7 +132,9 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMess
{ "org.freedesktop.systemd1.Mount", "Options", bus_mount_append_options, "s", u },
{ "org.freedesktop.systemd1.Mount", "Type", bus_mount_append_type, "s", u },
{ "org.freedesktop.systemd1.Mount", "TimeoutUSec", bus_property_append_usec, "t", &u->mount.timeout_usec },
- /* ExecCommand */
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", u->mount.exec_command+MOUNT_EXEC_MOUNT, "ExecMount"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", u->mount.exec_command+MOUNT_EXEC_UNMOUNT, "ExecUnmount"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", u->mount.exec_command+MOUNT_EXEC_REMOUNT, "ExecRemount"),
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Mount", u->mount.exec_context),
{ "org.freedesktop.systemd1.Mount", "KillMode", bus_unit_append_kill_mode, "s", &u->mount.kill_mode },
{ "org.freedesktop.systemd1.Mount", "ControlPID", bus_property_append_pid, "u", &u->mount.control_pid },
diff --git a/src/dbus-service.c b/src/dbus-service.c
index 26524f4..46a6ff1 100644
--- a/src/dbus-service.c
+++ b/src/dbus-service.c
@@ -33,6 +33,12 @@
" <property name=\"NotifyAccess\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"RestartUSec\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStart") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecReload") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStop") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \
BUS_EXEC_CONTEXT_INTERFACE \
" <property name=\"PermissionsStartOnly\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"RootDirectoryStartOnly\" type=\"b\" access=\"read\"/>\n" \
@@ -72,7 +78,12 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio
{ "org.freedesktop.systemd1.Service", "NotifyAccess", bus_service_append_notify_access, "s", &u->service.notify_access },
{ "org.freedesktop.systemd1.Service", "RestartUSec", bus_property_append_usec, "t", &u->service.restart_usec },
{ "org.freedesktop.systemd1.Service", "TimeoutUSec", bus_property_append_usec, "t", &u->service.timeout_usec },
- /* ExecCommand */
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", u->service.exec_command[SERVICE_EXEC_START_PRE], "ExecStartPre"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", u->service.exec_command[SERVICE_EXEC_START], "ExecStart"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", u->service.exec_command[SERVICE_EXEC_START_POST], "ExecStartPost"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", u->service.exec_command[SERVICE_EXEC_RELOAD], "ExecReload"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", u->service.exec_command[SERVICE_EXEC_STOP], "ExecStop"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Service", u->service.exec_command[SERVICE_EXEC_STOP_POST], "ExecStopPost"),
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Service", u->service.exec_context),
{ "org.freedesktop.systemd1.Service", "PermissionsStartOnly", bus_property_append_bool, "b", &u->service.permissions_start_only },
{ "org.freedesktop.systemd1.Service", "RootDirectoryStartOnly", bus_property_append_bool, "b", &u->service.root_directory_start_only },
diff --git a/src/dbus-socket.c b/src/dbus-socket.c
index 5f195a1..22a4ce8 100644
--- a/src/dbus-socket.c
+++ b/src/dbus-socket.c
@@ -30,6 +30,10 @@
" <property name=\"BindIPv6Only\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"Backlog\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStopPre") \
+ BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \
BUS_EXEC_CONTEXT_INTERFACE \
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
@@ -70,7 +74,10 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes
{ "org.freedesktop.systemd1.Socket", "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", &u->socket.bind_ipv6_only },
{ "org.freedesktop.systemd1.Socket", "Backlog", bus_property_append_unsigned, "u", &u->socket.backlog },
{ "org.freedesktop.systemd1.Socket", "TimeoutUSec", bus_property_append_usec, "t", &u->socket.timeout_usec },
- /* ExecCommand */
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", u->service.exec_command[SOCKET_EXEC_START_PRE], "ExecStartPre"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", u->service.exec_command[SOCKET_EXEC_START_POST], "ExecStartPost"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", u->service.exec_command[SOCKET_EXEC_STOP_PRE], "ExecStopPre"),
+ BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", u->service.exec_command[SOCKET_EXEC_STOP_POST], "ExecStopPost"),
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Socket", u->socket.exec_context),
{ "org.freedesktop.systemd1.Socket", "KillMode", bus_unit_append_kill_mode, "s", &u->socket.kill_mode },
{ "org.freedesktop.systemd1.Socket", "ControlPID", bus_property_append_pid, "u", &u->socket.control_pid },
diff --git a/src/systemctl.c b/src/systemctl.c
index f97fa10..12ddae8 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1166,7 +1166,68 @@ static int print_property(const char *name, DBusMessageIter *iter) {
if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 &&
bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 &&
bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0)
- printf("%s=%llu\n", base, (unsigned long long) value);
+ printf("%s={ value=%llu ; next_elapse=%llu }\n",
+ base,
+ (unsigned long long) value,
+ (unsigned long long) next_elapse);
+
+ dbus_message_iter_next(&sub);
+ }
+
+ return 0;
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) {
+
+ DBusMessageIter sub, sub2, sub3;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+ const char *path;
+ uint64_t start_time, exit_time;
+ uint32_t pid;
+ int32_t code, status;
+
+ dbus_message_iter_recurse(&sub, &sub2);
+
+ if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0)
+ continue;
+
+ if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING)
+ continue;
+
+ printf("%s={ path=%s ; argv[]=", name, path);
+
+ dbus_message_iter_recurse(&sub2, &sub3);
+
+ while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) {
+ const char *s;
+
+ assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING);
+ dbus_message_iter_get_basic(&sub3, &s);
+ printf("%s ", s);
+ dbus_message_iter_next(&sub3);
+ }
+
+ if (dbus_message_iter_next(&sub2) &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_time, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_time, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) >= 0) {
+
+ char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
+
+ printf("; start=%s ; stop=%s ; pid=%u ; code=%s ; status=%i/%s",
+ strna(format_timestamp(timestamp1, sizeof(timestamp1), start_time)),
+ strna(format_timestamp(timestamp2, sizeof(timestamp2), exit_time)),
+ (unsigned) pid,
+ sigchld_code_to_string(code),
+ status,
+ strna(code == CLD_EXITED ? NULL : strsignal(status)));
+ }
+
+ printf(" }\n");
dbus_message_iter_next(&sub);
}
commit b58b41160fde88a82cba1ddec4be7dfb08825e35
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 18:49:58 2010 +0200
dbus: complete exec status coverage
diff --git a/src/dbus-execute.h b/src/dbus-execute.h
index f6cca9c..1ab196f 100644
--- a/src/dbus-execute.h
+++ b/src/dbus-execute.h
@@ -26,6 +26,13 @@
#include "manager.h"
+#define BUS_EXEC_STATUS_INTERFACE(prefix) \
+ " <property name=\"" prefix "StartTimestamp\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"" prefix "ExitTimestamp\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"" prefix "PID\" type=\"u\" access=\"read\"/>\n" \
+ " <property name=\"" prefix "Code\" type=\"i\" access=\"read\"/>\n" \
+ " <property name=\"" prefix "Status\" type=\"i\" access=\"read\"/>\n"
+
#define BUS_EXEC_CONTEXT_INTERFACE \
" <property name=\"Environment\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"UMask\" type=\"u\" access=\"read\"/>\n" \
@@ -130,6 +137,13 @@
{ interface, "PrivateTmp", bus_property_append_bool, "b", &(context).private_tmp }, \
{ interface, "NoSetSID", bus_property_append_bool, "b", &(context).no_setsid }
+#define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix) \
+ { interface, prefix "StartTimestamp", bus_property_append_usec, "t", &(estatus).start_timestamp.realtime }, \
+ { interface, prefix "ExitTimestamp", bus_property_append_usec, "t", &(estatus).start_timestamp.realtime }, \
+ { interface, prefix "PID", bus_property_append_pid, "u", &(estatus).pid }, \
+ { interface, prefix "Code", bus_property_append_int, "i", &(estatus).code }, \
+ { interface, prefix "Status", bus_property_append_int, "i", &(estatus).status }
+
int bus_execute_append_output(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_input(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_oom_adjust(Manager *m, DBusMessageIter *i, const char *property, void *data);
diff --git a/src/dbus-service.c b/src/dbus-service.c
index 84c4730..26524f4 100644
--- a/src/dbus-service.c
+++ b/src/dbus-service.c
@@ -38,6 +38,7 @@
" <property name=\"RootDirectoryStartOnly\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"ValidNoProcess\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
+ BUS_EXEC_STATUS_INTERFACE("ExecMain") \
" <property name=\"MainPID\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"SysVStartPriority\" type=\"i\" access=\"read\"/>\n" \
@@ -77,7 +78,7 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio
{ "org.freedesktop.systemd1.Service", "RootDirectoryStartOnly", bus_property_append_bool, "b", &u->service.root_directory_start_only },
{ "org.freedesktop.systemd1.Service", "ValidNoProcess", bus_property_append_bool, "b", &u->service.valid_no_process },
{ "org.freedesktop.systemd1.Service", "KillMode", bus_unit_append_kill_mode, "s", &u->service.kill_mode },
- /* MainExecStatus */
+ BUS_EXEC_STATUS_PROPERTIES("org.freedesktop.systemd1.Service", u->service.main_exec_status, "ExecMain"),
{ "org.freedesktop.systemd1.Service", "MainPID", bus_property_append_pid, "u", &u->service.main_pid },
{ "org.freedesktop.systemd1.Service", "ControlPID", bus_property_append_pid, "u", &u->service.control_pid },
{ "org.freedesktop.systemd1.Service", "SysVPath", bus_property_append_string, "s", u->service.sysv_path },
diff --git a/src/execute.c b/src/execute.c
index 0bdd600..f3f95ff 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1281,8 +1281,7 @@ int exec_spawn(ExecCommand *command,
log_debug("Forked %s as %lu", command->path, (unsigned long) pid);
- command->exec_status.pid = pid;
- dual_timestamp_get(&command->exec_status.start_timestamp);
+ exec_status_start(&command->exec_status, pid);
*ret = pid;
return 0;
@@ -1561,9 +1560,21 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
}
}
-void exec_status_fill(ExecStatus *s, pid_t pid, int code, int status) {
+void exec_status_start(ExecStatus *s, pid_t pid) {
assert(s);
+ zero(*s);
+ s->pid = pid;
+ dual_timestamp_get(&s->start_timestamp);
+}
+
+void exec_status_exit(ExecStatus *s, pid_t pid, int code, int status) {
+ assert(s);
+
+ if ((s->pid && s->pid != pid) ||
+ !s->start_timestamp.realtime <= 0)
+ zero(*s);
+
s->pid = pid;
dual_timestamp_get(&s->exit_timestamp);
diff --git a/src/execute.h b/src/execute.h
index 9fb48e6..aa5f566 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -217,7 +217,8 @@ void exec_context_init(ExecContext *c);
void exec_context_done(ExecContext *c);
void exec_context_dump(ExecContext *c, FILE* f, const char *prefix);
-void exec_status_fill(ExecStatus *s, pid_t pid, int code, int status);
+void exec_status_start(ExecStatus *s, pid_t pid);
+void exec_status_exit(ExecStatus *s, pid_t pid, int code, int status);
void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
const char* exec_output_to_string(ExecOutput i);
diff --git a/src/mount.c b/src/mount.c
index 6b38741..b99e5ff 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -936,7 +936,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
m->failure = m->failure || !success;
if (m->control_command) {
- exec_status_fill(&m->control_command->exec_status, pid, code, status);
+ exec_status_exit(&m->control_command->exec_status, pid, code, status);
m->control_command = NULL;
m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
}
diff --git a/src/service.c b/src/service.c
index 04ed684..ae8a763 100644
--- a/src/service.c
+++ b/src/service.c
@@ -144,6 +144,8 @@ static int service_set_main_pid(Service *s, pid_t pid) {
s->main_pid = pid;
s->main_pid_known = true;
+ exec_status_start(&s->main_exec_status, pid);
+
return 0;
}
@@ -2082,7 +2084,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (s->main_pid == pid) {
- exec_status_fill(&s->main_exec_status, pid, code, status);
+ exec_status_exit(&s->main_exec_status, pid, code, status);
s->main_pid = 0;
if (s->type != SERVICE_FORKING) {
@@ -2138,7 +2140,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
} else if (s->control_pid == pid) {
if (s->control_command)
- exec_status_fill(&s->control_command->exec_status, pid, code, status);
+ exec_status_exit(&s->control_command->exec_status, pid, code, status);
s->control_pid = 0;
diff --git a/src/socket.c b/src/socket.c
index 03e556c..00e0685 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -1397,7 +1397,7 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
s->failure = s->failure || !success;
if (s->control_command)
- exec_status_fill(&s->control_command->exec_status, pid, code, status);
+ exec_status_exit(&s->control_command->exec_status, pid, code, status);
log_debug("%s control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
commit 14ad1d1437f51b8ebc8dc6e8d3707b41d48d0a3a
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 16:48:24 2010 +0200
dbus: include NextElapse field in timer properties
diff --git a/src/dbus-timer.c b/src/dbus-timer.c
index af0ae72..d548227 100644
--- a/src/dbus-timer.c
+++ b/src/dbus-timer.c
@@ -29,6 +29,7 @@
" <interface name=\"org.freedesktop.systemd1.Timer\">\n" \
" <property name=\"Unit\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"Timers\" type=\"a(stt)\" access=\"read\"/>\n" \
+ " <property name=\"NextElapse\" type=\"t\" access=\"read\"/>\n" \
" </interface>\n"
#define INTROSPECTION \
@@ -77,6 +78,7 @@ DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMess
BUS_UNIT_PROPERTIES,
{ "org.freedesktop.systemd1.Timer", "Unit", bus_property_append_string, "s", u->timer.unit->meta.id },
{ "org.freedesktop.systemd1.Timer", "Timers", bus_timer_append_timers, "a(stt)", u },
+ { "org.freedesktop.systemd1.Timer", "NextElapse", bus_property_append_usec, "t", &u->timer.next_elapse },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/systemctl.c b/src/systemctl.c
index 392ecf2..f97fa10 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1024,7 +1024,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
/* Yes, heuristics! But we can change this check
* should it turn out to not be sufficient */
- if (strstr(name, "Timestamp") || strstr(name, "Elapse")) {
+ if (strstr(name, "Timestamp")) {
char timestamp[FORMAT_TIMESTAMP_MAX], *t;
if ((t = format_timestamp(timestamp, sizeof(timestamp), u)) || arg_all)
commit 82c121a4754a9d405b07c75796e329942af2ccc5
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 16:44:58 2010 +0200
dbus: complete exec coverage
diff --git a/fixme b/fixme
index 2f0f929..55e47d7 100644
--- a/fixme
+++ b/fixme
@@ -39,6 +39,12 @@
* systemctl daemon-reload is kaputt
+* get rid of Subscribe() in systemctl
+
+* Unify NS, USec, NSec, Sec suffixes in properties, use format_timespan
+
+* Turn around negative options
+
External:
* patch /etc/init.d/functions with:
diff --git a/src/dbus-execute.c b/src/dbus-execute.c
index 8840396..a41b639 100644
--- a/src/dbus-execute.c
+++ b/src/dbus-execute.c
@@ -21,8 +21,228 @@
#include <errno.h>
#include <dbus/dbus.h>
+#include <sys/prctl.h>
#include "dbus-execute.h"
+#include "missing.h"
+#include "ioprio.h"
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput);
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput);
+
+int bus_execute_append_oom_adjust(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ int32_t n;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (c->oom_adjust_set)
+ n = c->oom_adjust;
+ else {
+ char *t;
+
+ n = 0;
+ if (read_one_line_file("/proc/self/oom_adj", &t) >= 0) {
+ safe_atoi(t, &n);
+ free(t);
+ }
+ }
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_nice(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ int32_t n;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (c->nice_set)
+ n = c->nice;
+ else
+ n = getpriority(PRIO_PROCESS, 0);
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_ioprio(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ int32_t n;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (c->ioprio_set)
+ n = c->ioprio;
+ else
+ n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_cpu_sched_policy(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ int32_t n;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (c->cpu_sched_set)
+ n = c->cpu_sched_policy;
+ else
+ n = sched_getscheduler(0);
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ int32_t n;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (c->cpu_sched_set)
+ n = c->cpu_sched_priority;
+ else {
+ struct sched_param p;
+ n = 0;
+
+ zero(p);
+ if (sched_getparam(0, &p) >= 0)
+ n = p.sched_priority;
+ }
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ dbus_bool_t b;
+ DBusMessageIter sub;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (!(dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub)))
+ return -ENOMEM;
+
+ if (c->cpuset)
+ b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
+ else
+ b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, 0);
+
+ if (!b)
+ return -ENOMEM;
+
+ if (!dbus_message_iter_close_container(i, &sub))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_timer_slack_ns(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ uint64_t u;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (c->timer_slack_ns_set)
+ u = (uint64_t) c->timer_slack_ns_set;
+ else
+ u = (uint64_t) prctl(PR_GET_TIMERSLACK);
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ char *t = NULL;
+ const char *s;
+ dbus_bool_t b;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ if (c->capabilities)
+ s = t = cap_to_text(c->capabilities, NULL);
+ else
+ s = "";
+
+ if (!t)
+ return -ENOMEM;
+
+ b = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &s);
+ cap_free(t);
+
+ if (!b)
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ int r;
+ uint64_t u;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ assert_se((r = rlimit_from_string(property)) >= 0);
+
+ if (c->rlimit[r])
+ u = (uint64_t) c->rlimit[r]->rlim_max;
+ else {
+ struct rlimit rl;
+
+ zero(rl);
+ getrlimit(r, &rl);
+
+ u = (uint64_t) rl.rlim_max;
+ }
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+ return -ENOMEM;
+
+ return 0;
+}
diff --git a/src/dbus-execute.h b/src/dbus-execute.h
index 1e83cac..f6cca9c 100644
--- a/src/dbus-execute.h
+++ b/src/dbus-execute.h
@@ -29,8 +29,31 @@
#define BUS_EXEC_CONTEXT_INTERFACE \
" <property name=\"Environment\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"UMask\" type=\"u\" access=\"read\"/>\n" \
+ " <property name=\"LimitCPU\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitFSIZE\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitDATA\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitSTACK\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitCORE\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitRSS\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitNOFILE\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitAS\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitNPROC\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitMEMLOCK\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitLOCKS\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitSIGPENDING\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitMSGQUEUE\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitNICE\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitRTPRIO\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"LimitRTTIME\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"WorkingDirectory\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"RootDirectory\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"OOMAdjust\" type=\"i\" access=\"read\"/>\n" \
+ " <property name=\"Nice\" type=\"i\" access=\"read\"/>\n" \
+ " <property name=\"IOScheduling\" type=\"i\" access=\"read\"/>\n" \
+ " <property name=\"CPUSchedulingPolicy\" type=\"i\" access=\"read\"/>\n" \
+ " <property name=\"CPUSchedulingPriority\" type=\"i\" access=\"read\"/>\n" \
+ " <property name=\"CPUAffinity\" type=\"ay\" access=\"read\"/>\n" \
+ " <property name=\"TimerSlackNS\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"CPUSchedulingResetOnFork\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"NonBlocking\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"StandardInput\" type=\"s\" access=\"read\"/>\n" \
@@ -39,27 +62,50 @@
" <property name=\"TTYPath\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"SyslogPriority\" type=\"i\" access=\"read\"/>\n" \
" <property name=\"SyslogIdentifier\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"SyslogNoPrefix\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"Capabilities\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"SecureBits\" type=\"i\" access=\"read\"/>\n" \
" <property name=\"CapabilityBoundingSetDrop\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"User\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"Group\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"SupplementaryGroups\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"TCPWrapName\" type=\"s\" access=\"read\"/>\n" \
- " <property name=\"PAMName\" type=\"s\" access=\"read\"/>\n"
+ " <property name=\"PAMName\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"ReadWriteDirectories\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"ReadOnlyDirectories\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"InaccessibleDirectories\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"MountFlags\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"PrivateTmp\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"NoSetSID\" type=\"b\" access=\"read\"/>\n" \
#define BUS_EXEC_CONTEXT_PROPERTIES(interface, context) \
{ interface, "Environment", bus_property_append_strv, "as", (context).environment }, \
{ interface, "UMask", bus_property_append_mode, "u", &(context).umask }, \
- /* RLimits */ \
+ { interface, "LimitCPU", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitFSIZE", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitDATA", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitSTACK", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitCORE", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitRSS", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitNOFILE", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitAS", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitNPROC", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitMEMLOCK", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitLOCKS", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitSIGPENDING", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitMSGQUEUE", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitNICE", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitRTPRIO", bus_execute_append_rlimits, "t", &(context) }, \
+ { interface, "LimitRTTIME", bus_execute_append_rlimits, "t", &(context) }, \
{ interface, "WorkingDirectory", bus_property_append_string, "s", (context).working_directory }, \
{ interface, "RootDirectory", bus_property_append_string, "s", (context).root_directory }, \
- /* OOM Adjust */ \
- /* Nice */ \
- /* IOPrio */ \
- /* CPUSchedPolicy */ \
- /* CPUSchedPriority */ \
- /* CPUAffinity */ \
- /* TimerSlackNS */ \
+ { interface, "OOMAdjust", bus_execute_append_oom_adjust, "i", &(context) }, \
+ { interface, "Nice", bus_execute_append_nice, "i", &(context) }, \
+ { interface, "IOScheduling", bus_execute_append_ioprio, "i", &(context) }, \
+ { interface, "CPUSchedulingPolicy", bus_execute_append_cpu_sched_policy, "i", &(context) }, \
+ { interface, "CPUSchedulingPriority", bus_execute_append_cpu_sched_priority, "i", &(context) }, \
+ { interface, "CPUAffinity", bus_execute_append_affinity,"ay", &(context) }, \
+ { interface, "TimerSlackNS", bus_execute_append_timer_slack_ns, "t", &(context) }, \
{ interface, "CPUSchedulingResetOnFork", bus_property_append_bool, "b", &(context).cpu_sched_reset_on_fork }, \
{ interface, "NonBlocking", bus_property_append_bool, "b", &(context).non_blocking }, \
{ interface, "StandardInput", bus_execute_append_input, "s", &(context).std_input }, \
@@ -68,16 +114,32 @@
{ interface, "TTYPath", bus_property_append_string, "s", (context).tty_path }, \
{ interface, "SyslogPriority", bus_property_append_int, "i", &(context).syslog_priority }, \
{ interface, "SyslogIdentifier", bus_property_append_string, "s", (context).syslog_identifier }, \
- /* CAPABILITIES */ \
+ { interface, "SyslogNoPrefix", bus_property_append_bool, "b", &(context).syslog_no_prefix }, \
+ { interface, "Capabilities", bus_property_append_string, "s", (context).capabilities }, \
{ interface, "SecureBits", bus_property_append_int, "i", &(context).secure_bits }, \
{ interface, "CapabilityBoundingSetDrop", bus_property_append_uint64, "t", &(context).capability_bounding_set_drop }, \
{ interface, "User", bus_property_append_string, "s", (context).user }, \
{ interface, "Group", bus_property_append_string, "s", (context).group }, \
{ interface, "SupplementaryGroups", bus_property_append_strv, "as", (context).supplementary_groups }, \
{ interface, "TCPWrapName", bus_property_append_string, "s", (context).tcpwrap_name }, \
- { interface, "PAMName", bus_property_append_string, "s", (context).pam_name }
+ { interface, "PAMName", bus_property_append_string, "s", (context).pam_name }, \
+ { interface, "ReadWriteDirectories", bus_property_append_strv, "as", (context).read_write_dirs }, \
+ { interface, "ReadOnlyDirectories", bus_property_append_strv, "as", (context).read_only_dirs }, \
+ { interface, "InaccessibleDirectories", bus_property_append_strv, "as", (context).inaccessible_dirs }, \
+ { interface, "MountFlags", bus_property_append_ul, "t", &(context).mount_flags }, \
+ { interface, "PrivateTmp", bus_property_append_bool, "b", &(context).private_tmp }, \
+ { interface, "NoSetSID", bus_property_append_bool, "b", &(context).no_setsid }
int bus_execute_append_output(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_input(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_oom_adjust(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_nice(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_ioprio(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_cpu_sched_policy(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_timer_slack_ns(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data);
#endif
diff --git a/src/dbus.c b/src/dbus.c
index 3a6d79f..405ea46 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -1473,6 +1473,22 @@ int bus_property_append_size(Manager *m, DBusMessageIter *i, const char *propert
return 0;
}
+int bus_property_append_ul(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ uint64_t u;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(data);
+
+ u = (uint64_t) *(unsigned long*) data;
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
+ return -ENOMEM;
+
+ return 0;
+}
+
int bus_parse_strv(DBusMessage *m, char ***_l) {
DBusMessageIter iter, sub;
unsigned n = 0, i = 0;
diff --git a/src/dbus.h b/src/dbus.h
index 91132fd..ccee74f 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -78,6 +78,7 @@ int bus_property_append_int32(Manager *m, DBusMessageIter *i, const char *proper
int bus_property_append_uint32(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_property_append_uint64(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_property_append_size(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_property_append_ul(Manager *m, DBusMessageIter *i, const char *property, void *data);
#define bus_property_append_int bus_property_append_int32
#define bus_property_append_pid bus_property_append_uint32
diff --git a/src/execute.c b/src/execute.c
index 9ded1c7..0bdd600 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1071,8 +1071,8 @@ int exec_spawn(ExecCommand *command,
}
}
- if (context->cpu_affinity_set)
- if (sched_setaffinity(0, sizeof(context->cpu_affinity), &context->cpu_affinity) < 0) {
+ if (context->cpuset)
+ if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
r = EXIT_CPUAFFINITY;
goto fail;
}
@@ -1350,6 +1350,9 @@ void exec_context_done(ExecContext *c) {
strv_free(c->inaccessible_dirs);
c->inaccessible_dirs = NULL;
+
+ if (c->cpuset)
+ CPU_FREE(c->cpuset);
}
void exec_command_done(ExecCommand *c) {
@@ -1458,10 +1461,10 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
prefix, c->cpu_sched_priority,
prefix, yes_no(c->cpu_sched_reset_on_fork));
- if (c->cpu_affinity_set) {
+ if (c->cpuset) {
fprintf(f, "%sCPUAffinity:", prefix);
- for (i = 0; i < CPU_SETSIZE; i++)
- if (CPU_ISSET(i, &c->cpu_affinity))
+ for (i = 0; i < c->cpuset_ncpus; i++)
+ if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
fprintf(f, " %i", i);
fputs("\n", f);
}
diff --git a/src/execute.h b/src/execute.h
index 841670a..9fb48e6 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -93,7 +93,8 @@ struct ExecContext {
int cpu_sched_policy;
int cpu_sched_priority;
- cpu_set_t cpu_affinity;
+ cpu_set_t *cpuset;
+ unsigned cpuset_ncpus;
unsigned long timer_slack_ns;
ExecInput std_input;
@@ -134,7 +135,6 @@ struct ExecContext {
bool nice_set:1;
bool ioprio_set:1;
bool cpu_sched_set:1;
- bool cpu_affinity_set:1;
bool timer_slack_ns_set:1;
/* This is not exposed to the user but available
@@ -142,7 +142,7 @@ struct ExecContext {
* /bin/mount it is run in the same process group as us so
* that the autofs logic detects that it belongs to us and we
* don't enter a trigger loop. */
- bool no_setsid:1;
+ bool no_setsid;
};
typedef enum ExitStatus {
diff --git a/src/load-fragment.c b/src/load-fragment.c
index e5c7ba2..a5ea0e4 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -725,19 +725,21 @@ static int config_parse_cpu_affinity(
if (!(t = strndup(w, l)))
return -ENOMEM;
+ if (!(c->cpuset))
+ if (!(c->cpuset = cpu_set_malloc(&c->cpuset_ncpus)))
+ return -ENOMEM;
+
r = safe_atou(t, &cpu);
free(t);
- if (r < 0 || cpu >= CPU_SETSIZE) {
+ if (r < 0 || cpu >= c->cpuset_ncpus) {
log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
return -EBADMSG;
}
- CPU_SET(cpu, &c->cpu_affinity);
+ CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset);
}
- c->cpu_affinity_set = true;
-
return 0;
}
diff --git a/src/missing.h b/src/missing.h
index 3b4cb9c..602d44a 100644
--- a/src/missing.h
+++ b/src/missing.h
@@ -27,6 +27,7 @@
#include <sys/resource.h>
#include <sys/syscall.h>
#include <fcntl.h>
+#include <unistd.h>
#ifndef RLIMIT_RTTIME
#define RLIMIT_RTTIME 15
diff --git a/src/systemctl.c b/src/systemctl.c
index 66d6ef0..392ecf2 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1111,7 +1111,29 @@ static int print_property(const char *name, DBusMessageIter *iter) {
}
return 0;
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_BYTE) {
+ DBusMessageIter sub;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ if (arg_all ||
+ dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ printf("%s=", name);
+
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ uint8_t u;
+ assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE);
+ dbus_message_iter_get_basic(&sub, &u);
+ printf("%02x", u);
+
+ dbus_message_iter_next(&sub);
+ }
+
+ puts("");
+ }
+
+ return 0;
} else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) {
DBusMessageIter sub, sub2;
diff --git a/src/util.c b/src/util.c
index b66eb46..ea8bfc1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2538,6 +2538,34 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
return 0;
}
+cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
+ cpu_set_t *r;
+ unsigned n = 1024;
+
+ /* Allocates the cpuset in the right size */
+
+ for (;;) {
+ if (!(r = CPU_ALLOC(n)))
+ return NULL;
+
+ if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
+ CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
+
+ if (ncpus)
+ *ncpus = n;
+
+ return r;
+ }
+
+ CPU_FREE(r);
+
+ if (errno != EINVAL)
+ return NULL;
+
+ n *= 2;
+ }
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
diff --git a/src/util.h b/src/util.h
index eda8e5c..50bac6e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
+#include <sched.h>
#include "macro.h"
@@ -284,6 +285,8 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
int rm_rf(const char *path, bool only_dirs, bool delete_root);
+cpu_set_t* cpu_set_malloc(unsigned *ncpus);
+
const char *ioprio_class_to_string(int i);
int ioprio_class_from_string(const char *s);
commit d264aa332a016501ae164a4316f0acc7da0636f4
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 05:14:30 2010 +0200
dbus: complete coverage of service units
diff --git a/src/dbus-service.c b/src/dbus-service.c
index 283932c..84c4730 100644
--- a/src/dbus-service.c
+++ b/src/dbus-service.c
@@ -30,6 +30,7 @@
" <property name=\"Type\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"Restart\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"PIDFile\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"NotifyAccess\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"RestartUSec\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
BUS_EXEC_CONTEXT_INTERFACE \
@@ -39,6 +40,8 @@
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"MainPID\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
+ " <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=\"BusName\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"StatusText\" type=\"s\" access=\"read\"/>\n" \
@@ -57,27 +60,31 @@ const char bus_service_interface[] = BUS_SERVICE_INTERFACE;
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType);
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart);
+static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_notify_access, notify_access, NotifyAccess);
DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Service", "Type", bus_service_append_type, "s", &u->service.type },
- { "org.freedesktop.systemd1.Service", "Restart", bus_service_append_restart, "s", &u->service.restart },
- { "org.freedesktop.systemd1.Service", "PIDFile", bus_property_append_string, "s", u->service.pid_file },
- { "org.freedesktop.systemd1.Service", "RestartUSec", bus_property_append_usec, "t", &u->service.restart_usec },
- { "org.freedesktop.systemd1.Service", "TimeoutUSec", bus_property_append_usec, "t", &u->service.timeout_usec },
+ { "org.freedesktop.systemd1.Service", "Type", bus_service_append_type, "s", &u->service.type },
+ { "org.freedesktop.systemd1.Service", "Restart", bus_service_append_restart, "s", &u->service.restart },
+ { "org.freedesktop.systemd1.Service", "PIDFile", bus_property_append_string, "s", u->service.pid_file },
+ { "org.freedesktop.systemd1.Service", "NotifyAccess", bus_service_append_notify_access, "s", &u->service.notify_access },
+ { "org.freedesktop.systemd1.Service", "RestartUSec", bus_property_append_usec, "t", &u->service.restart_usec },
+ { "org.freedesktop.systemd1.Service", "TimeoutUSec", bus_property_append_usec, "t", &u->service.timeout_usec },
/* ExecCommand */
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Service", u->service.exec_context),
- { "org.freedesktop.systemd1.Service", "PermissionsStartOnly", bus_property_append_bool, "b", &u->service.permissions_start_only },
+ { "org.freedesktop.systemd1.Service", "PermissionsStartOnly", bus_property_append_bool, "b", &u->service.permissions_start_only },
{ "org.freedesktop.systemd1.Service", "RootDirectoryStartOnly", bus_property_append_bool, "b", &u->service.root_directory_start_only },
- { "org.freedesktop.systemd1.Service", "ValidNoProcess", bus_property_append_bool, "b", &u->service.valid_no_process },
- { "org.freedesktop.systemd1.Service", "KillMode", bus_unit_append_kill_mode, "s", &u->service.kill_mode },
+ { "org.freedesktop.systemd1.Service", "ValidNoProcess", bus_property_append_bool, "b", &u->service.valid_no_process },
+ { "org.freedesktop.systemd1.Service", "KillMode", bus_unit_append_kill_mode, "s", &u->service.kill_mode },
/* MainExecStatus */
- { "org.freedesktop.systemd1.Service", "MainPID", bus_property_append_pid, "u", &u->service.main_pid },
- { "org.freedesktop.systemd1.Service", "ControlPID", bus_property_append_pid, "u", &u->service.control_pid },
- { "org.freedesktop.systemd1.Service", "SysVPath", bus_property_append_string, "s", u->service.sysv_path },
- { "org.freedesktop.systemd1.Service", "BusName", bus_property_append_string, "s", u->service.bus_name },
- { "org.freedesktop.systemd1.Service", "StatusText", bus_property_append_string, "s", u->service.status_text },
+ { "org.freedesktop.systemd1.Service", "MainPID", bus_property_append_pid, "u", &u->service.main_pid },
+ { "org.freedesktop.systemd1.Service", "ControlPID", bus_property_append_pid, "u", &u->service.control_pid },
+ { "org.freedesktop.systemd1.Service", "SysVPath", bus_property_append_string, "s", u->service.sysv_path },
+ { "org.freedesktop.systemd1.Service", "BusName", bus_property_append_string, "s", u->service.bus_name },
+ { "org.freedesktop.systemd1.Service", "StatusText", bus_property_append_string, "s", u->service.status_text },
+ { "org.freedesktop.systemd1.Service", "SysVRunLevels", bus_property_append_string, "s", u->service.sysv_runlevels },
+ { "org.freedesktop.systemd1.Service", "SysVStartPriority", bus_property_append_int, "i", &u->service.sysv_start_priority },
{ NULL, NULL, NULL, NULL, NULL }
};
commit 4e1e43c8f066c356aa5337156a1501b8ae4aef04
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 05:07:31 2010 +0200
dbus: complete socket unit coverage
diff --git a/src/dbus-socket.c b/src/dbus-socket.c
index cadb904..5f195a1 100644
--- a/src/dbus-socket.c
+++ b/src/dbus-socket.c
@@ -46,6 +46,9 @@
" <property name=\"PipeSize\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"FreeBind\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"Mark\" type=\"i\" access=\"read\"/>\n" \
+ " <property name=\"MaxConnections\" type=\"u\" access=\"read\"/>\n" \
+ " <property name=\"NAccepted\" type=\"u\" access=\"read\"/>\n" \
+ " <property name=\"NConnections\" type=\"u\" access=\"read\"/>\n" \
" </interface>\n" \
#define INTROSPECTION \
@@ -64,26 +67,29 @@ static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_
DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Socket", "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", &u->socket.bind_ipv6_only },
- { "org.freedesktop.systemd1.Socket", "Backlog", bus_property_append_unsigned, "u", &u->socket.backlog },
- { "org.freedesktop.systemd1.Socket", "TimeoutUSec", bus_property_append_usec, "t", &u->socket.timeout_usec },
+ { "org.freedesktop.systemd1.Socket", "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", &u->socket.bind_ipv6_only },
+ { "org.freedesktop.systemd1.Socket", "Backlog", bus_property_append_unsigned, "u", &u->socket.backlog },
+ { "org.freedesktop.systemd1.Socket", "TimeoutUSec", bus_property_append_usec, "t", &u->socket.timeout_usec },
/* ExecCommand */
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Socket", u->socket.exec_context),
- { "org.freedesktop.systemd1.Socket", "KillMode", bus_unit_append_kill_mode, "s", &u->socket.kill_mode },
- { "org.freedesktop.systemd1.Socket", "ControlPID", bus_property_append_pid, "u", &u->socket.control_pid },
- { "org.freedesktop.systemd1.Socket", "BindToDevice", bus_property_append_string, "s", u->socket.bind_to_device },
- { "org.freedesktop.systemd1.Socket", "DirectoryMode", bus_property_append_mode, "u", &u->socket.directory_mode },
- { "org.freedesktop.systemd1.Socket", "SocketMode", bus_property_append_mode, "u", &u->socket.socket_mode },
- { "org.freedesktop.systemd1.Socket", "Accept", bus_property_append_bool, "b", &u->socket.accept },
- { "org.freedesktop.systemd1.Socket", "KeepAlive", bus_property_append_bool, "b", &u->socket.keep_alive },
- { "org.freedesktop.systemd1.Socket", "Priority", bus_property_append_int, "i", &u->socket.priority },
- { "org.freedesktop.systemd1.Socket", "ReceiveBuffer", bus_property_append_size, "t", &u->socket.receive_buffer },
- { "org.freedesktop.systemd1.Socket", "SendBuffer", bus_property_append_size, "t", &u->socket.send_buffer },
- { "org.freedesktop.systemd1.Socket", "IPTOS", bus_property_append_int, "i", &u->socket.ip_tos },
- { "org.freedesktop.systemd1.Socket", "IPTTL", bus_property_append_int, "i", &u->socket.ip_ttl },
- { "org.freedesktop.systemd1.Socket", "PipeSize", bus_property_append_size, "t", &u->socket.pipe_size },
- { "org.freedesktop.systemd1.Socket", "FreeBind", bus_property_append_bool, "b", &u->socket.free_bind },
- { "org.freedesktop.systemd1.Socket", "Mark", bus_property_append_int, "i", &u->socket.mark },
+ { "org.freedesktop.systemd1.Socket", "KillMode", bus_unit_append_kill_mode, "s", &u->socket.kill_mode },
+ { "org.freedesktop.systemd1.Socket", "ControlPID", bus_property_append_pid, "u", &u->socket.control_pid },
+ { "org.freedesktop.systemd1.Socket", "BindToDevice", bus_property_append_string, "s", u->socket.bind_to_device },
+ { "org.freedesktop.systemd1.Socket", "DirectoryMode", bus_property_append_mode, "u", &u->socket.directory_mode },
+ { "org.freedesktop.systemd1.Socket", "SocketMode", bus_property_append_mode, "u", &u->socket.socket_mode },
+ { "org.freedesktop.systemd1.Socket", "Accept", bus_property_append_bool, "b", &u->socket.accept },
+ { "org.freedesktop.systemd1.Socket", "KeepAlive", bus_property_append_bool, "b", &u->socket.keep_alive },
+ { "org.freedesktop.systemd1.Socket", "Priority", bus_property_append_int, "i", &u->socket.priority },
+ { "org.freedesktop.systemd1.Socket", "ReceiveBuffer", bus_property_append_size, "t", &u->socket.receive_buffer },
+ { "org.freedesktop.systemd1.Socket", "SendBuffer", bus_property_append_size, "t", &u->socket.send_buffer },
+ { "org.freedesktop.systemd1.Socket", "IPTOS", bus_property_append_int, "i", &u->socket.ip_tos },
+ { "org.freedesktop.systemd1.Socket", "IPTTL", bus_property_append_int, "i", &u->socket.ip_ttl },
+ { "org.freedesktop.systemd1.Socket", "PipeSize", bus_property_append_size, "t", &u->socket.pipe_size },
+ { "org.freedesktop.systemd1.Socket", "FreeBind", bus_property_append_bool, "b", &u->socket.free_bind },
+ { "org.freedesktop.systemd1.Socket", "Mark", bus_property_append_int, "i", &u->socket.mark },
+ { "org.freedesktop.systemd1.Socket", "MaxConnections", bus_property_append_unsigned, "u", &u->socket.max_connections },
+ { "org.freedesktop.systemd1.Socket", "NConnections", bus_property_append_unsigned, "u", &u->socket.n_connections },
+ { "org.freedesktop.systemd1.Socket", "NAccepted", bus_property_append_unsigned, "u", &u->socket.n_accepted },
{ NULL, NULL, NULL, NULL, NULL }
};
commit 6681ad4d4164d59175064c42f90dd0641bfa66fd
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 05:01:36 2010 +0200
dbus: complete target unit coverage
diff --git a/src/dbus-target.c b/src/dbus-target.c
index fb84430..c109d9a 100644
--- a/src/dbus-target.c
+++ b/src/dbus-target.c
@@ -19,11 +19,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <errno.h>
+
#include "dbus-unit.h"
#include "dbus-target.h"
#define BUS_TARGET_INTERFACE \
" <interface name=\"org.freedesktop.systemd1.Target\">\n" \
+ " <property name=\"SysVRunLevel\" type=\"s\" access=\"read\"/>\n" \
" </interface>\n"
#define INTROSPECTION \
@@ -37,9 +40,31 @@
const char bus_target_interface[] = BUS_TARGET_INTERFACE;
+static int bus_target_append_runlevel(Manager *n, DBusMessageIter *i, const char *property, void *data) {
+ Target *t = data;
+ const char *d;
+ char buf[2];
+
+ assert(n);
+ assert(i);
+ assert(property);
+ assert(t);
+
+ buf[0] = (char) target_get_runlevel(t);
+ buf[1] = 0;
+
+ d = buf;
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
+ return -ENOMEM;
+
+ return 0;
+}
+
DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
+ { "org.freedesktop.systemd1.Target", "SysVRunLevel", bus_target_append_runlevel, "s", u },
{ NULL, NULL, NULL, NULL, NULL }
};
commit 5bd0707340570f48675a53f5dec8dd34b162e415
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 04:55:33 2010 +0200
dbus: complete automount and mount unit coverage
diff --git a/src/dbus-automount.c b/src/dbus-automount.c
index 61732f9..ada2d22 100644
--- a/src/dbus-automount.c
+++ b/src/dbus-automount.c
@@ -25,6 +25,7 @@
#define BUS_AUTOMOUNT_INTERFACE \
" <interface name=\"org.freedesktop.systemd1.Automount\">\n" \
" <property name=\"Where\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
" </interface>\n"
#define INTROSPECTION \
@@ -41,7 +42,8 @@ const char bus_automount_interface[] = BUS_AUTOMOUNT_INTERFACE;
DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Automount", "Where", bus_property_append_string, "s", u->automount.where },
+ { "org.freedesktop.systemd1.Automount", "Where", bus_property_append_string, "s", u->automount.where },
+ { "org.freedesktop.systemd1.Automount", "DirectoryMode", bus_property_append_mode, "u", &u->automount.directory_mode },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/dbus-mount.c b/src/dbus-mount.c
index 0f417e7..5e17ec2 100644
--- a/src/dbus-mount.c
+++ b/src/dbus-mount.c
@@ -35,6 +35,7 @@
BUS_EXEC_CONTEXT_INTERFACE \
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
+ " <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
" </interface>\n"
#define INTROSPECTION \
@@ -123,15 +124,16 @@ static int bus_mount_append_type(Manager *n, DBusMessageIter *i, const char *pro
DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Mount", "Where", bus_property_append_string, "s", u->mount.where },
- { "org.freedesktop.systemd1.Mount", "What", bus_mount_append_what, "s", u },
- { "org.freedesktop.systemd1.Mount", "Options", bus_mount_append_options, "s", u },
- { "org.freedesktop.systemd1.Mount", "Type", bus_mount_append_type, "s", u },
- { "org.freedesktop.systemd1.Mount", "TimeoutUSec", bus_property_append_usec, "t", &u->mount.timeout_usec },
+ { "org.freedesktop.systemd1.Mount", "Where", bus_property_append_string, "s", u->mount.where },
+ { "org.freedesktop.systemd1.Mount", "What", bus_mount_append_what, "s", u },
+ { "org.freedesktop.systemd1.Mount", "Options", bus_mount_append_options, "s", u },
+ { "org.freedesktop.systemd1.Mount", "Type", bus_mount_append_type, "s", u },
+ { "org.freedesktop.systemd1.Mount", "TimeoutUSec", bus_property_append_usec, "t", &u->mount.timeout_usec },
/* ExecCommand */
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Mount", u->mount.exec_context),
- { "org.freedesktop.systemd1.Mount", "KillMode", bus_unit_append_kill_mode, "s", &u->mount.kill_mode },
- { "org.freedesktop.systemd1.Mount", "ControlPID", bus_property_append_pid, "u", &u->mount.control_pid },
+ { "org.freedesktop.systemd1.Mount", "KillMode", bus_unit_append_kill_mode, "s", &u->mount.kill_mode },
+ { "org.freedesktop.systemd1.Mount", "ControlPID", bus_property_append_pid, "u", &u->mount.control_pid },
+ { "org.freedesktop.systemd1.Mount", "DirectoryMode", bus_property_append_mode, "u", &u->mount.directory_mode },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/systemctl.c b/src/systemctl.c
index dddd689..66d6ef0 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1039,7 +1039,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
uint32_t u;
dbus_message_iter_get_basic(iter, &u);
- if (strstr(name, "UMask"))
+ if (strstr(name, "UMask") || strstr(name, "Mode"))
printf("%s=%04o\n", name, u);
else
printf("%s=%u\n", name, (unsigned) u);
commit f295f5c0c0a31afd1914adf5d8a4d7f51e8e0be0
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 04:47:19 2010 +0200
dbus: complete coverage of manager interface
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index f68092a..705a4dc 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -109,6 +109,11 @@
" <property name=\"NNames\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"NJobs\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"Environment\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"ConfirmSpawn\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"UnitPath\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"SysVInitPath\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"SysVRcndPath\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"NotifySocket\" type=\"s\" access=\"read\"/>\n" \
" </interface>\n"
#define INTROSPECTION_BEGIN \
@@ -189,14 +194,19 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
Manager *m = data;
const BusProperty properties[] = {
- { "org.freedesktop.systemd1.Manager", "Version", bus_property_append_string, "s", PACKAGE_STRING },
- { "org.freedesktop.systemd1.Manager", "RunningAs", bus_manager_append_running_as, "s", &m->running_as },
- { "org.freedesktop.systemd1.Manager", "StartupTimestamp", bus_property_append_uint64, "t", &m->startup_timestamp.realtime },
- { "org.freedesktop.systemd1.Manager", "LogLevel", bus_manager_append_log_level, "s", NULL },
- { "org.freedesktop.systemd1.Manager", "LogTarget", bus_manager_append_log_target, "s", NULL },
- { "org.freedesktop.systemd1.Manager", "NNames", bus_manager_append_n_names, "u", NULL },
- { "org.freedesktop.systemd1.Manager", "NJobs", bus_manager_append_n_jobs, "u", NULL },
- { "org.freedesktop.systemd1.Manager", "Environment", bus_property_append_strv, "as", m->environment },
+ { "org.freedesktop.systemd1.Manager", "Version", bus_property_append_string, "s", PACKAGE_STRING },
+ { "org.freedesktop.systemd1.Manager", "RunningAs", bus_manager_append_running_as, "s", &m->running_as },
+ { "org.freedesktop.systemd1.Manager", "StartupTimestamp", bus_property_append_uint64, "t", &m->startup_timestamp.realtime },
+ { "org.freedesktop.systemd1.Manager", "LogLevel", bus_manager_append_log_level, "s", NULL },
+ { "org.freedesktop.systemd1.Manager", "LogTarget", bus_manager_append_log_target, "s", NULL },
+ { "org.freedesktop.systemd1.Manager", "NNames", bus_manager_append_n_names, "u", NULL },
+ { "org.freedesktop.systemd1.Manager", "NJobs", bus_manager_append_n_jobs, "u", NULL },
+ { "org.freedesktop.systemd1.Manager", "Environment", bus_property_append_strv, "as", m->environment },
+ { "org.freedesktop.systemd1.Manager", "ConfirmSpawn", bus_property_append_bool, "b", &m->confirm_spawn },
+ { "org.freedesktop.systemd1.Manager", "UnitPath", bus_property_append_strv, "as", m->lookup_paths.unit_path },
+ { "org.freedesktop.systemd1.Manager", "SysVInitPath", bus_property_append_strv, "as", m->lookup_paths.sysvinit_path },
+ { "org.freedesktop.systemd1.Manager", "SysVRcndPath", bus_property_append_strv, "as", m->lookup_paths.sysvrcnd_path },
+ { "org.freedesktop.systemd1.Manager", "NotifySocket", bus_property_append_string, "s", m->notify_socket },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/manager.h b/src/manager.h
index eed137b..e856f53 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -192,7 +192,7 @@ struct Manager {
bool utmp_reboot_written:1;
- bool confirm_spawn:1;
+ bool confirm_spawn;
};
int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **m);
commit 707e5e52804a8f041f0d2f822f0bcf7062ad24ac
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 04:37:03 2010 +0200
dbus: complete coverage of timer units
diff --git a/src/dbus-timer.c b/src/dbus-timer.c
index 68bd8a4..af0ae72 100644
--- a/src/dbus-timer.c
+++ b/src/dbus-timer.c
@@ -27,8 +27,9 @@
#define BUS_TIMER_INTERFACE \
" <interface name=\"org.freedesktop.systemd1.Timer\">\n" \
- " <property name=\"Unit\" type=\"s\" access=\"read\"/>\n" \
- " </interface>\n" \
+ " <property name=\"Unit\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"Timers\" type=\"a(stt)\" access=\"read\"/>\n" \
+ " </interface>\n"
#define INTROSPECTION \
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
@@ -41,10 +42,41 @@
const char bus_timer_interface[] = BUS_TIMER_INTERFACE;
+static int bus_timer_append_timers(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ Timer *p = data;
+ DBusMessageIter sub, sub2;
+ TimerValue *k;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(p);
+
+ if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(stt)", &sub))
+ return -ENOMEM;
+
+ LIST_FOREACH(value, k, p->values) {
+ const char *t = timer_base_to_string(k->base);
+
+ if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &t) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->value) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) ||
+ !dbus_message_iter_close_container(&sub, &sub2))
+ return -ENOMEM;
+ }
+
+ if (!dbus_message_iter_close_container(i, &sub))
+ return -ENOMEM;
+
+ return 0;
+}
+
DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Timer", "Unit", bus_property_append_string, "s", &u->timer.unit->meta.id },
+ { "org.freedesktop.systemd1.Timer", "Unit", bus_property_append_string, "s", u->timer.unit->meta.id },
+ { "org.freedesktop.systemd1.Timer", "Timers", bus_timer_append_timers, "a(stt)", u },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/systemctl.c b/src/systemctl.c
index 4620315..dddd689 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1024,7 +1024,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
/* Yes, heuristics! But we can change this check
* should it turn out to not be sufficient */
- if (strstr(name, "Timestamp")) {
+ if (strstr(name, "Timestamp") || strstr(name, "Elapse")) {
char timestamp[FORMAT_TIMESTAMP_MAX], *t;
if ((t = format_timestamp(timestamp, sizeof(timestamp), u)) || arg_all)
@@ -1130,6 +1130,26 @@ static int print_property(const char *name, DBusMessageIter *iter) {
}
return 0;
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) {
+ DBusMessageIter sub, sub2;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+ const char *base;
+ uint64_t value, next_elapse;
+
+ dbus_message_iter_recurse(&sub, &sub2);
+
+ if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0)
+ printf("%s=%llu\n", base, (unsigned long long) value);
+
+ dbus_message_iter_next(&sub);
+ }
+
+ return 0;
}
break;
commit e87d1818cdf26b8d946776a2182e4ef2847bc0aa
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 04:24:23 2010 +0200
systemctl: load unit when introspecting
diff --git a/src/systemctl.c b/src/systemctl.c
index 63d5d9c..4620315 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1264,7 +1264,7 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "GetUnit"))) {
+ "LoadUnit"))) {
log_error("Could not allocate message.");
r = -ENOMEM;
goto finish;
commit a68c7a7ace65354d09e8bb751ae416db4460a20f
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 04:24:07 2010 +0200
dbus: complete coverage for unit interface
diff --git a/src/dbus-unit.h b/src/dbus-unit.h
index 5662d30..7babb23 100644
--- a/src/dbus-unit.h
+++ b/src/dbus-unit.h
@@ -72,6 +72,8 @@
" <property name=\"Job\" type=\"(uo)\" access=\"read\"/>\n" \
" <property name=\"RecursiveStop\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"StopWhenUneeded\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"OnlyByDependency\" type=\"b\" access=\"read\"/>\n" \
+ " <property name=\"DefaultDependencies\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"DefaultControlGroup\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ControlGroups\" type=\"as\" access=\"read\"/>\n" \
" </interface>\n"
@@ -104,6 +106,8 @@
{ "org.freedesktop.systemd1.Unit", "Job", bus_unit_append_job, "(uo)", u }, \
{ "org.freedesktop.systemd1.Unit", "RecursiveStop", bus_property_append_bool, "b", &u->meta.recursive_stop }, \
{ "org.freedesktop.systemd1.Unit", "StopWhenUneeded", bus_property_append_bool, "b", &u->meta.stop_when_unneeded }, \
+ { "org.freedesktop.systemd1.Unit", "OnlyByDependency", bus_property_append_bool, "b", &u->meta.only_by_dependency }, \
+ { "org.freedesktop.systemd1.Unit", "DefaultDependencies", bus_property_append_bool, "b", &u->meta.default_dependencies }, \
{ "org.freedesktop.systemd1.Unit", "DefaultControlGroup", bus_unit_append_default_cgroup, "s", u }, \
{ "org.freedesktop.systemd1.Unit", "ControlGroups", bus_unit_append_cgroups, "as", u }
commit ebf57b80c37c3931ec7503b63da1a34f702d9cca
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 04:23:48 2010 +0200
dbus: complete coverage for path units
diff --git a/src/dbus-path.c b/src/dbus-path.c
index 7589f5b..8d58de3 100644
--- a/src/dbus-path.c
+++ b/src/dbus-path.c
@@ -25,26 +25,57 @@
#include "dbus-path.h"
#include "dbus-execute.h"
-#define BUS_PATH_INTERFACE \
- " <interface name=\"org.freedesktop.systemd1.Path\">\n" \
- " <property name=\"Unit\" type=\"s\" access=\"read\"/>\n" \
- " </interface>\n" \
+#define BUS_PATH_INTERFACE \
+ " <interface name=\"org.freedesktop.systemd1.Path\">\n" \
+ " <property name=\"Unit\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"Paths\" type=\"a(ss)\" access=\"read\"/>\n" \
+ " </interface>\n"
#define INTROSPECTION \
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
"<node>\n" \
BUS_UNIT_INTERFACE \
- BUS_PATH_INTERFACE \
+ BUS_PATH_INTERFACE \
BUS_PROPERTIES_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_path_interface[] = BUS_PATH_INTERFACE;
+static int bus_path_append_paths(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ Path *p = data;
+ DBusMessageIter sub, sub2;
+ PathSpec *k;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(p);
+
+ if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &sub))
+ return -ENOMEM;
+
+ LIST_FOREACH(spec, k, p->specs) {
+ const char *t = path_type_to_string(k->type);
+
+ if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &t) ||
+ !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &k->path) ||
+ !dbus_message_iter_close_container(&sub, &sub2))
+ return -ENOMEM;
+ }
+
+ if (!dbus_message_iter_close_container(i, &sub))
+ return -ENOMEM;
+
+ return 0;
+}
+
DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
- { "org.freedesktop.systemd1.Path", "Unit", bus_property_append_string, "s", &u->path.unit->meta.id },
+ { "org.freedesktop.systemd1.Path", "Unit", bus_property_append_string, "s", u->path.unit->meta.id },
+ { "org.freedesktop.systemd1.Path", "Paths", bus_path_append_paths, "a(ss)", u },
{ NULL, NULL, NULL, NULL, NULL }
};
diff --git a/src/systemctl.c b/src/systemctl.c
index b66901b..63d5d9c 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -1059,7 +1059,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
- if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && strstr(name, "Job")) {
+ if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && streq(name, "Job")) {
uint32_t u;
dbus_message_iter_get_basic(&sub, &u);
@@ -1070,7 +1070,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
printf("%s=\n", name);
return 0;
- } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && strstr(name, "Unit")) {
+ } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Unit")) {
const char *s;
dbus_message_iter_get_basic(&sub, &s);
@@ -1111,6 +1111,25 @@ static int print_property(const char *name, DBusMessageIter *iter) {
}
return 0;
+
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) {
+ DBusMessageIter sub, sub2;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+ const char *type, *path;
+
+ dbus_message_iter_recurse(&sub, &sub2);
+
+ if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0)
+ printf("%s=%s\n", type, path);
+
+ dbus_message_iter_next(&sub);
+ }
+
+ return 0;
}
break;
commit 48220598fed70bd2c310c52a4f9af9224b87abf4
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 03:43:57 2010 +0200
systemctl: implement 'show' command
diff --git a/src/systemctl.c b/src/systemctl.c
index 8445430..b66901b 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -43,6 +43,7 @@
#include "strv.h"
static const char *arg_type = NULL;
+static const char *arg_property = NULL;
static bool arg_all = false;
static bool arg_replace = false;
static bool arg_session = false;
@@ -987,7 +988,332 @@ finish:
dbus_error_free(&error);
return r;
+}
+
+static int print_property(const char *name, DBusMessageIter *iter) {
+ assert(name);
+ assert(iter);
+
+ if (arg_property && !streq(name, arg_property))
+ return 0;
+
+ switch (dbus_message_iter_get_arg_type(iter)) {
+
+ case DBUS_TYPE_STRING: {
+ const char *s;
+ dbus_message_iter_get_basic(iter, &s);
+
+ if (arg_all || s[0])
+ printf("%s=%s\n", name, s);
+
+ return 0;
+ }
+
+ case DBUS_TYPE_BOOLEAN: {
+ dbus_bool_t b;
+ dbus_message_iter_get_basic(iter, &b);
+ printf("%s=%s\n", name, yes_no(b));
+
+ return 0;
+ }
+
+ case DBUS_TYPE_UINT64: {
+ uint64_t u;
+ dbus_message_iter_get_basic(iter, &u);
+
+ /* Yes, heuristics! But we can change this check
+ * should it turn out to not be sufficient */
+
+ if (strstr(name, "Timestamp")) {
+ char timestamp[FORMAT_TIMESTAMP_MAX], *t;
+
+ if ((t = format_timestamp(timestamp, sizeof(timestamp), u)) || arg_all)
+ printf("%s=%s\n", name, strempty(t));
+ } else
+ printf("%s=%llu\n", name, (unsigned long long) u);
+
+ return 0;
+ }
+
+ case DBUS_TYPE_UINT32: {
+ uint32_t u;
+ dbus_message_iter_get_basic(iter, &u);
+
+ if (strstr(name, "UMask"))
+ printf("%s=%04o\n", name, u);
+ else
+ printf("%s=%u\n", name, (unsigned) u);
+
+ return 0;
+ }
+
+ case DBUS_TYPE_INT32: {
+ int32_t i;
+ dbus_message_iter_get_basic(iter, &i);
+
+ printf("%s=%i\n", name, (int) i);
+ return 0;
+ }
+
+ case DBUS_TYPE_STRUCT: {
+ DBusMessageIter sub;
+ dbus_message_iter_recurse(iter, &sub);
+
+ if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && strstr(name, "Job")) {
+ uint32_t u;
+
+ dbus_message_iter_get_basic(&sub, &u);
+
+ if (u)
+ printf("%s=%u\n", name, (unsigned) u);
+ else if (arg_all)
+ printf("%s=\n", name);
+
+ return 0;
+ } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && strstr(name, "Unit")) {
+ const char *s;
+
+ dbus_message_iter_get_basic(&sub, &s);
+
+ if (arg_all || s[0])
+ printf("%s=%s\n", name, s);
+
+ return 0;
+ }
+
+ break;
+ }
+
+ case DBUS_TYPE_ARRAY:
+
+ if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) {
+ DBusMessageIter sub;
+ bool space = false;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ if (arg_all ||
+ dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ printf("%s=", name);
+
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ const char *s;
+
+ assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
+ dbus_message_iter_get_basic(&sub, &s);
+ printf("%s%s", space ? " " : "", s);
+
+ space = true;
+ dbus_message_iter_next(&sub);
+ }
+
+ puts("");
+ }
+
+ return 0;
+ }
+
+ break;
+ }
+
+ if (arg_all)
+ printf("%s=[unprintable]\n", name);
+
+ return 0;
+}
+
+static int show_one(DBusConnection *bus, const char *path) {
+ DBusMessage *m = NULL, *reply = NULL;
+ const char *interface = "";
+ int r;
+ DBusError error;
+ DBusMessageIter iter, sub, sub2, sub3;
+
+ assert(bus);
+ assert(path);
+
+ dbus_error_init(&error);
+
+ if (!(m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+ path,
+ "org.freedesktop.DBus.Properties",
+ "GetAll"))) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+ log_error("Failed to issue method call: %s", error.message);
+ r = -EIO;
+ goto finish;
+ }
+
+ if (!dbus_message_iter_init(reply, &iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
+ log_error("Failed to parse reply.");
+ r = -EIO;
+ goto finish;
+ }
+
+ dbus_message_iter_recurse(&iter, &sub);
+
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ const char *name;
+
+ if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
+ log_error("Failed to parse reply.");
+ r = -EIO;
+ goto finish;
+ }
+
+ dbus_message_iter_recurse(&sub, &sub2);
+
+ if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
+ log_error("Failed to parse reply.");
+ r = -EIO;
+ goto finish;
+ }
+
+ if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) {
+ log_error("Failed to parse reply.");
+ r = -EIO;
+ goto finish;
+ }
+
+ dbus_message_iter_recurse(&sub2, &sub3);
+
+ if (print_property(name, &sub3) < 0) {
+ log_error("Failed to parse reply.");
+ r = -EIO;
+ goto finish;
+ }
+
+ dbus_message_iter_next(&sub);
+ }
+
+ r = 0;
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+ dbus_error_free(&error);
+
+ return r;
+}
+
+static int show(DBusConnection *bus, char **args, unsigned n) {
+ DBusMessage *m = NULL, *reply = NULL;
+ int r;
+ DBusError error;
+ unsigned i;
+
+ assert(bus);
+ assert(args);
+
+ dbus_error_init(&error);
+
+ if (n <= 1) {
+ /* If not argument is specified inspect the manager
+ * itself */
+
+ r = show_one(bus, "/org/freedesktop/systemd1");
+ goto finish;
+ }
+
+ for (i = 1; i < n; i++) {
+ const char *path = NULL;
+ uint32_t id;
+
+ if (safe_atou32(args[i], &id) < 0) {
+
+ if (!(m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "GetUnit"))) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_STRING, &args[i],
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ } else {
+
+ if (!(m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "GetJob"))) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_UINT32, &id,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+ }
+
+ if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+ log_error("Failed to issue method call: %s", error.message);
+ r = -EIO;
+ goto finish;
+ }
+
+ if (!dbus_message_get_args(reply, &error,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID)) {
+ log_error("Failed to parse reply: %s", error.message);
+ r = -EIO;
+ goto finish;
+ }
+
+ if ((r = show_one(bus, path)) < 0)
+ goto finish;
+
+ dbus_message_unref(m);
+ dbus_message_unref(reply);
+ m = reply = NULL;
+ }
+
+ r = 0;
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return r;
}
static DBusHandlerResult monitor_filter(DBusConnection *connection, DBusMessage *message, void *data) {
@@ -1656,27 +1982,29 @@ static int systemctl_help(void) {
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
"Send control commands to the systemd manager.\n\n"
- " -h --help Show this help\n"
- " -t --type=TYPE List only units of a particular type\n"
- " -a --all Show all units, including dead ones\n"
- " --replace When installing a new job, replace existing conflicting ones\n"
- " --system Connect to system bus\n"
- " --session Connect to session bus\n"
- " -q --quiet Suppress output\n"
- " --no-block Do not wait until operation finished\n"
- " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
+ " -h --help Show this help\n"
+ " -t --type=TYPE List only units of a particular type\n"
+ " -p --property=NAME Show only property by this name\n"
+ " -a --all Show all units/properties, including dead/empty ones\n"
+ " --replace When installing a new job, replace existing conflicting ones\n"
+ " --system Connect to system bus\n"
+ " --session Connect to session bus\n"
+ " -q --quiet Suppress output\n"
+ " --no-block Do not wait until operation finished\n"
+ " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
"Commands:\n"
" list-units List units\n"
- " list-jobs List jobs\n"
- " clear-jobs Cancel all jobs\n"
- " load [NAME...] Load one or more units\n"
- " cancel [JOB...] Cancel one or more jobs\n"
" start [NAME...] Start one or more units\n"
" stop [NAME...] Stop one or more units\n"
" restart [NAME...] Restart one or more units\n"
" reload [NAME...] Reload one or more units\n"
" isolate [NAME] Start one unit and stop all others\n"
" check [NAME...] Check whether any of the passed units are active\n"
+ " show [NAME...|JOB...] Show information about one or more units\n"
+ " load [NAME...] Load one or more units\n"
+ " list-jobs List jobs\n"
+ " cancel [JOB...] Cancel one or more jobs\n"
+ " clear-jobs Cancel all jobs\n"
" monitor Monitor unit/job changes\n"
" dump Dump server status\n"
" snapshot [NAME] Create a snapshot\n"
@@ -1776,6 +2104,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "type", required_argument, NULL, 't' },
+ { "property", required_argument, NULL, 'p' },
{ "all", no_argument, NULL, 'a' },
{ "replace", no_argument, NULL, ARG_REPLACE },
{ "session", no_argument, NULL, ARG_SESSION },
@@ -1791,7 +2120,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "htaq", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "ht:p:aq", options, NULL)) >= 0) {
switch (c) {
@@ -1803,6 +2132,15 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_type = optarg;
break;
+ case 'p':
+ arg_property = optarg;
+
+ /* If the user asked for a particular
+ * property, show it to him, even if it is
+ * empty. */
+ arg_all = true;
+ break;
+
case 'a':
arg_all = true;
break;
@@ -2343,6 +2681,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[]) {
{ "restart", MORE, 2, start_unit },
{ "isolate", EQUAL, 2, start_unit },
{ "check", MORE, 2, check_unit },
+ { "show", MORE, 1, show },
{ "monitor", EQUAL, 1, monitor },
{ "dump", EQUAL, 1, dump },
{ "snapshot", LESS, 2, snapshot },
commit 09c661966c31301ced89de93a97e9758a50fe071
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 03:43:20 2010 +0200
dbus: implement GetAll() with empty interface string properly
diff --git a/src/dbus.c b/src/dbus.c
index 2c2a9cd..3a6d79f 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -1201,7 +1201,6 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu
const char *interface;
const BusProperty *p;
DBusMessageIter iter, sub, sub2, sub3;
- bool any = false;
if (!dbus_message_get_args(
message,
@@ -1219,7 +1218,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu
goto oom;
for (p = properties; p->property; p++) {
- if (!streq(p->interface, interface))
+ if (interface[0] && !streq(p->interface, interface))
continue;
if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2) ||
@@ -1239,8 +1238,6 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu
if (!dbus_message_iter_close_container(&sub2, &sub3) ||
!dbus_message_iter_close_container(&sub, &sub2))
goto oom;
-
- any = true;
}
if (!dbus_message_iter_close_container(&iter, &sub))
commit 0442c13bfa7bff1e47312606a75f22f75aa4b60d
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Jul 4 03:42:55 2010 +0200
dbus: properly name StartupTimestamp property
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index b3e42fc..f68092a 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -103,7 +103,7 @@
" </signal>" \
" <property name=\"Version\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"RunningAs\" type=\"s\" access=\"read\"/>\n" \
- " <property name=\"BootTimestamp\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"StartupTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"LogLevel\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"LogTarget\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"NNames\" type=\"u\" access=\"read\"/>\n" \
@@ -191,12 +191,12 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
const BusProperty properties[] = {
{ "org.freedesktop.systemd1.Manager", "Version", bus_property_append_string, "s", PACKAGE_STRING },
{ "org.freedesktop.systemd1.Manager", "RunningAs", bus_manager_append_running_as, "s", &m->running_as },
- { "org.freedesktop.systemd1.Manager", "BootTimestamp", bus_property_append_uint64, "t", &m->startup_timestamp.realtime },
+ { "org.freedesktop.systemd1.Manager", "StartupTimestamp", bus_property_append_uint64, "t", &m->startup_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "LogLevel", bus_manager_append_log_level, "s", NULL },
{ "org.freedesktop.systemd1.Manager", "LogTarget", bus_manager_append_log_target, "s", NULL },
{ "org.freedesktop.systemd1.Manager", "NNames", bus_manager_append_n_names, "u", NULL },
{ "org.freedesktop.systemd1.Manager", "NJobs", bus_manager_append_n_jobs, "u", NULL },
- { "org.freedesktop.systemd1.Manager", "Environment", bus_property_append_strv, "as", m->environment },
+ { "org.freedesktop.systemd1.Manager", "Environment", bus_property_append_strv, "as", m->environment },
{ NULL, NULL, NULL, NULL, NULL }
};
More information about the systemd-commits
mailing list