mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 04:03:36 +08:00
Merge pull request #33430 from YHNdnzj/buserror-notify
core/service: store BUSERROR= & VARLINKERROR= received and show them through systemctl status
This commit is contained in:
commit
d42edbf1b8
4
TODO
4
TODO
@ -478,10 +478,6 @@ Features:
|
||||
- kernel-install
|
||||
- systemd-mount (with PK so that desktop environments could use it to mount disks)
|
||||
|
||||
* in the service manager, pick up ERRNO= + BUSERROR= + VARLINKERROR= error
|
||||
identifiers, and store them along with the exit status of a server and report
|
||||
via "systemctl status".
|
||||
|
||||
* enumerate virtiofs devices during boot-up in a generator, and synthesize
|
||||
mounts for rootfs, /usr/, /home/, /srv/ and some others from it, depending on
|
||||
the "tag". (waits for: https://gitlab.com/virtio-fs/virtiofsd/-/issues/128)
|
||||
|
@ -2745,6 +2745,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
readonly s FileDescriptorStorePreserve = '...';
|
||||
readonly s StatusText = '...';
|
||||
readonly i StatusErrno = ...;
|
||||
readonly s StatusBusError = '...';
|
||||
readonly s StatusVarlinkError = '...';
|
||||
readonly s Result = '...';
|
||||
readonly s ReloadResult = '...';
|
||||
readonly s CleanResult = '...';
|
||||
@ -3404,8 +3406,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<!--property FileDescriptorStorePreserve is not documented!-->
|
||||
|
||||
<!--property StatusErrno is not documented!-->
|
||||
|
||||
<!--property ReloadResult is not documented!-->
|
||||
|
||||
<!--property CleanResult is not documented!-->
|
||||
@ -4026,6 +4026,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="StatusErrno"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="StatusBusError"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="StatusVarlinkError"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Result"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="ReloadResult"/>
|
||||
@ -4732,11 +4736,11 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
process is currently running while the latter possible contains information collected from the last run
|
||||
even if the process is no longer around.</para>
|
||||
|
||||
<para><varname>StatusText</varname> contains the status text passed to the service manager via a call
|
||||
to
|
||||
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||
This may be used by services to inform the service manager about its internal state with a nice
|
||||
explanatory string.</para>
|
||||
<para><varname>StatusText</varname>, <varname>StatusErrno</varname>, <varname>StatusBusError</varname>,
|
||||
and <varname>StatusVarlinkError</varname> contain the status text, the error number,
|
||||
and the D-Bus/Varlink error name passed to the service manager via
|
||||
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||
respectively. They may be used by services to inform the service manager about its internal state.</para>
|
||||
|
||||
<para><varname>Result</varname> encodes the execution result of the last run of the service. It is
|
||||
useful to determine the reason a service failed if it is in the <literal>failed</literal> state (see
|
||||
@ -12221,6 +12225,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<varname>EffectiveMemoryMax</varname>,
|
||||
<varname>EffectiveTasksMax</varname>, and
|
||||
<varname>MemoryZSwapWriteback</varname> were added in version 256.</para>
|
||||
<para><varname>StatusBusError</varname>
|
||||
and <varname>StatusVarlinkError</varname> were added in version 257.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Job Objects</title>
|
||||
|
@ -258,12 +258,20 @@
|
||||
<term>BUSERROR=…</term>
|
||||
|
||||
<listitem><para>If a service fails, the D-Bus error-style error code. Example:
|
||||
<literal>BUSERROR=org.freedesktop.DBus.Error.TimedOut</literal>. Note that this assignment is
|
||||
currently not used by <command>systemd</command>.</para>
|
||||
<literal>BUSERROR=org.freedesktop.DBus.Error.TimedOut</literal>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v233"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>VARLINKERROR=…</term>
|
||||
|
||||
<listitem><para>If a service fails, the Varlink error-style error code. Example:
|
||||
<literal>VARLINKERROR=org.varlink.service.InvalidParameter</literal>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>EXIT_STATUS=…</term>
|
||||
|
||||
|
@ -159,6 +159,14 @@ static int acquire_bus(bool set_monitor, sd_bus **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void notify_bus_error(const sd_bus_error *error) {
|
||||
|
||||
if (!sd_bus_error_is_set(error))
|
||||
return;
|
||||
|
||||
(void) sd_notifyf(/* unset_environment= */ false, "BUSERROR=%s", error->name);
|
||||
}
|
||||
|
||||
static int list_bus_names(int argc, char **argv, void *userdata) {
|
||||
_cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
@ -459,6 +467,7 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p
|
||||
"org.freedesktop.DBus.Introspectable", "Introspect",
|
||||
&error, &reply, NULL);
|
||||
if (r < 0) {
|
||||
notify_bus_error(&error);
|
||||
printf("%sFailed to introspect object %s of service %s: %s%s\n",
|
||||
ansi_highlight_red(),
|
||||
path, service, bus_error_message(&error, r),
|
||||
@ -996,9 +1005,11 @@ static int introspect(int argc, char **argv, void *userdata) {
|
||||
r = sd_bus_call_method(bus, argv[1], argv[2],
|
||||
"org.freedesktop.DBus.Introspectable", "Introspect",
|
||||
&error, &reply_xml, NULL);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
notify_bus_error(&error);
|
||||
return log_error_errno(r, "Failed to introspect object %s of service %s: %s",
|
||||
argv[2], argv[1], bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
r = sd_bus_message_read(reply_xml, "s", &xml);
|
||||
if (r < 0)
|
||||
@ -1032,9 +1043,11 @@ static int introspect(int argc, char **argv, void *userdata) {
|
||||
r = sd_bus_call_method(bus, argv[1], argv[2],
|
||||
"org.freedesktop.DBus.Properties", "GetAll",
|
||||
&error, &reply, "s", m->interface);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
notify_bus_error(&error);
|
||||
return log_error_errno(r, "Failed to get all properties on interface %s: %s",
|
||||
m->interface, bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "{sv}");
|
||||
if (r < 0)
|
||||
@ -1305,9 +1318,11 @@ static int monitor(int argc, char **argv, int (*dump)(sd_bus_message *m, FILE *f
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_call(bus, message, arg_timeout, &error, NULL);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
notify_bus_error(&error);
|
||||
return log_error_errno(r, "Call to org.freedesktop.DBus.Monitoring.BecomeMonitor failed: %s",
|
||||
bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
r = sd_bus_get_unique_name(bus, &unique_name);
|
||||
if (r < 0)
|
||||
@ -2076,8 +2091,10 @@ static int call(int argc, char **argv, void *userdata) {
|
||||
}
|
||||
|
||||
r = sd_bus_call(bus, m, arg_timeout, &error, &reply);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
notify_bus_error(&error);
|
||||
return log_error_errno(r, "Call failed: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
r = sd_bus_message_is_empty(reply);
|
||||
if (r < 0)
|
||||
@ -2180,10 +2197,12 @@ static int get_property(int argc, char **argv, void *userdata) {
|
||||
r = sd_bus_call_method(bus, argv[1], argv[2],
|
||||
"org.freedesktop.DBus.Properties", "Get",
|
||||
&error, &reply, "ss", argv[3], *i);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
notify_bus_error(&error);
|
||||
return log_error_errno(r, "Failed to get property %s on interface %s: %s",
|
||||
*i, argv[3],
|
||||
bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
r = sd_bus_message_peek_type(reply, &type, &contents);
|
||||
if (r < 0)
|
||||
@ -2267,10 +2286,12 @@ static int set_property(int argc, char **argv, void *userdata) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too many parameters for signature.");
|
||||
|
||||
r = sd_bus_call(bus, m, arg_timeout, &error, NULL);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
notify_bus_error(&error);
|
||||
return log_error_errno(r, "Failed to set property %s on interface %s: %s",
|
||||
argv[4], argv[3],
|
||||
bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -351,6 +351,8 @@ const sd_bus_vtable bus_service_vtable[] = {
|
||||
SD_BUS_PROPERTY("FileDescriptorStorePreserve", "s", bus_property_get_exec_preserve_mode, offsetof(Service, fd_store_preserve_mode), 0),
|
||||
SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("StatusErrno", "i", bus_property_get_int, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("StatusBusError", "s", NULL, offsetof(Service, status_bus_error), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("StatusVarlinkError", "s", NULL, offsetof(Service, status_varlink_error), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("ReloadResult", "s", property_get_result, offsetof(Service, reload_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("CleanResult", "s", property_get_result, offsetof(Service, clean_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
@ -468,6 +468,8 @@ static void service_done(Unit *u) {
|
||||
|
||||
s->pid_file = mfree(s->pid_file);
|
||||
s->status_text = mfree(s->status_text);
|
||||
s->status_bus_error = mfree(s->status_bus_error);
|
||||
s->status_varlink_error = mfree(s->status_varlink_error);
|
||||
|
||||
s->exec_runtime = exec_runtime_free(s->exec_runtime);
|
||||
|
||||
@ -1045,6 +1047,14 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
fprintf(f, "%sStatus Errno: %s\n",
|
||||
prefix, STRERROR(s->status_errno));
|
||||
|
||||
if (s->status_bus_error)
|
||||
fprintf(f, "%sStatus Bus Error: %s\n",
|
||||
prefix, s->status_bus_error);
|
||||
|
||||
if (s->status_varlink_error)
|
||||
fprintf(f, "%sStatus Varlink Error: %s\n",
|
||||
prefix, s->status_varlink_error);
|
||||
|
||||
if (s->n_fd_store_max > 0)
|
||||
fprintf(f,
|
||||
"%sFile Descriptor Store Max: %u\n"
|
||||
@ -2765,6 +2775,8 @@ static int service_start(Unit *u) {
|
||||
|
||||
s->status_text = mfree(s->status_text);
|
||||
s->status_errno = 0;
|
||||
s->status_bus_error = mfree(s->status_bus_error);
|
||||
s->status_varlink_error = mfree(s->status_varlink_error);
|
||||
|
||||
s->notify_access_override = _NOTIFY_ACCESS_INVALID;
|
||||
s->notify_state = NOTIFY_UNKNOWN;
|
||||
@ -3036,6 +3048,8 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
return r;
|
||||
|
||||
(void) serialize_item_format(f, "status-errno", "%d", s->status_errno);
|
||||
(void) serialize_item(f, "status-bus-error", s->status_bus_error);
|
||||
(void) serialize_item(f, "status-varlink-error", s->status_varlink_error);
|
||||
|
||||
(void) serialize_dual_timestamp(f, "watchdog-timestamp", &s->watchdog_timestamp);
|
||||
|
||||
@ -3370,6 +3384,14 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
else
|
||||
s->status_errno = i;
|
||||
|
||||
} else if (streq(key, "status-bus-error")) {
|
||||
if (free_and_strdup(&s->status_bus_error, value) < 0)
|
||||
log_oom_debug();
|
||||
|
||||
} else if (streq(key, "status-varlink-error")) {
|
||||
if (free_and_strdup(&s->status_varlink_error, value) < 0)
|
||||
log_oom_debug();
|
||||
|
||||
} else if (streq(key, "watchdog-timestamp"))
|
||||
(void) deserialize_dual_timestamp(value, &s->watchdog_timestamp);
|
||||
else if (streq(key, "watchdog-original-usec"))
|
||||
@ -4353,7 +4375,7 @@ static void service_notify_message(
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *cc = strv_join(tags, ", ");
|
||||
log_unit_debug(u, "Got notification message from PID "PID_FMT" (%s)", ucred->pid, empty_to_na(cc));
|
||||
log_unit_debug(u, "Got notification message from PID "PID_FMT": %s", ucred->pid, empty_to_na(cc));
|
||||
}
|
||||
|
||||
usec_t monotonic_usec = USEC_INFINITY;
|
||||
@ -4479,7 +4501,7 @@ static void service_notify_message(
|
||||
else {
|
||||
t = strdup(e);
|
||||
if (!t)
|
||||
log_oom();
|
||||
log_oom_warning();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4523,10 +4545,35 @@ static void service_notify_message(
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *tag;
|
||||
size_t status_offset;
|
||||
} status_errors[] = {
|
||||
{ "BUSERROR=", offsetof(Service, status_bus_error) },
|
||||
{ "VARLINKERROR=", offsetof(Service, status_varlink_error) },
|
||||
};
|
||||
|
||||
FOREACH_ELEMENT(i, status_errors) {
|
||||
e = strv_find_startswith(tags, i->tag);
|
||||
if (!e)
|
||||
continue;
|
||||
|
||||
char **status_error = (char**) ((uint8_t*) s + i->status_offset);
|
||||
|
||||
e = empty_to_null(e);
|
||||
|
||||
if (e && !string_is_safe_ascii(e)) {
|
||||
_cleanup_free_ char *escaped = cescape(e);
|
||||
log_unit_warning(u, "Got invalid %s string, ignoring: %s", i->tag, strna(escaped));
|
||||
} else if (free_and_strdup_warn(status_error, e) > 0)
|
||||
notify_dbus = true;
|
||||
}
|
||||
|
||||
/* Interpret EXTEND_TIMEOUT= */
|
||||
e = strv_find_startswith(tags, "EXTEND_TIMEOUT_USEC=");
|
||||
if (e) {
|
||||
usec_t extend_timeout_usec;
|
||||
|
||||
if (safe_atou64(e, &extend_timeout_usec) < 0)
|
||||
log_unit_warning(u, "Failed to parse EXTEND_TIMEOUT_USEC=%s", e);
|
||||
else
|
||||
|
@ -198,6 +198,8 @@ struct Service {
|
||||
char *bus_name;
|
||||
|
||||
char *status_text;
|
||||
char *status_bus_error;
|
||||
char *status_varlink_error;
|
||||
int status_errno;
|
||||
|
||||
sd_event_source *timer_event_source;
|
||||
|
@ -62,12 +62,10 @@ extern const sd_bus_error_map __stop_SYSTEMD_BUS_ERROR_MAP[];
|
||||
static const sd_bus_error_map **additional_error_maps = NULL;
|
||||
|
||||
static int bus_error_name_to_errno(const char *name) {
|
||||
const sd_bus_error_map **map, *m;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
if (!name)
|
||||
return EINVAL;
|
||||
assert_return(name, EINVAL);
|
||||
|
||||
p = startswith(name, "System.Error.");
|
||||
if (p) {
|
||||
@ -79,8 +77,8 @@ static int bus_error_name_to_errno(const char *name) {
|
||||
}
|
||||
|
||||
if (additional_error_maps)
|
||||
for (map = additional_error_maps; *map; map++)
|
||||
for (m = *map;; m++) {
|
||||
for (const sd_bus_error_map **map = additional_error_maps; *map; map++)
|
||||
for (const sd_bus_error_map *m = *map;; m++) {
|
||||
/* For additional error maps the end marker is actually the end marker */
|
||||
if (m->code == BUS_ERROR_MAP_END_MARKER)
|
||||
break;
|
||||
@ -91,25 +89,22 @@ static int bus_error_name_to_errno(const char *name) {
|
||||
}
|
||||
}
|
||||
|
||||
m = ALIGN_PTR(__start_SYSTEMD_BUS_ERROR_MAP);
|
||||
while (m < __stop_SYSTEMD_BUS_ERROR_MAP) {
|
||||
/* For magic ELF error maps, the end marker might
|
||||
* appear in the middle of things, since multiple maps
|
||||
* might appear in the same section. Hence, let's skip
|
||||
* over it, but realign the pointer to the next 8 byte
|
||||
* boundary, which is the selected alignment for the
|
||||
* arrays. */
|
||||
if (m->code == BUS_ERROR_MAP_END_MARKER) {
|
||||
m = ALIGN_PTR(m + 1);
|
||||
const sd_bus_error_map *elf_map = ALIGN_PTR(__start_SYSTEMD_BUS_ERROR_MAP);
|
||||
while (elf_map < __stop_SYSTEMD_BUS_ERROR_MAP) {
|
||||
/* For magic ELF error maps, the end marker might appear in the middle of things, since
|
||||
* multiple maps might appear in the same section. Hence, let's skip over it, but realign
|
||||
* the pointer to the next 8 byte boundary, which is the selected alignment for the arrays. */
|
||||
if (elf_map->code == BUS_ERROR_MAP_END_MARKER) {
|
||||
elf_map = ALIGN_PTR(elf_map + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (streq(m->name, name)) {
|
||||
assert(m->code > 0);
|
||||
return m->code;
|
||||
if (streq(elf_map->name, name)) {
|
||||
assert(elf_map->code > 0);
|
||||
return elf_map->code;
|
||||
}
|
||||
|
||||
m++;
|
||||
elf_map++;
|
||||
}
|
||||
|
||||
return EIO;
|
||||
@ -389,7 +384,7 @@ _public_ int sd_bus_error_has_names_sentinel(const sd_bus_error *e, ...) {
|
||||
return !!p;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_error_get_errno(const sd_bus_error* e) {
|
||||
_public_ int sd_bus_error_get_errno(const sd_bus_error *e) {
|
||||
if (!e || !e->name)
|
||||
return 0;
|
||||
|
||||
|
@ -202,11 +202,13 @@ typedef struct UnitStatusInfo {
|
||||
bool transient;
|
||||
|
||||
/* Service */
|
||||
bool running;
|
||||
pid_t main_pid;
|
||||
pid_t control_pid;
|
||||
const char *status_text;
|
||||
const char *pid_file;
|
||||
bool running;
|
||||
const char *status_text;
|
||||
const char *status_bus_error;
|
||||
const char *status_varlink_error;
|
||||
int status_errno;
|
||||
|
||||
uint32_t fd_store_max;
|
||||
@ -681,9 +683,26 @@ static void print_status_info(
|
||||
|
||||
if (i->status_text)
|
||||
printf(" Status: \"%s%s%s\"\n", ansi_highlight_cyan(), i->status_text, ansi_normal());
|
||||
if (i->status_errno > 0) {
|
||||
errno = i->status_errno;
|
||||
printf(" Error: %i (%m)\n", i->status_errno);
|
||||
|
||||
if (i->status_errno > 0 || i->status_bus_error || i->status_varlink_error) {
|
||||
const char *prefix = " ";
|
||||
|
||||
printf(" Error:");
|
||||
|
||||
if (i->status_errno > 0) {
|
||||
printf("%scode: %i (%s)", prefix, i->status_errno, STRERROR(i->status_errno));
|
||||
prefix = "; ";
|
||||
}
|
||||
if (i->status_bus_error) {
|
||||
printf("%sD-Bus: %s", prefix, i->status_bus_error);
|
||||
prefix = "; ";
|
||||
}
|
||||
if (i->status_varlink_error) {
|
||||
printf("%sVarlink: %s", prefix, i->status_varlink_error);
|
||||
prefix = "; ";
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
if (i->ip_ingress_bytes != UINT64_MAX && i->ip_egress_bytes != UINT64_MAX)
|
||||
@ -2041,9 +2060,11 @@ static int show_one(
|
||||
{ "ExecMainPID", "u", NULL, offsetof(UnitStatusInfo, main_pid) },
|
||||
{ "MainPID", "u", map_main_pid, 0 },
|
||||
{ "ControlPID", "u", NULL, offsetof(UnitStatusInfo, control_pid) },
|
||||
{ "StatusText", "s", NULL, offsetof(UnitStatusInfo, status_text) },
|
||||
{ "PIDFile", "s", NULL, offsetof(UnitStatusInfo, pid_file) },
|
||||
{ "StatusText", "s", NULL, offsetof(UnitStatusInfo, status_text) },
|
||||
{ "StatusErrno", "i", NULL, offsetof(UnitStatusInfo, status_errno) },
|
||||
{ "StatusBusError", "s", NULL, offsetof(UnitStatusInfo, status_bus_error) },
|
||||
{ "StatusVarlinkError", "s", NULL, offsetof(UnitStatusInfo, status_varlink_error) },
|
||||
{ "FileDescriptorStoreMax", "u", NULL, offsetof(UnitStatusInfo, fd_store_max) },
|
||||
{ "NFileDescriptorStore", "u", NULL, offsetof(UnitStatusInfo, n_fd_store) },
|
||||
{ "ExecMainStartTimestamp", "t", NULL, offsetof(UnitStatusInfo, start_timestamp) },
|
||||
|
@ -54,10 +54,21 @@ sync_in b
|
||||
|
||||
echo "toplevel again: $BASHPID"
|
||||
|
||||
systemd-notify --ready --status="OK"
|
||||
systemd-notify --ready
|
||||
systemd-notify "ERRNO=1" "BUSERROR=org.freedesktop.DBus.Error.InvalidArgs" "VARLINKERROR=org.varlink.service.InvalidParameter"
|
||||
|
||||
sync_out e
|
||||
sync_in f
|
||||
|
||||
systemd-notify "ERRNO=bogus" "BUSERROR=草wwww" "VARLINKERROR=systemköttel"
|
||||
|
||||
sync_out g
|
||||
sync_in h
|
||||
|
||||
systemd-notify --status="OK"
|
||||
systemd-notify "NOTIFYACCESS=none"
|
||||
systemd-notify --status="BOGUS3"
|
||||
|
||||
sync_out e
|
||||
sync_out i
|
||||
|
||||
exec sleep infinity
|
||||
|
@ -20,6 +20,8 @@ sync_out() {
|
||||
|
||||
export SYSTEMD_LOG_LEVEL=debug
|
||||
|
||||
# Test NotifyAccess= override through sd_notify()
|
||||
|
||||
systemctl --no-block start notify.service
|
||||
|
||||
sync_in a
|
||||
@ -38,6 +40,22 @@ sync_out d
|
||||
sync_in e
|
||||
|
||||
systemctl --quiet is-active notify.service
|
||||
[[ "$(systemctl show notify.service -P StatusText)" != BOGUS* ]]
|
||||
|
||||
assert_eq "$(systemctl show notify.service -P StatusErrno)" "1"
|
||||
assert_eq "$(systemctl show notify.service -P StatusBusError)" "org.freedesktop.DBus.Error.InvalidArgs"
|
||||
assert_eq "$(systemctl show notify.service -P StatusVarlinkError)" "org.varlink.service.InvalidParameter"
|
||||
|
||||
sync_out f
|
||||
sync_in g
|
||||
|
||||
assert_eq "$(systemctl show notify.service -P StatusErrno)" "1"
|
||||
assert_eq "$(systemctl show notify.service -P StatusBusError)" "org.freedesktop.DBus.Error.InvalidArgs"
|
||||
assert_eq "$(systemctl show notify.service -P StatusVarlinkError)" "org.varlink.service.InvalidParameter"
|
||||
|
||||
sync_out h
|
||||
sync_in i
|
||||
|
||||
assert_eq "$(systemctl show notify.service -p StatusText --value)" "OK"
|
||||
assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "none"
|
||||
|
||||
@ -46,6 +64,12 @@ assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "all"
|
||||
|
||||
rm /tmp/syncfifo1 /tmp/syncfifo2
|
||||
|
||||
# Explicitly test busctl's BUSERROR= reporting and systemctl status should show it
|
||||
|
||||
(! systemd-run --wait --unit="TEST-80-BUSERROR.service" -p NotifyAccess=main busctl introspect org.freedesktop.systemd1 /bogus/001)
|
||||
assert_eq "$(systemctl show TEST-80-BUSERROR.service -P StatusBusError)" "org.freedesktop.DBus.Error.UnknownObject"
|
||||
assert_in "D-Bus: org.freedesktop.DBus.Error.UnknownObject" "$(systemctl status TEST-80-BUSERROR.service)"
|
||||
|
||||
# Now test basic fdstore behaviour
|
||||
|
||||
MYSCRIPT="/tmp/myscript$RANDOM.sh"
|
||||
|
Loading…
Reference in New Issue
Block a user