- 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)
readonly s FileDescriptorStorePreserve = '...';
readonly s StatusText = '...';
readonly i StatusErrno = ...;
+ readonly s StatusBusError = '...';
+ readonly s StatusVarlinkError = '...';
readonly s Result = '...';
readonly s ReloadResult = '...';
readonly s CleanResult = '...';
<!--property FileDescriptorStorePreserve is not documented!-->
- <!--property StatusErrno is not documented!-->
-
<!--property ReloadResult is not documented!-->
<!--property CleanResult is not documented!-->
<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"/>
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
<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>
<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>
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),
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);
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"
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;
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);
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"))
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;
else {
t = strdup(e);
if (!t)
- log_oom();
+ log_oom_warning();
}
}
}
}
+ 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
char *bus_name;
char *status_text;
+ char *status_bus_error;
+ char *status_varlink_error;
int status_errno;
sd_event_source *timer_event_source;