ACTION!="remove", SUBSYSTEM=="drm", SUBSYSTEMS=="pci|usb|platform", IMPORT{builtin}="path_id"
# by-path
-ENV{ID_PATH}=="?*", KERNEL=="card*", SYMLINK+="dri/by-path/$env{ID_PATH}-card"
-ENV{ID_PATH}=="?*", KERNEL=="controlD*", SYMLINK+="dri/by-path/$env{ID_PATH}-control"
-ENV{ID_PATH}=="?*", KERNEL=="renderD*", SYMLINK+="dri/by-path/$env{ID_PATH}-render"
+KERNEL=="card*", ENV{ID_PATH}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH}-card"
+KERNEL=="card*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH_WITH_USB_REVISION}-card"
+KERNEL=="controlD*", ENV{ID_PATH}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH}-control"
+KERNEL=="controlD*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH_WITH_USB_REVISION}-control"
+KERNEL=="renderD*", ENV{ID_PATH}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH}-render"
+KERNEL=="renderD*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH_WITH_USB_REVISION}-render"
ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
IMPORT{builtin}="path_id"
-ENV{ID_PATH}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH}"
+ENV{ID_PATH}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH}"
+ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH_WITH_USB_REVISION}"
LABEL="persistent_alsa_end"
# by-path
SUBSYSTEMS=="pci|usb|platform|acpi", IMPORT{builtin}="path_id"
-ENV{ID_PATH}=="?*", KERNEL=="mouse*|js*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{.INPUT_CLASS}"
-ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{.INPUT_CLASS}"
+ENV{.INPUT_CLASS}=="?*", KERNEL=="mouse*|js*", ENV{ID_PATH}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{.INPUT_CLASS}"
+ENV{.INPUT_CLASS}=="?*", KERNEL=="mouse*|js*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="input/by-path/$env{ID_PATH_WITH_USB_REVISION}-$env{.INPUT_CLASS}"
+ENV{.INPUT_CLASS}=="?*", KERNEL=="event*", ENV{ID_PATH}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{.INPUT_CLASS}"
+ENV{.INPUT_CLASS}=="?*", KERNEL=="event*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="input/by-path/$env{ID_PATH_WITH_USB_REVISION}-event-$env{.INPUT_CLASS}"
# allow empty class for platform, usb and i2c devices; platform supports only a single interface that way
-SUBSYSTEMS=="usb|platform|i2c", ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", \
+SUBSYSTEMS=="usb|platform|i2c", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ENV{ID_PATH}=="?*", \
SYMLINK+="input/by-path/$env{ID_PATH}-event"
+SUBSYSTEMS=="usb|platform|i2c", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ENV{ID_PATH_WITH_USB_REVISION}=="?*", \
+ SYMLINK+="input/by-path/$env{ID_PATH_WITH_USB_REVISION}-event"
LABEL="persistent_input_end"
ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="persistent_storage_tape_end"
# type 8 devices are "Medium Changers"
-SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{program}="scsi_id --sg-version=3 --export --allowlisted -d $devnode", \
- SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL} tape/by-id/scsi-$env{ID_SERIAL}-changer"
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", GOTO="medium_changer_begin"
+GOTO="medium_changer_end"
+
+LABEL="medium_changer_begin"
+
+IMPORT{program}="scsi_id --sg-version=3 --export --allowlisted -d $devnode"
+ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL} tape/by-id/scsi-$env{ID_SERIAL}-changer"
# iSCSI devices from the same host have all the same ID_SERIAL,
# but additionally a property named ID_SCSI_SERIAL.
-SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", ENV{ID_SCSI_SERIAL}=="?*", \
- SYMLINK+="tape/by-id/scsi-$env{ID_SCSI_SERIAL}"
+ENV{ID_SCSI_SERIAL}=="?*", SYMLINK+="tape/by-id/scsi-$env{ID_SCSI_SERIAL}"
+
+IMPORT{builtin}="path_id"
+ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-changer"
+ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH_WITH_USB_REVISION}-changer"
-SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{builtin}="path_id", \
- SYMLINK+="tape/by-path/$env{ID_PATH}-changer"
+LABEL="medium_changer_end"
SUBSYSTEM!="scsi_tape", GOTO="persistent_storage_tape_end"
# by-path (parent device path)
KERNEL=="st*[0-9]|nst*[0-9]", IMPORT{builtin}="path_id"
-KERNEL=="st*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}"
-KERNEL=="nst*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-nst"
+KERNEL=="st*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}"
+KERNEL=="st*[0-9]", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH_WITH_USB_REVISION}"
+KERNEL=="nst*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-nst"
+KERNEL=="nst*[0-9]", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH_WITH_USB_REVISION}-nst"
LABEL="persistent_storage_tape_end"
# by-path
ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
ENV{DEVTYPE}=="disk", SUBSYSTEMS=="nvme-subsystem", IMPORT{builtin}="path_id"
-KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n"
-KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
-ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
-# compatible links for ATA devices
-KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH_ATA_COMPAT}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_ATA_COMPAT}"
-ENV{DEVTYPE}=="partition", ENV{ID_PATH_ATA_COMPAT}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_ATA_COMPAT}-part%n"
+KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n"
+KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_WITH_USB_REVISION}-boot%n"
+KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
+KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH_ATA_COMPAT}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_ATA_COMPAT}"
+KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_WITH_USB_REVISION}"
+ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
+ENV{DEVTYPE}=="partition", ENV{ID_PATH_ATA_COMPAT}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_ATA_COMPAT}-part%n"
+ENV{DEVTYPE}=="partition", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_WITH_USB_REVISION}-part%n"
# legacy virtio-pci by-path links (deprecated)
-KERNEL=="vd*[!0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}"
-KERNEL=="vd*[0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}-part%n"
+KERNEL=="vd*[!0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}"
+KERNEL=="vd*[!0-9]", ENV{ID_PATH_WITH_USB_REVISION}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH_WITH_USB_REVISION}"
+KERNEL=="vd*[0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}-part%n"
+KERNEL=="vd*[0-9]", ENV{ID_PATH_WITH_USB_REVISION}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH_WITH_USB_REVISION}-part%n"
{% if HAVE_BLKID %}
# allow admin to disable probing the filesystem for slow devices like floppy disk drives
ATTR{index}!="?*", GOTO="persistent_v4l_end"
IMPORT{builtin}="path_id"
-ENV{ID_PATH}=="?*", KERNEL=="video*|vbi*", SYMLINK+="v4l/by-path/$env{ID_PATH}-video-index$attr{index}"
-ENV{ID_PATH}=="?*", KERNEL=="audio*", SYMLINK+="v4l/by-path/$env{ID_PATH}-audio-index$attr{index}"
+KERNEL=="video*|vbi*", ENV{ID_PATH}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH}-video-index$attr{index}"
+KERNEL=="video*|vbi*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH_WITH_USB_REVISION}-video-index$attr{index}"
+KERNEL=="audio*", ENV{ID_PATH}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH}-audio-index$attr{index}"
+KERNEL=="audio*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH_WITH_USB_REVISION}-audio-index$attr{index}"
LABEL="persistent_v4l_end"
SUBSYSTEMS=="usb-serial", ENV{.ID_PORT}="$attr{port_number}"
IMPORT{builtin}="path_id"
-ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}"
-ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}"
+ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}"
+ENV{ID_PATH_WITH_USB_REVISION}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH_WITH_USB_REVISION}"
+ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}"
+ENV{ID_PATH_WITH_USB_REVISION}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH_WITH_USB_REVISION}-port$env{.ID_PORT}"
ENV{ID_BUS}=="", GOTO="serial_end"
ENV{ID_SERIAL}=="", GOTO="serial_end"
printf("%s", special_glyph(last ? SPECIAL_GLYPH_TREE_RIGHT : SPECIAL_GLYPH_TREE_BRANCH));
if (times) {
- if (times->time > 0)
+ if (timestamp_is_set(times->time))
printf("%s%s @%s +%s%s", ansi_highlight_red(), name,
FORMAT_TIMESPAN(times->activating - boot->userspace_time, USEC_PER_MSEC),
FORMAT_TIMESPAN(times->time, USEC_PER_MSEC), ansi_normal());
if (boot->firmware_time > boot->loader_time)
m++;
- if (boot->loader_time > 0) {
+ if (timestamp_is_set(boot->loader_time)) {
m++;
if (width < 1000.0)
width = 1000.0;
}
- if (boot->initrd_time > 0)
+ if (timestamp_is_set(boot->initrd_time))
m++;
- if (boot->kernel_done_time > 0)
+ if (timestamp_is_set(boot->kernel_done_time))
m++;
for (u = times; u->has_data; u++) {
svg("<g transform=\"translate(%.3f,100)\">\n", 20.0 + (SCALE_X * boot->firmware_time));
svg_graph_box(m, -(double) boot->firmware_time, boot->finish_time);
- if (boot->firmware_time > 0) {
+ if (timestamp_is_set(boot->firmware_time)) {
svg_bar("firmware", -(double) boot->firmware_time, -(double) boot->loader_time, y);
svg_text(true, -(double) boot->firmware_time, y, "firmware");
y++;
}
- if (boot->loader_time > 0) {
+ if (timestamp_is_set(boot->loader_time)) {
svg_bar("loader", -(double) boot->loader_time, 0, y);
svg_text(true, -(double) boot->loader_time, y, "loader");
y++;
}
- if (boot->kernel_done_time > 0) {
+ if (timestamp_is_set(boot->kernel_done_time)) {
svg_bar("kernel", 0, boot->kernel_done_time, y);
svg_text(true, 0, y, "kernel");
y++;
}
- if (boot->initrd_time > 0) {
+ if (timestamp_is_set(boot->initrd_time)) {
svg_bar("initrd", boot->initrd_time, boot->userspace_time, y);
if (boot->initrd_security_start_time < boot->initrd_security_finish_time)
svg_bar("security", boot->initrd_security_start_time, boot->initrd_security_finish_time, y);
}
svg_bar("active", boot->userspace_time, boot->finish_time, y);
- if (boot->security_start_time > 0)
+ if (timestamp_is_set(boot->security_start_time))
svg_bar("security", boot->security_start_time, boot->security_finish_time, y);
svg_bar("generators", boot->generators_start_time, boot->generators_finish_time, y);
svg_bar("unitsload", boot->unitsload_start_time, boot->unitsload_finish_time, y);
svg_bar("deactivating", 0, 300000, y);
svg_text(true, 400000, y, "Deactivating");
y++;
- if (boot->security_start_time > 0) {
+ if (timestamp_is_set(boot->security_start_time)) {
svg_bar("security", 0, 300000, y);
svg_text(true, 400000, y, "Setting up security module");
y++;
if (!text)
return log_oom();
- if (t->firmware_time > 0 && !strextend(&text, FORMAT_TIMESPAN(t->firmware_time - t->loader_time, USEC_PER_MSEC), " (firmware) + "))
+ if (timestamp_is_set(t->firmware_time) && !strextend(&text, FORMAT_TIMESPAN(t->firmware_time - t->loader_time, USEC_PER_MSEC), " (firmware) + "))
return log_oom();
- if (t->loader_time > 0 && !strextend(&text, FORMAT_TIMESPAN(t->loader_time, USEC_PER_MSEC), " (loader) + "))
+ if (timestamp_is_set(t->loader_time) && !strextend(&text, FORMAT_TIMESPAN(t->loader_time, USEC_PER_MSEC), " (loader) + "))
return log_oom();
- if (t->kernel_done_time > 0 && !strextend(&text, FORMAT_TIMESPAN(t->kernel_done_time, USEC_PER_MSEC), " (kernel) + "))
+ if (timestamp_is_set(t->kernel_done_time) && !strextend(&text, FORMAT_TIMESPAN(t->kernel_done_time, USEC_PER_MSEC), " (kernel) + "))
return log_oom();
- if (t->initrd_time > 0 && !strextend(&text, FORMAT_TIMESPAN(t->userspace_time - t->initrd_time, USEC_PER_MSEC), " (initrd) + "))
+ if (timestamp_is_set(t->initrd_time) && !strextend(&text, FORMAT_TIMESPAN(t->userspace_time - t->initrd_time, USEC_PER_MSEC), " (initrd) + "))
return log_oom();
if (!strextend(&text, FORMAT_TIMESPAN(t->finish_time - t->userspace_time, USEC_PER_MSEC), " (userspace) "))
return log_oom();
- if (t->kernel_done_time > 0)
+ if (timestamp_is_set(t->kernel_done_time))
if (!strextend(&text, "= ", FORMAT_TIMESPAN(t->firmware_time + t->finish_time, USEC_PER_MSEC), " "))
return log_oom();
if (unit_id && timestamp_is_set(activated_time)) {
- usec_t base = t->userspace_time > 0 ? t->userspace_time : t->reverse_offset;
+ usec_t base = timestamp_is_set(t->userspace_time) ? t->userspace_time : t->reverse_offset;
if (!strextend(&text, "\n", unit_id, " reached after ", FORMAT_TIMESPAN(activated_time - base, USEC_PER_MSEC), " in userspace."))
return log_oom();
if (streq(key, k)) {
va_end(aq);
- free(*v);
- *v = value;
+ free_and_replace(*v, value);
return 1;
}
#include "alloc-util.h"
#include "escape.h"
#include "extract-word.h"
+#include "fd-util.h"
#include "fileio.h"
#include "gunicode.h"
#include "locale-util.h"
STATE_CSI,
STATE_CSO,
} state = STATE_OTHER;
- char *obuf = NULL;
+ _cleanup_free_ char *obuf = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
size_t osz = 0, isz, shift[2] = {}, n_carriage_returns = 0;
- FILE *f;
assert(ibuf);
assert(*ibuf);
}
}
- if (fflush_and_check(f) < 0) {
- fclose(f);
- return mfree(obuf);
- }
- fclose(f);
+ if (fflush_and_check(f) < 0)
+ return NULL;
+
+ f = safe_fclose(f);
+
+ if (!obuf)
+ return NULL;
free_and_replace(*ibuf, obuf);
} else
t = NULL;
- free(*p);
- *p = t;
+ free_and_replace(*p, t);
return 1;
}
if (!v)
return NULL;
- free(*s);
- *s = v;
+ free_and_replace(*s, v);
}
return l;
mf = safe_fclose(mf);
+ if (!buf)
+ return bus_log_parse_error(ENOMEM);
+
z = set_get(members, &((Member) {
.type = "property",
.interface = m->interface,
if (state != old_state)
log_unit_debug(UNIT(a), "Changed %s -> %s", automount_state_to_string(old_state), automount_state_to_string(state));
- unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static int automount_coldplug(Unit *u) {
if (state != old_state)
log_unit_debug(UNIT(d), "Changed %s -> %s", device_state_to_string(old_state), device_state_to_string(state));
- unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) {
f = safe_fclose(f);
+ if (!dump)
+ return -ENOMEM;
+
*ret = TAKE_PTR(dump);
return 0;
if (state != old_state)
log_unit_debug(UNIT(m), "Changed %s -> %s", mount_state_to_string(old_state), mount_state_to_string(state));
- unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state],
- m->reload_result == MOUNT_SUCCESS ? 0 : UNIT_NOTIFY_RELOAD_FAILURE);
+ unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
}
static int mount_coldplug(Unit *u) {
if (state != old_state)
log_unit_debug(UNIT(p), "Changed %s -> %s", path_state_to_string(old_state), path_state_to_string(state));
- unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static void path_enter_waiting(Path *p, bool initial, bool from_trigger_notify);
if (state != old_state)
log_debug("%s changed %s -> %s", UNIT(s)->id, scope_state_to_string(old_state), scope_state_to_string(state));
- unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static int scope_add_default_dependencies(Scope *s) {
if (old_state != state)
log_unit_debug(UNIT(s), "Changed %s -> %s", service_state_to_string(old_state), service_state_to_string(state));
- unit_notify(UNIT(s), table[old_state], table[state],
- (s->reload_result == SERVICE_SUCCESS ? 0 : UNIT_NOTIFY_RELOAD_FAILURE) |
- (s->will_auto_restart ? UNIT_NOTIFY_WILL_AUTO_RESTART : 0));
+ unit_notify(UNIT(s), table[old_state], table[state], s->reload_result == SERVICE_SUCCESS);
}
static usec_t service_coldplug_timeout(Service *s) {
assert(s);
- if (s->will_auto_restart)
- return true;
if (IN_SET(s->state, SERVICE_DEAD_BEFORE_AUTO_RESTART, SERVICE_FAILED_BEFORE_AUTO_RESTART, SERVICE_AUTO_RESTART))
return true;
log_unit_debug(UNIT(s), "Service restart not allowed.");
else {
const char *reason;
- bool shall_restart;
- shall_restart = service_shall_restart(s, &reason);
+ allow_restart = service_shall_restart(s, &reason);
log_unit_debug(UNIT(s), "Service will %srestart (%s)",
- shall_restart ? "" : "not ",
+ allow_restart ? "" : "not ",
reason);
- if (shall_restart)
- s->will_auto_restart = true;
}
- if (s->will_auto_restart) {
- s->will_auto_restart = false;
-
+ if (allow_restart) {
/* We make two state changes here: one that maps to the high-level UNIT_INACTIVE/UNIT_FAILED
* state (i.e. a state indicating deactivation), and then one that that maps to the
* high-level UNIT_STARTING state (i.e. a state indicating activation). We do this so that
bool main_pid_alien:1;
bool bus_name_good:1;
bool forbid_restart:1;
- /* Keep restart intention between UNIT_FAILED and UNIT_ACTIVATING */
- bool will_auto_restart:1;
bool start_timeout_defined:1;
bool exec_fd_hot:1;
slice_state_to_string(old_state),
slice_state_to_string(state));
- unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static int slice_add_parent_slice(Slice *s) {
prefix, strna(s->user),
prefix, strna(s->group));
- if (s->keep_alive_time > 0)
+ if (timestamp_is_set(s->keep_alive_time))
fprintf(f,
"%sKeepAliveTimeSec: %s\n",
prefix, FORMAT_TIMESPAN(s->keep_alive_time, USEC_PER_SEC));
log_unit_warning_errno(UNIT(s), r, "SO_KEEPALIVE failed: %m");
}
- if (s->keep_alive_time > 0) {
+ if (timestamp_is_set(s->keep_alive_time)) {
r = setsockopt_int(fd, SOL_TCP, TCP_KEEPIDLE, s->keep_alive_time / USEC_PER_SEC);
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "TCP_KEEPIDLE failed: %m");
if (state != old_state)
log_unit_debug(UNIT(s), "Changed %s -> %s", socket_state_to_string(old_state), socket_state_to_string(state));
- unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static int socket_coldplug(Unit *u) {
if (state != old_state)
log_unit_debug(UNIT(s), "Changed %s -> %s", swap_state_to_string(old_state), swap_state_to_string(state));
- unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
/* If there other units for the same device node have a job
queued it might be worth checking again if it is runnable
target_state_to_string(old_state),
target_state_to_string(state));
- unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static int target_add_default_dependencies(Target *t) {
if (state != old_state)
log_unit_debug(UNIT(t), "Changed %s -> %s", timer_state_to_string(old_state), timer_state_to_string(state));
- unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0);
+ unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], /* reload_success = */ true);
}
static void timer_enter_waiting(Timer *t, bool time_change);
* to that. If we don't, just start from
* the activation time. */
- if (t->last_trigger.realtime > 0)
+ if (dual_timestamp_is_set(&t->last_trigger))
b = t->last_trigger.realtime;
- else {
- if (state_translation_table[t->state] == UNIT_ACTIVE)
- b = UNIT(t)->inactive_exit_timestamp.realtime;
- else
- b = ts.realtime;
- }
+ else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp))
+ b = UNIT(t)->inactive_exit_timestamp.realtime;
+ else
+ b = ts.realtime;
r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
if (r < 0)
(void) serialize_item(f, "state", timer_state_to_string(t->state));
(void) serialize_item(f, "result", timer_result_to_string(t->result));
- if (t->last_trigger.realtime > 0)
+ if (dual_timestamp_is_set(&t->last_trigger))
(void) serialize_usec(f, "last-trigger-realtime", t->last_trigger.realtime);
if (t->last_trigger.monotonic > 0)
if (!UNIT_VTABLE(u)->reload) {
/* Unit doesn't have a reload function, but we need to propagate the reload anyway */
- unit_notify(u, unit_active_state(u), unit_active_state(u), 0);
+ unit_notify(u, unit_active_state(u), unit_active_state(u), /* reload_success = */ true);
return 0;
}
}
}
-static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags) {
+static bool unit_process_job(Job *j, UnitActiveState ns, bool reload_success) {
bool unexpected = false;
JobResult result;
if (j->state == JOB_RUNNING) {
if (ns == UNIT_ACTIVE)
- job_finish_and_invalidate(j, (flags & UNIT_NOTIFY_RELOAD_FAILURE) ? JOB_FAILED : JOB_DONE, true, false);
+ job_finish_and_invalidate(j, reload_success ? JOB_DONE : JOB_FAILED, true, false);
else if (!IN_SET(ns, UNIT_ACTIVATING, UNIT_RELOADING)) {
unexpected = true;
return unexpected;
}
-void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags) {
+void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
const char *reason;
Manager *m;
/* Let's propagate state changes to the job */
if (u->job)
- unexpected = unit_process_job(u->job, ns, flags);
+ unexpected = unit_process_job(u->job, ns, reload_success);
else
unexpected = true;
if (ns != os && ns == UNIT_FAILED) {
log_unit_debug(u, "Unit entered failed state.");
-
- if (!(flags & UNIT_NOTIFY_WILL_AUTO_RESTART))
- unit_start_on_failure(u, "OnFailure=", UNIT_ATOM_ON_FAILURE, u->on_failure_job_mode);
+ unit_start_on_failure(u, "OnFailure=", UNIT_ATOM_ON_FAILURE, u->on_failure_job_mode);
}
if (UNIT_IS_ACTIVE_OR_RELOADING(ns) && !UNIT_IS_ACTIVE_OR_RELOADING(os)) {
unit_log_resources(u);
}
- if (ns == UNIT_INACTIVE && !IN_SET(os, UNIT_FAILED, UNIT_INACTIVE, UNIT_MAINTENANCE) &&
- !(flags & UNIT_NOTIFY_WILL_AUTO_RESTART))
+ if (ns == UNIT_INACTIVE && !IN_SET(os, UNIT_FAILED, UNIT_INACTIVE, UNIT_MAINTENANCE))
unit_start_on_failure(u, "OnSuccess=", UNIT_ATOM_ON_SUCCESS, u->on_success_job_mode);
}
void unit_notify_cgroup_oom(Unit *u, bool managed_oom);
-typedef enum UnitNotifyFlags {
- UNIT_NOTIFY_RELOAD_FAILURE = 1 << 0,
- UNIT_NOTIFY_WILL_AUTO_RESTART = 1 << 1,
-} UnitNotifyFlags;
-
-void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags);
+void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success);
int unit_watch_pid(Unit *u, pid_t pid, bool exclusive);
void unit_unwatch_pid(Unit *u, pid_t pid);
if (!n)
return log_oom();
- free(c->oldest_file);
- c->oldest_file = n;
+ free_and_replace(c->oldest_file, n);
c->oldest_mtime = t;
}
if (errno > 0)
return -errno;
+ if (!buffer)
+ return -ENOMEM;
+
*open_fds = TAKE_PTR(buffer);
return 0;
#include "blockdev-util.h"
#include "btrfs-util.h"
#include "bus-common-errors.h"
+#include "bus-locator.h"
#include "data-fd-util.h"
#include "env-util.h"
#include "errno-list.h"
if (asprintf(&unit, "user-" UID_FMT ".slice", h->uid) < 0)
return log_oom();
- r = sd_bus_call_method(
- h->manager->bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "KillUnit",
- &error,
- NULL,
- "ssi", unit, "all", SIGKILL);
+ r = bus_call_method(h->manager->bus, bus_systemd_mgr, "KillUnit", &error, NULL, "ssi", unit, "all", SIGKILL);
if (r < 0)
log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ? LOG_DEBUG : LOG_WARNING,
r, "Failed to kill login processes of user, ignoring: %s", bus_error_message(&error, r));
#include "build.h"
#include "bus-common-errors.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "bus-map-properties.h"
#include "format-table.h"
#include "hostname-setup.h"
/* This obtains one string property, and copy it if 'ret' is set, or print it otherwise. */
- r = sd_bus_get_property(
- bus,
- "org.freedesktop.hostname1",
- "/org/freedesktop/hostname1",
- "org.freedesktop.hostname1",
- attr,
- &error, &reply, "s");
+ r = bus_get_property(bus, bus_hostname, attr, &error, &reply, "s");
if (r < 0)
return log_error_errno(r, "Could not get property: %s", bus_error_message(&error, r));
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
const char *text = NULL;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.hostname1",
- "/org/freedesktop/hostname1",
- "org.freedesktop.hostname1",
- "Describe",
- &error,
- &reply,
- NULL);
+ r = bus_call_method(bus, bus_hostname, "Describe", &error, &reply, NULL);
if (r < 0)
return log_error_errno(r, "Could not get description: %s", bus_error_message(&error, r));
if (!error)
error = &e;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.hostname1",
- "/org/freedesktop/hostname1",
- "org.freedesktop.hostname1",
- method,
- error, NULL,
- "sb", value, arg_ask_password);
+ r = bus_call_method(bus, bus_hostname, method, error, NULL, "sb", value, arg_ask_password);
if (r < 0)
return log_error_errno(r, "Could not set %s: %s", target, bus_error_message(error, r));
#include "alloc-util.h"
#include "build.h"
+#include "bus-locator.h"
#include "bus-util.h"
#include "errno-util.h"
#include "fd-util.h"
if (r < 0)
return r;
- r = sd_bus_get_property_string(
- bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "Virtualization",
- NULL,
- &b);
+ r = bus_get_property_string(bus, bus_systemd_mgr, "Virtualization", NULL, &b);
if (r < 0)
return r;
/* truncate the potential old error message */
u->error[0] = '\0';
- free(u->answer);
- u->answer = 0;
+ u->answer = mfree(u->answer);
}
/* upload to this place */
#include "alloc-util.h"
#include "build.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "bus-util.h"
#include "catalog.h"
#include "chase.h"
return r;
f = safe_fclose(f);
+
+ if (!url)
+ return -ENOMEM;
+
*ret_url = TAKE_PTR(url);
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to open system bus: %m");
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "OpenMachineRootDirectory",
- &error,
- &reply,
- "s", arg_machine);
+ r = bus_call_method(bus, bus_machine_mgr, "OpenMachineRootDirectory", &error, &reply, "s", arg_machine);
if (r < 0)
return log_error_errno(r, "Failed to open root directory: %s", bus_error_message(&error, r));
char *t;
t = memdup_suffix0(p + 18, l - 18);
- if (t) {
- free(*identifier);
- *identifier = t;
- }
+ if (t)
+ free_and_replace(*identifier, t);
} else if (l >= 8 &&
startswith(p, "MESSAGE=")) {
char *t;
t = memdup_suffix0(p + 8, l - 8);
- if (t) {
- free(*message);
- *message = t;
- }
+ if (t)
+ free_and_replace(*message, t);
} else if (l > STRLEN("OBJECT_PID=") &&
l < STRLEN("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
if (!k)
return log_oom_debug();
- free(*s);
- *s = k;
+ free_and_replace(*s, k);
return 1;
}
if (!addresses)
return -ENOMEM;
- free(*ret);
- *ret = addresses;
+ free_and_replace(*ret, addresses);
*n_ret = n_addresses;
}
if (!p)
return -ENOMEM;
- free(lease->vendor_specific);
- lease->vendor_specific = p;
+ free_and_replace(lease->vendor_specific, p);
}
lease->vendor_specific_len = len;
if (!p)
return -ENOMEM;
- free(lease->client_id);
- lease->client_id = p;
+ free_and_replace(lease->client_id, p);
lease->client_id_len = client_id_len;
}
if (r < 0)
return r;
- free(c->label);
- c->label = strndup(p, sz);
- if (!c->label)
- return -ENOMEM;
+ r = free_and_strndup(&c->label, p, sz);
+ if (r < 0)
+ return r;
c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
return r;
i->f = safe_fclose(i->f);
+
+ if (!i->introspection)
+ return -ENOMEM;
+
*ret = TAKE_PTR(i->introspection);
return 0;
char *bus_match_to_string(struct bus_match_component *components, size_t n_components) {
_cleanup_free_ char *buffer = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
size_t size = 0;
int r;
assert(components);
- FILE *f = open_memstream_unlocked(&buffer, &size);
+ f = open_memstream_unlocked(&buffer, &size);
if (!f)
return NULL;
}
r = fflush_and_check(f);
- safe_fclose(f);
if (r < 0)
return NULL;
+
+ f = safe_fclose(f);
+
return TAKE_PTR(buffer);
}
b->auth_iovec[0].iov_base = p;
b->auth_iovec[0].iov_len += l;
- free(b->auth_buffer);
- b->auth_buffer = p;
+ free_and_replace(b->auth_buffer, p);
b->auth_index = 0;
return 0;
}
goto fail;
}
- free(absolute);
- absolute = c;
+ free_and_replace(absolute, c);
max_follow--;
}
char *payload, size_t payload_size) {
_cleanup_free_ CatalogItem *i = NULL;
- _cleanup_free_ char *prev = NULL, *combined = NULL;
+ _cleanup_free_ char *combined = NULL;
+ char *prev;
+ int r;
assert(h);
assert(payload);
if (!combined)
return log_oom();
- if (ordered_hashmap_update(h, i, combined) < 0)
- return log_oom();
- combined = NULL;
+ r = ordered_hashmap_update(h, i, combined);
+ if (r < 0)
+ return r;
+
+ TAKE_PTR(combined);
+ free(prev);
} else {
/* A new item */
combined = memdup(payload, payload_size + 1);
if (!combined)
return log_oom();
- if (ordered_hashmap_put(h, i, combined) < 0)
- return log_oom();
- i = NULL;
- combined = NULL;
+ r = ordered_hashmap_put(h, i, combined);
+ if (r < 0)
+ return r;
+
+ TAKE_PTR(i);
+ TAKE_PTR(combined);
}
return 0;
* cgroup, let's return the "/" in the public APIs instead, as
* that's easier and less ambiguous for people to grok. */
if (isempty(c)) {
- free(c);
- c = strdup("/");
- if (!c)
- return -ENOMEM;
+ r = free_and_strdup(&c, "/");
+ if (r < 0)
+ return r;
}
free(ai->ai_addr);
free(ai->ai_canonname);
- free(ai);
- ai = next;
+ free_and_replace(ai, next);
}
}
#include "alloc-util.h"
#include "build.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "bus-util.h"
#include "fd-util.h"
#include "format-table.h"
int r;
int fd;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "Inhibit",
- error,
- &reply,
- "ssss", arg_what, arg_who, arg_why, arg_mode);
+ r = bus_call_method(bus, bus_login_mgr, "Inhibit", error, &reply, "ssss", arg_what, arg_who, arg_why, arg_mode);
if (r < 0)
return r;
pager_open(arg_pager_flags);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "ListInhibitors",
- &error,
- &reply,
- "");
+ r = bus_call_method(bus, bus_login_mgr, "ListInhibitors", &error, &reply, NULL);
if (r < 0)
return log_error_errno(r, "Could not get active inhibitors: %s", bus_error_message(&error, r));
STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
-static OutputFlags get_output_flags(void) {
+typedef struct SessionStatusInfo {
+ const char *id;
+ uid_t uid;
+ const char *name;
+ dual_timestamp timestamp;
+ unsigned vtnr;
+ const char *seat;
+ const char *tty;
+ const char *display;
+ bool remote;
+ const char *remote_host;
+ const char *remote_user;
+ const char *service;
+ pid_t leader;
+ const char *type;
+ const char *class;
+ const char *state;
+ const char *scope;
+ const char *desktop;
+ bool idle_hint;
+ usec_t idle_hint_timestamp;
+} SessionStatusInfo;
+typedef struct UserStatusInfo {
+ uid_t uid;
+ bool linger;
+ const char *name;
+ dual_timestamp timestamp;
+ const char *state;
+ char **sessions;
+ const char *display;
+ const char *slice;
+} UserStatusInfo;
+
+typedef struct SeatStatusInfo {
+ const char *id;
+ const char *active_session;
+ char **sessions;
+} SeatStatusInfo;
+
+static void user_status_info_done(UserStatusInfo *info) {
+ assert(info);
+
+ strv_free(info->sessions);
+}
+
+static void seat_status_info_done(SeatStatusInfo *info) {
+ assert(info);
+
+ strv_free(info->sessions);
+}
+
+static OutputFlags get_output_flags(void) {
return
FLAGS_SET(arg_print_flags, BUS_PRINT_PROPERTY_SHOW_EMPTY) * OUTPUT_SHOW_ALL |
(arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
static int get_session_path(sd_bus *bus, const char *session_id, sd_bus_error *error, char **path) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- int r;
char *ans;
+ int r;
+
+ assert(bus);
+ assert(session_id);
+ assert(error);
+ assert(path);
r = bus_call_method(bus, bus_login_mgr, "GetSession", error, &reply, "s", session_id);
if (r < 0)
}
static int list_sessions(int argc, char *argv[], void *userdata) {
+
+ static const struct bus_properties_map map[] = {
+ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
+ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) },
+ { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
+ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
+ {},
+ };
+
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
if (r < 0)
return bus_log_parse_error(r);
- table = table_new("session", "uid", "user", "seat", "tty", "state");
+ table = table_new("session", "uid", "user", "seat", "tty", "state", "idle", "since");
if (!table)
return log_oom();
(void) table_set_align_percent(table, TABLE_HEADER_CELL(1), 100);
for (;;) {
- _cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *tty = NULL, *state = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
const char *id, *user, *seat, *object;
uint32_t uid;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ SessionStatusInfo i = {};
r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object);
if (r < 0)
if (r == 0)
break;
- r = sd_bus_get_property_string(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.Session",
- "TTY",
- &error_property,
- &tty);
+ r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i);
if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The session is already closed when we're querying the property */
- continue;
-
- log_warning_errno(r, "Failed to get TTY for session %s, ignoring: %s",
- id, bus_error_message(&error_property, r));
-
- sd_bus_error_free(&error_property);
- }
-
- r = sd_bus_get_property_string(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.Session",
- "State",
- &error_property,
- &state);
- if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The session is already closed when we're querying the property */
- continue;
-
- return log_error_errno(r, "Failed to get state for session %s: %s",
- id, bus_error_message(&error_property, r));
+ log_full_errno(sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING,
+ r,
+ "Failed to get properties of session %s, ignoring: %s",
+ id, bus_error_message(&e, r));
+ continue;
}
r = table_add_many(table,
TABLE_UID, (uid_t) uid,
TABLE_STRING, user,
TABLE_STRING, seat,
- TABLE_STRING, strna(tty),
- TABLE_STRING, state);
+ TABLE_STRING, strna(i.tty),
+ TABLE_STRING, i.state,
+ TABLE_BOOLEAN, i.idle_hint);
+ if (r < 0)
+ return table_log_add_error(r);
+
+ if (i.idle_hint)
+ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp);
+ else
+ r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
if (r < 0)
return table_log_add_error(r);
}
}
static int list_users(int argc, char *argv[], void *userdata) {
+
+ static const struct bus_properties_map property_map[] = {
+ { "Linger", "b", NULL, offsetof(UserStatusInfo, linger) },
+ { "State", "s", NULL, offsetof(UserStatusInfo, state) },
+ {},
+ };
+
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
for (;;) {
_cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *state = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_property = NULL;
+ _cleanup_(user_status_info_done) UserStatusInfo info = {};
const char *user, *object;
uint32_t uid;
- int linger;
r = sd_bus_message_read(reply, "(uso)", &uid, &user, &object);
if (r < 0)
if (r == 0)
break;
- r = sd_bus_get_property_trivial(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.User",
- "Linger",
- &error_property,
- 'b',
- &linger);
- if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The user logged out when we're querying the property */
- continue;
-
- return log_error_errno(r, "Failed to get linger status for user %s: %s",
- user, bus_error_message(&error_property, r));
- }
-
- r = sd_bus_get_property_string(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.User",
- "State",
- &error_property,
- &state);
+ r = bus_map_all_properties(bus,
+ "org.freedesktop.login1",
+ object,
+ property_map,
+ BUS_MAP_BOOLEAN_AS_BOOL,
+ &error_property,
+ &reply_property,
+ &info);
if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The user logged out when we're querying the property */
- continue;
-
- return log_error_errno(r, "Failed to get state for user %s: %s",
- user, bus_error_message(&error_property, r));
+ log_full_errno(sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING,
+ r,
+ "Failed to get properties of user %s, ignoring: %s",
+ user, bus_error_message(&error_property, r));
+ continue;
}
r = table_add_many(table,
TABLE_UID, (uid_t) uid,
TABLE_STRING, user,
- TABLE_BOOLEAN, linger,
- TABLE_STRING, state);
+ TABLE_BOOLEAN, info.linger,
+ TABLE_STRING, info.state);
if (r < 0)
return table_log_add_error(r);
}
return 0;
}
-typedef struct SessionStatusInfo {
- const char *id;
- uid_t uid;
- const char *name;
- struct dual_timestamp timestamp;
- unsigned vtnr;
- const char *seat;
- const char *tty;
- const char *display;
- bool remote;
- const char *remote_host;
- const char *remote_user;
- const char *service;
- pid_t leader;
- const char *type;
- const char *class;
- const char *state;
- const char *scope;
- const char *desktop;
-} SessionStatusInfo;
-
-typedef struct UserStatusInfo {
- uid_t uid;
- bool linger;
- const char *name;
- struct dual_timestamp timestamp;
- const char *state;
- char **sessions;
- const char *display;
- const char *slice;
-} UserStatusInfo;
-
-typedef struct SeatStatusInfo {
- const char *id;
- const char *active_session;
- char **sessions;
-} SeatStatusInfo;
-
-static void user_status_info_clear(UserStatusInfo *info) {
- if (info) {
- strv_free(info->sessions);
- zero(*info);
- }
-}
-
-static void seat_status_info_clear(SeatStatusInfo *info) {
- if (info) {
- strv_free(info->sessions);
- zero(*info);
- }
-}
-
static int prop_map_first_of_struct(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
const char *contents;
int r;
+ assert(bus);
+ assert(m);
+
r = sd_bus_message_peek_type(m, NULL, &contents);
if (r < 0)
return r;
static int print_session_status_info(sd_bus *bus, const char *path, bool *new_line) {
- static const struct bus_properties_map map[] = {
- { "Id", "s", NULL, offsetof(SessionStatusInfo, id) },
- { "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
- { "Display", "s", NULL, offsetof(SessionStatusInfo, display) },
- { "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) },
- { "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) },
- { "Service", "s", NULL, offsetof(SessionStatusInfo, service) },
- { "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) },
- { "Type", "s", NULL, offsetof(SessionStatusInfo, type) },
- { "Class", "s", NULL, offsetof(SessionStatusInfo, class) },
- { "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) },
- { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
- { "VTNr", "u", NULL, offsetof(SessionStatusInfo, vtnr) },
- { "Leader", "u", NULL, offsetof(SessionStatusInfo, leader) },
- { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) },
- { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) },
- { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) },
- { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) },
- { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) },
+ static const struct bus_properties_map map[] = {
+ { "Id", "s", NULL, offsetof(SessionStatusInfo, id) },
+ { "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
+ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
+ { "Display", "s", NULL, offsetof(SessionStatusInfo, display) },
+ { "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) },
+ { "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) },
+ { "Service", "s", NULL, offsetof(SessionStatusInfo, service) },
+ { "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) },
+ { "Type", "s", NULL, offsetof(SessionStatusInfo, type) },
+ { "Class", "s", NULL, offsetof(SessionStatusInfo, class) },
+ { "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) },
+ { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
+ { "VTNr", "u", NULL, offsetof(SessionStatusInfo, vtnr) },
+ { "Leader", "u", NULL, offsetof(SessionStatusInfo, leader) },
+ { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) },
+ { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) },
+ { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) },
+ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
+ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) },
+ { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) },
+ { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) },
{}
};
if (i.state)
printf("\t State: %s\n", i.state);
+ if (i.idle_hint && timestamp_is_set(i.idle_hint_timestamp))
+ printf("\t Idle: %s since %s (%s)\n",
+ yes_no(i.idle_hint),
+ FORMAT_TIMESTAMP(i.idle_hint_timestamp),
+ FORMAT_TIMESTAMP_RELATIVE(i.idle_hint_timestamp));
+ else
+ printf("\t Idle: %s\n", yes_no(i.idle_hint));
+
if (i.scope) {
printf("\t Unit: %s\n", i.scope);
show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i.scope, i.leader);
static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line) {
- static const struct bus_properties_map map[] = {
+ static const struct bus_properties_map map[] = {
{ "Name", "s", NULL, offsetof(UserStatusInfo, name) },
{ "Linger", "b", NULL, offsetof(UserStatusInfo, linger) },
{ "Slice", "s", NULL, offsetof(UserStatusInfo, slice) },
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(user_status_info_clear) UserStatusInfo i = {};
+ _cleanup_(user_status_info_done) UserStatusInfo i = {};
int r;
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, BUS_MAP_BOOLEAN_AS_BOOL, &error, &m, &i);
static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line) {
- static const struct bus_properties_map map[] = {
+ static const struct bus_properties_map map[] = {
{ "Id", "s", NULL, offsetof(SeatStatusInfo, id) },
{ "ActiveSession", "(so)", prop_map_first_of_struct, offsetof(SeatStatusInfo, active_session) },
{ "Sessions", "a(so)", prop_map_sessions_strv, offsetof(SeatStatusInfo, sessions) },
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(seat_status_info_clear) SeatStatusInfo i = {};
+ _cleanup_(seat_status_info_done) SeatStatusInfo i = {};
int r;
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, 0, &error, &m, &i);
if (r < 0)
return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "GetUser",
- &error, &reply,
- "u", (uint32_t) uid);
+ r = bus_call_method(bus, bus_login_mgr, "GetUser", &error, &reply, "u", (uint32_t) uid);
if (r < 0)
return log_error_errno(r, "Failed to get user: %s", bus_error_message(&error, r));
}
for (int i = 1; i < argc; i++) {
-
r = bus_call_method(
bus,
bus_login_mgr,
arg_kill_whom = "all";
for (int i = 1; i < argc; i++) {
-
r = bus_call_method(
bus,
bus_login_mgr,
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "clean-ipc.h"
u->user_record->io_weight == UINT64_MAX)
return 0;
- r = sd_bus_message_new_method_call(
- u->manager->bus,
- &m,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "SetUnitProperties");
+ r = bus_message_new_method_call(u->manager->bus, &m, bus_systemd_mgr, "SetUnitProperties");
if (r < 0)
return bus_log_create_error(r);
#include "sd-bus.h"
+#include "bus-locator.h"
#include "bus-util.h"
#include "fd-util.h"
#include "macro.h"
int fd;
int r;
- r = sd_bus_call_method(bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "Inhibit",
- &error,
- &reply,
- "ssss", what, who, reason, mode);
+ r = bus_call_method(bus, bus_login_mgr, "Inhibit", &error, &reply, "ssss", what, who, reason, mode);
assert_se(r >= 0);
r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_UNIX_FD, &fd);
unsigned n = 0;
int r;
- r = sd_bus_call_method(bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "ListInhibitors",
- &error,
- &reply,
- "");
+ r = bus_call_method(bus, bus_login_mgr, "ListInhibitors", &error, &reply, NULL);
assert_se(r >= 0);
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
/* Type is reset to the original value when we release control of the session */
assert_se(!streq(type, "tty"));
- assert_se(bus_call_method(bus, &session, "ReleaseControl", NULL, NULL, "") >= 0);
+ assert_se(bus_call_method(bus, &session, "ReleaseControl", NULL, NULL, NULL) >= 0);
type = mfree(type);
assert_se(bus_get_property_string(bus, &session, "Type", NULL, &type) >= 0);
assert_se(streq(type, "tty"));
#include "sd-bus.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "dev-setup.h"
#include "format-util.h"
#include "fs-util.h"
if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m");
- r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectorySize", &error, 't', size);
+ r = bus_get_property_trivial(bus, bus_login_mgr, "RuntimeDirectorySize", &error, 't', size);
if (r < 0) {
log_warning_errno(r, "Failed to acquire runtime directory size, ignoring: %s", bus_error_message(&error, r));
*size = physical_memory_scale(10U, 100U); /* 10% */
}
- r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectoryInodesMax", &error, 't', inodes);
+ r = bus_get_property_trivial(bus, bus_login_mgr, "RuntimeDirectoryInodesMax", &error, 't', inodes);
if (r < 0) {
log_warning_errno(r, "Failed to acquire number of inodes for runtime directory, ignoring: %s", bus_error_message(&error, r));
*inodes = DIV_ROUND_UP(*size, 4096);
int network_format(Network *network, char **ret) {
_cleanup_free_ char *s = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
size_t sz = 0;
int r;
assert(network);
assert(ret);
- {
- _cleanup_fclose_ FILE *f = NULL;
-
- f = open_memstream_unlocked(&s, &sz);
- if (!f)
- return -ENOMEM;
+ f = open_memstream_unlocked(&s, &sz);
+ if (!f)
+ return -ENOMEM;
- network_dump(network, f);
+ network_dump(network, f);
- /* Add terminating 0, so that the output buffer is a valid string. */
- fputc('\0', f);
+ /* Add terminating 0, so that the output buffer is a valid string. */
+ fputc('\0', f);
- r = fflush_and_check(f);
- }
+ r = fflush_and_check(f);
if (r < 0)
return r;
- assert(s);
+ f = safe_fclose(f);
+
+ if (!s)
+ return -ENOMEM;
+
*ret = TAKE_PTR(s);
assert(sz > 0);
return (int) sz - 1;
int netdev_format(NetDev *netdev, char **ret) {
_cleanup_free_ char *s = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
size_t sz = 0;
int r;
assert(netdev);
assert(ret);
- {
- _cleanup_fclose_ FILE *f = NULL;
-
- f = open_memstream_unlocked(&s, &sz);
- if (!f)
- return -ENOMEM;
+ f = open_memstream_unlocked(&s, &sz);
+ if (!f)
+ return -ENOMEM;
- netdev_dump(netdev, f);
+ netdev_dump(netdev, f);
- /* Add terminating 0, so that the output buffer is a valid string. */
- fputc('\0', f);
+ /* Add terminating 0, so that the output buffer is a valid string. */
+ fputc('\0', f);
- r = fflush_and_check(f);
- }
+ r = fflush_and_check(f);
if (r < 0)
return r;
- assert(s);
+ f = safe_fclose(f);
+
+ if (!s)
+ return -ENOMEM;
+
*ret = TAKE_PTR(s);
assert(sz > 0);
return (int) sz - 1;
int link_format(Link *link, char **ret) {
_cleanup_free_ char *s = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
size_t sz = 0;
int r;
assert(link);
assert(ret);
- {
- _cleanup_fclose_ FILE *f = NULL;
-
- f = open_memstream_unlocked(&s, &sz);
- if (!f)
- return -ENOMEM;
+ f = open_memstream_unlocked(&s, &sz);
+ if (!f)
+ return -ENOMEM;
- link_dump(link, f);
+ link_dump(link, f);
- /* Add terminating 0, so that the output buffer is a valid string. */
- fputc('\0', f);
+ /* Add terminating 0, so that the output buffer is a valid string. */
+ fputc('\0', f);
- r = fflush_and_check(f);
- }
+ r = fflush_and_check(f);
if (r < 0)
return r;
- assert(s);
+ f = safe_fclose(f);
+
+ if (!s)
+ return -ENOMEM;
+
*ret = TAKE_PTR(s);
assert(sz > 0);
return (int) sz - 1;
for (const char *p = rvalue;;) {
_cleanup_free_ struct ifla_vlan_qos_mapping *m = NULL;
_cleanup_free_ char *w = NULL;
+ unsigned from, to;
r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
if (r == -ENOMEM)
if (r == 0)
return 0;
- m = new0(struct ifla_vlan_qos_mapping, 1);
- if (!m)
- return log_oom();
-
- r = parse_range(w, &m->from, &m->to);
+ r = parse_range(w, &from, &to);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s, ignoring: %s", lvalue, w);
continue;
}
- if (m->to > m->from || m->to == 0 || m->from == 0) {
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s, ignoring: %s", lvalue, w);
- continue;
- }
+ m = new(struct ifla_vlan_qos_mapping, 1);
+ if (!m)
+ return log_oom();
+
+ *m = (struct ifla_vlan_qos_mapping) {
+ .from = from,
+ .to = to,
+ };
r = set_ensure_consume(s, &vlan_qos_maps_hash_ops, TAKE_PTR(m));
if (r < 0) {
if (r < 0)
return log_error_errno(r, "Failed to request match on Connected signal: %m");
- r = sd_bus_match_signal_async(
+ r = bus_match_signal_async(
m->bus,
NULL,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
+ bus_login_mgr,
"PrepareForSleep",
match_prepare_for_sleep, NULL, m);
if (r < 0)
if (r < 0)
return r;
if (r == 0 || !ifname_valid(b)) {
- free(b);
- b = strdup(a);
- if (!b)
- return -ENOMEM;
+ r = free_and_strdup(&b, a);
+ if (r < 0)
+ return r;
}
if (p)
#include "btrfs-util.h"
#include "build.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "bus-util.h"
#include "cap-list.h"
#include "capability-util.h"
if (r == 0)
return 0;
- r = sd_bus_get_property_string(bus,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "DNSStubListener",
- &error,
- &dns_stub_listener_mode);
+ r = bus_get_property_string(bus, bus_resolve_mgr, "DNSStubListener", &error, &dns_stub_listener_mode);
if (r < 0)
return log_debug_errno(r, "Failed to query DNSStubListener property: %s", bus_error_message(&error, r));
#include "build.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "copy.h"
#include "main-func.h"
#include "pretty-print.h"
pager_open(arg_pager_flags);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.oom1",
- "/org/freedesktop/oom1",
- "org.freedesktop.oom1.Manager",
- "DumpByFileDescriptor",
- &error,
- &reply,
- NULL);
+ r = bus_call_method(bus, bus_oom_mgr, "DumpByFileDescriptor", &error, &reply, NULL);
if (r < 0)
return log_error_errno(r, "Failed to dump context: %s", bus_error_message(&error, r));
f = safe_fclose(f);
+ if (!dump)
+ return -ENOMEM;
+
*ret = TAKE_PTR(dump);
return 0;
}
if (r < 0)
return r;
+ f = safe_fclose(f);
+
+ if (!dump)
+ return -ENOMEM;
+
return log_dump(LOG_INFO, dump);
}
#include "bus-common-errors.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "chase.h"
#include "conf-files.h"
#include "copy.h"
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
const char *at, *prefix, *joined;
- r = sd_bus_message_new_method_call(
- bus,
- &m,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "ListUnitsByPatterns");
+ r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "ListUnitsByPatterns");
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_bus_message_new_method_call(
- *bus,
- &m,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "Reload");
+ r = bus_message_new_method_call(*bus, &m, bus_systemd_mgr, "Reload");
if (r < 0)
return bus_log_create_error(r);
if (!names)
return log_oom();
- r = sd_bus_message_new_method_call(
+ r = bus_message_new_method_call(
bus,
&m,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
+ bus_systemd_mgr,
enable ? "EnableUnitFilesWithFlags" : "DisableUnitFilesWithFlags");
if (r < 0)
return bus_log_create_error(r);
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-get-properties.h"
+#include "bus-locator.h"
#include "bus-log-control-api.h"
#include "bus-message-util.h"
#include "bus-polkit.h"
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
- r = sd_bus_match_signal_async(
+ r = bus_match_signal_async(
m->bus,
NULL,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
+ bus_login_mgr,
"PrepareForSleep",
match_prepare_for_sleep,
NULL,
}
r = fflush_and_check(f);
- f = safe_fclose(f); /* sig_data may be reallocated when f is closed. */
if (r < 0)
return r;
+ f = safe_fclose(f); /* sig_data may be reallocated when f is closed. */
+
+ if (!sig_data)
+ return -ENOMEM;
+
*ret_sig_data = TAKE_PTR(sig_data);
*ret_sig_size = sig_size;
return 0;
return 0;
r = dns_packet_append_rr(&packet, rr, 0, &start, &rds);
- if (r < 0)
+ if (r < 0) {
+ dns_packet_unref(&packet);
return r;
+ }
assert(start == 0);
assert(packet._data);
free(rr->wire_format);
- rr->wire_format = packet._data;
+ rr->wire_format = TAKE_PTR(packet._data);
rr->wire_format_size = packet.size;
rr->wire_format_rdata_offset = rds;
rr->wire_format_canonical = canonical;
- packet._data = NULL;
dns_packet_unref(&packet);
return 0;
if (fflush_and_check(f) < 0)
return log_oom();
+ f = safe_fclose(f);
+
+ if (!buffer)
+ return -ENOMEM;
+
log_dump(LOG_INFO, buffer);
return 0;
}
#include "af-list.h"
#include "alloc-util.h"
#include "bus-common-errors.h"
+#include "bus-locator.h"
#include "dns-type.h"
#include "random-util.h"
#include "resolved-def.h"
name = m;
}
- assert_se(sd_bus_message_new_method_call(
- bus,
- &req,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "ResolveRecord") >= 0);
+ assert_se(bus_message_new_method_call(bus, &req, bus_resolve_mgr, "ResolveRecord") >= 0);
assert_se(sd_bus_message_append(req, "isqqt", 0, name, DNS_CLASS_IN, type, UINT64_C(0)) >= 0);
name = m;
}
- assert_se(sd_bus_message_new_method_call(
- bus,
- &req,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "ResolveHostname") >= 0);
+ assert_se(bus_message_new_method_call(bus, &req, bus_resolve_mgr, "ResolveHostname") >= 0);
assert_se(sd_bus_message_append(req, "isit", 0, name, family, UINT64_C(0)) >= 0);
.interface = "org.freedesktop.network1.Manager"
};
+const BusLocator* const bus_oom_mgr = &(BusLocator){
+ .destination = "org.freedesktop.oom1",
+ .path = "/org/freedesktop/oom1",
+ .interface = "org.freedesktop.oom1.Manager"
+};
+
const BusLocator* const bus_portable_mgr = &(BusLocator){
.destination = "org.freedesktop.portable1",
.path = "/org/freedesktop/portable1",
.interface = "org.freedesktop.timedate1"
};
+const BusLocator* const bus_timesync_mgr = &(BusLocator){
+ .destination = "org.freedesktop.timesync1",
+ .path = "/org/freedesktop/timesync1",
+ .interface = "org.freedesktop.timesync1.Manager"
+};
+
const BusLocator* const bus_hostname = &(BusLocator){
.destination = "org.freedesktop.hostname1",
.path = "/org/freedesktop/hostname1",
} BusLocator;
extern const BusLocator* const bus_home_mgr;
+extern const BusLocator* const bus_hostname;
extern const BusLocator* const bus_import_mgr;
extern const BusLocator* const bus_locale;
extern const BusLocator* const bus_login_mgr;
extern const BusLocator* const bus_machine_mgr;
extern const BusLocator* const bus_network_mgr;
+extern const BusLocator* const bus_oom_mgr;
extern const BusLocator* const bus_portable_mgr;
extern const BusLocator* const bus_resolve_mgr;
extern const BusLocator* const bus_systemd_mgr;
extern const BusLocator* const bus_timedate;
-extern const BusLocator* const bus_hostname;
+extern const BusLocator* const bus_timesync_mgr;
/* Shorthand flavors of the sd-bus convenience helpers with destination,path,interface strings encapsulated
* within a single struct. */
dump_file = safe_fclose(dump_file);
+ if (!dump)
+ return -ENOMEM;
+
fd = acquire_data_fd(dump, dump_size, 0);
if (fd < 0)
return fd;
#include "alloc-util.h"
#include "calendarspec.h"
#include "errno-util.h"
+#include "fd-util.h"
#include "fileio.h"
#include "macro.h"
#include "parse-util.h"
static CalendarComponent* chain_free(CalendarComponent *c) {
while (c) {
CalendarComponent *n = c->next;
- free(c);
- c = n;
+ free_and_replace(c, n);
}
return NULL;
}
}
int calendar_spec_to_string(const CalendarSpec *c, char **p) {
- char *buf = NULL;
+ _cleanup_free_ char *buf = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
size_t sz = 0;
- FILE *f;
int r;
assert(c);
}
r = fflush_and_check(f);
- fclose(f);
-
- if (r < 0) {
- free(buf);
+ if (r < 0)
return r;
- }
- *p = buf;
+ f = safe_fclose(f);
+
+ if (!buf)
+ return -ENOMEM;
+
+ *p = TAKE_PTR(buf);
return 0;
}
return log_warning_errno(r, "Could not parse core file, flushing file buffer failed: %m");
c.f = safe_fclose(c.f);
+
+ if (!buf)
+ return log_oom();
+
*ret = TAKE_PTR(buf);
}
+
if (ret_package_metadata)
*ret_package_metadata = TAKE_PTR(package_metadata);
return log_warning_errno(r, "Could not parse ELF file, flushing file buffer failed: %m");
c.f = safe_fclose(c.f);
+
+ if (!buf)
+ return log_oom();
+
*ret = TAKE_PTR(buf);
}
+
if (ret_package_metadata)
*ret_package_metadata = TAKE_PTR(elf_metadata);
f = safe_fclose(f);
+ if (!buf)
+ return -ENOMEM;
+
*ret = TAKE_PTR(buf);
return 0;
int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
_cleanup_free_ char *s = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
size_t sz = 0;
int r;
if (flags & JSON_FORMAT_OFF)
return -ENOEXEC;
- {
- _cleanup_fclose_ FILE *f = NULL;
-
- f = open_memstream_unlocked(&s, &sz);
- if (!f)
- return -ENOMEM;
+ f = open_memstream_unlocked(&s, &sz);
+ if (!f)
+ return -ENOMEM;
- r = json_variant_dump(v, flags, f, NULL);
- if (r < 0)
- return r;
+ r = json_variant_dump(v, flags, f, NULL);
+ if (r < 0)
+ return r;
- /* Add terminating 0, so that the output buffer is a valid string. */
- fputc('\0', f);
+ /* Add terminating 0, so that the output buffer is a valid string. */
+ fputc('\0', f);
- r = fflush_and_check(f);
- }
+ r = fflush_and_check(f);
if (r < 0)
return r;
- assert(s);
+ f = safe_fclose(f);
+
+ if (!s)
+ return -ENOMEM;
+
*ret = TAKE_PTR(s);
assert(sz > 0);
return (int) sz - 1;
* installation. */
static int parse_os_release_specifier(const char *root, const char *id, char **ret) {
- char *v = NULL;
+ _cleanup_free_ char *v = NULL;
int r;
assert(ret);
if (r >= 0)
/* parse_os_release() calls parse_env_file() which only sets the return value for
* entries found. Let's make sure we set the return value in all cases. */
- *ret = v;
+ *ret = TAKE_PTR(v);
/* Translate error for missing os-release file to EUNATCH. */
return r == -ENOENT ? -EUNATCH : r;
if (r < 0)
return log_warning_errno(r, "Failed to connect to system bus, ignoring: %m");
- r = sd_bus_message_new_method_call(
- bus,
- &m,
- "org.freedesktop.home1",
- "/org/freedesktop/home1",
- "org.freedesktop.home1.Manager",
- "LockAllHomes");
+ r = bus_message_new_method_call(bus, &m, bus_home_mgr, "LockAllHomes");
if (r < 0)
return bus_log_create_error(r);
static const char *arg_dest = NULL;
static int generate_symlink(void) {
- _cleanup_free_ char *j = NULL;
-
FOREACH_STRING(p, "/system-update", "/etc/system-update") {
- if (laccess(p, F_OK) >= 0)
- goto link_found;
+ if (laccess(p, F_OK) >= 0) {
+ _cleanup_free_ char *j = NULL;
+
+ j = path_join(arg_dest, SPECIAL_DEFAULT_TARGET);
+ if (!j)
+ return log_oom();
+
+ if (symlink(SYSTEM_DATA_UNIT_DIR "/system-update.target", j) < 0)
+ return log_error_errno(errno, "Failed to create symlink %s: %m", j);
+
+ return 1;
+ }
if (errno != ENOENT)
log_warning_errno(errno, "Failed to check if %s symlink exists, ignoring: %m", p);
}
return 0;
-
-link_found:
- j = path_join(arg_dest, SPECIAL_DEFAULT_TARGET);
- if (!j)
- return log_oom();
-
- if (symlink(SYSTEM_DATA_UNIT_DIR "/system-update.target", j) < 0)
- return log_error_errno(errno, "Failed to create symlink %s: %m", j);
-
- return 1;
}
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
+#include <linux/usb/ch11.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include "alloc-util.h"
+#include "device-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "parse-util.h"
path_prepend(path, "st%c", name[2]);
}
+static int get_usb_revision(sd_device *dev) {
+ uint8_t protocol;
+ const char *s;
+ int r;
+
+ assert(dev);
+
+ /* Returns usb revision 1, 2, or 3. */
+
+ r = sd_device_get_sysattr_value(dev, "bDeviceProtocol", &s);
+ if (r < 0)
+ return r;
+
+ r = safe_atou8_full(s, 16, &protocol);
+ if (r < 0)
+ return r;
+
+ switch (protocol) {
+ case USB_HUB_PR_HS_NO_TT: /* Full speed hub (USB1) or Hi-speed hub without TT (USB2) */
+
+ /* See speed_show() in drivers/usb/core/sysfs.c of the kernel. */
+ r = sd_device_get_sysattr_value(dev, "speed", &s);
+ if (r < 0)
+ return r;
+
+ if (streq(s, "480"))
+ return 2;
+
+ return 1;
+
+ case USB_HUB_PR_HS_SINGLE_TT: /* Hi-speed hub with single TT */
+ case USB_HUB_PR_HS_MULTI_TT: /* Hi-speed hub with multiple TT */
+ return 2;
+
+ case USB_HUB_PR_SS: /* Super speed hub */
+ return 3;
+
+ default:
+ return -EPROTONOSUPPORT;
+ }
+}
+
static sd_device *handle_usb(sd_device *parent, char **path) {
const char *devtype, *str, *port;
+ int r;
if (sd_device_get_devtype(parent, &devtype) < 0)
return parent;
return parent;
port++;
- /* USB host number may change across reboots (and probably even without reboot). The part after
- * USB host number is determined by device topology and so does not change. Hence, drop the
- * host number and always use '0' instead. */
+ parent = skip_subsystem(parent, "usb");
+ if (!parent)
+ return NULL;
- path_prepend(path, "usb-0:%s", port);
- return skip_subsystem(parent, "usb");
+ /* USB host number may change across reboots (and probably even without reboot). The part after USB
+ * host number is determined by device topology and so does not change. Hence, drop the host number
+ * and always use '0' instead.
+ *
+ * xHCI host controllers may register two (or more?) USB root hubs for USB 2.0 and USB 3.0, and the
+ * sysname, whose host number replaced with 0, of a device under the hubs may conflict with others.
+ * To avoid the conflict, let's include the USB revision of the root hub to the PATH_ID.
+ * See issue https://github.com/systemd/systemd/issues/19406 for more details. */
+ r = get_usb_revision(parent);
+ if (r < 0) {
+ log_device_debug_errno(parent, r, "Failed to get the USB revision number, ignoring: %m");
+ path_prepend(path, "usb-0:%s", port);
+ } else {
+ assert(r > 0);
+ path_prepend(path, "usbv%i-0:%s", r, port);
+ }
+
+ return parent;
}
static sd_device *handle_bcma(sd_device *parent, char **path) {
return 0;
}
+static void add_id_with_usb_revision(sd_device *dev, bool test, char *path) {
+ char *p;
+ int r;
+
+ assert(dev);
+ assert(path);
+
+ /* When the path contains the USB revision, let's adds ID_PATH_WITH_USB_REVISION property and
+ * drop the version specifier for later use. */
+
+ p = strstrafter(path, "-usbv");
+ if (!p)
+ return;
+ if (!ascii_isdigit(p[0]))
+ return;
+ if (p[1] != '-')
+ return;
+
+ r = udev_builtin_add_property(dev, test, "ID_PATH_WITH_USB_REVISION", path);
+ if (r < 0)
+ log_device_debug_errno(dev, r, "Failed to add ID_PATH_WITH_USB_REVISION property, ignoring: %m");
+
+ /* Drop the USB revision specifier for backward compatibility. */
+ memmove(p - 1, p + 1, strlen(p + 1) + 1);
+}
+
+static void add_id_tag(sd_device *dev, bool test, const char *path) {
+ char tag[UDEV_NAME_SIZE];
+ size_t i = 0;
+ int r;
+
+ /* compose valid udev tag name */
+ for (const char *p = path; *p; p++) {
+ if (ascii_isdigit(*p) ||
+ ascii_isalpha(*p) ||
+ *p == '-') {
+ tag[i++] = *p;
+ continue;
+ }
+
+ /* skip all leading '_' */
+ if (i == 0)
+ continue;
+
+ /* avoid second '_' */
+ if (tag[i-1] == '_')
+ continue;
+
+ tag[i++] = '_';
+ }
+ /* strip trailing '_' */
+ while (i > 0 && tag[i-1] == '_')
+ i--;
+ tag[i] = '\0';
+
+ r = udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag);
+ if (r < 0)
+ log_device_debug_errno(dev, r, "Failed to add ID_PATH_TAG property, ignoring: %m");
+}
+
static int builtin_path_id(UdevEvent *event, int argc, char *argv[], bool test) {
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
_cleanup_(sd_device_unrefp) sd_device *dev_other_branch = NULL;
!supported_transport)
return -ENOENT;
- {
- char tag[UDEV_NAME_SIZE];
- size_t i = 0;
-
- /* compose valid udev tag name */
- for (const char *p = path; *p; p++) {
- if (ascii_isdigit(*p) ||
- ascii_isalpha(*p) ||
- *p == '-') {
- tag[i++] = *p;
- continue;
- }
-
- /* skip all leading '_' */
- if (i == 0)
- continue;
-
- /* avoid second '_' */
- if (tag[i-1] == '_')
- continue;
+ add_id_with_usb_revision(dev, test, path);
- tag[i++] = '_';
- }
- /* strip trailing '_' */
- while (i > 0 && tag[i-1] == '_')
- i--;
- tag[i] = '\0';
+ r = udev_builtin_add_property(dev, test, "ID_PATH", path);
+ if (r < 0)
+ log_device_debug_errno(dev, r, "Failed to add ID_PATH property, ignoring: %m");
- udev_builtin_add_property(dev, test, "ID_PATH", path);
- udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag);
- }
+ add_id_tag(dev, test, path);
/*
* Compatible link generation for ATA devices
if sign_kernel:
linux_signed = tempfile.NamedTemporaryFile(prefix='linux-signed')
- linux = linux_signed.name
+ linux = pathlib.Path(linux_signed.name)
sign(sign_tool, opts.linux, linux, opts=opts)
else:
linux = opts.linux
#include "alloc-util.h"
#include "bus-error.h"
+#include "bus-locator.h"
#include "bus-util.h"
#include "format-util.h"
#include "log.h"
#include "macro.h"
#include "main-func.h"
#include "process-util.h"
+#include "random-util.h"
#include "special.h"
#include "stdio-util.h"
#include "strv.h"
#include "unit-name.h"
#include "utmp-wtmp.h"
+#include "verbs.h"
typedef struct Context {
sd_bus *bus;
#endif
}
-static usec_t get_startup_monotonic_time(Context *c) {
+static int get_startup_monotonic_time(Context *c, usec_t *ret) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- usec_t t = 0;
int r;
assert(c);
+ assert(ret);
- r = sd_bus_get_property_trivial(
+ r = bus_get_property_trivial(
c->bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
+ bus_systemd_mgr,
"UserspaceTimestampMonotonic",
&error,
- 't', &t);
- if (r < 0) {
- log_error_errno(r, "Failed to get timestamp: %s", bus_error_message(&error, r));
- return 0;
- }
+ 't', ret);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to get timestamp, ignoring: %s", bus_error_message(&error, r));
- return t;
+ return 0;
}
static int get_current_runlevel(Context *c) {
const int runlevel;
const char *special;
} table[] = {
- /* The first target of this list that is active or has
- * a job scheduled wins. We prefer runlevels 5 and 3
- * here over the others, since these are the main
- * runlevels used on Fedora. It might make sense to
- * change the order on some distributions. */
+ /* The first target of this list that is active or has a job scheduled wins. We prefer
+ * runlevels 5 and 3 here over the others, since these are the main runlevels used on Fedora.
+ * It might make sense to change the order on some distributions. */
{ '5', SPECIAL_GRAPHICAL_TARGET },
{ '3', SPECIAL_MULTI_USER_TARGET },
{ '1', SPECIAL_RESCUE_TARGET },
};
-
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(c);
- for (size_t i = 0; i < ELEMENTSOF(table); i++) {
- _cleanup_free_ char *state = NULL, *path = NULL;
-
- path = unit_dbus_path_from_name(table[i].special);
- if (!path)
- return log_oom();
-
- r = sd_bus_get_property_string(
- c->bus,
- "org.freedesktop.systemd1",
- path,
- "org.freedesktop.systemd1.Unit",
- "ActiveState",
- &error,
- &state);
- if (r < 0)
- return log_warning_errno(r, "Failed to get state: %s", bus_error_message(&error, r));
+ for (unsigned n_attempts = 0;;) {
+ FOREACH_ARRAY(e, table, ELEMENTSOF(table)) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *state = NULL, *path = NULL;
+
+ path = unit_dbus_path_from_name(e->special);
+ if (!path)
+ return log_oom();
+
+ r = sd_bus_get_property_string(
+ c->bus,
+ "org.freedesktop.systemd1",
+ path,
+ "org.freedesktop.systemd1.Unit",
+ "ActiveState",
+ &error,
+ &state);
+ if ((r == -ENOTCONN ||
+ sd_bus_error_has_names(&error,
+ SD_BUS_ERROR_NO_REPLY,
+ SD_BUS_ERROR_DISCONNECTED)) &&
+ ++n_attempts < 64) {
+
+ /* systemd might have dropped off momentarily, let's not make this an error,
+ * and wait some random time. Let's pick a random time in the range 0ms…250ms,
+ * linearly scaled by the number of failed attempts. */
+
+ usec_t usec = random_u64_range(UINT64_C(10) * USEC_PER_MSEC +
+ UINT64_C(240) * USEC_PER_MSEC * n_attempts/64);
+ log_debug_errno(r, "Failed to get state of %s, retrying after %s: %s",
+ e->special, FORMAT_TIMESPAN(usec, USEC_PER_MSEC), bus_error_message(&error, r));
+ (void) usleep(usec);
+ goto reconnect;
+ }
+ if (r < 0)
+ return log_warning_errno(r, "Failed to get state of %s: %s", e->special, bus_error_message(&error, r));
+
+ if (STR_IN_SET(state, "active", "reloading"))
+ return e->runlevel;
+ }
- if (STR_IN_SET(state, "active", "reloading"))
- return table[i].runlevel;
- }
+ return 0;
- return 0;
+reconnect:
+ c->bus = sd_bus_flush_close_unref(c->bus);
+ r = bus_connect_system_systemd(&c->bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to reconnect to system bus: %m");
+ }
}
-static int on_reboot(Context *c) {
- int r = 0, q;
- usec_t t;
- usec_t boottime;
+static int on_reboot(int argc, char *argv[], void *userdata) {
+ Context *c = ASSERT_PTR(userdata);
+ usec_t t = 0, boottime;
+ int r, q = 0;
- assert(c);
-
- /* We finished start-up, so let's write the utmp
- * record and send the audit msg */
+ /* We finished start-up, so let's write the utmp record and send the audit msg. */
#if HAVE_AUDIT
if (c->audit_fd >= 0)
if (audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_BOOT, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
errno != EPERM)
- r = log_error_errno(errno, "Failed to send audit message: %m");
+ q = log_error_errno(errno, "Failed to send audit message: %m");
#endif
- /* If this call fails it will return 0, which
- * utmp_put_reboot() will then fix to the current time */
- t = get_startup_monotonic_time(c);
+ /* If this call fails, then utmp_put_reboot() will fix to the current time. */
+ (void) get_startup_monotonic_time(c, &t);
boottime = map_clock_usec(t, CLOCK_MONOTONIC, CLOCK_REALTIME);
- /* We query the recorded monotonic time here (instead of the system clock CLOCK_REALTIME),
- * even though we actually want the system clock time. That's because there's a likely
- * chance that the system clock wasn't set right during early boot. By manually converting
- * the monotonic clock to the system clock here we can compensate
- * for incorrectly set clocks during early boot. */
+ /* We query the recorded monotonic time here (instead of the system clock CLOCK_REALTIME), even
+ * though we actually want the system clock time. That's because there's a likely chance that the
+ * system clock wasn't set right during early boot. By manually converting the monotonic clock to the
+ * system clock here we can compensate for incorrectly set clocks during early boot. */
- q = utmp_put_reboot(boottime);
- if (q < 0)
- r = log_error_errno(q, "Failed to write utmp record: %m");
+ r = utmp_put_reboot(boottime);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write utmp record: %m");
- return r;
+ return q;
}
-static int on_shutdown(Context *c) {
- int r = 0, q;
-
- assert(c);
+static int on_shutdown(int argc, char *argv[], void *userdata) {
+ int r, q = 0;
- /* We started shut-down, so let's write the utmp
- * record and send the audit msg */
+ /* We started shut-down, so let's write the utmp record and send the audit msg. */
#if HAVE_AUDIT
+ Context *c = ASSERT_PTR(userdata);
+
if (c->audit_fd >= 0)
if (audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_SHUTDOWN, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
errno != EPERM)
- r = log_error_errno(errno, "Failed to send audit message: %m");
+ q = log_error_errno(errno, "Failed to send audit message: %m");
#endif
- q = utmp_put_shutdown();
- if (q < 0)
- r = log_error_errno(q, "Failed to write utmp record: %m");
+ r = utmp_put_shutdown();
+ if (r < 0)
+ return log_error_errno(r, "Failed to write utmp record: %m");
- return r;
+ return q;
}
-static int on_runlevel(Context *c) {
- int r = 0, q, previous, runlevel;
+static int on_runlevel(int argc, char *argv[], void *userdata) {
+ Context *c = ASSERT_PTR(userdata);
+ int r, q = 0, previous, runlevel;
- assert(c);
-
- /* We finished changing runlevel, so let's write the
- * utmp record and send the audit msg */
+ /* We finished changing runlevel, so let's write the utmp record and send the audit msg. */
/* First, get last runlevel */
- q = utmp_get_runlevel(&previous, NULL);
-
- if (q < 0) {
- if (!IN_SET(q, -ESRCH, -ENOENT))
- return log_error_errno(q, "Failed to get current runlevel: %m");
+ r = utmp_get_runlevel(&previous, NULL);
+ if (r < 0) {
+ if (!IN_SET(r, -ESRCH, -ENOENT))
+ return log_error_errno(r, "Failed to get the last runlevel from utmp: %m");
previous = 0;
}
if (runlevel < 0)
return runlevel;
if (runlevel == 0) {
- log_warning("Failed to get new runlevel, utmp update skipped.");
+ log_warning("Failed to get the current runlevel, utmp update skipped.");
return 0;
}
if (audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_RUNLEVEL, s,
"systemd-update-utmp", NULL, NULL, NULL, 1) < 0 && errno != EPERM)
- r = log_error_errno(errno, "Failed to send audit message: %m");
+ q = log_error_errno(errno, "Failed to send audit message: %m");
}
#endif
- q = utmp_put_runlevel(runlevel, previous);
- if (q < 0 && !IN_SET(q, -ESRCH, -ENOENT))
- return log_error_errno(q, "Failed to write utmp record: %m");
+ r = utmp_put_runlevel(runlevel, previous);
+ if (r < 0 && !IN_SET(r, -ESRCH, -ENOENT))
+ return log_error_errno(r, "Failed to write utmp record: %m");
- return r;
+ return q;
}
static int run(int argc, char *argv[]) {
+ static const Verb verbs[] = {
+ { "reboot", 1, 1, 0, on_reboot },
+ { "shutdown", 1, 1, 0, on_shutdown },
+ { "runlevel", 1, 1, 0, on_runlevel },
+ {}
+ };
+
_cleanup_(context_clear) Context c = {
#if HAVE_AUDIT
.audit_fd = -EBADF,
};
int r;
- if (argc != 2)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "This program requires one argument.");
-
log_setup();
umask(0022);
/* If the kernel lacks netlink or audit support, don't worry about it. */
c.audit_fd = audit_open();
if (c.audit_fd < 0)
- log_full_errno(IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT) ? LOG_DEBUG : LOG_ERR,
- errno, "Failed to connect to audit log: %m");
+ log_full_errno(IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT) ? LOG_DEBUG : LOG_WARNING,
+ errno, "Failed to connect to audit log, ignoring: %m");
#endif
r = bus_connect_system_systemd(&c.bus);
if (r < 0)
return log_error_errno(r, "Failed to get D-Bus connection: %m");
- if (streq(argv[1], "reboot"))
- return on_reboot(&c);
- if (streq(argv[1], "shutdown"))
- return on_shutdown(&c);
- if (streq(argv[1], "runlevel"))
- return on_runlevel(&c);
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown command %s", argv[1]);
+ return dispatch_verb(argc, argv, verbs, &c);
}
DEFINE_MAIN_FUNCTION(run);
[VLAN]
Id=99
-GVRP=true
-MVRP=true
-LooseBinding=true
-ReorderHeader=true
+GVRP=yes
+MVRP=yes
+LooseBinding=yes
+ReorderHeader=yes
+EgressQOSMaps=0-1 1-3 10-3 6-6 7-7
+IngressQOSMaps=15-13 20-100
output = check_output('ip -d link show vlan99')
print(output)
- self.assertRegex(output, ' mtu 2000 ')
- self.assertRegex(output, 'REORDER_HDR')
- self.assertRegex(output, 'LOOSE_BINDING')
- self.assertRegex(output, 'GVRP')
- self.assertRegex(output, 'MVRP')
- self.assertRegex(output, ' id 99 ')
+ self.assertIn(' mtu 2000 ', output)
+ self.assertIn('REORDER_HDR', output)
+ self.assertIn('LOOSE_BINDING', output)
+ self.assertIn('GVRP', output)
+ self.assertIn('MVRP', output)
+ self.assertIn(' id 99 ', output)
+ self.assertIn('ingress-qos-map { 4:100 7:13 }', output)
+ self.assertIn('egress-qos-map { 0:1 1:3 6:6 7:7 10:3 }', output)
output = check_output('ip -4 address show dev test1')
print(output)
# SPDX-License-Identifier: LGPL-2.1-or-later
[Unit]
Description=TEST-01-BASIC
-# Order the test unit after systemd-update-utmp-runlevel.service, since
-# the service doesn't play well with daemon-reexec
-# See: https://github.com/systemd/systemd/issues/27167
-After=multi-user.target systemd-update-utmp-runlevel.service
+After=multi-user.target
Wants=systemd-resolved.service systemd-networkd.service
[Service]
# of systemd-analyze blame. See issue #27187.
systemd-analyze blame
+# Test for 'systemd-update-utmp runlevel' vs 'systemctl daemon-reexec'.
+# See issue #27163.
+# shellcheck disable=SC2034
+for _ in {0..10}; do
+ systemctl daemon-reexec &
+ pid_reexec=$!
+ # shellcheck disable=SC2034
+ for _ in {0..10}; do
+ SYSTEMD_LOG_LEVEL=debug /usr/lib/systemd/systemd-update-utmp runlevel
+ done
+ wait "$pid_reexec"
+done
+
echo OK >/testok
/usr/lib/systemd/tests/unit-tests/manual/test-session-properties "/org/freedesktop/login1/session/_3${s?}" /dev/tty2
}
-testcase_list_users_sessions() {
+testcase_list_users_sessions_seats() {
+ local session seat
+
if [[ ! -c /dev/tty2 ]]; then
echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
return
# Activate the session
loginctl activate "$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }')"
+ session=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $1 }')
+ : check that we got a valid session id
+ busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session Id
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $2 }')" "$(id -ru logind-test-user)"
+ seat=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $4 }')
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $5 }')" tty2
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $6 }')" active
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $7 }')" no
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $8 }')" ''
+
+ loginctl list-seats --no-legend | grep -Fwq "${seat?}"
+
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $1 }')" "$(id -ru logind-test-user)"
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" no
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $4 }')" active
- assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $6 }')" active
loginctl enable-linger logind-test-user
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" yes