static bool arg_full = false;
static bool arg_force = false;
static bool arg_defaults = false;
+static bool arg_sysv_compat = false; /* this is undocumented, and
+ * exists simply to make
+ * implementation of SysV
+ * compatible shell glue
+ * easier */
static char **arg_wall = NULL;
static usec_t arg_when = 0;
static enum action {
return b ? ANSI_HIGHLIGHT_GREEN_ON : ANSI_HIGHLIGHT_OFF;
}
-static bool error_is_no_service(DBusError *error) {
-
+static bool error_is_no_service(const DBusError *error) {
assert(error);
if (!dbus_error_is_set(error))
}
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
qsort(unit_infos, c, sizeof(struct unit_info), compare_unit_info);
- if (isatty(STDOUT_FILENO))
- printf("%-45s %-6s %-12s %-12s %-15s %s\n", "UNIT", "LOAD", "ACTIVE", "SUB", "JOB", "DESCRIPTION");
+ if (isatty(STDOUT_FILENO)) {
+ if (columns() >= 80+12 || arg_full)
+ printf("%-25s %-6s %-12s %-18s %-15s %s\n", "UNIT", "LOAD", "ACTIVE", "SUB", "JOB", "DESCRIPTION");
+ else
+ printf("%-25s %-6s %-12s %-18s %-15s\n", "UNIT", "LOAD", "ACTIVE", "SUB", "JOB");
+ }
for (k = 0; k < c; k++) {
const char *dot;
(arg_all || !(streq(u->active_state, "inactive") || u->following[0]) || u->job_id > 0)) {
char *e;
int a = 0, b = 0;
- const char *on, *off;
+ const char *on_loaded, *off_loaded;
+ const char *on_active, *off_active;
- if (streq(u->active_state, "maintenance")) {
- on = ansi_highlight(true);
- off = ansi_highlight(false);
+ if (!streq(u->load_state, "loaded")) {
+ on_loaded = ansi_highlight(true);
+ off_loaded = ansi_highlight(false);
} else
- on = off = "";
+ on_loaded = off_loaded = "";
+
+ if (streq(u->active_state, "failed")) {
+ on_active = ansi_highlight(true);
+ off_active = ansi_highlight(false);
+ } else
+ on_active = off_active = "";
+
+ e = arg_full ? NULL : ellipsize(u->id, 25, 33);
+
+ printf("%-25s %s%-6s%s %s%-12s %-18s%s%n",
+ e ? e : u->id,
+ on_loaded, u->load_state, off_loaded,
+ on_active, u->active_state, u->sub_state, off_active,
+ &a);
- e = arg_full ? NULL : ellipsize(u->id, 45, 33);
- printf("%-45s %-6s %s%-12s %-12s%s%n", e ? e : u->id, u->load_state, on, u->active_state, u->sub_state, off, &a);
free(e);
- a -= strlen(on) + strlen(off);
+ a -= strlen(on_loaded) + strlen(off_loaded);
+ a -= strlen(on_active) + strlen(off_active);
if (u->job_id != 0)
- printf(" => %-12s%n", u->job_type, &b);
+ printf(" %-15s%n", u->job_type, &b);
else
b = 1 + 15;
- if (a + b + 2 < columns()) {
+ if (a + b + 1 < columns()) {
if (u->job_id == 0)
printf(" ");
- printf(" %.*s", columns() - a - b - 2, u->description);
+ if (arg_full)
+ printf(" %s", u->description);
+ else
+ printf(" %.*s", columns() - a - b - 1, u->description);
}
fputs("\n", stdout);
}
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
dbus_message_iter_recurse(&iter, &sub);
- printf("%4s %-45s %-17s %-7s\n", "JOB", "UNIT", "TYPE", "STATE");
+ if (isatty(STDOUT_FILENO))
+ printf("%4s %-25s %-15s %-7s\n", "JOB", "UNIT", "TYPE", "STATE");
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
const char *name, *type, *state, *job_path, *unit_path;
goto finish;
}
- e = arg_full ? NULL : ellipsize(name, 45, 33);
- printf("%4u %-45s %-17s %-7s\n", id, e ? e : name, type, state);
+ e = arg_full ? NULL : ellipsize(name, 25, 33);
+ printf("%4u %-25s %-15s %-7s\n", id, e ? e : name, type, state);
free(e);
k++;
dbus_message_iter_next(&sub);
}
- printf("\n%u jobs listed.\n", k);
+ if (isatty(STDOUT_FILENO))
+ printf("\n%u jobs listed.\n", k);
+
r = 0;
finish:
}
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
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);
+ log_error("Failed to parse reply: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
dbus_message_unref(reply);
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_BOOLEAN, &success,
DBUS_TYPE_INVALID))
- log_error("Failed to parse message: %s", error.message);
+ log_error("Failed to parse message: %s", bus_error_message(&error));
else {
char *p;
&error);
if (dbus_error_is_set(&error)) {
- log_error("Failed to add match: %s", error.message);
+ log_error("Failed to add match: %s", bus_error_message(&error));
dbus_error_free(&error);
return -EIO;
}
goto finish;
}
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
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);
+ log_error("Failed to parse reply: %s", bus_error_message(&error));
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);
+ log_error("Failed to parse reply: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
dbus_message_unref(reply);
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
if (!arg_quiet)
puts(state);
- if (streq(state, "active") || startswith(state, "reloading"))
+ if (streq(state, "active") || streq(state, "reloading"))
r = 0;
dbus_message_unref(m);
const char *path;
const char *default_control_group;
+ usec_t inactive_exit_timestamp;
+ usec_t active_enter_timestamp;
+ usec_t active_exit_timestamp;
+ usec_t inactive_enter_timestamp;
+
bool need_daemon_reload;
/* Service */
static void print_status_info(UnitStatusInfo *i) {
ExecStatusInfo *p;
const char *on, *off, *ss;
+ usec_t timestamp;
+ char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1;
+ char since2[FORMAT_TIMESTAMP_MAX], *s2;
assert(i);
ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
- if (streq_ptr(i->active_state, "maintenance")) {
+ if (streq_ptr(i->active_state, "failed")) {
on = ansi_highlight(true);
off = ansi_highlight(false);
} else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
on = off = "";
if (ss)
- printf("\t Active: %s%s (%s)%s\n",
+ printf("\t Active: %s%s (%s)%s",
on,
strna(i->active_state),
ss,
off);
else
- printf("\t Active: %s%s%s\n",
+ printf("\t Active: %s%s%s",
on,
strna(i->active_state),
off);
+ timestamp = (streq_ptr(i->active_state, "active") ||
+ streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
+ (streq_ptr(i->active_state, "inactive") ||
+ streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
+ streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
+ i->active_exit_timestamp;
+
+ s1 = format_timestamp_pretty(since1, sizeof(since1), timestamp);
+ s2 = format_timestamp(since2, sizeof(since2), timestamp);
+
+ if (s1)
+ printf(" since [%s; %s]\n", s2, s1);
+ else if (s2)
+ printf(" since [%s]\n", s2);
+ else
+ printf("\n");
+
if (i->sysfs_path)
printf("\t Device: %s\n", i->sysfs_path);
else if (i->where)
continue;
t = strv_join(p->argv, " ");
- printf("\t Exited: %u (%s, code=%s, ", p->pid, strna(t), sigchld_code_to_string(p->code));
+ printf("\t Process: %u (%s, code=%s, ", p->pid, strna(t), sigchld_code_to_string(p->code));
free(t);
if (p->code == CLD_EXITED) {
printf("\t");
if (i->main_pid > 0) {
- printf(" Main: %u", (unsigned) i->main_pid);
+ printf("Main PID: %u", (unsigned) i->main_pid);
if (i->running) {
char *t = NULL;
i->start_timestamp = (usec_t) u;
else if (streq(name, "ExecMainExitTimestamp"))
i->exit_timestamp = (usec_t) u;
+ else if (streq(name, "ActiveEnterTimestamp"))
+ i->active_enter_timestamp = (usec_t) u;
+ else if (streq(name, "InactiveEnterTimestamp"))
+ i->inactive_enter_timestamp = (usec_t) u;
+ else if (streq(name, "InactiveExitTimestamp"))
+ i->inactive_exit_timestamp = (usec_t) u;
+ else if (streq(name, "ActiveExitTimestamp"))
+ i->active_exit_timestamp = (usec_t) u;
break;
}
}
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
dbus_message_iter_next(&sub);
}
- if (!show_properties)
- print_status_info(&info);
+ r = 0;
+
+ if (!show_properties) {
+ if (arg_sysv_compat &&
+ !streq_ptr(info.active_state, "active") &&
+ !streq_ptr(info.active_state, "reloading")) {
+
+ /* If the SysV compatibility mode is on, we
+ * will refuse to run "status" on units that
+ * aren't active */
+ log_error("Unit not active.");
+ r = -EADDRNOTAVAIL;
+ } else
+ print_status_info(&info);
+ }
while ((p = info.exec)) {
LIST_REMOVE(ExecStatusInfo, exec, info.exec, p);
exec_status_info_free(p);
}
- r = 0;
-
finish:
if (m)
dbus_message_unref(m);
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
if (!dbus_error_has_name(&error, DBUS_ERROR_ACCESS_DENIED)) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
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);
+ log_error("Failed to parse reply: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
DBUS_TYPE_STRING, &id,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
- log_error("Failed to parse message: %s", error.message);
+ log_error("Failed to parse message: %s", bus_error_message(&error));
else if (streq(dbus_message_get_member(message), "UnitNew"))
printf("Unit %s added.\n", id);
else
DBUS_TYPE_UINT32, &id,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
- log_error("Failed to parse message: %s", error.message);
+ log_error("Failed to parse message: %s", bus_error_message(&error));
else if (streq(dbus_message_get_member(message), "JobNew"))
printf("Job %u added.\n", id);
else
printf("Job %u removed.\n", id);
- } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Unit", "Changed") ||
- dbus_message_is_signal(message, "org.freedesktop.systemd1.Job", "Changed")) {
+ } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) {
const char *path, *interface, *property = "Id";
DBusMessageIter iter, sub;
path = dbus_message_get_path(message);
- interface = dbus_message_get_interface(message);
+
+ if (!dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_INVALID)) {
+ log_error("Failed to parse message: %s", bus_error_message(&error));
+ goto finish;
+ }
+
+ if (!streq(interface, "org.freedesktop.systemd1.Job") &&
+ !streq(interface, "org.freedesktop.systemd1.Unit"))
+ goto finish;
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
}
if (!(reply = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
goto finish;
}
&error);
if (dbus_error_is_set(&error)) {
- log_error("Failed to add match: %s", error.message);
+ log_error("Failed to add match: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
dbus_bus_add_match(bus,
"type='signal',"
"sender='org.freedesktop.systemd1',"
- "interface='org.freedesktop.systemd1.Unit',"
- "member='Changed'",
+ "interface='org.freedesktop.DBus.Properties',"
+ "member='PropertiesChanged'",
&error);
if (dbus_error_is_set(&error)) {
- log_error("Failed to add match: %s", error.message);
- r = -EIO;
- goto finish;
- }
-
- dbus_bus_add_match(bus,
- "type='signal',"
- "sender='org.freedesktop.systemd1',"
- "interface='org.freedesktop.systemd1.Job',"
- "member='Changed'",
- &error);
-
- if (dbus_error_is_set(&error)) {
- log_error("Failed to add match: %s", error.message);
+ log_error("Failed to add match: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
if (!dbus_message_get_args(reply, &error,
DBUS_TYPE_STRING, &text,
DBUS_TYPE_INVALID)) {
- log_error("Failed to parse reply: %s", error.message);
+ log_error("Failed to parse reply: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
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);
+ log_error("Failed to parse reply: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
dbus_message_unref(reply);
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
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);
+ log_error("Failed to parse reply: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
dbus_message_unref(reply);
if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
streq(args[0], "clear-jobs") ||
streq(args[0], "cancel") ? "ClearJobs" :
streq(args[0], "daemon-reexec") ? "Reexecute" :
- streq(args[0], "reset-maintenance") ? "ResetMaintenance" :
+ streq(args[0], "reset-failed") ? "ResetFailed" :
streq(args[0], "daemon-exit") ? "Exit" :
"Reload";
}
goto finish;
}
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
return r;
}
-static int reset_maintenance(DBusConnection *bus, char **args, unsigned n) {
+static int reset_failed(DBusConnection *bus, char **args, unsigned n) {
DBusMessage *m = NULL, *reply = NULL;
unsigned i;
int r;
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "ResetMaintenanceUnit"))) {
+ "ResetFailedUnit"))) {
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
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);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
" status [NAME...|PID...] Show runtime status of one or more units\n"
" show [NAME...|JOB...] Show properties of one or more\n"
" units/jobs or the manager\n"
- " reset-maintenance [NAME...] Reset maintenance state for all, one,\n"
- " or more units\n"
+ " reset-failed [NAME...] Reset failed state for all, one, or more\n"
+ " units\n"
" enable [NAME...] Enable one or more unit files\n"
" disable [NAME...] Disable one or more unit files\n"
" is-enabled [NAME...] Check whether unit files are enabled\n"
ARG_FULL,
ARG_FORCE,
ARG_NO_RELOAD,
- ARG_DEFAULTS
+ ARG_DEFAULTS,
+ ARG_SYSV_COMPAT
};
static const struct option options[] = {
{ "require", no_argument, NULL, ARG_REQUIRE },
{ "force", no_argument, NULL, ARG_FORCE },
{ "no-reload", no_argument, NULL, ARG_NO_RELOAD },
- { "defaults", no_argument, NULL, ARG_DEFAULTS },
+ { "defaults", no_argument, NULL, ARG_DEFAULTS },
+ { "sysv-compat", no_argument, NULL, ARG_SYSV_COMPAT },
{ NULL, 0, NULL, 0 }
};
arg_defaults = true;
break;
+ case ARG_SYSV_COMPAT:
+ arg_sysv_compat = true;
+ break;
+
case '?':
return -EINVAL;
goto finish;
}
- log_error("Failed to connect to Upstart bus: %s", error.message);
+ log_error("Failed to connect to Upstart bus: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
goto finish;
}
- log_error("Failed to issue method call: %s", error.message);
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
}
{ "default", EQUAL, 1, start_special },
{ "rescue", EQUAL, 1, start_special },
{ "emergency", EQUAL, 1, start_special },
- { "reset-maintenance", MORE, 1, reset_maintenance },
+ { "reset-failed", MORE, 1, reset_failed },
{ "enable", MORE, 2, enable_unit },
{ "disable", MORE, 2, enable_unit },
{ "is-enabled", MORE, 2, enable_unit }
int r;
if (geteuid() != 0) {
- log_error("Must to be root.");
+ log_error("Must be root.");
return -EPERM;
}