From 65057f8149e3318384c1de3614f5e81d847dc2a7 Mon Sep 17 00:00:00 2001 From: Tollef Fog Heen Date: Tue, 5 Jun 2012 20:59:36 +0200 Subject: [PATCH 01/29] Bring tmpfiles.d/tmp.conf in line with Debian defaults Closes: #675422 --- tmpfiles.d/tmp.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf index fe5225d751c..39cb5cccaa6 100644 --- a/tmpfiles.d/tmp.conf +++ b/tmpfiles.d/tmp.conf @@ -8,5 +8,5 @@ # See tmpfiles.d(5) for details # Clear tmp directories separately, to make them easier to override -q /tmp 1777 root root 10d -q /var/tmp 1777 root root 30d +D /tmp 1777 root root - +#q /var/tmp 1777 root root 30d From 3333915c2609c9e74ecd21d7af078a1a1bbbc47a Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 5 Sep 2014 01:15:16 +0200 Subject: [PATCH 02/29] Make /run/lock tmpfs an API fs The /run/lock directory is world-writable in Debian due to historic reasons. To avoid user processes filling up /run, we mount a separate tmpfs for /run/lock. As this directory needs to be available during early boot, we make it an API fs. Drop it from tmpfiles.d/legacy.conf to not clobber the permissions. Closes: #751392 --- src/shared/mount-setup.c | 2 ++ tmpfiles.d/legacy.conf.in | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c index 1226ca121e1..2d599550378 100644 --- a/src/shared/mount-setup.c +++ b/src/shared/mount-setup.c @@ -101,6 +101,8 @@ static const MountPoint mount_table[] = { #endif { "tmpfs", "/run", "tmpfs", "mode=0755" TMPFS_LIMITS_RUN, MS_NOSUID|MS_NODEV|MS_STRICTATIME, NULL, MNT_FATAL|MNT_IN_CONTAINER }, + { "tmpfs", "/run/lock", "tmpfs", "mode=1777,size=5242880", MS_NOSUID|MS_NOEXEC|MS_NODEV, + NULL, MNT_FATAL|MNT_IN_CONTAINER }, { "cgroup2", "/sys/fs/cgroup", "cgroup2", "nsdelegate,memory_recursiveprot", MS_NOSUID|MS_NOEXEC|MS_NODEV, check_recursiveprot_supported, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE }, { "cgroup2", "/sys/fs/cgroup", "cgroup2", "nsdelegate", MS_NOSUID|MS_NOEXEC|MS_NODEV, diff --git a/tmpfiles.d/legacy.conf.in b/tmpfiles.d/legacy.conf.in index 4f2c0d7c431..fb1d6bf6e96 100644 --- a/tmpfiles.d/legacy.conf.in +++ b/tmpfiles.d/legacy.conf.in @@ -10,7 +10,6 @@ # These files are considered legacy and are unnecessary on legacy-free # systems. -d /run/lock 0755 root root - L /var/lock - - - - ../run/lock {% if CREATE_LOG_DIRS %} L /var/log/README - - - - ../..{{DOC_DIR}}/README.logs From 0ceed7741e78d66fd99ed7215dda3df1f63a1e2d Mon Sep 17 00:00:00 2001 From: Didier Roche Date: Fri, 22 May 2015 13:04:38 +0200 Subject: [PATCH 03/29] fsckd daemon for inter-fsckd communication Global logic: Add systemd-fsckd multiplexer which accepts multiple (via systemd-fsck's /run/systemd/fsck.progress socket) fsck instances to connect to it and sends progress report. systemd-fsckd then computes and writes to /dev/console the number of devices currently being checked and the minimum fsck progress. Plymouth and user interaction: Forward the progress to plymouth and support canellation of in progress fsck. Try to connect and send to plymouth (if running) some checked report progress, using direct plymouth protocole. Update message is the following: fsckd::: * num_devices corresponds to the current number of devices being checked (int) * progress corresponds to the current minimum percentage of all devices being checked (float, from 0 to 100) * string is a translated message ready to be displayed by the plymouth theme displaying the information above. It can be overridden by plymouth themes supporting i18n. Grab in fsckd plymouth watch key Control+C, and propagate this cancel request to systemd-fsck which will terminate fsck. Send a message to signal to user what key we are grabbing for fsck cancel. Message is: fsckd-cancel-msg: Where string is a translated string ready to be displayed by the plymouth theme indicating that Control+C can be used to cancel current checks. It can be overridden (matching only fsckd-cancel-msg prefix) for themes supporting i18n. Misc: systemd-fsckd stops on idle when no fsck is connected. Add man page explaining the plymouth theme protocol, usage of the daemon as well as the socket activation part. Adapt existing fsck man page. Note that fsckd had lived in the upstream tree for a while, but was removed. More information at http://lists.freedesktop.org/archives/systemd-devel/2015-April/030175.html - --- man/rules/meson.build | 1 + man/systemd-fsckd.service.xml | 162 +++++++ meson.build | 1 + po/POTFILES.in | 1 + src/fsckd/fsckd.c | 705 +++++++++++++++++++++++++++++ src/fsckd/meson.build | 8 + units/meson.build | 2 + units/systemd-fsck-root.service.in | 2 + units/systemd-fsck@.service.in | 3 +- units/systemd-fsckd.service.in | 17 + units/systemd-fsckd.socket | 15 + 11 files changed, 916 insertions(+), 1 deletion(-) create mode 100644 man/systemd-fsckd.service.xml create mode 100644 src/fsckd/fsckd.c create mode 100644 src/fsckd/meson.build create mode 100644 units/systemd-fsckd.service.in create mode 100644 units/systemd-fsckd.socket diff --git a/man/rules/meson.build b/man/rules/meson.build index 5dc3e08896d..5feb43d1d29 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -933,6 +933,7 @@ manpages = [ '8', ['systemd-fsck', 'systemd-fsck-root.service', 'systemd-fsck-usr.service'], ''], + ['systemd-fsckd.service', '8', ['systemd-fsckd.socket', 'systemd-fsckd'], ''], ['systemd-fstab-generator', '8', [], ''], ['systemd-getty-generator', '8', [], ''], ['systemd-gpt-auto-generator', '8', [], 'HAVE_BLKID'], diff --git a/man/systemd-fsckd.service.xml b/man/systemd-fsckd.service.xml new file mode 100644 index 00000000000..b7ad58d272f --- /dev/null +++ b/man/systemd-fsckd.service.xml @@ -0,0 +1,162 @@ + + + + + + + + systemd-fsckd.service + systemd + + + + Developer + Didier + Roche + didrocks@ubuntu.com + + + + + + systemd-fsckd.service + 8 + + + + systemd-fsckd.service + systemd-fsckd.socket + systemd-fsckd + File system check progress reporting + + + + systemd-fsckd.service + systemd-fsckd.socket + /usr/lib/systemd/systemd-fsckd + + + + Description + + systemd-fsckd.service is a service responsible + for receiving file system check progress, and communicating some + consolidated data to console and plymouth (if running). It also handles + possible check cancellations. + + systemd-fsckd receives messages about file + system check progress from fsck through an + UNIX domain socket. It can display the progress of the least advanced + fsck as well as the total number of devices being checked in parallel + to the console. It will also send progress messages to plymouth. + Both the raw data and translated messages are sent, so compiled + plymouth themes can use the raw data to display custom messages, and + scripted themes, not supporting i18n, can display the translated + versions. + + systemd-fsckd will instruct plymouth to grab + Control+C keypresses. When the key is pressed, running checks will be + terminated. It will also cancel any newly connected fsck instances for + the lifetime of systemd-fsckd. + + + + Protocol for communication with plymouth + + systemd-fsckd passes the + following messages to the theme: + + Progress update, sent as a plymouth update message: + fsckd:<num_devices>:<progress>:<string> + + + <num_devices> + the current number of devices + being checked (int) + + + <progress> + the current minimum percentage of + all devices being checking (float, from 0 to 100) + + + <string> + a translated message ready to be displayed + by the plymouth theme displaying the data above. It can be overridden + by themes supporting i18n. + + + + + Cancel message, sent as a traditional plymouth message: + fsckd-cancel-msg:<string> + + + <strings> + a translated string ready to be displayed + by the plymouth theme indicating that Control+C can be used to cancel + current checks. It can be overridden (matching only + fsckd-cancel-msg prefix) + by themes supporting i18n. + + + + + + + Options + + The following options are understood: + + + + + + + + + + Exit status + + On success, 0 is returned, a non-zero failure + code otherwise. Note that the daemon stays idle for + a while to accept new fsck + connections before exiting. + + + + See Also + + systemd1, + systemd-fsck8, + fsck8, + systemd-quotacheck.service8, + fsck.btrfs8, + fsck.cramfs8, + fsck.ext48, + fsck.fat8, + fsck.hfsplus8, + fsck.minix8, + fsck.ntfs8, + fsck.xfs8 + + + + diff --git a/meson.build b/meson.build index 7419e2b0b09..4efaa1bc96c 100644 --- a/meson.build +++ b/meson.build @@ -2149,6 +2149,7 @@ subdir('src/environment-d-generator') subdir('src/escape') subdir('src/firstboot') subdir('src/fsck') +subdir('src/fsckd') subdir('src/fstab-generator') subdir('src/getty-generator') subdir('src/gpt-auto-generator') diff --git a/po/POTFILES.in b/po/POTFILES.in index 16899fd5f9f..6bba341ca0c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -13,3 +13,4 @@ src/portable/org.freedesktop.portable1.policy src/resolve/org.freedesktop.resolve1.policy src/timedate/org.freedesktop.timedate1.policy src/core/dbus-unit.c +src/fsckd/fsckd.c diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c new file mode 100644 index 00000000000..e9a8019c894 --- /dev/null +++ b/src/fsckd/fsckd.c @@ -0,0 +1,705 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2015 Canonical + + Author: + Didier Roche + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sd-daemon.h" +#include "build.h" +#include "constants.h" +#include "sd-event.h" +#include "log.h" +#include "list.h" +#include "macro.h" +#include "socket-netlink.h" +#include "socket-util.h" +#include "fd-util.h" +#include "string-util.h" +#include "io-util.h" +#include "alloc-util.h" +#include "locale-util.h" +#include "logarithm.h" + +#define FSCKD_SOCKET_PATH "/run/systemd/fsck.progress" +#define IDLE_TIME_SECONDS 30 +#define PLYMOUTH_REQUEST_KEY "K\2\2\3" +#define CLIENTS_MAX 128 + +struct Manager; + +typedef struct Client { + struct Manager *manager; + char *device_name; + /* device id refers to "fd " until it gets a name as "device_name" */ + char *device_id; + + pid_t fsck_pid; + FILE *fsck_f; + + size_t cur; + size_t max; + int pass; + + double percent; + + bool cancelled; + bool bad_input; + + sd_event_source *event_source; + + LIST_FIELDS(struct Client, clients); +} Client; + +typedef struct Manager { + sd_event *event; + + LIST_HEAD(Client, clients); + unsigned n_clients; + + size_t clear; + + int connection_fd; + sd_event_source *connection_event_source; + + bool show_status_console; + + double percent; + int numdevices; + + int plymouth_fd; + sd_event_source *plymouth_event_source; + bool plymouth_cancel_sent; + + bool cancel_requested; +} Manager; + +static Client* client_free(Client *c); +static Manager* manager_free(Manager *m); + +DEFINE_TRIVIAL_CLEANUP_FUNC(Client*, client_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); + +static void init_gettext(void) { + setlocale(LC_ALL, ""); + textdomain(GETTEXT_PACKAGE); +} + +static bool plymouth_running(void) { + return access("/run/plymouth/pid", F_OK) >= 0; +} + +static int manager_write_console(Manager *m, const char *message) { + _cleanup_fclose_ FILE *console = NULL; + int l; + size_t j; + + assert(m); + + if (!m->show_status_console) + return 0; + + /* Nothing to display, and nothing to clear: return now. */ + if (message == NULL && m->clear == 0) { + return 0; + } + + /* Reduce the SAK window by opening and closing console on every request */ + console = fopen("/dev/console", "we"); + if (!console) + return -errno; + + if (message) { + fprintf(console, "\r%s\r%n", message, &l); + if (m->clear < (size_t)l) + m->clear = (size_t)l; + } else { + fputc('\r', console); + for (j = 0; j < m->clear; j++) + fputc(' ', console); + fputc('\r', console); + } + fflush(console); + + return 0; +} + +static double compute_percent(int pass, size_t cur, size_t max) { + /* Values stolen from e2fsck */ + + static const double pass_table[] = { + 0, 70, 90, 92, 95, 100 + }; + + if (pass <= 0) + return 0.0; + + if ((unsigned) pass >= ELEMENTSOF(pass_table) || max == 0) + return 100.0; + + return pass_table[pass-1] + + (pass_table[pass] - pass_table[pass-1]) * + (double) cur / max; +} + +static int client_request_cancel(Client *c) { + assert(c); + + if (c->cancelled) + return 0; + + log_info("Request to cancel fsck for %s from fsckd", c->device_id); + if (kill(c->fsck_pid, SIGTERM) < 0) { + /* ignore the error and consider that cancel was sent if fsck just exited */ + if (errno != ESRCH) + return log_error_errno(errno, "Cannot send cancel to fsck for %s: %m", c->device_id); + } + + c->cancelled = true; + return 1; +} + +static Client* client_free(Client *c) { + assert(c); + + if (c->manager) { + LIST_REMOVE(clients, c->manager->clients, c); + c->manager->n_clients--; + } + + sd_event_source_unref(c->event_source); + fclose(c->fsck_f); + if (c->device_name) + free(c->device_name); + if (c->device_id) + free(c->device_id); + return mfree(c); +} + +static void manager_disconnect_plymouth(Manager *m) { + assert(m); + + m->plymouth_event_source = sd_event_source_unref(m->plymouth_event_source); + m->plymouth_fd = safe_close(m->plymouth_fd); + m->plymouth_cancel_sent = false; +} + +static int manager_plymouth_feedback_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + Manager *m = userdata; + char buffer[6]; + ssize_t l; + + assert(m); + + l = read(m->plymouth_fd, buffer, sizeof(buffer)); + if (l < 0) { + log_warning_errno(errno, "Got error while reading from plymouth: %m"); + manager_disconnect_plymouth(m); + return -errno; + } + if (l == 0) { + manager_disconnect_plymouth(m); + return 0; + } + + if (l > 1 && buffer[0] == '\15') + log_error("Message update to plymouth wasn't delivered successfully"); + + /* the only answer support type we requested is a key interruption */ + if (l > 2 && buffer[0] == '\2' && buffer[5] == '\3') { + m->cancel_requested = true; + + /* cancel all connected clients */ + LIST_FOREACH(clients, current, m->clients) + client_request_cancel(current); + } + + return 0; +} + +static int manager_connect_plymouth(Manager *m) { + union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + .un.sun_path = "\0/org/freedesktop/plymouthd", + }; + int r; + + if (!plymouth_running()) + return 0; + + /* try to connect or reconnect if sending a message */ + if (m->plymouth_fd >= 0) + return 1; + + m->plymouth_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + if (m->plymouth_fd < 0) + return log_warning_errno(errno, "Connection to plymouth socket failed: %m"); + + if (connect(m->plymouth_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + r = log_warning_errno(errno, "Couldn't connect to plymouth: %m"); + goto fail; + } + + r = sd_event_add_io(m->event, &m->plymouth_event_source, m->plymouth_fd, EPOLLIN, manager_plymouth_feedback_handler, m); + if (r < 0) { + log_warning_errno(r, "Can't listen to plymouth socket: %m"); + goto fail; + } + + return 1; + +fail: + manager_disconnect_plymouth(m); + return r; +} + +static int plymouth_send_message(int plymouth_fd, const char *message, bool update) { + _cleanup_free_ char *packet = NULL; + int n; + char mode = 'M'; + + if (update) + mode = 'U'; + + if (asprintf(&packet, "%c\002%c%s%n", mode, (int) (strlen(message) + 1), message, &n) < 0) + return log_oom(); + + return loop_write_full(plymouth_fd, packet, n + 1, USEC_INFINITY); +} + +static int manager_send_plymouth_message(Manager *m, const char *message) { + const char *plymouth_cancel_message = NULL, *l10n_cancel_message = NULL; + int r; + + r = manager_connect_plymouth(m); + if (r < 0) + return r; + /* 0 means that plymouth isn't running, do not send any message yet */ + else if (r == 0) + return 0; + + if (!m->plymouth_cancel_sent) { + + /* Indicate to plymouth that we listen to Ctrl+C */ + r = loop_write_full(m->plymouth_fd, PLYMOUTH_REQUEST_KEY, sizeof(PLYMOUTH_REQUEST_KEY), USEC_INFINITY); + if (r < 0) + return log_warning_errno(r, "Can't send to plymouth cancel key: %m"); + + m->plymouth_cancel_sent = true; + + l10n_cancel_message = _("Press Ctrl+C to cancel all filesystem checks in progress"); + plymouth_cancel_message = strjoina("fsckd-cancel-msg:", l10n_cancel_message); + + r = plymouth_send_message(m->plymouth_fd, plymouth_cancel_message, false); + if (r < 0) + log_warning_errno(r, "Can't send filesystem cancel message to plymouth: %m"); + + } else if (m->numdevices == 0) { + + m->plymouth_cancel_sent = false; + + r = plymouth_send_message(m->plymouth_fd, "", false); + if (r < 0) + log_warning_errno(r, "Can't clear plymouth filesystem cancel message: %m"); + } + + r = plymouth_send_message(m->plymouth_fd, message, true); + if (r < 0) + return log_warning_errno(r, "Couldn't send \"%s\" to plymouth: %m", message); + + return 0; +} + +static int manager_update_global_progress(Manager *m) { + _cleanup_free_ char *console_message = NULL; + _cleanup_free_ char *fsck_message = NULL; + int current_numdevices = 0, r; + double current_percent = 100; + + /* get the overall percentage */ + LIST_FOREACH(clients, current, m->clients) { + current_numdevices++; + + /* right now, we only keep the minimum % of all fsckd processes. We could in the future trying to be + linear, but max changes and corresponds to the pass. We have all the informations into fsckd + already if we can treat that in a smarter way. */ + current_percent = MIN(current_percent, current->percent); + } + + /* update if there is anything user-visible to update */ + if (fabs(current_percent - m->percent) > 0.001 || current_numdevices != m->numdevices) { + m->numdevices = current_numdevices; + m->percent = current_percent; + + if (asprintf(&console_message, + ngettext("Checking in progress on %d disk (%3.1f%% complete)", + "Checking in progress on %d disks (%3.1f%% complete)", m->numdevices), + m->numdevices, m->percent) < 0) + return -ENOMEM; + + if (asprintf(&fsck_message, "fsckd:%d:%3.1f:%s", m->numdevices, m->percent, console_message) < 0) + return -ENOMEM; + + r = manager_write_console(m, console_message); + if (r < 0) + return r; + + /* try to connect to plymouth and send message */ + r = manager_send_plymouth_message(m, fsck_message); + if (r < 0) + return r; + } + return 0; +} + +static int client_progress_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + Client *client = userdata; + char line[LINE_MAX]; + Manager *m; + + assert(client); + m = client->manager; + + /* check first if we need to cancel this client */ + if (m->cancel_requested) + client_request_cancel(client); + + while (fgets(line, sizeof(line), client->fsck_f) != NULL) { + int pass; + size_t cur, max; + _cleanup_free_ char *device = NULL, *old_device_id = NULL; + + if (sscanf(line, "%i %zu %zu %ms", &pass, &cur, &max, &device) == 4) { + if (!client->device_name) { + client->device_name = strdup(device); + if (!client->device_name) { + log_oom(); + continue; + } + old_device_id = client->device_id; + client->device_id = strdup(device); + if (!client->device_id) { + log_oom(); + client->device_id = old_device_id; + old_device_id = NULL; + continue; + } + } + client->pass = pass; + client->cur = cur; + client->max = max; + client->bad_input = false; + client->percent = compute_percent(client->pass, client->cur, client->max); + log_debug("Getting progress for %s (%zu, %zu, %d) : %3.1f%%", client->device_id, + client->cur, client->max, client->pass, client->percent); + } else { + if (errno == ENOMEM) { + log_oom(); + continue; + } + + /* if previous input was already garbage, kick it off from progress report */ + if (client->bad_input) { + log_warning("Closing connection on incorrect input of fsck connection for %s", client->device_id); + client_free(client); + manager_update_global_progress(m); + return 0; + } + client->bad_input = true; + } + + } + + if (feof(client->fsck_f)) { + log_debug("Fsck client %s disconnected", client->device_id); + client_free(client); + } + + manager_update_global_progress(m); + return 0; +} + +static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + _cleanup_(client_freep) Client *c = NULL; + _cleanup_close_ int new_fsck_fd = -1; + _cleanup_fclose_ FILE *new_fsck_f = NULL; + struct ucred ucred = {}; + Manager *m = userdata; + int r; + + assert(m); + + /* Initialize and list new clients */ + new_fsck_fd = accept4(m->connection_fd, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK); + if (new_fsck_fd < 0) { + log_error_errno(errno, "Couldn't accept a new connection: %m"); + return 0; + } + + if (m->n_clients >= CLIENTS_MAX) { + log_error("Too many clients, refusing connection."); + return 0; + } + + + new_fsck_f = fdopen(new_fsck_fd, "r"); + if (!new_fsck_f) { + log_error_errno(errno, "Couldn't fdopen new connection for fd %d: %m", new_fsck_fd); + return 0; + } + new_fsck_fd = -1; + + r = getpeercred(fileno(new_fsck_f), &ucred); + if (r < 0) { + log_error_errno(r, "Couldn't get credentials for fsck: %m"); + return 0; + } + + c = new0(Client, 1); + if (!c) { + log_oom(); + return 0; + } + + c->fsck_pid = ucred.pid; + c->fsck_f = new_fsck_f; + new_fsck_f = NULL; + + if (asprintf(&(c->device_id), "fd %d", fileno(c->fsck_f)) < 0) { + log_oom(); + return 0; + } + + r = sd_event_add_io(m->event, &c->event_source, fileno(c->fsck_f), EPOLLIN, client_progress_handler, c); + if (r < 0) { + log_oom(); + return 0; + } + + LIST_PREPEND(clients, m->clients, c); + m->n_clients++; + c->manager = m; + + log_debug("New fsck client connected: %s", c->device_id); + + /* only request the client to cancel now in case the request is dropped by the client (chance to recancel) */ + if (m->cancel_requested) + client_request_cancel(c); + + c = NULL; + return 0; +} + +static Manager* manager_free(Manager *m) { + if (!m) + return NULL; + + /* clear last line */ + manager_write_console(m, NULL); + + sd_event_source_unref(m->connection_event_source); + safe_close(m->connection_fd); + + while (m->clients) + client_free(m->clients); + + manager_disconnect_plymouth(m); + + sd_event_unref(m->event); + + return mfree(m); +} + +static int manager_new(Manager **ret, int fd) { + _cleanup_(manager_freep) Manager *m = NULL; + int r; + + assert(ret); + + m = new0(Manager, 1); + if (!m) + return -ENOMEM; + + m->plymouth_fd = -1; + m->connection_fd = fd; + m->percent = 100; + + r = sd_event_default(&m->event); + if (r < 0) + return r; + + if (access("/run/systemd/show-status", F_OK) >= 0) + m->show_status_console = true; + + r = sd_event_add_io(m->event, &m->connection_event_source, fd, EPOLLIN, manager_new_connection_handler, m); + if (r < 0) + return r; + + *ret = m; + m = NULL; + + return 0; +} + +static int run_event_loop_with_timeout(Manager *m, usec_t timeout) { + int r, code; + sd_event *e = m->event; + + assert(e); + + for (;;) { + r = sd_event_get_state(e); + if (r < 0) + return r; + if (r == SD_EVENT_FINISHED) + break; + + r = sd_event_run(e, timeout); + if (r < 0) + return r; + + /* Exit if we reached the idle timeout and no more clients are + connected. If there is still an fsck process running but + simply slow to send us progress updates, exiting would mean + that this fsck process receives SIGPIPE resulting in an + aborted file system check. */ + if (r == 0 && m->n_clients == 0) { + sd_event_exit(e, 0); + break; + } + } + + r = sd_event_get_exit_code(e, &code); + if (r < 0) + return r; + + return code; +} + +static void help(void) { + printf("%s [OPTIONS...]\n\n" + "Capture fsck progress and forward one stream to plymouth\n\n" + " -h --help Show this help\n" + " --version Show package version\n", + program_invocation_short_name); +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_ROOT, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + {} + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + version(); + return 0; + + case '?': + return -EINVAL; + + default: + assert_not_reached(); + } + + if (optind < argc) { + log_error("Extraneous arguments"); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + _cleanup_(manager_freep) Manager *m = NULL; + int fd = -1; + int r, n; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + init_gettext(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + n = sd_listen_fds(0); + if (n > 1) { + log_error("Too many file descriptors received."); + r = -EINVAL; + goto finish; + } else if (n == 1) + fd = SD_LISTEN_FDS_START + 0; + else { + fd = make_socket_fd(LOG_DEBUG, FSCKD_SOCKET_PATH, SOCK_STREAM, SOCK_CLOEXEC); + if (fd < 0) { + r = log_error_errno(fd, "Couldn't create listening socket fd on %s: %m", FSCKD_SOCKET_PATH); + goto finish; + } + } + + r = manager_new(&m, fd); + if (r < 0) { + log_error_errno(r, "Failed to allocate manager: %m"); + goto finish; + } + + r = run_event_loop_with_timeout(m, IDLE_TIME_SECONDS * USEC_PER_SEC); + if (r < 0) { + log_error_errno(r, "Failed to run event loop: %m"); + goto finish; + } + + sd_event_get_exit_code(m->event, &r); + +finish: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/fsckd/meson.build b/src/fsckd/meson.build new file mode 100644 index 00000000000..6d3c125b3ef --- /dev/null +++ b/src/fsckd/meson.build @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +executables += [ + libexec_template + { + 'name' : 'systemd-fsckd', + 'sources' : files('fsckd.c'), + }, +] diff --git a/units/meson.build b/units/meson.build index e7bfb7f838f..0aee5736977 100644 --- a/units/meson.build +++ b/units/meson.build @@ -288,6 +288,8 @@ units = [ }, { 'file' : 'systemd-fsck-root.service.in' }, { 'file' : 'systemd-fsck@.service.in' }, + { 'file' : 'systemd-fsckd.socket' }, + { 'file' : 'systemd-fsckd.service.in' }, { 'file' : 'systemd-growfs-root.service.in' }, { 'file' : 'systemd-growfs@.service.in' }, { 'file' : 'systemd-halt.service' }, diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in index ebe8262a49e..ca9c7cefb3b 100644 --- a/units/systemd-fsck-root.service.in +++ b/units/systemd-fsck-root.service.in @@ -13,6 +13,8 @@ Documentation=man:systemd-fsck-root.service(8) DefaultDependencies=no Conflicts=shutdown.target Before=local-fs.target shutdown.target +Wants=systemd-fsckd.socket +After=systemd-fsckd.socket ConditionPathIsReadWrite=!/ OnFailure=emergency.target OnFailureJobMode=replace-irreversibly diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in index 65521b1087b..cd8bac1f33f 100644 --- a/units/systemd-fsck@.service.in +++ b/units/systemd-fsck@.service.in @@ -13,7 +13,8 @@ Documentation=man:systemd-fsck@.service(8) DefaultDependencies=no BindsTo=%i.device Conflicts=shutdown.target -After=%i.device systemd-fsck-root.service local-fs-pre.target +Wants=systemd-fsckd.socket +After=%i.device systemd-fsck-root.service local-fs-pre.target systemd-fsckd.socket Before=systemd-quotacheck.service shutdown.target [Service] diff --git a/units/systemd-fsckd.service.in b/units/systemd-fsckd.service.in new file mode 100644 index 00000000000..845788c47ca --- /dev/null +++ b/units/systemd-fsckd.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=File System Check Daemon to report status +Documentation=man:systemd-fsckd.service(8) +DefaultDependencies=no +Requires=systemd-fsckd.socket +Before=shutdown.target + +[Service] +ExecStart={{LIBEXECDIR}}/systemd-fsckd +StandardOutput=journal+console diff --git a/units/systemd-fsckd.socket b/units/systemd-fsckd.socket new file mode 100644 index 00000000000..61fec97865a --- /dev/null +++ b/units/systemd-fsckd.socket @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=fsck to fsckd communication Socket +Documentation=man:systemd-fsckd.service(8) man:systemd-fsck@.service(8) man:systemd-fsck-root.service(8) +DefaultDependencies=no + +[Socket] +ListenStream=/run/systemd/fsck.progress +SocketMode=0600 From 5c55e68b82d3a691a56353b1dd3fbd9eb13734a8 Mon Sep 17 00:00:00 2001 From: Nis Martensen Date: Tue, 19 Jan 2016 22:01:43 +0100 Subject: [PATCH 04/29] Skip filesystem check if already done by the initramfs Newer versions of initramfs-tools already fsck and mount / and /usr in the initramfs. Skip the filesystem check in this case. Based on a previous patch by Michael Biebl . Closes: #782522 Closes: #810748 --- src/fstab-generator/fstab-generator.c | 11 ++++++++--- units/systemd-fsck-root.service.in | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 016f3baa7f8..f63a1d1470d 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -519,6 +519,7 @@ static int add_mount( _cleanup_strv_free_ char **wanted_by = NULL, **required_by = NULL; _cleanup_fclose_ FILE *f = NULL; int r; + struct stat sb; assert(what); assert(where); @@ -604,9 +605,13 @@ static int add_mount( fprintf(f, "Before=%s\n", target_unit); if (passno != 0) { - r = generator_write_fsck_deps(f, dest, what, where, fstype); - if (r < 0) - return r; + if (streq(where, "/usr") && stat("/run/initramfs/fsck-usr", &sb) == 0) + ; /* skip /usr fsck if it has already been checked in the initramfs */ + else { + r = generator_write_fsck_deps(f, dest, what, where, fstype); + if (r < 0) + return r; + } } r = generator_write_blockdev_dependency(f, what); diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in index ca9c7cefb3b..27783a9c824 100644 --- a/units/systemd-fsck-root.service.in +++ b/units/systemd-fsck-root.service.in @@ -16,6 +16,7 @@ Before=local-fs.target shutdown.target Wants=systemd-fsckd.socket After=systemd-fsckd.socket ConditionPathIsReadWrite=!/ +ConditionPathExists=!/run/initramfs/fsck-root OnFailure=emergency.target OnFailureJobMode=replace-irreversibly From d0cc58668935f2b9c9768137fa6360af7a6e3229 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sat, 27 Feb 2016 12:27:06 +0100 Subject: [PATCH 05/29] Revert "core: set RLIMIT_CORE to unlimited by default" Partially revert commit 15a900327ab as this completely breaks core dumps without systemd-coredump. It's also contradicting core(8), and it's not systemd's place to redefine the kernel definitions of core files. Commit bdfd7b2c now honours the process' RLIMIT_CORE for systemd-coredump. This isn't what RLIMIT_CORE is supposed to do (it limits the size of the core *file*, but the kernel deliberately ignores it for piping), so set a static 2^63 core size limit for systemd-coredump to go back to the previous behaviour (otherwise the change above would break systemd-coredump). Bug-Debian: https://bugs.debian.org/815020 --- src/core/main.c | 18 ------------------ sysctl.d/50-coredump.conf.in | 2 +- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 3f71cc09479..876c7d587a1 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1653,22 +1653,6 @@ static void cmdline_take_random_seed(void) { "This functionality should not be used outside of testing environments."); } -static void initialize_coredump(bool skip_setup) { - if (getpid_cached() != 1) - return; - - /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour - * the limit) will process core dumps for system services by default. */ - if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0) - log_warning_errno(errno, "Failed to set RLIMIT_CORE: %m"); - - /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored - * until the systemd-coredump tool is enabled via sysctl. However it can be changed via the kernel - * command line later so core dumps can still be generated during early startup and in initrd. */ - if (!skip_setup) - disable_coredumps(); -} - static void initialize_core_pattern(bool skip_setup) { int r; @@ -2922,8 +2906,6 @@ int main(int argc, char *argv[]) { kernel_timestamp = DUAL_TIMESTAMP_NULL; } - initialize_coredump(skip_setup); - r = fixup_environment(); if (r < 0) { log_struct_errno(LOG_EMERG, r, diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in index 90c080bdfef..17308415b1f 100644 --- a/sysctl.d/50-coredump.conf.in +++ b/sysctl.d/50-coredump.conf.in @@ -13,7 +13,7 @@ # the core dump. # # See systemd-coredump(8) and core(5). -kernel.core_pattern=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h +kernel.core_pattern=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t 9223372036854775808 %h # Allow 16 coredumps to be dispatched in parallel by the kernel. # We collect metadata from /proc/%P/, and thus need to make sure the crashed From 58f01f66ebecfc2d73c338ca667f5a85a6fd09b4 Mon Sep 17 00:00:00 2001 From: Ioanna Alifieraki Date: Thu, 17 Dec 2020 14:52:07 +0000 Subject: [PATCH 06/29] systemctl: do not shutdown immediately on scheduled shutdown When, for whatever reason, a scheduled shutdown fails to be set, systemd will proceed with immediate shutdown without allowing the user to react. This is counterintuitive because when a scheduled shutdown is issued, it means the user wants to shutdown at a specified time in the future, not immediately. This patch prevents the immediate shutdown and informs the user that no action will be taken. Fixes: #17575 --- src/systemctl/systemctl-compat-halt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/systemctl/systemctl-compat-halt.c b/src/systemctl/systemctl-compat-halt.c index 4f6e3048167..520e794ad2c 100644 --- a/src/systemctl/systemctl-compat-halt.c +++ b/src/systemctl/systemctl-compat-halt.c @@ -155,9 +155,11 @@ int halt_main(void) { if (arg_force == 0) { /* always try logind first */ - if (arg_when > 0) + if (arg_when > 0) { r = logind_schedule_shutdown(arg_action); - else { + if (r < 0) + return r; + } else { r = logind_check_inhibitors(arg_action); if (r < 0) return r; From f7b63179b6c0e145df871e5bc6697ecdc6ba63e8 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 16 Feb 2021 00:18:50 +0100 Subject: [PATCH 07/29] Downgrade a couple of warnings to debug If a package still ships only a SysV init script or if a service file or tmpfile uses /var/run, downgrade those messages to debug. We can use lintian to detect those issues. For service files and tmpfiles in /etc, keep the warning, as those files are typically added locally and aren't checked by lintian. Closes: #981407 --- src/core/load-fragment.c | 4 +++- src/sysv-generator/sysv-generator.c | 2 +- src/tmpfiles/tmpfiles.c | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index f442bd82036..a92f683a3f7 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -544,6 +544,7 @@ static int patch_var_run( const char *e; char *z; + int log_level; e = path_startswith(*path, "/var/run/"); if (!e) @@ -553,7 +554,8 @@ static int patch_var_run( if (!z) return log_oom(); - log_syntax(unit, LOG_NOTICE, filename, line, 0, + log_level = path_startswith(filename, "/etc") ? LOG_NOTICE : LOG_DEBUG; + log_syntax(unit, log_level, filename, line, 0, "%s= references a path below legacy directory /var/run/, updating %s → %s; " "please update the unit file accordingly.", lvalue, *path, z); diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c index 4485e2e3680..d0e8ed84bc5 100644 --- a/src/sysv-generator/sysv-generator.c +++ b/src/sysv-generator/sysv-generator.c @@ -762,7 +762,7 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) { if (!fpath) return log_oom(); - log_struct(LOG_WARNING, + log_struct(LOG_DEBUG, LOG_MESSAGE("SysV service '%s' lacks a native systemd unit file. " "%s Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it safe, robust and future-proof. " "%s This compatibility logic is deprecated, expect removal soon. %s", diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 230ec09b979..d513d402408 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -3266,6 +3266,7 @@ static int specifier_expansion_from_arg(const Specifier *specifier_table, Item * static int patch_var_run(const char *fname, unsigned line, char **path) { const char *k; char *n; + int log_level; assert(path); assert(*path); @@ -3291,7 +3292,8 @@ static int patch_var_run(const char *fname, unsigned line, char **path) { /* Also log about this briefly. We do so at LOG_NOTICE level, as we fixed up the situation automatically, hence * there's no immediate need for action by the user. However, in the interest of making things less confusing * to the user, let's still inform the user that these snippets should really be updated. */ - log_syntax(NULL, LOG_NOTICE, fname, line, 0, + log_level = path_startswith(fname, "/etc") ? LOG_NOTICE : LOG_DEBUG; + log_syntax(NULL, log_level, fname, line, 0, "Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", *path, n); From fcf9c5248ca26c9fc0c001566739971c487dd702 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 13 Dec 2022 00:32:17 +0100 Subject: [PATCH 08/29] Skip flaky test_resolved_domain_restricted_dns in networkd-test.py This test is part of DnsmasqClientTest and does not work reliably under LXC/debci, so skip it for the time being. Closes: #1025908 --- test/networkd-test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/networkd-test.py b/test/networkd-test.py index 512137cacc9..1bf153825b5 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -639,6 +639,7 @@ def print_server_log(self, log_file=None): with open(path) as f: sys.stdout.write('\n\n---- {} ----\n{}\n------\n\n'.format(os.path.basename(path), f.read())) + @unittest.skip("test is flaky: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1025908") def test_resolved_domain_restricted_dns(self): '''resolved: domain-restricted DNS servers''' From 912699519748ed9948b7512a9f7943c3d19ec00d Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 8 Feb 2023 20:34:38 +0000 Subject: [PATCH 09/29] localectl-disable-keymap-support We no longer support old debianisms such as /etc/default/keyboard, so disable the keymap interface in localectl until a definitive solution is found. Update the test suite to skip tests for unsupported localectl features. --- src/locale/localectl.c | 11 ++++++----- test/units/testsuite-73.sh | 6 ++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 32354027f17..c4fb1f2aa61 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -383,6 +383,10 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) { return 0; } +static int not_supported(int argc, char **argv, void *userdata) { + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Setting X11 and console keymaps is not supported in Debian."); +} + static int help(void) { _cleanup_free_ char *link = NULL; int r; @@ -397,10 +401,7 @@ static int help(void) { " status Show current locale settings\n" " set-locale LOCALE... Set system locale\n" " list-locales Show known locales\n" - " set-keymap MAP [MAP] Set console and X11 keyboard mappings\n" " list-keymaps Show known virtual console keyboard mappings\n" - " set-x11-keymap LAYOUT [MODEL [VARIANT [OPTIONS]]]\n" - " Set X11 and console keyboard mappings\n" " list-x11-keymap-models Show known X11 keyboard mapping models\n" " list-x11-keymap-layouts Show known X11 keyboard mapping layouts\n" " list-x11-keymap-variants [LAYOUT]\n" @@ -500,9 +501,9 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) { { "status", VERB_ANY, 1, VERB_DEFAULT, show_status }, { "set-locale", 2, VERB_ANY, 0, set_locale }, { "list-locales", VERB_ANY, 1, 0, list_locales }, - { "set-keymap", 2, 3, 0, set_vconsole_keymap }, + { "set-keymap", 2, 3, 0, not_supported }, { "list-keymaps", VERB_ANY, 1, 0, list_vconsole_keymaps }, - { "set-x11-keymap", 2, 5, 0, set_x11_keymap }, + { "set-x11-keymap", 2, 5, 0, not_supported }, { "list-x11-keymap-models", VERB_ANY, 1, 0, list_x11_keymaps }, { "list-x11-keymap-layouts", VERB_ANY, 1, 0, list_x11_keymaps }, { "list-x11-keymap-variants", VERB_ANY, 2, 0, list_x11_keymaps }, diff --git a/test/units/testsuite-73.sh b/test/units/testsuite-73.sh index df5af4ba873..ec3fa6c75bd 100755 --- a/test/units/testsuite-73.sh +++ b/test/units/testsuite-73.sh @@ -227,6 +227,9 @@ wait_vconsole_setup() { testcase_vc_keymap() { local i output vc + echo "Setting X11 and console keymaps is not supported in Debian, skipping test." + return + if [[ -z "$(localectl list-keymaps)" ]]; then echo "No vconsole keymap installed, skipping test." return @@ -297,6 +300,9 @@ testcase_vc_keymap() { testcase_x11_keymap() { local output + echo "Setting X11 and console keymaps is not supported in Debian, skipping test." + return + if [[ -z "$(localectl list-x11-keymap-layouts)" ]]; then echo "No x11 keymap installed, skipping test." return From 509dfda465308e3a94bcb1b208bbadfa562dd897 Mon Sep 17 00:00:00 2001 From: "Eugenio Paolantonio (g7)" Date: Thu, 28 Dec 2023 03:40:09 +0100 Subject: [PATCH 10/29] [systemd] Add circleci rules Signed-off-by: Eugenio Paolantonio (g7) --- .circleci/config.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000000..466c20c1c91 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,25 @@ +version: 2.1 + +setup: true + +orbs: + continuation: circleci/continuation@0.1.2 + droidian-buildd: droidian-releng/droidian-buildd-orb@volatile + +jobs: + setup: + executor: continuation/default + resource_class: small + steps: + - droidian-buildd/checkout + - droidian-buildd/generate + - continuation/continue: + configuration_path: generated_config.yml + +workflows: + setup: + jobs: + - setup: + filters: + tags: + only: /^droidian\/.*\/.*/ From 76a52d0b94c7f9279ae9e26184f4e085155ee7f6 Mon Sep 17 00:00:00 2001 From: "Eugenio Paolantonio (g7)" Date: Thu, 28 Dec 2023 03:43:54 +0100 Subject: [PATCH 11/29] (temporary) Conflict with droidian-quirks-brightness < 79 Both systemd 255 and droidian-quirks-brightness install their service files in the same directory. This commit gives APT an hint on how to order the dependency installation graph. Signed-off-by: Eugenio Paolantonio (g7) --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index feb756bba16..80f3b9f9a04 100644 --- a/debian/control +++ b/debian/control @@ -105,6 +105,7 @@ Conflicts: consolekit, libpam-ck-connector, systemd-shim, opensysusers, + droidian-quirks-brightness (< 79), Breaks: less (<< 563), sicherboot (<< 0.1.6), dracut (<< 059-5), From f05fd019f82fbd43eb86d78faa1408d3762ef33b Mon Sep 17 00:00:00 2001 From: "Eugenio Paolantonio (g7)" Date: Thu, 28 Dec 2023 04:07:18 +0100 Subject: [PATCH 12/29] [packaging] Disable tests Some tests unfortunately fail on the resource constrained buildds we have. Disable tests for now. Keep in mind that this version of systemd is temporary and Droidian will revert to the stock Debian one in the near future. Signed-off-by: Eugenio Paolantonio (g7) --- debian/rules | 4 ---- 1 file changed, 4 deletions(-) diff --git a/debian/rules b/debian/rules index fb9f2e496ed..fc3bb71f0b4 100755 --- a/debian/rules +++ b/debian/rules @@ -261,10 +261,6 @@ override_dh_makeshlibs: dh_makeshlibs --remaining-packages -- -c$(GENSYMBOLS_LEVEL) override_dh_auto_test: -ifeq (, $(filter nocheck, $(DEB_BUILD_OPTIONS))) - # some tests hang under fakeroot, so disable fakeroot - env -u LD_PRELOAD meson test -C obj-$(DEB_HOST_GNU_TYPE) --print-errorlogs $(TEST_TIMEOUT_MULTIPLIER) -endif %: dh $@ --without autoreconf --buildsystem=meson From a82ebee2d54f239aafe29beb22b5305aa0e4fc64 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sat, 30 Dec 2023 12:20:51 +0100 Subject: [PATCH 13/29] Cherry-pick fixes for upstream integration tests Fixes TEST-07-PID1 [1], TEST-08-INITRD [2], TEST-26-SYSTEMCTL [3] and TEST-75-RESOLVED [4]. [1] https://github.com/systemd/systemd/issues/30664 [2] https://github.com/systemd/systemd/issues/30481 [3] https://github.com/systemd/systemd/issues/30478 [4] https://github.com/systemd/systemd/issues/30477 --- debian/patches/series | 5 + ...-Dinstall-tests-true-with-NO_BUILD-1.patch | 27 +++++ ...socket-once-the-triggered-unit-exits.patch | 56 ++++++++++ ...ll-empty-directories-with-NO_BUILD-1.patch | 76 +++++++++++++ ...TRD-if-systemd-didn-t-run-in-the-ini.patch | 51 +++++++++ ...d-anchors-from-etc-bind.keys-explici.patch | 103 ++++++++++++++++++ 6 files changed, 318 insertions(+) create mode 100644 debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch create mode 100644 debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch create mode 100644 debian/patches/test-install-empty-directories-with-NO_BUILD-1.patch create mode 100644 debian/patches/test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch create mode 100644 debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch diff --git a/debian/patches/series b/debian/patches/series index 145e1738717..de08274dfe1 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -7,3 +7,8 @@ debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch debian/Downgrade-a-couple-of-warnings-to-debug.patch debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch debian/localectl-disable-keymap-support.patch +test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch +test-install-empty-directories-with-NO_BUILD-1.patch +test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch +test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch +test-flush-the-socket-once-the-triggered-unit-exits.patch diff --git a/debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch b/debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch new file mode 100644 index 00000000000..99e161fcbb5 --- /dev/null +++ b/debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch @@ -0,0 +1,27 @@ +From: Frantisek Sumsal +Date: Thu, 14 Dec 2023 15:06:46 +0100 +Subject: test: don't check for -Dinstall-tests=true with NO_BUILD=1 + +(cherry picked from commit 58bcbad86cc910e007fae3c66c3a5cfc17046801) +--- + test/test-functions | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/test/test-functions b/test/test-functions +index 6a6f624..f887346 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -3309,9 +3309,10 @@ test_create_image() { + } + + test_setup() { +- if get_bool "${TEST_REQUIRE_INSTALL_TESTS:?}" && \ +- command -v meson >/dev/null && \ +- [[ "$(meson configure "${BUILD_DIR:?}" | grep install-tests | awk '{ print $2 }')" != "true" ]]; then ++ if ! get_bool "$NO_BUILD" && \ ++ get_bool "${TEST_REQUIRE_INSTALL_TESTS:?}" && \ ++ command -v meson >/dev/null && \ ++ [[ "$(meson configure "${BUILD_DIR:?}" | grep install-tests | awk '{ print $2 }')" != "true" ]]; then + dfatal "$BUILD_DIR needs to be built with -Dinstall-tests=true" + exit 1 + fi diff --git a/debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch b/debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch new file mode 100644 index 00000000000..eb32fc77be7 --- /dev/null +++ b/debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch @@ -0,0 +1,56 @@ +From: Frantisek Sumsal +Date: Sun, 24 Dec 2023 12:53:53 +0100 +Subject: test: flush the socket once the triggered unit exits + +Since the triggered unit intentionally fails without consuming any data +from the socket, we'd try to trigger it again and again, and we might +try to check the unit state in one of the "in-between" states, failing +the test: + +[ 165.271698] H testsuite-07.sh[1032]: + systemctl start badbin_assert.socket +[ 165.977637] H testsuite-07.sh[1032]: + socat - ABSTRACT-CONNECT:badbin_assert.socket +[ 165.983787] H systemd[1]: Cannot find unit for notify message of PID 1039, ignoring. +[ 166.817187] H testsuite-07.sh[1032]: + timeout 10 sh -c 'while systemctl is-active badbin_assert.service; do sleep .5; done' +[ 167.049218] H testsuite-07.sh[1065]: active +[ 167.146854] H systemd[1]: Listening on badbin_assert.socket. +[ 167.163473] H systemd[1]: badbin_assert.socket: Incoming traffic +[ 167.542626] H systemd[1]: Cannot find unit for notify message of PID 1065, ignoring. +[ 167.543437] H (badbin)[1062]: badbin_assert.service: Failed to execute /tmp/badbin: Exec format error +[ 167.548346] H systemd[1]: badbin_assert.service: Main process exited, code=exited, status=203/EXEC +[ 167.549482] H systemd[1]: badbin_assert.service: Failed with result 'exit-code'. +[ 167.561537] H systemd[1]: badbin_assert.socket: Incoming traffic +[ 167.933390] H systemd[1]: Started badbin_assert.service. +[ 167.950489] H (badbin)[1070]: badbin_assert.service: Failed to execute /tmp/badbin: Exec format error +[ 167.956318] H systemd[1]: badbin_assert.service: Main process exited, code=exited, status=203/EXEC +[ 167.957173] H systemd[1]: badbin_assert.service: Failed with result 'exit-code'. +[ 167.974609] H systemd[1]: badbin_assert.socket: Incoming traffic +[ 168.042838] H testsuite-07.sh[1072]: failed +[ 168.094431] H testsuite-07.sh[1075]: ++ systemctl show -P ExecMainStatus badbin_assert.service +[ 168.704022] H systemd[1]: Started badbin_assert.service. +[ 168.778680] H (badbin)[1074]: badbin_assert.service: Failed to execute /tmp/badbin: Exec format error +[ 168.826881] H systemd[1]: badbin_assert.service: Main process exited, code=exited, status=203/EXEC +[ 168.833825] H systemd[1]: badbin_assert.service: Failed with result 'exit-code'. +[ 168.923931] H testsuite-07.sh[1032]: + [[ 0 == 203 ]] +[ 168.951492] H systemd[1]: Cannot find unit for notify message of PID 1075, ignoring. +[ 168.999862] H testsuite-07.sh[615]: + echo 'Subtest /usr/lib/systemd/tests/testdata/units/testsuite-07.issue-30412.sh failed' +[ 168.999862] H testsuite-07.sh[615]: Subtest /usr/lib/systemd/tests/testdata/units/testsuite-07.issue-30412.sh failed + +Follow-up for 1eeaa93de36 and 28a2d27650c. + +(cherry picked from commit 4ddf27c57bbaaa66bed5cfa951e60a83b9f64e29) +--- + test/units/testsuite-07.issue-30412.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/test/units/testsuite-07.issue-30412.sh b/test/units/testsuite-07.issue-30412.sh +index 61801c5..c1cb00e 100755 +--- a/test/units/testsuite-07.issue-30412.sh ++++ b/test/units/testsuite-07.issue-30412.sh +@@ -20,6 +20,7 @@ EOF + cat >/run/systemd/system/badbin_assert.socket < +Date: Thu, 14 Dec 2023 15:06:12 +0100 +Subject: test: install empty directories with NO_BUILD=1 + +Resolves: #30478 +(cherry picked from commit fdd380dde2ec2cbcecbd20b91cf6b819ef3dc0db) +--- + test/test-functions | 42 ++++++++++++++++++++++++------------------ + 1 file changed, 24 insertions(+), 18 deletions(-) + +diff --git a/test/test-functions b/test/test-functions +index 4606745..6a6f624 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -1310,19 +1310,35 @@ install_compiled_systemd() { + fi + } + ++install_package_file() { ++ local file="${1:?}" ++ ++ # Skip missing files (like /etc/machine-info) ++ [[ ! -e "$file" ]] && return 0 ++ # Skip python unit tests, since the image_install machinery will try to pull ++ # in the whole python stack in a very questionable state, making the tests fail. ++ # And given we're trying to transition to mkosi-based images anyway I'm not even ++ # going to bother ++ [[ "$file" =~ /tests/unit-tests/.*.py$ ]] && return 0 ++ # If the current file is a directory, create it with the original ++ # mode; if it's a symlink to a directory, copy it as-is ++ if [[ -d "$file" ]]; then ++ inst_dir "$file" ++ else ++ inst "$file" ++ fi ++} ++ + install_debian_systemd() { + dinfo "Install debian systemd" + +- local files ++ local deb file + + while read -r deb; do +- files="$(dpkg-query -L "$deb" 2>/dev/null)" || continue + ddebug "Install debian files from package $deb" +- for file in $files; do +- [ -e "$file" ] || continue +- [ ! -L "$file" ] && [ -d "$file" ] && continue +- inst "$file" +- done ++ while read -r file; do ++ install_package_file "$file" ++ done < <(dpkg-query -L "$deb" 2>/dev/null) + done < <(grep -E '^Package:' "${SOURCE_DIR}/debian/control" | cut -d ':' -f 2) + } + +@@ -1337,17 +1353,7 @@ install_rpm() { + + dinfo "Installing contents of RPM $rpm" + while read -r file; do +- # Skip missing files (like /etc/machine-info) +- [[ ! -e "$file" ]] && continue +- # Skip directories unless they are a symlink (both -L and -d pass in this case) +- [[ -d "$file" && ! -L "$file" ]] && continue +- # Skip python unit tests, since the image_install machinery will try to pull +- # in the whole python stack in a very questionable state, making the tests fail. +- # And given we're trying to transition to mkosi-based images anyway I'm not even +- # going to bother +- [[ "$file" =~ /tests/unit-tests/.*.py$ ]] && continue +- +- image_install "$file" ++ install_package_file "$file" + done < <(rpm -ql "$rpm") + } + diff --git a/debian/patches/test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch b/debian/patches/test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch new file mode 100644 index 00000000000..602fc344ce7 --- /dev/null +++ b/debian/patches/test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch @@ -0,0 +1,51 @@ +From: Frantisek Sumsal +Date: Fri, 15 Dec 2023 11:04:39 +0100 +Subject: test: skip TEST-08-INITRD if systemd didn't run in the initrd + +This test requires systemd in the initrd, which is not the case in +mkinitrd-based initrds (Ubuntu/Debian). + +Resolves: #30481 +(cherry picked from commit 57d61ff319ec217294d9e0c4646010322b8be5e5) +--- + test/TEST-08-INITRD/test.sh | 5 +++++ + test/units/testsuite-08.sh | 8 ++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/test/TEST-08-INITRD/test.sh b/test/TEST-08-INITRD/test.sh +index 29fd1f7..caa27f6 100755 +--- a/test/TEST-08-INITRD/test.sh ++++ b/test/TEST-08-INITRD/test.sh +@@ -44,8 +44,13 @@ EOF + } + + check_result_qemu_hook() { ++ local workspace="${1:?}" + local console_log="${TESTDIR:?}/console.log" + ++ if [[ -e "$workspace/skipped" ]]; then ++ return 0 ++ fi ++ + if [[ ! -e "$console_log" ]]; then + dfatal "Missing console log - this shouldn't happen" + return 1 +diff --git a/test/units/testsuite-08.sh b/test/units/testsuite-08.sh +index 9598c8e..5c6b4ce 100755 +--- a/test/units/testsuite-08.sh ++++ b/test/units/testsuite-08.sh +@@ -8,6 +8,14 @@ if systemd-detect-virt -qc; then + exit 1 + fi + ++# This test requires systemd to run in the initrd as well, which is not the case ++# for mkinitrd-based initrd (Ubuntu/Debian) ++if [[ "$(systemctl show -P InitRDTimestampMonotonic)" -eq 0 ]]; then ++ echo "systemd didn't run in the initrd, skipping the test" ++ touch /skipped ++ exit 0 ++fi ++ + # We should've created a mount under /run in initrd (see the other half of the test) + # that should've survived the transition from initrd to the real system + test -d /run/initrd-mount-target diff --git a/debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch b/debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch new file mode 100644 index 00000000000..ba928cb9a6b --- /dev/null +++ b/debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch @@ -0,0 +1,103 @@ +From: Frantisek Sumsal +Date: Thu, 14 Dec 2023 16:59:21 +0100 +Subject: test: tell delv to load anchors from /etc/bind.keys explicitly + +Since [0] delv no longer does that automagically, so we have to that +explicitly with each delv invocation. + +Resolves: #30477 + +[0] https://github.com/isc-projects/bind9/commit/c144fd2871206d209ccdb916f5959a3ceab1d44c + +(cherry picked from commit 438c7cb20e83a3b88f6accc3e78d3da5e21f6db2) +--- + test/units/testsuite-75.sh | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/test/units/testsuite-75.sh b/test/units/testsuite-75.sh +index 5dc31f8..093fdf9 100755 +--- a/test/units/testsuite-75.sh ++++ b/test/units/testsuite-75.sh +@@ -20,6 +20,12 @@ run() { + "$@" |& tee "$RUN_OUT" + } + ++run_delv() { ++ # Since [0] delv no longer loads /etc/(bind/)bind.keys by default, so we ++ # have to do that explicitly for each invocation ++ run delv -a /etc/bind.keys "$@" ++} ++ + disable_ipv6() { + sysctl -w net.ipv6.conf.all.disable_ipv6=1 + } +@@ -356,15 +362,15 @@ grep -qF "unsigned.test IN MX 15 mail.unsigned.test" "$RUN_OUT" + # Check the trust chain (with and without systemd-resolved in between + # Issue: https://github.com/systemd/systemd/issues/22002 + # PR: https://github.com/systemd/systemd/pull/23289 +-run delv @ns1.unsigned.test signed.test ++run_delv @ns1.unsigned.test signed.test + grep -qF "; fully validated" "$RUN_OUT" +-run delv signed.test ++run_delv signed.test + grep -qF "; fully validated" "$RUN_OUT" + + for addr in "${DNS_ADDRESSES[@]}"; do +- run delv "@$addr" -t A mail.signed.test ++ run_delv "@$addr" -t A mail.signed.test + grep -qF "; fully validated" "$RUN_OUT" +- run delv "@$addr" -t AAAA mail.signed.test ++ run_delv "@$addr" -t AAAA mail.signed.test + grep -qF "; fully validated" "$RUN_OUT" + done + run resolvectl query mail.signed.test +@@ -402,7 +408,7 @@ grep -qF "10.0.0.123" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::123" "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" + # Check OPENPGPKEY support +-run delv -t OPENPGPKEY 5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test ++run_delv -t OPENPGPKEY 5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test + grep -qF "; fully validated" "$RUN_OUT" + run resolvectl openpgp mr.smith@signed.test + grep -qF "5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test" "$RUN_OUT" +@@ -418,11 +424,11 @@ check_domain() { + local addr + + for addr in "${DNS_ADDRESSES[@]}"; do +- run delv "@$addr" -t "$record" "$domain" ++ run_delv "@$addr" -t "$record" "$domain" + grep -qF "$message" "$RUN_OUT" + done + +- run delv -t "$record" "$domain" ++ run_delv -t "$record" "$domain" + grep -qF "$message" "$RUN_OUT" + + run resolvectl query "$domain" +@@ -458,9 +464,9 @@ grep -qE "^follow14\.final\.signed\.test\..+IN\s+NSEC\s+" "$RUN_OUT" + # Check the trust chain (with and without systemd-resolved in between + # Issue: https://github.com/systemd/systemd/issues/22002 + # PR: https://github.com/systemd/systemd/pull/23289 +-run delv @ns1.unsigned.test sub.onlinesign.test ++run_delv @ns1.unsigned.test sub.onlinesign.test + grep -qF "; fully validated" "$RUN_OUT" +-run delv sub.onlinesign.test ++run_delv sub.onlinesign.test + grep -qF "; fully validated" "$RUN_OUT" + + run dig +short sub.onlinesign.test +@@ -474,11 +480,11 @@ run resolvectl query --legend=no -t TXT onlinesign.test + grep -qF 'onlinesign.test IN TXT "hello from onlinesign"' "$RUN_OUT" + + for addr in "${DNS_ADDRESSES[@]}"; do +- run delv "@$addr" -t A dual.onlinesign.test ++ run_delv "@$addr" -t A dual.onlinesign.test + grep -qF "10.0.0.135" "$RUN_OUT" +- run delv "@$addr" -t AAAA dual.onlinesign.test ++ run_delv "@$addr" -t AAAA dual.onlinesign.test + grep -qF "fd00:dead:beef:cafe::135" "$RUN_OUT" +- run delv "@$addr" -t ANY ipv6.onlinesign.test ++ run_delv "@$addr" -t ANY ipv6.onlinesign.test + grep -qF "fd00:dead:beef:cafe::136" "$RUN_OUT" + done + run resolvectl query dual.onlinesign.test From 8f889f22c09e4da43f6f3edb803a57f9707b13e4 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sun, 31 Dec 2023 23:18:58 +0100 Subject: [PATCH 14/29] Add explicit Build-Depends on debhelper (>= 13.11.6) This ensures we have a recent enough version of dh_installsystemd that supports service files in /usr/lib/. --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index 80f3b9f9a04..8d06e4d2c3e 100644 --- a/debian/control +++ b/debian/control @@ -14,6 +14,7 @@ Vcs-Git: https://salsa.debian.org/systemd-team/systemd.git Vcs-Browser: https://salsa.debian.org/systemd-team/systemd Homepage: https://www.freedesktop.org/wiki/Software/systemd Build-Depends: debhelper-compat (= 13), + debhelper (>= 13.11.6), dh-exec, dh-package-notes, dh-sequence-installnss, From 196ed16cb339aa484795c3d627b7fa754f138f55 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 2 Jan 2024 11:10:57 +0100 Subject: [PATCH 15/29] test: deny-list TEST-13-NSPAWN The default ram size of 1024M for qemu virt is not sufficient to make the test pass reliably on Debian sid/trixie. Disable the test for now until this has been addressed in debci: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1059840 --- .../test-deny-list-TEST-13-NSPAWN.patch | 23 +++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 24 insertions(+) create mode 100644 debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch diff --git a/debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch b/debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch new file mode 100644 index 00000000000..f0a90f63b1a --- /dev/null +++ b/debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch @@ -0,0 +1,23 @@ +From: Michael Biebl +Date: Tue, 2 Jan 2024 11:09:56 +0100 +Subject: test: deny-list TEST-13-NSPAWN + +The default ram size of 1024M for qemu virt is not sufficient +to make the test pass reliably on Debian sid/trixie. +Disable the test for now until this has been addressed in debci: +https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1059840 +--- + test/TEST-13-NSPAWN/deny-list-upstream-ci | 4 ++++ + 1 file changed, 4 insertions(+) + create mode 100644 test/TEST-13-NSPAWN/deny-list-upstream-ci + +diff --git a/test/TEST-13-NSPAWN/deny-list-upstream-ci b/test/TEST-13-NSPAWN/deny-list-upstream-ci +new file mode 100644 +index 0000000..2a8a53a +--- /dev/null ++++ b/test/TEST-13-NSPAWN/deny-list-upstream-ci +@@ -0,0 +1,4 @@ ++# The default ram size of 1024M for qemu virt is not sufficient ++# to make the test pass reliably on Debian sid/trixie. ++# Disable the test for now until this has been addressed in debci: ++# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1059840 diff --git a/debian/patches/series b/debian/patches/series index de08274dfe1..2abc37a7c45 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -7,6 +7,7 @@ debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch debian/Downgrade-a-couple-of-warnings-to-debug.patch debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch debian/localectl-disable-keymap-support.patch +debian/test-deny-list-TEST-13-NSPAWN.patch test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch test-install-empty-directories-with-NO_BUILD-1.patch test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch From d6a37a58af7db6605a57669b15c1244d5a9145e9 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 2 Jan 2024 11:46:03 +0100 Subject: [PATCH 16/29] Release version 255.2-3 to unstable --- debian/changelog | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/debian/changelog b/debian/changelog index 93d49861ef8..63ddf2ccdd9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +systemd (255.2-3) sid; urgency=medium + + * Cherry-pick fixes for upstream integration tests. + Fixes TEST-07-PID1, TEST-08-INITRD (skip), TEST-26-SYSTEMCTL and + TEST-75-RESOLVED. + * Add explicit Build-Depends on debhelper (>= 13.11.6) + This ensures we have a recent enough version of dh_installsystemd that + supports service files in /usr/lib/. + * test: deny-list TEST-13-NSPAWN. + The default ram size of 1024M for qemu virt is not sufficient + to make the test pass reliably on Debian sid/trixie. + Disable the test for now until this has been addressed in debci: + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1059840 + + -- Michael Biebl Tue, 02 Jan 2024 11:44:49 +0100 + systemd (255.2-2) unstable; urgency=medium * udev: mips does not install dmi_memory_id and its rules From b17ad980ccd2f2ae3ba0a32757fcb9344fd16bd9 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 2 Jan 2024 13:31:26 +0100 Subject: [PATCH 17/29] autopkgtest: add btrfs-progs Depends to upstream suite Required by TEST-83-BTRFS and testcase_btrfs_basic from TEST-64-UDEV-STORAGE. --- debian/tests/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/tests/control b/debian/tests/control index 2a2caf23139..e80ce33a3c3 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -199,6 +199,7 @@ Depends: systemd-tests, nvme-cli, mdadm, lvm2, + btrfs-progs, Restrictions: needs-root, allow-stderr, isolation-machine Tests: boot-smoke From 38ca1d3842a8cc5c036012cc5755a2cf2a2ab9c2 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 2 Jan 2024 23:03:35 +0100 Subject: [PATCH 18/29] Revert "test: deny-list TEST-13-NSPAWN" This reverts commit df8e5367aca20e0c75c9c91f826d22d8a0f7e36d. --- .../test-deny-list-TEST-13-NSPAWN.patch | 23 ------------------- debian/patches/series | 1 - 2 files changed, 24 deletions(-) delete mode 100644 debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch diff --git a/debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch b/debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch deleted file mode 100644 index f0a90f63b1a..00000000000 --- a/debian/patches/debian/test-deny-list-TEST-13-NSPAWN.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: Michael Biebl -Date: Tue, 2 Jan 2024 11:09:56 +0100 -Subject: test: deny-list TEST-13-NSPAWN - -The default ram size of 1024M for qemu virt is not sufficient -to make the test pass reliably on Debian sid/trixie. -Disable the test for now until this has been addressed in debci: -https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1059840 ---- - test/TEST-13-NSPAWN/deny-list-upstream-ci | 4 ++++ - 1 file changed, 4 insertions(+) - create mode 100644 test/TEST-13-NSPAWN/deny-list-upstream-ci - -diff --git a/test/TEST-13-NSPAWN/deny-list-upstream-ci b/test/TEST-13-NSPAWN/deny-list-upstream-ci -new file mode 100644 -index 0000000..2a8a53a ---- /dev/null -+++ b/test/TEST-13-NSPAWN/deny-list-upstream-ci -@@ -0,0 +1,4 @@ -+# The default ram size of 1024M for qemu virt is not sufficient -+# to make the test pass reliably on Debian sid/trixie. -+# Disable the test for now until this has been addressed in debci: -+# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1059840 diff --git a/debian/patches/series b/debian/patches/series index 2abc37a7c45..de08274dfe1 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -7,7 +7,6 @@ debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch debian/Downgrade-a-couple-of-warnings-to-debug.patch debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch debian/localectl-disable-keymap-support.patch -debian/test-deny-list-TEST-13-NSPAWN.patch test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch test-install-empty-directories-with-NO_BUILD-1.patch test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch From 25ea84d284a1a2d45d82cb43644c603d679a894b Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Wed, 3 Jan 2024 00:55:54 +0100 Subject: [PATCH 19/29] autopkgtest: add multipath-tools and kpartx Depends to upstream suite Required by testcase_multipath_basic_failover from TEST-64-UDEV-STORAGE. --- debian/tests/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/tests/control b/debian/tests/control index e80ce33a3c3..ff77da87d2d 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -200,6 +200,8 @@ Depends: systemd-tests, mdadm, lvm2, btrfs-progs, + multipath-tools, + kpartx, Restrictions: needs-root, allow-stderr, isolation-machine Tests: boot-smoke From 5fc46acf1c0db9c0e3fad2076741652d743a4ca5 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 4 Jan 2024 17:28:59 +0100 Subject: [PATCH 20/29] test: install correct kpartx udev rules on Debian --- debian/patches/series | 1 + ...-correct-kpartx-udev-rules-on-Debian.patch | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 debian/patches/test-install-correct-kpartx-udev-rules-on-Debian.patch diff --git a/debian/patches/series b/debian/patches/series index de08274dfe1..3f277c76cf4 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -12,3 +12,4 @@ test-install-empty-directories-with-NO_BUILD-1.patch test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch test-flush-the-socket-once-the-triggered-unit-exits.patch +test-install-correct-kpartx-udev-rules-on-Debian.patch diff --git a/debian/patches/test-install-correct-kpartx-udev-rules-on-Debian.patch b/debian/patches/test-install-correct-kpartx-udev-rules-on-Debian.patch new file mode 100644 index 00000000000..d77a55ca467 --- /dev/null +++ b/debian/patches/test-install-correct-kpartx-udev-rules-on-Debian.patch @@ -0,0 +1,25 @@ +From: Frantisek Sumsal +Date: Wed, 3 Jan 2024 17:24:03 +0100 +Subject: test: install correct kpartx udev rules on Debian + +Resolves: #30703 +(cherry picked from commit 519f0074cf87391b17a82ea983daed6183d62fb6) +--- + test/test-functions | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index f887346..2c79a66 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -1151,7 +1151,9 @@ install_multipath() { + image_install kpartx /lib/udev/kpartx_id lsmod mpathpersist multipath multipathd partx + image_install "${ROOTLIBDIR:?}"/system/multipathd.{service,socket} + if get_bool "$LOOKS_LIKE_DEBIAN"; then +- inst_rules 56-dm-parts.rules 56-dm-mpath.rules 60-multipath.rules 68-del-part-nodes.rules 95-kpartx.rules ++ # Note: try both 60-kpartx.rules (as seen on Debian Sid with 0.9.4-7) and 90-kpartx.rules (as seen on ++ # Ubuntu Jammy with 0.8.8-1ubuntu1.22.04.4) ++ inst_rules 56-dm-parts.rules 56-dm-mpath.rules 60-kpartx.rules 60-multipath.rules 68-del-part-nodes.rules 90-kpartx.rules + else + inst_rules 11-dm-mpath.rules 11-dm-parts.rules 62-multipath.rules 66-kpartx.rules 68-del-part-nodes.rules + fi From 5e870788da372a9f3b9aea755ba5265cf73cc33d Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sat, 6 Jan 2024 16:21:46 +0100 Subject: [PATCH 21/29] Release version 255.2-4 to unstable Signed-off-by: Bardia Moshiri --- debian/changelog | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/debian/changelog b/debian/changelog index 63ddf2ccdd9..ccfdcc23cee 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +systemd (255.2-4) sid; urgency=medium + + * autopkgtest: add btrfs-progs Depends to upstream suite. + Required by TEST-83-BTRFS and testcase_btrfs_basic from + TEST-64-UDEV-STORAGE. + * Revert "test: deny-list TEST-13-NSPAWN" + This reverts commit df8e5367aca20e0c75c9c91f826d22d8a0f7e36d. + * autopkgtest: add multipath-tools and kpartx Depends to upstream suite. + Required by testcase_multipath_basic_failover from TEST-64-UDEV-STORAGE. + * test: install correct kpartx udev rules on Debian + + -- Michael Biebl Sat, 06 Jan 2024 16:21:03 +0100 + systemd (255.2-3) sid; urgency=medium * Cherry-pick fixes for upstream integration tests. From 9e167420e0e1ed05afbb6984c5872c8a4c602d9b Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 24 Jan 2024 20:00:06 +0000 Subject: [PATCH 22/29] New upstream version 255.3 --- .packit.yml | 7 + factory/etc/pam.d/system-auth | 2 +- hwdb.d/60-evdev.hwdb | 9 + hwdb.d/60-sensor.hwdb | 13 + hwdb.d/70-sound-card.hwdb | 7 + man/loginctl.xml | 29 +- man/org.freedesktop.login1.xml | 1 - man/org.freedesktop.systemd1.xml | 2 +- man/pam_systemd.xml | 3 +- man/pam_systemd_home.xml | 2 +- man/systemctl.xml | 25 +- man/systemd-analyze.xml | 11 +- man/systemd-detect-virt.xml | 7 +- man/systemd-firstboot.xml | 2 +- man/systemd-resolved.service.xml | 2 +- man/systemd-sleep.conf.xml | 32 ++- man/systemd-sysctl.service.xml | 2 +- man/systemd-tmpfiles.xml | 2 +- man/systemd-vconsole-setup.service.xml | 2 +- man/systemd.link.xml | 2 +- meson.build | 5 +- .../system/mkosi.conf.d/10-centos-fedora.conf | 1 + .../system/mkosi.conf.d/10-centos/mkosi.conf | 4 + .../10-centos/mkosi.conf.d/10-centos8.conf | 9 - .../10-centos/mkosi.conf.d/10-centos9.conf | 9 - .../system/mkosi.conf.d/10-fedora.conf | 1 - mkosi.images/system/mkosi.postinst.chroot | 12 +- modprobe.d/systemd.conf | 4 + rules.d/50-udev-default.rules.in | 2 + rules.d/99-systemd.rules.in | 2 +- shell-completion/bash/systemctl.in | 32 ++- shell-completion/bash/systemd-analyze | 2 +- src/analyze/analyze.c | 5 +- src/basic/alloc-util.h | 12 +- src/basic/fd-util.c | 59 ++-- src/basic/fd-util.h | 4 +- src/basic/macro.h | 8 +- src/basic/sigbus.c | 6 +- src/basic/strv.c | 16 ++ src/basic/strv.h | 2 + src/basic/virt.c | 35 +-- src/basic/virt.h | 1 + src/boot/efi/util.h | 4 +- src/busctl/busctl.c | 26 +- src/cgtop/cgtop.c | 4 +- src/core/execute-serialize.c | 17 +- src/core/execute.c | 4 - src/core/manager.c | 6 +- src/core/unit.c | 2 +- src/cryptenroll/cryptenroll.c | 2 +- src/firstboot/firstboot.c | 4 +- src/home/org.freedesktop.home1.conf | 4 + src/journal-remote/microhttpd-util.c | 42 +-- src/journal-remote/microhttpd-util.h | 31 ++- src/kernel-install/kernel-install.c | 37 +-- src/libsystemd/sd-bus/bus-message.c | 2 +- src/libsystemd/sd-id128/id128-util.c | 8 + src/libsystemd/sd-journal/journal-file.c | 7 +- src/libsystemd/sd-login/sd-login.c | 2 +- src/libsystemd/sd-netlink/netlink-util.c | 2 +- src/libsystemd/sd-netlink/test-netlink.c | 4 + src/login/logind-action.c | 4 +- src/login/logind-button.c | 4 + src/login/logind-dbus.c | 4 +- src/login/logind-session.c | 2 +- src/login/pam_systemd.c | 56 ++-- src/network/netdev/tuntap.c | 13 + src/network/networkd-link.c | 26 +- src/network/networkd-ndisc.c | 12 +- src/network/networkd-network.c | 4 +- src/network/networkd-queue.c | 20 +- src/network/networkd-route.c | 1 + src/nspawn/nspawn-bind-user.c | 2 +- src/partition/repart.c | 37 ++- src/pcrlock/pcrlock.c | 10 +- src/resolve/dns-type.h | 32 ++- src/resolve/resolved-dns-cache.c | 4 + src/resolve/resolved-dns-packet.c | 21 +- src/resolve/resolved-dns-transaction.c | 19 +- src/resolve/resolved-llmnr.c | 2 +- src/resolve/resolved-mdns.c | 2 +- src/shared/battery-util.c | 4 +- src/shared/discover-image.c | 10 +- src/shared/efi-loader.c | 7 +- src/shared/find-esp.c | 86 +++--- src/shared/hibernate-util.c | 16 +- src/shared/killall.c | 2 +- src/shared/tpm2-util.c | 34 ++- src/shared/utmp-wtmp.h | 3 +- src/shared/watchdog.c | 11 +- src/sleep/sleep.c | 6 +- src/storagetm/storagetm.c | 7 +- src/systemctl/systemctl-is-system-running.c | 2 +- src/systemctl/systemctl-start-special.c | 29 +- src/test/test-alloc-util.c | 4 +- src/test/test-execute.c | 8 +- src/test/test-tpm2.c | 67 ++++- src/timesync/timesyncd-manager.c | 3 +- src/udev/dmi_memory_id/dmi_memory_id.c | 11 +- src/udev/udevadm-test-builtin.c | 6 +- src/udev/udevadm-test.c | 1 + src/udev/udevadm.c | 2 +- test/TEST-24-CRYPTSETUP/test.sh | 6 +- test/TEST-64-UDEV-STORAGE/test.sh | 4 +- test/TEST-74-AUX-UTILS/test.sh | 9 + test/test-functions | 58 +++- test/test-network/systemd-networkd-tests.py | 2 +- test/units/testsuite-07.exec-context.sh | 36 ++- test/units/testsuite-07.issue-30412.sh | 1 + test/units/testsuite-17.03.sh | 4 + test/units/testsuite-17.10.sh | 13 + test/units/testsuite-58.sh | 23 ++ test/units/testsuite-64.sh | 9 +- test/units/testsuite-74.bootctl.sh | 261 ++++++++++++++++++ test/units/testsuite-75.sh | 3 + units/systemd-hibernate.service.in | 2 +- units/systemd-hybrid-sleep.service.in | 2 +- units/systemd-resolved.service.in | 2 +- .../systemd-suspend-then-hibernate.service.in | 2 +- 119 files changed, 1163 insertions(+), 469 deletions(-) delete mode 100644 mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos8.conf delete mode 100644 mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos9.conf create mode 100755 test/units/testsuite-74.bootctl.sh diff --git a/.packit.yml b/.packit.yml index b886632a95d..ada6f8b487a 100644 --- a/.packit.yml +++ b/.packit.yml @@ -16,6 +16,13 @@ upstream_tag_template: "v{version}" srpm_build_deps: [] actions: + get-current-version: + # Show the closest matching tag for the checked out revision, otherwise + # Packit tries to get the latest tag by creation date, which doesn't work + # well in the systemd-stable repo. We also need to sanitize it manually + # since "upstream_tag_template" defined above doesn't apply here. + - "bash -ec 'git describe --tags --abbrev=0 | cut -b 2-'" + post-upstream-clone: # Use the Fedora Rawhide specfile - "git clone https://src.fedoraproject.org/rpms/systemd .packit_rpm --depth=1" diff --git a/factory/etc/pam.d/system-auth b/factory/etc/pam.d/system-auth index c2d6240930f..cb4e5703616 100644 --- a/factory/etc/pam.d/system-auth +++ b/factory/etc/pam.d/system-auth @@ -13,7 +13,7 @@ account sufficient pam_unix.so account required pam_permit.so -password sufficient pam_systemd_home.so -password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok +password sufficient pam_unix.so sha512 shadow try_first_pass password required pam_deny.so -session optional pam_keyinit.so revoke diff --git a/hwdb.d/60-evdev.hwdb b/hwdb.d/60-evdev.hwdb index a9ce4e2862d..9a90420b5f1 100644 --- a/hwdb.d/60-evdev.hwdb +++ b/hwdb.d/60-evdev.hwdb @@ -237,6 +237,15 @@ evdev:name:SYNA3602:00 0911:5288 Touchpad:dmi:*svnBANGHO:pnCLOUDPRO:* EVDEV_ABS_35=52:1747:17 EVDEV_ABS_36=45:954:14 +######################################### +# Bosto +######################################### + +# Bosto BT-12HD series +evdev:input:b0003v0ED1p7821* + EVDEV_ABS_00=::2271 + EVDEV_ABS_01=::5080 + ######################################### # Dell ######################################### diff --git a/hwdb.d/60-sensor.hwdb b/hwdb.d/60-sensor.hwdb index 75efc3c1904..b002be4ece9 100644 --- a/hwdb.d/60-sensor.hwdb +++ b/hwdb.d/60-sensor.hwdb @@ -309,6 +309,10 @@ sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvrY13D_KB133.103:b sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo*:pnC3W6_AP108_4GB:* ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 +# Chuwi Ubook X (CWI535) +sensor:modalias:acpi:MXC6655*:dmi*:svnCHUWIInnovationAndTechnology*:pnUBookX:* + ACCEL_MOUNT_MATRIX=0, 0, -1; 1, 0, 0; 0, 1, 0 + ######################################### # Connect ######################################### @@ -392,6 +396,9 @@ sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0CC4:* sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0CC5:* sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0CC7:* sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0CC8:* +sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0CB2:* +sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:skuOCB4:* +sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0CB3:* ACCEL_LOCATION=base # Dell Venue 8 Pro 3845 @@ -1018,6 +1025,10 @@ sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.011:bd11/03/20 sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX98PlusII:* ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 +# Teclast X98 Pro +sensor:modalias:acpi:BMA250E*:dmi:*:svnTECLAST:pnX98Pro:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ######################################### # Thundersoft ######################################### @@ -1067,6 +1078,7 @@ sensor:modalias:acpi:BOSC0200*:dmi:*:bvrTP15-VT5.2.1.3:*:svnTrekStor*:pnSurfTabt ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, -1 sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnPrimebookC11B:* +sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnPrimebookC13:* sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnPRIMEBOOKC11B:* sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnYourbookC11B:* sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnYOURBOOKC11B:* @@ -1075,6 +1087,7 @@ sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnYOURBOOKC11B:* sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnPrimebookC11B:* sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnPRIMEBOOKC11B:* +sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnPrimebookC13:* sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnYourbookC11B:* sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnYOURBOOKC11B:* ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 diff --git a/hwdb.d/70-sound-card.hwdb b/hwdb.d/70-sound-card.hwdb index 51b235d94d0..dd5ef055835 100644 --- a/hwdb.d/70-sound-card.hwdb +++ b/hwdb.d/70-sound-card.hwdb @@ -8,6 +8,13 @@ # systemd-hwdb update # udevadm trigger +########################################################### +# Corsair +########################################################### +# Void Headsets +usb:v1B1Cp0A51* + SOUND_FORM_FACTOR=headset + ########################################################### # Steelseries ########################################################### diff --git a/man/loginctl.xml b/man/loginctl.xml index 9dd424efe2e..bf489a28506 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -71,16 +71,15 @@ show-session ID - Show properties of one or more sessions or the - manager itself. If no argument is specified, properties of the - manager will be shown. If a session ID is specified, - properties of the session are shown. By default, empty - properties are suppressed. Use to show - those too. To select specific properties to show, use - . This command is intended to be - used whenever computer-parsable output is required. Use - session-status if you are looking for - formatted human-readable output. + Show properties of one or more sessions or the manager itself. If no argument is + specified, properties of the manager will be shown. If a session ID is specified, properties of + the session are shown. Specially, if the given ID is self, the session to which + the loginctl process belongs is used. If auto, the current + session is used as with self if exists, and falls back to the current user's + graphical session. By default, empty properties are suppressed. Use to show + those too. To select specific properties to show, use . This command + is intended to be used whenever computer-parsable output is required. Use session-status + if you are looking for formatted human-readable output. @@ -358,12 +357,10 @@ - When used with - kill-session, choose which processes to - kill. Must be one of , or - to select whether to kill only the leader - process of the session or all processes of the session. If - omitted, defaults to . + When used with kill-session, choose which processes to kill. + Takes one of leader or all, to select whether to kill only + the leader process of the session or all processes of the session. If omitted, defaults to + . diff --git a/man/org.freedesktop.login1.xml b/man/org.freedesktop.login1.xml index 877bf463a07..519a6862c4b 100644 --- a/man/org.freedesktop.login1.xml +++ b/man/org.freedesktop.login1.xml @@ -253,7 +253,6 @@ node /org/freedesktop/login1 { readonly (st) ScheduledShutdown = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly b Docked = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly b LidClosed = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly b OnExternalPower = ...; diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index 277d924a30a..a1bcbba02f1 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -2612,7 +2612,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { enqueued and complete successfully. The key value pairs correspond (in lowercase) to the environment variables described in the Environment Variables Set or Propagated by the Service Manager section in - systemd.exec1. Note + systemd.exec5. Note that new key value pair may be added at any time in future versions. Existing entries will not be removed. diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index 4aff032a0dc..50f44f08eb3 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -364,8 +364,7 @@ account sufficient pam_unix.so account required pam_permit.so -password sufficient pam_systemd_home.so -password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok - +password sufficient pam_unix.so sha512 shadow try_first_pass password required pam_deny.so -session optional pam_keyinit.so revoke diff --git a/man/pam_systemd_home.xml b/man/pam_systemd_home.xml index e81fdbf28a3..dd28de1176b 100644 --- a/man/pam_systemd_home.xml +++ b/man/pam_systemd_home.xml @@ -158,7 +158,7 @@ account sufficient pam_unix.so account required pam_permit.so -password sufficient pam_systemd_home.so -password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok +password sufficient pam_unix.so sha512 shadow try_first_pass password required pam_deny.so -session optional pam_keyinit.so revoke diff --git a/man/systemctl.xml b/man/systemctl.xml index 1d791b44fd3..25b6e46c607 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -2589,9 +2589,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err - When used with the reboot command, indicate to the system's firmware to - reboot into the firmware setup interface. Note that this functionality is not available on all - systems. + When used with the reboot, poweroff, or + halt command, indicate to the system's firmware to reboot into the firmware + setup interface for the next boot. Note that this functionality is not available on all systems. + @@ -2601,10 +2602,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err - When used with the reboot command, indicate to the system's boot loader to - show the boot loader menu on the following boot. Takes a time value as parameter — indicating the - menu timeout. Pass zero in order to disable the menu timeout. Note that not all boot loaders - support this functionality. + When used with the reboot, poweroff, or + halt command, indicate to the system's boot loader to show the boot loader menu + on the following boot. Takes a time value as parameter — indicating the menu timeout. Pass zero + in order to disable the menu timeout. Note that not all boot loaders support this functionality. + @@ -2614,10 +2616,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err - When used with the reboot command, indicate to the system's boot loader to - boot into a specific boot loader entry on the following boot. Takes a boot loader entry identifier - as argument, or help in order to list available entries. Note that not all boot - loaders support this functionality. + When used with the reboot, poweroff, or + halt command, indicate to the system's boot loader to boot into a specific + boot loader entry on the following boot. Takes a boot loader entry identifier as argument, + or help in order to list available entries. Note that not all boot loaders + support this functionality. diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index 2f2873452ac..35ad8435f4f 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -136,13 +136,13 @@ systemd-analyze OPTIONS verify - FILE + FILE systemd-analyze OPTIONS security - UNIT + UNIT systemd-analyze @@ -160,7 +160,7 @@ systemd-analyze OPTIONS fdstore - UNIT + UNIT systemd-analyze @@ -833,7 +833,7 @@ alias.service:7: Unknown key name 'MysteryKey' in section 'Service', ignoring. - <command>systemd-analyze fdstore <optional><replaceable>UNIT</replaceable>...</optional></command> + <command>systemd-analyze fdstore <replaceable>UNIT</replaceable>...</command> Lists the current contents of the specified service unit's file descriptor store. This shows names, inode types, device numbers, inode numbers, paths and open modes of the open file @@ -862,7 +862,7 @@ stored sock 0:8 4213190 - socket:[4213190] ro - <command>systemd-analyze image-policy <optional><replaceable>POLICY</replaceable>…</optional></command> + <command>systemd-analyze image-policy <replaceable>POLICY</replaceable>…</command> This command analyzes the specified image policy string, as per systemd.image-policy7. The @@ -1481,6 +1481,7 @@ NR NAME SHA256 + Suppress hints and other non-essential output. diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml index cc0238dd2d8..e1caa4fc26d 100644 --- a/man/systemd-detect-virt.xml +++ b/man/systemd-detect-virt.xml @@ -139,7 +139,7 @@ apple - Apple Virtualization.framework + Apple virtualization framework @@ -147,6 +147,11 @@ LMHS SRE hypervisor + + google + Google Compute Engine + + Container openvz diff --git a/man/systemd-firstboot.xml b/man/systemd-firstboot.xml index 7145c768c21..e07e157889a 100644 --- a/man/systemd-firstboot.xml +++ b/man/systemd-firstboot.xml @@ -343,7 +343,7 @@ systemd-firstboot supports the service credentials logic as implemented by ImportCredential=/LoadCredential=/SetCredential= - (see systemd.exec1 for + (see systemd.exec5 for details). The following credentials are used when passed in: diff --git a/man/systemd-resolved.service.xml b/man/systemd-resolved.service.xml index cc98f1bd8de..85c857dc2f7 100644 --- a/man/systemd-resolved.service.xml +++ b/man/systemd-resolved.service.xml @@ -424,7 +424,7 @@ search foobar.com barbar.com systemd-resolved supports the service credentials logic as implemented by ImportCredential=/LoadCredential=/SetCredential= - (see systemd.exec1 for + (see systemd.exec5 for details). The following credentials are used when passed in: diff --git a/man/systemd-sleep.conf.xml b/man/systemd-sleep.conf.xml index ee13ce8703f..7c2adb068f5 100644 --- a/man/systemd-sleep.conf.xml +++ b/man/systemd-sleep.conf.xml @@ -84,14 +84,20 @@ suspend-then-hibernate - A low power state where the system is initially suspended (the state is stored in - RAM). If the system supports low-battery alarms (ACPI _BTP), then the system will be woken up by - the ACPI low-battery signal and hibernated (the state is then stored on disk). Also, if not - interrupted within the timespan specified by HibernateDelaySec= or the estimated - timespan until the system battery charge level goes down to 5%, then the system will be woken up by the - RTC alarm and hibernated. The estimated timespan is calculated from the change of the battery - capacity level after the time specified by SuspendEstimationSec= or when - the system is woken up from the suspend. + A low power state where the system is initially suspended (the state is stored in RAM). + When the battery level is too low (less than 5%) or a certain timespan has passed, whichever + happens first, the system is automatically woken up and then hibernated. This establishes a balance + between speed and safety. + + If the system has no battery, it would be hibernated after HibernateDelaySec= + has passed. If not set, then defaults to 2h. + + If the system has battery and HibernateDelaySec= is not set, low-battery + alarms (ACPI _BTP) are tried first for detecting battery percentage and wake up the system for hibernation. + If not available, or HibernateDelaySec= is set, the system would regularly wake + up to check the time and detect the battery percentage/discharging rate. The rate is used to + schedule the next detection. If that is also not available, SuspendEstimationSec= + is used as last resort. @@ -192,8 +198,8 @@ The amount of time the system spends in suspend mode before the system is automatically put into hibernate mode. Only used by systemd-suspend-then-hibernate.service8. - If the system has a battery, then defaults to the estimated timespan until the system battery charge level goes down to 5%. - If the system has no battery, then defaults to 2h. + Refer to suspend-then-hibernate for details on how this option interacts with + other options/system battery state. @@ -204,10 +210,10 @@ The RTC alarm will wake the system after the specified timespan to measure the system battery - capacity level and estimate battery discharging rate, which is used for estimating timespan until the system battery charge - level goes down to 5%. Only used by + capacity level and estimate battery discharging rate. Only used by systemd-suspend-then-hibernate.service8. - Defaults to 1h. + Refer to suspend-then-hibernate for details on how this option interacts with + other options/system battery state. diff --git a/man/systemd-sysctl.service.xml b/man/systemd-sysctl.service.xml index 4c63ed17230..cce32849eff 100644 --- a/man/systemd-sysctl.service.xml +++ b/man/systemd-sysctl.service.xml @@ -91,7 +91,7 @@ systemd-sysctl supports the service credentials logic as implemented by ImportCredential=/LoadCredential=/SetCredential= - (see systemd.exec1 for + (see systemd.exec5 for details). The following credentials are used when passed in: diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 95e1e2951c8..d0f8ed34e9d 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -269,7 +269,7 @@ systemd-tmpfiles supports the service credentials logic as implemented by ImportCredential=/LoadCredential=/SetCredential= - (see systemd.exec1 for + (see systemd.exec5 for details). The following credentials are used when passed in: diff --git a/man/systemd-vconsole-setup.service.xml b/man/systemd-vconsole-setup.service.xml index 90931126db8..0962dc90ad8 100644 --- a/man/systemd-vconsole-setup.service.xml +++ b/man/systemd-vconsole-setup.service.xml @@ -58,7 +58,7 @@ systemd-vconsole-setup supports the service credentials logic as implemented by ImportCredential=/LoadCredential=/SetCredential= - (see systemd.exec1 for + (see systemd.exec5 for details). The following credentials are used when passed in: diff --git a/man/systemd.link.xml b/man/systemd.link.xml index 04b424b910b..063f8e3566f 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -727,7 +727,7 @@ 60-foo.link.wol.password), and if the credential not found, then read from wol.password. See ImportCredential=/LoadCredential=/SetCredential= in - systemd.exec1 + systemd.exec5 for details. The password in the credential, must be 6 bytes in hex format with each byte separated by a colon (:) like an Ethernet MAC address, e.g., aa:bb:cc:dd:ee:ff. diff --git a/meson.build b/meson.build index 4efaa1bc96c..24f5bd2aaf0 100644 --- a/meson.build +++ b/meson.build @@ -328,6 +328,7 @@ endif basic_disabled_warnings = [ '-Wno-missing-field-initializers', '-Wno-unused-parameter', + '-Wno-nonnull-compare', ] possible_common_cc_flags = [ @@ -1804,7 +1805,9 @@ if have and efi_arch == 'x64' and cc.links(''' efi_cpu_family_alt = 'x86' endif -want_ukify = get_option('ukify').require(python_39, error_message : 'Python >= 3.9 required').allowed() +pefile = pymod.find_installation('python3', required: false, modules : ['pefile']) + +want_ukify = get_option('ukify').require(python_39 and (want_tests != 'true' or pefile.found()), error_message : 'Python >= 3.9 and pefile required').allowed() conf.set10('ENABLE_UKIFY', want_ukify) ############################################################ diff --git a/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf b/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf index 145c79bf63d..67d46432d40 100644 --- a/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf +++ b/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf @@ -14,6 +14,7 @@ Packages= integritysetup iproute iproute-tc + kernel-core libcap-ng-utils netcat openssh-server diff --git a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf index af4862d4b14..146e03a8955 100644 --- a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf @@ -2,3 +2,7 @@ [Match] Distribution=centos + +[Content] +Packages= + kernel-modules # For squashfs support diff --git a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos8.conf b/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos8.conf deleted file mode 100644 index 30643e72b36..00000000000 --- a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos8.conf +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later - -[Match] -Release=8 - -[Content] -Packages= - kernel-core-4.18.0-521.el8 - kernel-modules-4.18.0-521.el8 # For squashfs support diff --git a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos9.conf b/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos9.conf deleted file mode 100644 index a21739f2300..00000000000 --- a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf.d/10-centos9.conf +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later - -[Match] -Release=9 - -[Content] -Packages= - kernel-core - kernel-modules diff --git a/mkosi.images/system/mkosi.conf.d/10-fedora.conf b/mkosi.images/system/mkosi.conf.d/10-fedora.conf index 281e9464f62..42d0093a89c 100644 --- a/mkosi.images/system/mkosi.conf.d/10-fedora.conf +++ b/mkosi.images/system/mkosi.conf.d/10-fedora.conf @@ -8,4 +8,3 @@ Packages= btrfs-progs compsize f2fs-tools - kernel-core diff --git a/mkosi.images/system/mkosi.postinst.chroot b/mkosi.images/system/mkosi.postinst.chroot index e0728de2798..0cb9b9cf677 100755 --- a/mkosi.images/system/mkosi.postinst.chroot +++ b/mkosi.images/system/mkosi.postinst.chroot @@ -65,9 +65,17 @@ if [ -n "$IMAGE_VERSION" ] ; then fi if command -v authselect >/dev/null; then - authselect select minimal + # authselect 1.5.0 renamed the minimal profile to the local profile without keeping backwards compat so + # let's use the new name if it exists. + if [ -d /usr/share/authselect/default/local ]; then + PROFILE=local + else + PROFILE=minimal + fi + + authselect select "$PROFILE" - if authselect list-features minimal | grep -q "with-homed"; then + if authselect list-features "$PROFILE" | grep -q "with-homed"; then authselect enable-feature with-homed fi fi diff --git a/modprobe.d/systemd.conf b/modprobe.d/systemd.conf index 652254155c2..e6499a0d612 100644 --- a/modprobe.d/systemd.conf +++ b/modprobe.d/systemd.conf @@ -18,3 +18,7 @@ options bonding max_bonds=0 # Do the same for dummy0. options dummy numdummies=0 + +# Do the same for ifb0. + +options ifb numifbs=0 diff --git a/rules.d/50-udev-default.rules.in b/rules.d/50-udev-default.rules.in index 10234fd9e0b..af4f5947916 100644 --- a/rules.d/50-udev-default.rules.in +++ b/rules.d/50-udev-default.rules.in @@ -14,6 +14,8 @@ SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio- SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc" SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100" +SUBSYSTEM=="hidraw", IMPORT{builtin}="hwdb" + SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}" diff --git a/rules.d/99-systemd.rules.in b/rules.d/99-systemd.rules.in index 455a2368eb7..a99eab96488 100644 --- a/rules.d/99-systemd.rules.in +++ b/rules.d/99-systemd.rules.in @@ -73,7 +73,7 @@ ACTION=="add", SUBSYSTEM=="net", KERNEL!="lo", RUN+="{{LIBEXECDIR}}/systemd-sysc # Pull in backlight save/restore for all backlight devices and # keyboard backlights SUBSYSTEM=="backlight", TAG+="systemd", IMPORT{builtin}="path_id", ENV{SYSTEMD_WANTS}+="systemd-backlight@backlight:$name.service" -SUBSYSTEM=="leds", KERNEL=="*kbd_backlight", TAG+="systemd", IMPORT{builtin}="path_id", ENV{SYSTEMD_WANTS}+="systemd-backlight@leds:$name.service" +SUBSYSTEM=="leds", KERNEL=="*kbd_backlight*", TAG+="systemd", IMPORT{builtin}="path_id", ENV{SYSTEMD_WANTS}+="systemd-backlight@leds:$name.service" {% endif %} # Pull in rfkill save/restore for all rfkill devices diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in index 03c3b701504..5c444b7fa4a 100644 --- a/shell-completion/bash/systemctl.in +++ b/shell-completion/bash/systemctl.in @@ -62,6 +62,8 @@ __get_template_names () { __systemctl $1 list-unit-files "$2*" \ | { while read -r a b; do [[ $a =~ @\. ]] && echo " ${a%%@.*}@"; done; }; } __get_active_units () { __systemctl $1 list-units "$2*" \ | { while read -r a b; do echo " $a"; done; }; } +__get_active_services() { __systemctl $1 list-units "$2*.service" \ + | { while read -r a b; do echo " $a"; done; }; } __get_not_masked_unit_files() { # filter out masked, not-found, or template units. @@ -231,12 +233,15 @@ _systemctl () { list-timers list-units list-unit-files poweroff reboot rescue show-environment suspend get-default is-system-running preset-all list-automounts list-paths' - [FILE]='link switch-root bind mount-image' + [FILE]='link switch-root' [TARGETS]='set-default' [MACHINES]='list-machines' [LOG_LEVEL]='log-level' [LOG_TARGET]='log-target' + [SERVICE_LOG_LEVEL]='service-log-level' + [SERVICE_LOG_TARGET]='service-log-target' [SERVICE_WATCHDOGS]='service-watchdogs' + [MOUNT]='bind mount-image' ) for ((i=0; i < COMP_CWORD; i++)); do @@ -365,8 +370,33 @@ _systemctl () { comps='debug info notice warning err crit alert emerg' elif __contains_word "$verb" ${VERBS[LOG_TARGET]}; then comps='console journal kmsg journal-or-kmsg null' + elif __contains_word "$verb" ${VERBS[SERVICE_LOG_LEVEL]}; then + if __contains_word "$prev" ${VERBS[SERVICE_LOG_LEVEL]}; then + comps=$( __get_all_unit_files $mode "$cur" ) + elif __contains_word "$prev" debug info notice warning err crit alert emerg; then + return 0 + else + comps='debug info notice warning err crit alert emerg' + fi + elif __contains_word "$verb" ${VERBS[SERVICE_LOG_TARGET]}; then + if __contains_word "$prev" ${VERBS[SERVICE_LOG_TARGET]}; then + comps=$( __get_all_unit_files $mode "$cur" ) + elif __contains_word "$prev" console journal kmsg journal-or-kmsg null; then + return 0 + else + comps='console journal kmsg journal-or-kmsg null' + fi elif __contains_word "$verb" ${VERBS[SERVICE_WATCHDOGS]}; then comps='on off' + elif __contains_word "$verb" ${VERBS[MOUNT]}; then + if __contains_word "$prev" ${VERBS[MOUNT]}; then + comps=$( __get_active_services $mode "$cur" ) + elif [[ "$prev" =~ .service ]]; then + comps=$( compgen -A file -- "$cur" ) + compopt -o filenames + else + return 0 + fi fi COMPREPLY=( $(compgen -o filenames -W '$comps' -- "$cur_orig") ) diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze index 8ecf9935715..1fde67218b9 100644 --- a/shell-completion/bash/systemd-analyze +++ b/shell-completion/bash/systemd-analyze @@ -57,7 +57,7 @@ _systemd_analyze() { local -A OPTS=( [STANDALONE]='-h --help --version --system --user --global --order --require --no-pager - --man=no --generators=yes --quiet' + --man=no --generators=yes -q --quiet' [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern --root' ) diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index d2be144f4f4..021de65bdbf 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -217,7 +217,7 @@ static int help(int argc, char *argv[], void *userdata) { " dot [UNIT...] Output dependency graph in %s format\n" " dump [PATTERN...] Output state serialization of service\n" " manager\n" - " cat-config Show configuration file and drop-ins\n" + " cat-config NAME|PATH... Show configuration file and drop-ins\n" " unit-files List files and symlinks for units\n" " unit-paths List load directories for units\n" " exit-status [STATUS...] List exit status definitions\n" @@ -236,6 +236,7 @@ static int help(int argc, char *argv[], void *userdata) { " inspect-elf FILE... Parse and print ELF package metadata\n" " malloc [D-BUS SERVICE...] Dump malloc stats of a D-Bus service\n" " fdstore SERVICE... Show file descriptor store contents of service\n" + " image-policy POLICY... Analyze image policy string\n" " pcrs [PCR...] Show TPM2 PCRs and their names\n" " srk > FILE Write TPM2 SRK to stdout\n" "\nOptions:\n" @@ -360,7 +361,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hH:M:U:", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "hH:M:U:q", options, NULL)) >= 0) switch (c) { case 'h': diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index 4f86334d7d4..136d2b3e687 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -20,7 +20,7 @@ typedef void* (*mfree_func_t)(void *p); * proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */ #define ALLOCA_MAX (4U*1024U*1024U) -#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) +#define new(t, n) ((t*) malloc_multiply((n), sizeof(t))) #define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t))) @@ -45,9 +45,9 @@ typedef void* (*mfree_func_t)(void *p); (t*) alloca0((sizeof(t)*_n_)); \ }) -#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) +#define newdup(t, p, n) ((t*) memdup_multiply(p, (n), sizeof(t))) -#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n))) +#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, (n), sizeof(t))) #define malloc0(n) (calloc(1, (n) ?: 1)) @@ -112,7 +112,7 @@ static inline bool size_multiply_overflow(size_t size, size_t need) { return _unlikely_(need != 0 && size > (SIZE_MAX / need)); } -_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) { +_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t need, size_t size) { if (size_multiply_overflow(size, need)) return NULL; @@ -128,7 +128,7 @@ _alloc_(2, 3) static inline void *reallocarray(void *p, size_t need, size_t size } #endif -_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) { +_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t need, size_t size) { if (size_multiply_overflow(size, need)) return NULL; @@ -137,7 +137,7 @@ _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, si /* Note that we can't decorate this function with _alloc_() since the returned memory area is one byte larger * than the product of its parameters. */ -static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) { +static inline void *memdup_suffix0_multiply(const void *p, size_t need, size_t size) { if (size_multiply_overflow(size, need)) return NULL; diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 0690bcd8300..fa3fc770937 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -92,22 +92,22 @@ void safe_close_pair(int p[static 2]) { p[1] = safe_close(p[1]); } -void close_many(const int fds[], size_t n_fd) { - assert(fds || n_fd <= 0); +void close_many(const int fds[], size_t n_fds) { + assert(fds || n_fds == 0); - for (size_t i = 0; i < n_fd; i++) - safe_close(fds[i]); + FOREACH_ARRAY(fd, fds, n_fds) + safe_close(*fd); } -void close_many_unset(int fds[], size_t n_fd) { - assert(fds || n_fd <= 0); +void close_many_unset(int fds[], size_t n_fds) { + assert(fds || n_fds == 0); - for (size_t i = 0; i < n_fd; i++) - fds[i] = safe_close(fds[i]); + FOREACH_ARRAY(fd, fds, n_fds) + *fd = safe_close(*fd); } void close_many_and_free(int *fds, size_t n_fds) { - assert(fds || n_fds <= 0); + assert(fds || n_fds == 0); close_many(fds, n_fds); free(fds); @@ -187,32 +187,32 @@ int fd_cloexec(int fd, bool cloexec) { } int fd_cloexec_many(const int fds[], size_t n_fds, bool cloexec) { - int ret = 0, r; + int r = 0; - assert(n_fds == 0 || fds); + assert(fds || n_fds == 0); - for (size_t i = 0; i < n_fds; i++) { - if (fds[i] < 0) /* Skip gracefully over already invalidated fds */ + FOREACH_ARRAY(fd, fds, n_fds) { + if (*fd < 0) /* Skip gracefully over already invalidated fds */ continue; - r = fd_cloexec(fds[i], cloexec); - if (r < 0 && ret >= 0) /* Continue going, but return first error */ - ret = r; - else - ret = 1; /* report if we did anything */ + RET_GATHER(r, fd_cloexec(*fd, cloexec)); + + if (r >= 0) + r = 1; /* report if we did anything */ } - return ret; + return r; } -static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) { - assert(n_fdset == 0 || fdset); +static bool fd_in_set(int fd, const int fds[], size_t n_fds) { + assert(fd >= 0); + assert(fds || n_fds == 0); - for (size_t i = 0; i < n_fdset; i++) { - if (fdset[i] < 0) + FOREACH_ARRAY(i, fds, n_fds) { + if (*i < 0) continue; - if (fdset[i] == fd) + if (*i == fd) return true; } @@ -243,7 +243,7 @@ int get_max_fd(void) { static int close_all_fds_frugal(const int except[], size_t n_except) { int max_fd, r = 0; - assert(n_except == 0 || except); + assert(except || n_except == 0); /* This is the inner fallback core of close_all_fds(). This never calls malloc() or opendir() or so * and hence is safe to be called in signal handler context. Most users should call close_all_fds(), @@ -258,8 +258,7 @@ static int close_all_fds_frugal(const int except[], size_t n_except) { * spin the CPU for a long time. */ if (max_fd > MAX_FD_LOOP_LIMIT) return log_debug_errno(SYNTHETIC_ERRNO(EPERM), - "Refusing to loop over %d potential fds.", - max_fd); + "Refusing to loop over %d potential fds.", max_fd); for (int fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -EBADF) { int q; @@ -268,8 +267,8 @@ static int close_all_fds_frugal(const int except[], size_t n_except) { continue; q = close_nointr(fd); - if (q < 0 && q != -EBADF && r >= 0) - r = q; + if (q != -EBADF) + RET_GATHER(r, q); } return r; @@ -598,7 +597,7 @@ int move_fd(int from, int to, int cloexec) { if (fl < 0) return -errno; - cloexec = !!(fl & FD_CLOEXEC); + cloexec = FLAGS_SET(fl, FD_CLOEXEC); } r = dup3(from, to, cloexec ? O_CLOEXEC : 0); diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index 5061e32196a..d3e91921f3c 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -32,8 +32,8 @@ static inline int safe_close_above_stdio(int fd) { return safe_close(fd); } -void close_many(const int fds[], size_t n_fd); -void close_many_unset(int fds[], size_t n_fd); +void close_many(const int fds[], size_t n_fds); +void close_many_unset(int fds[], size_t n_fds); void close_many_and_free(int *fds, size_t n_fds); int fclose_nointr(FILE *f); diff --git a/src/basic/macro.h b/src/basic/macro.h index d3eb980abd3..d63aa816ccb 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -383,10 +383,10 @@ assert_cc(sizeof(dummy_t) == 0); /* Iterate through each variadic arg. All must be the same type as 'entry' or must be implicitly * convertible. The iteration variable 'entry' must already be defined. */ #define VA_ARGS_FOREACH(entry, ...) \ - _VA_ARGS_FOREACH(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), ##__VA_ARGS__) -#define _VA_ARGS_FOREACH(entry, _entries_, _current_, ...) \ - for (typeof(entry) _entries_[] = { __VA_ARGS__ }, *_current_ = _entries_; \ - ((long)(_current_ - _entries_) < (long)ELEMENTSOF(_entries_)) && ({ entry = *_current_; true; }); \ + _VA_ARGS_FOREACH(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), UNIQ_T(_va_sentinel_, UNIQ), ##__VA_ARGS__) +#define _VA_ARGS_FOREACH(entry, _entries_, _current_, _va_sentinel_, ...) \ + for (typeof(entry) _va_sentinel_[1] = {}, _entries_[] = { __VA_ARGS__ __VA_OPT__(,) _va_sentinel_[0] }, *_current_ = _entries_; \ + ((long)(_current_ - _entries_) < (long)(ELEMENTSOF(_entries_) - 1)) && ({ entry = *_current_; true; }); \ _current_++) #include "log.h" diff --git a/src/basic/sigbus.c b/src/basic/sigbus.c index 7e5a493f6b0..47ab0b81d88 100644 --- a/src/basic/sigbus.c +++ b/src/basic/sigbus.c @@ -40,14 +40,14 @@ static void sigbus_push(void *addr) { } /* If we can't, make sure the queue size is out of bounds, to - * mark it as overflow */ + * mark it as overflowed */ for (;;) { sig_atomic_t c; __atomic_thread_fence(__ATOMIC_SEQ_CST); c = n_sigbus_queue; - if (c > SIGBUS_QUEUE_MAX) /* already overflow */ + if (c > SIGBUS_QUEUE_MAX) /* already overflowed */ return; /* OK if we clobber c here, since we either immediately return @@ -70,7 +70,7 @@ int sigbus_pop(void **ret) { if (_likely_(c == 0)) return 0; - if (_unlikely_(c >= SIGBUS_QUEUE_MAX)) + if (_unlikely_(c > SIGBUS_QUEUE_MAX)) return -EOVERFLOW; for (u = 0; u < SIGBUS_QUEUE_MAX; u++) { diff --git a/src/basic/strv.c b/src/basic/strv.c index c2109d35bc2..1065e1bcdef 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -123,6 +123,22 @@ char** strv_copy_n(char * const *l, size_t m) { return TAKE_PTR(result); } +int strv_copy_unless_empty(char * const *l, char ***ret) { + assert(ret); + + if (strv_isempty(l)) { + *ret = NULL; + return 0; + } + + char **copy = strv_copy(l); + if (!copy) + return -ENOMEM; + + *ret = TAKE_PTR(copy); + return 1; +} + size_t strv_length(char * const *l) { size_t n = 0; diff --git a/src/basic/strv.h b/src/basic/strv.h index fec26167339..03089d54988 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -38,6 +38,8 @@ char** strv_copy_n(char * const *l, size_t n); static inline char** strv_copy(char * const *l) { return strv_copy_n(l, SIZE_MAX); } +int strv_copy_unless_empty(char * const *l, char ***ret); + size_t strv_length(char * const *l) _pure_; int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates); diff --git a/src/basic/virt.c b/src/basic/virt.c index a0b6fbcd658..e6c95fdae73 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -53,6 +53,7 @@ static Virtualization detect_vm_cpuid(void) { { "ACRNACRNACRN", VIRTUALIZATION_ACRN }, /* https://www.lockheedmartin.com/en-us/products/Hardened-Security-for-Intel-Processors.html */ { "SRESRESRESRE", VIRTUALIZATION_SRE }, + { "Apple VZ", VIRTUALIZATION_APPLE }, }; uint32_t eax, ebx, ecx, edx; @@ -168,22 +169,23 @@ static Virtualization detect_vm_dmi_vendor(void) { const char *vendor; Virtualization id; } dmi_vendor_table[] = { - { "KVM", VIRTUALIZATION_KVM }, - { "OpenStack", VIRTUALIZATION_KVM }, /* Detect OpenStack instance as KVM in non x86 architecture */ - { "KubeVirt", VIRTUALIZATION_KVM }, /* Detect KubeVirt instance as KVM in non x86 architecture */ - { "Amazon EC2", VIRTUALIZATION_AMAZON }, - { "QEMU", VIRTUALIZATION_QEMU }, - { "VMware", VIRTUALIZATION_VMWARE }, /* https://kb.vmware.com/s/article/1009458 */ - { "VMW", VIRTUALIZATION_VMWARE }, - { "innotek GmbH", VIRTUALIZATION_ORACLE }, - { "VirtualBox", VIRTUALIZATION_ORACLE }, - { "Xen", VIRTUALIZATION_XEN }, - { "Bochs", VIRTUALIZATION_BOCHS }, - { "Parallels", VIRTUALIZATION_PARALLELS }, + { "KVM", VIRTUALIZATION_KVM }, + { "OpenStack", VIRTUALIZATION_KVM }, /* Detect OpenStack instance as KVM in non x86 architecture */ + { "KubeVirt", VIRTUALIZATION_KVM }, /* Detect KubeVirt instance as KVM in non x86 architecture */ + { "Amazon EC2", VIRTUALIZATION_AMAZON }, + { "QEMU", VIRTUALIZATION_QEMU }, + { "VMware", VIRTUALIZATION_VMWARE }, /* https://kb.vmware.com/s/article/1009458 */ + { "VMW", VIRTUALIZATION_VMWARE }, + { "innotek GmbH", VIRTUALIZATION_ORACLE }, + { "VirtualBox", VIRTUALIZATION_ORACLE }, + { "Xen", VIRTUALIZATION_XEN }, + { "Bochs", VIRTUALIZATION_BOCHS }, + { "Parallels", VIRTUALIZATION_PARALLELS }, /* https://wiki.freebsd.org/bhyve */ - { "BHYVE", VIRTUALIZATION_BHYVE }, - { "Hyper-V", VIRTUALIZATION_MICROSOFT }, - { "Apple Virtualization", VIRTUALIZATION_APPLE }, + { "BHYVE", VIRTUALIZATION_BHYVE }, + { "Hyper-V", VIRTUALIZATION_MICROSOFT }, + { "Apple Virtualization", VIRTUALIZATION_APPLE }, + { "Google Compute Engine", VIRTUALIZATION_GOOGLE }, /* https://cloud.google.com/run/docs/container-contract#sandbox */ }; int r; @@ -1000,7 +1002,7 @@ static bool real_has_cpu_with_flag(const char *flag) { return true; } - if (__get_cpuid(7, &eax, &ebx, &ecx, &edx)) { + if (__get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx)) { if (given_flag_in_set(flag, leaf7_ebx, ELEMENTSOF(leaf7_ebx), ebx)) return true; } @@ -1049,6 +1051,7 @@ static const char *const virtualization_table[_VIRTUALIZATION_MAX] = { [VIRTUALIZATION_POWERVM] = "powervm", [VIRTUALIZATION_APPLE] = "apple", [VIRTUALIZATION_SRE] = "sre", + [VIRTUALIZATION_GOOGLE] = "google", [VIRTUALIZATION_VM_OTHER] = "vm-other", [VIRTUALIZATION_SYSTEMD_NSPAWN] = "systemd-nspawn", diff --git a/src/basic/virt.h b/src/basic/virt.h index d49f3237e81..dea39e4e763 100644 --- a/src/basic/virt.h +++ b/src/basic/virt.h @@ -27,6 +27,7 @@ typedef enum Virtualization { VIRTUALIZATION_POWERVM, VIRTUALIZATION_APPLE, VIRTUALIZATION_SRE, + VIRTUALIZATION_GOOGLE, VIRTUALIZATION_VM_OTHER, VIRTUALIZATION_VM_LAST = VIRTUALIZATION_VM_OTHER, diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index aef831d1327..6e15a8b85dc 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -36,7 +36,7 @@ static inline void *xmalloc(size_t size) { } _malloc_ _alloc_(1, 2) _returns_nonnull_ _warn_unused_result_ -static inline void *xmalloc_multiply(size_t size, size_t n) { +static inline void *xmalloc_multiply(size_t n, size_t size) { assert_se(!__builtin_mul_overflow(size, n, &size)); return xmalloc(size); } @@ -57,7 +57,7 @@ static inline void* xmemdup(const void *p, size_t l) { return memcpy(xmalloc(l), p, l); } -#define xnew(type, n) ((type *) xmalloc_multiply(sizeof(type), (n))) +#define xnew(type, n) ((type *) xmalloc_multiply((n), sizeof(type))) typedef struct { EFI_PHYSICAL_ADDRESS addr; diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 9f82198f2f1..39d22f29127 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -1320,24 +1320,24 @@ static int monitor(int argc, char **argv, int (*dump)(sd_bus_message *m, FILE *f if (r < 0) return log_error_errno(r, "Failed to process bus: %m"); - if (!is_monitor) { - const char *name; + if (m) { + if (!is_monitor) { + const char *name; - /* wait until we lose our unique name */ - if (sd_bus_message_is_signal(m, "org.freedesktop.DBus", "NameLost") <= 0) - continue; + /* wait until we lose our unique name */ + if (sd_bus_message_is_signal(m, "org.freedesktop.DBus", "NameLost") <= 0) + continue; - r = sd_bus_message_read(m, "s", &name); - if (r < 0) - return bus_log_parse_error(r); + r = sd_bus_message_read(m, "s", &name); + if (r < 0) + return bus_log_parse_error(r); - if (streq(name, unique_name)) - is_monitor = true; + if (streq(name, unique_name)) + is_monitor = true; - continue; - } + continue; + } - if (m) { dump(m, stdout); fflush(stdout); diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index e34da7cf728..ca514554408 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -310,9 +310,9 @@ static int process( if (all_unified) { while (!isempty(l)) { - if (sscanf(l, "rbytes=%" SCNu64, &k)) + if (sscanf(l, "rbytes=%" SCNu64, &k) == 1) rd += k; - else if (sscanf(l, "wbytes=%" SCNu64, &k)) + else if (sscanf(l, "wbytes=%" SCNu64, &k) == 1) wr += k; l += strcspn(l, WHITESPACE); diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c index 6c62bdf7c5b..b1e716e8cc3 100644 --- a/src/core/execute-serialize.c +++ b/src/core/execute-serialize.c @@ -1931,7 +1931,7 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) { _cleanup_free_ char *path_escaped = NULL; - path_escaped = shell_escape(i->path, ":"); + path_escaped = shell_escape(i->path, ":" WHITESPACE); if (!path_escaped) return log_oom_debug(); @@ -1944,7 +1944,7 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { STRV_FOREACH(d, i->symlinks) { _cleanup_free_ char *link_escaped = NULL; - link_escaped = shell_escape(*d, ":"); + link_escaped = shell_escape(*d, ":" WHITESPACE); if (!link_escaped) return log_oom_debug(); @@ -2263,11 +2263,11 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) { _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL; - src_escaped = shell_escape(mount->source, ":"); + src_escaped = shell_escape(mount->source, ":" WHITESPACE); if (!src_escaped) return log_oom_debug(); - dst_escaped = shell_escape(mount->destination, ":"); + dst_escaped = shell_escape(mount->destination, ":" WHITESPACE); if (!dst_escaped) return log_oom_debug(); @@ -2454,11 +2454,11 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) { _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL; - source_escaped = shell_escape(mount->source, " "); + source_escaped = shell_escape(mount->source, WHITESPACE); if (!source_escaped) return log_oom_debug(); - dest_escaped = shell_escape(mount->destination, " "); + dest_escaped = shell_escape(mount->destination, WHITESPACE); if (!dest_escaped) return log_oom_debug(); @@ -2495,7 +2495,7 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) { _cleanup_free_ char *s = NULL, *source_escaped = NULL; - source_escaped = shell_escape(mount->source, ":"); + source_escaped = shell_escape(mount->source, ":" WHITESPACE); if (!source_escaped) return log_oom_debug(); @@ -2846,7 +2846,8 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL; const char *p; - r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_RETAIN_ESCAPE); + /* Use EXTRACT_UNESCAPE_RELAX here, as we unescape the colons in subsequent calls */ + r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX); if (r < 0) return r; if (r == 0) diff --git a/src/core/execute.c b/src/core/execute.c index ef0bf886874..8dbdfcf3691 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -382,10 +382,6 @@ int exec_spawn(Unit *unit, if (r < 0) return log_unit_error_errno(unit, r, "Failed to load environment files: %m"); - /* Fork with up-to-date SELinux label database, so the child inherits the up-to-date db - and, until the next SELinux policy changes, we save further reloads in future children. */ - mac_selinux_maybe_reload(); - /* We won't know the real executable path until we create the mount namespace in the child, but we want to log from the parent, so we use the possibly inaccurate path here. */ log_command_line(unit, "About to execute", command->path, command->argv); diff --git a/src/core/manager.c b/src/core/manager.c index 37e4f709500..88eebfc626b 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1016,9 +1016,9 @@ int manager_new(RuntimeScope runtime_scope, ManagerTestRunFlags test_run_flags, m->executor_fd = open(SYSTEMD_EXECUTOR_BINARY_PATH, O_CLOEXEC|O_PATH); if (m->executor_fd < 0) - return log_warning_errno(errno, - "Failed to open executor binary '%s': %m", - SYSTEMD_EXECUTOR_BINARY_PATH); + return log_emergency_errno(errno, + "Failed to open executor binary '%s': %m", + SYSTEMD_EXECUTOR_BINARY_PATH); } else if (!FLAGS_SET(test_run_flags, MANAGER_TEST_DONT_OPEN_EXECUTOR)) { _cleanup_free_ char *self_exe = NULL, *executor_path = NULL; _cleanup_close_ int self_dir_fd = -EBADF; diff --git a/src/core/unit.c b/src/core/unit.c index 41f3bdb226a..2fc9f5ad2d3 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -6605,7 +6605,7 @@ int activation_details_append_pair(ActivationDetails *details, char ***strv) { return r; } - if (ACTIVATION_DETAILS_VTABLE(details)->append_env) { + if (ACTIVATION_DETAILS_VTABLE(details)->append_pair) { r = ACTIVATION_DETAILS_VTABLE(details)->append_pair(details, strv); if (r < 0) return r; diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index 5a7f7c3bff7..be6892bbd30 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -488,7 +488,7 @@ static int parse_argv(int argc, char *argv[]) { if (n > INT_MAX) return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Slot index out of range: %u", n); - a = reallocarray(arg_wipe_slots, sizeof(int), arg_n_wipe_slots + 1); + a = reallocarray(arg_wipe_slots, arg_n_wipe_slots + 1, sizeof(int)); if (!a) return log_oom(); diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index 17d344e9803..28b2083a1b7 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -1239,11 +1239,13 @@ static int help(void) { " --timezone=TIMEZONE Set timezone\n" " --hostname=NAME Set hostname\n" " --setup-machine-id Set a random machine ID\n" - " --machine-ID=ID Set specified machine ID\n" + " --machine-id=ID Set specified machine ID\n" " --root-password=PASSWORD Set root password from plaintext password\n" " --root-password-file=FILE Set root password from file\n" " --root-password-hashed=HASH Set root password from hashed password\n" " --root-shell=SHELL Set root shell\n" + " --kernel-command-line=CMDLINE\n" + " Set kernel command line\n" " --prompt-locale Prompt the user for locale settings\n" " --prompt-keymap Prompt the user for keymap settings\n" " --prompt-timezone Prompt the user for timezone\n" diff --git a/src/home/org.freedesktop.home1.conf b/src/home/org.freedesktop.home1.conf index de1fb93cc0d..5af1a686074 100644 --- a/src/home/org.freedesktop.home1.conf +++ b/src/home/org.freedesktop.home1.conf @@ -125,6 +125,10 @@ send_interface="org.freedesktop.home1.Manager" send_member="LockAllHomes"/> + + diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c index 9e6c36f87d1..c1e35b7ed34 100644 --- a/src/journal-remote/microhttpd-util.c +++ b/src/journal-remote/microhttpd-util.c @@ -25,11 +25,13 @@ void microhttpd_logger(void *arg, const char *fmt, va_list ap) { REENABLE_WARNING; } -static int mhd_respond_internal(struct MHD_Connection *connection, - enum MHD_RequestTerminationCode code, - const char *buffer, - size_t size, - enum MHD_ResponseMemoryMode mode) { +int mhd_respond_internal( + struct MHD_Connection *connection, + enum MHD_RequestTerminationCode code, + const char *buffer, + size_t size, + enum MHD_ResponseMemoryMode mode) { + assert(connection); _cleanup_(MHD_destroy_responsep) struct MHD_Response *response @@ -43,29 +45,16 @@ static int mhd_respond_internal(struct MHD_Connection *connection, return MHD_queue_response(connection, code, response); } -int mhd_respond(struct MHD_Connection *connection, - enum MHD_RequestTerminationCode code, - const char *message) { - - const char *fmt; - - fmt = strjoina(message, "\n"); - - return mhd_respond_internal(connection, code, - fmt, strlen(message) + 1, - MHD_RESPMEM_PERSISTENT); -} - int mhd_respond_oom(struct MHD_Connection *connection) { - return mhd_respond(connection, MHD_HTTP_SERVICE_UNAVAILABLE, "Out of memory."); + return mhd_respond(connection, MHD_HTTP_SERVICE_UNAVAILABLE, "Out of memory."); } -int mhd_respondf(struct MHD_Connection *connection, - int error, - enum MHD_RequestTerminationCode code, - const char *format, ...) { +int mhd_respondf_internal( + struct MHD_Connection *connection, + int error, + enum MHD_RequestTerminationCode code, + const char *format, ...) { - const char *fmt; char *m; int r; va_list ap; @@ -76,11 +65,8 @@ int mhd_respondf(struct MHD_Connection *connection, if (error < 0) error = -error; errno = -error; - fmt = strjoina(format, "\n"); va_start(ap, format); - DISABLE_WARNING_FORMAT_NONLITERAL; - r = vasprintf(&m, fmt, ap); - REENABLE_WARNING; + r = vasprintf(&m, format, ap); va_end(ap); if (r < 0) diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h index 140e7f62235..309c39aab08 100644 --- a/src/journal-remote/microhttpd-util.h +++ b/src/journal-remote/microhttpd-util.h @@ -62,17 +62,34 @@ void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0); /* respond_oom() must be usable with return, hence this form. */ #define respond_oom(connection) log_oom(), mhd_respond_oom(connection) -int mhd_respondf(struct MHD_Connection *connection, - int error, - enum MHD_RequestTerminationCode code, - const char *format, ...) _printf_(4,5); - -int mhd_respond(struct MHD_Connection *connection, +int mhd_respond_internal( + struct MHD_Connection *connection, enum MHD_RequestTerminationCode code, - const char *message); + const char *buffer, + size_t size, + enum MHD_ResponseMemoryMode mode); + +#define mhd_respond(connection, code, message) \ + mhd_respond_internal( \ + connection, code, \ + message "\n", \ + strlen(message) + 1, \ + MHD_RESPMEM_PERSISTENT) int mhd_respond_oom(struct MHD_Connection *connection); +int mhd_respondf_internal( + struct MHD_Connection *connection, + int error, + enum MHD_RequestTerminationCode code, + const char *format, ...) _printf_(4,5); + +#define mhd_respondf(connection, error, code, format, ...) \ + mhd_respondf_internal( \ + connection, error, code, \ + format "\n", \ + ##__VA_ARGS__) + int check_permissions(struct MHD_Connection *connection, int *code, char **hostname); /* Set gnutls internal logging function to a callback which uses our diff --git a/src/kernel-install/kernel-install.c b/src/kernel-install/kernel-install.c index 45f0c1e7a8c..14ae1a84c5d 100644 --- a/src/kernel-install/kernel-install.c +++ b/src/kernel-install/kernel-install.c @@ -132,9 +132,10 @@ static int context_copy(const Context *source, Context *ret) { assert(source); assert(ret); + assert(source->rfd >= 0 || source->rfd == AT_FDCWD); _cleanup_(context_done) Context copy = (Context) { - .rfd = -EBADF, + .rfd = AT_FDCWD, .action = source->action, .machine_id = source->machine_id, .machine_id_is_random = source->machine_id_is_random, @@ -143,9 +144,11 @@ static int context_copy(const Context *source, Context *ret) { .entry_token_type = source->entry_token_type, }; - copy.rfd = fd_reopen(source->rfd, O_CLOEXEC|O_DIRECTORY|O_PATH); - if (copy.rfd < 0) - return copy.rfd; + if (source->rfd >= 0) { + copy.rfd = fd_reopen(source->rfd, O_CLOEXEC|O_DIRECTORY|O_PATH); + if (copy.rfd < 0) + return copy.rfd; + } r = strdup_or_null(source->layout_other, ©.layout_other); if (r < 0) @@ -168,9 +171,9 @@ static int context_copy(const Context *source, Context *ret) { r = strdup_or_null(source->kernel, ©.kernel); if (r < 0) return r; - copy.initrds = strv_copy(source->initrds); - if (!copy.initrds) - return -ENOMEM; + r = strv_copy_unless_empty(source->initrds, ©.initrds); + if (r < 0) + return r; r = strdup_or_null(source->initrd_generator, ©.initrd_generator); if (r < 0) return r; @@ -180,15 +183,15 @@ static int context_copy(const Context *source, Context *ret) { r = strdup_or_null(source->staging_area, ©.staging_area); if (r < 0) return r; - copy.plugins = strv_copy(source->plugins); - if (!copy.plugins) - return -ENOMEM; - copy.argv = strv_copy(source->argv); - if (!copy.argv) - return -ENOMEM; - copy.envp = strv_copy(source->envp); - if (!copy.envp) - return -ENOMEM; + r = strv_copy_unless_empty(source->plugins, ©.plugins); + if (r < 0) + return r; + r = strv_copy_unless_empty(source->argv, ©.argv); + if (r < 0) + return r; + r = strv_copy_unless_empty(source->envp, ©.envp); + if (r < 0) + return r; *ret = copy; copy = CONTEXT_NULL; @@ -1283,7 +1286,7 @@ static int verb_add_all(int argc, char *argv[], void *userdata) { } if (n > 0) - log_info("Installed %zu kernels.", n); + log_debug("Installed %zu kernel(s).", n); else if (ret == 0) ret = log_error_errno(SYNTHETIC_ERRNO(ENOENT), "No kernels to install found."); diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index ff0228081fe..ab8b06896d7 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -1288,7 +1288,7 @@ static int message_push_fd(sd_bus_message *m, int fd) { if (copy < 0) return -errno; - f = reallocarray(m->fds, sizeof(int), m->n_fds + 1); + f = reallocarray(m->fds, m->n_fds + 1, sizeof(int)); if (!f) { m->poisoned = true; safe_close(copy); diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index dbe4d201505..9d32d95589f 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -13,6 +13,7 @@ #include "stdio-util.h" #include "string-util.h" #include "sync-util.h" +#include "virt.h" int id128_from_string_nonzero(const char *s, sd_id128_t *ret) { sd_id128_t t; @@ -223,6 +224,13 @@ int id128_get_product(sd_id128_t *ret) { /* Reads the systems product UUID from DMI or devicetree (where it is located on POWER). This is * particularly relevant in VM environments, where VM managers typically place a VM uuid there. */ + r = detect_container(); + if (r < 0) + return r; + if (r > 0) /* Refuse returning this in containers, as this is not a property of our system then, but + * of the host */ + return -ENOENT; + r = id128_read("/sys/class/dmi/id/product_uuid", ID128_FORMAT_UUID, &uuid); if (r == -ENOENT) r = id128_read("/proc/device-tree/vm,uuid", ID128_FORMAT_UUID, &uuid); diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index 2812eb386a2..d2493a027a4 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -2464,6 +2464,11 @@ int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t) assert(e); assert(t); + /* If we are already going down, we cannot install the timer. + * In such case, the caller needs to call journal_file_post_change() explicitly. */ + if (IN_SET(sd_event_get_state(e), SD_EVENT_EXITING, SD_EVENT_FINISHED)) + return 0; + r = sd_event_add_time(e, &timer, CLOCK_MONOTONIC, 0, 0, post_change_thunk, f); if (r < 0) return r; @@ -2475,7 +2480,7 @@ int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t) f->post_change_timer = TAKE_PTR(timer); f->post_change_timer_period = t; - return r; + return 1; } static int entry_item_cmp(const EntryItem *a, const EntryItem *b) { diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 4d09b156536..f9e86c6608e 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -1081,7 +1081,7 @@ _public_ int sd_get_uids(uid_t **users) { uid_t *t; n = MAX(16, 2*r); - t = reallocarray(l, sizeof(uid_t), n); + t = reallocarray(l, n, sizeof(uid_t)); if (!t) return -ENOMEM; diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 636af1a2d59..832159a6498 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -376,7 +376,7 @@ int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, char assert(ifindex > 0); if (ret) { - r = sd_netlink_message_read_string_strdup(message, IFLA_IFNAME, ret); + r = sd_netlink_message_read_string_strdup(reply, IFLA_IFNAME, ret); if (r < 0) return r; } diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 4c2d3173fbe..13aedc4dbec 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -677,6 +677,10 @@ TEST(rtnl_set_link_name) { assert_se(!strv_contains(alternative_names, "testlongalternativename")); assert_se(strv_contains(alternative_names, "test-additional-name")); assert_se(!strv_contains(alternative_names, "test-shortname")); + + _cleanup_free_ char *resolved = NULL; + assert_se(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", &resolved) == ifindex); + assert_se(streq_ptr(resolved, "test-shortname")); } DEFINE_TEST_MAIN(LOG_DEBUG); diff --git a/src/login/logind-action.c b/src/login/logind-action.c index e678edd66fb..8269f529344 100644 --- a/src/login/logind-action.c +++ b/src/login/logind-action.c @@ -165,8 +165,8 @@ static int handle_action_execute( if (m->delayed_action) return log_debug_errno(SYNTHETIC_ERRNO(EALREADY), - "Action already in progress (%s), ignoring requested %s operation.", - inhibit_what_to_string(m->delayed_action->inhibit_what), + "Action %s already in progress, ignoring requested %s operation.", + handle_action_to_string(m->delayed_action->handle), handle_action_to_string(handle)); inhibit_operation = handle_action_lookup(handle)->inhibit_what; diff --git a/src/login/logind-button.c b/src/login/logind-button.c index 7f95fa7a4f7..14835aedc15 100644 --- a/src/login/logind-button.c +++ b/src/login/logind-button.c @@ -11,6 +11,7 @@ #include "async.h" #include "fd-util.h" #include "logind-button.h" +#include "logind-dbus.h" #include "missing_input.h" #include "string-util.h" @@ -343,6 +344,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u b->lid_closed = true; button_lid_switch_handle_action(b->manager, true); button_install_check_event_source(b); + manager_send_changed(b->manager, "LidClosed", NULL); } else if (ev.code == SW_DOCK) { log_struct(LOG_INFO, @@ -361,6 +363,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u b->lid_closed = false; b->check_event_source = sd_event_source_unref(b->check_event_source); + manager_send_changed(b->manager, "LidClosed", NULL); } else if (ev.code == SW_DOCK) { log_struct(LOG_INFO, @@ -514,6 +517,7 @@ int button_check_switches(Button *b) { b->lid_closed = bitset_get(switches, SW_LID); b->docked = bitset_get(switches, SW_DOCK); + manager_send_changed(b->manager, "LidClosed", NULL); if (b->lid_closed) button_install_check_event_source(b); diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index ae9b2cbf363..ec1f2f33059 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -3539,7 +3539,7 @@ static const sd_bus_vtable manager_vtable[] = { SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0), SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0), SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0), - SD_BUS_PROPERTY("LidClosed", "b", property_get_lid_closed, 0, 0), + SD_BUS_PROPERTY("LidClosed", "b", property_get_lid_closed, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("OnExternalPower", "b", property_get_on_external_power, 0, 0), SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RuntimeDirectorySize", "t", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST), @@ -3964,7 +3964,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err if (m->action_job && streq(m->action_job, path)) { assert(m->delayed_action); - log_info("Operation '%s' finished.", inhibit_what_to_string(m->delayed_action->inhibit_what)); + log_info("Operation '%s' finished.", handle_action_to_string(m->delayed_action->handle)); /* Tell people that they now may take a lock again */ (void) send_prepare_for(m, m->delayed_action, false); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 3f5decd8d9b..3988e553f3e 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -93,7 +93,7 @@ static void session_reset_leader(Session *s) { if (!pidref_is_set(&s->leader)) return; - assert_se(hashmap_remove_value(s->manager->sessions_by_leader, &s->leader, s)); + (void) hashmap_remove_value(s->manager->sessions_by_leader, &s->leader, s); return pidref_done(&s->leader); } diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index b8da266e277..3b6539aaac1 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -802,13 +802,21 @@ typedef struct SessionContext { const char *runtime_max_sec; } SessionContext; -static int create_session_message(sd_bus *bus, pam_handle_t *handle, const SessionContext *context, bool avoid_pidfd, sd_bus_message **ret) { +static int create_session_message( + sd_bus *bus, + pam_handle_t *handle, + const SessionContext *context, + bool avoid_pidfd, + sd_bus_message **ret) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; - int r, pidfd = -EBADFD; + _cleanup_close_ int pidfd = -EBADF; + int r; assert(bus); assert(handle); assert(context); + assert(ret); if (!avoid_pidfd) { pidfd = pidfd_open(getpid_cached(), 0); @@ -1083,39 +1091,39 @@ _public_ PAM_EXTERN int pam_sm_open_session( r = create_session_message(bus, handle, &context, - false /* avoid_pidfd = */, + /* avoid_pidfd = */ false, &m); if (r < 0) return pam_bus_log_create_error(handle, r); r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply); + if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) { + sd_bus_error_free(&error); + pam_debug_syslog(handle, debug, + "CreateSessionWithPIDFD() API is not available, retrying with CreateSession()."); + + m = sd_bus_message_unref(m); + r = create_session_message(bus, + handle, + &context, + /* avoid_pidfd = */ true, + &m); + if (r < 0) + return pam_bus_log_create_error(handle, r); + + r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply); + } if (r < 0) { if (sd_bus_error_has_name(&error, BUS_ERROR_SESSION_BUSY)) { + /* We are already in a session, don't do anything */ pam_debug_syslog(handle, debug, "Not creating session: %s", bus_error_message(&error, r)); - /* We are already in a session, don't do anything */ goto success; - } else if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) { - pam_debug_syslog(handle, debug, - "CreateSessionWithPIDFD() API is not available, retrying with CreateSession()."); - - m = sd_bus_message_unref(m); - r = create_session_message(bus, - handle, - &context, - true /* avoid_pidfd = */, - &m); - if (r < 0) - return pam_bus_log_create_error(handle, r); - - sd_bus_error_free(&error); - r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply); - } - if (r < 0) { - pam_syslog(handle, LOG_ERR, - "Failed to create session: %s", bus_error_message(&error, r)); - return PAM_SESSION_ERR; } + + pam_syslog(handle, LOG_ERR, + "Failed to create session: %s", bus_error_message(&error, r)); + return PAM_SESSION_ERR; } r = sd_bus_message_read(reply, diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c index 1a37ba34652..9e909d1abce 100644 --- a/src/network/netdev/tuntap.c +++ b/src/network/netdev/tuntap.c @@ -137,6 +137,19 @@ static int netdev_create_tuntap(NetDev *netdev) { if (ioctl(fd, TUNSETIFF, &ifr) < 0) return log_netdev_error_errno(netdev, errno, "TUNSETIFF failed: %m"); + if (t->multi_queue) { + /* If we don't detach the queue, the kernel will send packets to our queue and they + * will be dropped because we never read them, which is especially important in case + * of KeepCarrier option which persists open FD. So detach our queue right after + * device create/attach to make kernel not send the packets to it. The option is + * available for multi-queue devices only. + * + * See https://github.com/systemd/systemd/pull/30504 for details. */ + struct ifreq detach_request = { .ifr_flags = IFF_DETACH_QUEUE }; + if (ioctl(fd, TUNSETQUEUE, &detach_request) < 0) + return log_netdev_error_errno(netdev, errno, "TUNSETQUEUE failed: %m"); + } + if (t->user_name) { const char *user = t->user_name; uid_t uid; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index ee5f0f2c0a4..6e4e2af9c14 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1654,7 +1654,7 @@ static int link_carrier_lost(Link *link) { usec = 5 * USEC_PER_SEC; else - /* Otherwise, use the currently set value. */ + /* Otherwise, use the implied default value. */ usec = link->network->ignore_carrier_loss_usec; if (usec == USEC_INFINITY) @@ -1989,20 +1989,18 @@ static int link_update_master(Link *link, sd_netlink_message *message) { if (master_ifindex == link->ifindex) master_ifindex = 0; - if (master_ifindex == link->master_ifindex) - return 0; - - if (link->master_ifindex == 0) - log_link_debug(link, "Attached to master interface: %i", master_ifindex); - else if (master_ifindex == 0) - log_link_debug(link, "Detached from master interface: %i", link->master_ifindex); - else - log_link_debug(link, "Master interface changed: %i %s %i", link->master_ifindex, - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), master_ifindex); - - link_drop_from_master(link); + if (master_ifindex != link->master_ifindex) { + if (link->master_ifindex == 0) + log_link_debug(link, "Attached to master interface: %i", master_ifindex); + else if (master_ifindex == 0) + log_link_debug(link, "Detached from master interface: %i", link->master_ifindex); + else + log_link_debug(link, "Master interface changed: %i %s %i", link->master_ifindex, + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), master_ifindex); - link->master_ifindex = master_ifindex; + link_drop_from_master(link); + link->master_ifindex = master_ifindex; + } r = link_append_to_master(link); if (r < 0) diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index ab9eeb13a5d..840ccb158d1 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -355,8 +355,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { } static int ndisc_router_process_icmp6_ratelimit(Link *link, sd_ndisc_router *rt) { - char buf[DECIMAL_STR_MAX(usec_t)]; - usec_t icmp6_ratelimit; + usec_t icmp6_ratelimit, msec; int r; assert(link); @@ -372,14 +371,17 @@ static int ndisc_router_process_icmp6_ratelimit(Link *link, sd_ndisc_router *rt) return 0; } + /* We do not allow 0 here. */ if (!timestamp_is_set(icmp6_ratelimit)) return 0; + msec = DIV_ROUND_UP(icmp6_ratelimit, USEC_PER_MSEC); + if (msec <= 0 || msec > INT_MAX) + return 0; + /* Limit the maximal rates for sending ICMPv6 packets. 0 to disable any limiting, otherwise the * minimal space between responses in milliseconds. Default: 1000. */ - xsprintf(buf, USEC_FMT, DIV_ROUND_UP(icmp6_ratelimit, USEC_PER_MSEC)); - - r = sysctl_write_ip_property(AF_INET6, NULL, "icmp/ratelimit", buf); + r = sysctl_write_ip_property_int(AF_INET6, NULL, "icmp/ratelimit", (int) msec); if (r < 0) log_link_warning_errno(link, r, "Failed to apply ICMP6 ratelimit, ignoring: %m"); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 6cbaf82d6fa..dcd3e5ae12c 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -274,10 +274,8 @@ int network_verify(Network *network) { network->ignore_carrier_loss_usec = USEC_INFINITY; } - if (!network->ignore_carrier_loss_set) { - network->ignore_carrier_loss_set = true; + if (!network->ignore_carrier_loss_set) /* Set implied default. */ network->ignore_carrier_loss_usec = network->configure_without_carrier ? USEC_INFINITY : 0; - } if (IN_SET(network->activation_policy, ACTIVATION_POLICY_DOWN, ACTIVATION_POLICY_ALWAYS_DOWN, ACTIVATION_POLICY_MANUAL)) { if (network->required_for_online < 0 || diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 1695aacf765..1128987a33d 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -133,11 +133,8 @@ static int request_new( assert(process); req = new(Request, 1); - if (!req) { - if (free_func) - free_func(userdata); + if (!req) return -ENOMEM; - } *req = (Request) { .n_ref = 1, @@ -179,12 +176,19 @@ int netdev_queue_request( request_process_func_t process, Request **ret) { + int r; + assert(netdev); - return request_new(netdev->manager, NULL, REQUEST_TYPE_NETDEV_INDEPENDENT, - netdev_ref(netdev), (mfree_func_t) netdev_unref, - trivial_hash_func, trivial_compare_func, - process, NULL, NULL, ret); + r = request_new(netdev->manager, NULL, REQUEST_TYPE_NETDEV_INDEPENDENT, + netdev, (mfree_func_t) netdev_unref, + trivial_hash_func, trivial_compare_func, + process, NULL, NULL, ret); + if (r <= 0) + return r; + + netdev_ref(netdev); + return 1; } int link_queue_request_full( diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 7218d799fc8..eb502ae2cf3 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -2920,6 +2920,7 @@ int config_parse_multipath_route( if (isempty(rvalue)) { n->multipath_routes = ordered_set_free_with_destructor(n->multipath_routes, multipath_route_free); + TAKE_PTR(n); return 0; } diff --git a/src/nspawn/nspawn-bind-user.c b/src/nspawn/nspawn-bind-user.c index 0a8653033d0..61d8d304e69 100644 --- a/src/nspawn/nspawn-bind-user.c +++ b/src/nspawn/nspawn-bind-user.c @@ -286,7 +286,7 @@ int bind_user_prepare( if (!sd) return log_oom(); - cm = reallocarray(*custom_mounts, sizeof(CustomMount), *n_custom_mounts + 1); + cm = reallocarray(*custom_mounts, *n_custom_mounts + 1, sizeof(CustomMount)); if (!cm) return log_oom(); diff --git a/src/partition/repart.c b/src/partition/repart.c index e4c876ff354..6312d7a4e8f 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -2908,12 +2908,13 @@ static int context_dump_partitions(Context *context) { return table_print_with_pager(t, arg_json_format_flags, arg_pager_flags, arg_legend); } -static void context_bar_char_process_partition( +static int context_bar_char_process_partition( Context *context, Partition *bar[], size_t n, Partition *p, - size_t *ret_start) { + size_t **start_array, + size_t *n_start_array) { uint64_t from, to, total; size_t x, y; @@ -2922,9 +2923,11 @@ static void context_bar_char_process_partition( assert(bar); assert(n > 0); assert(p); + assert(start_array); + assert(n_start_array); if (p->dropped) - return; + return 0; assert(p->offset != UINT64_MAX); assert(p->new_size != UINT64_MAX); @@ -2947,7 +2950,10 @@ static void context_bar_char_process_partition( for (size_t i = x; i < y; i++) bar[i] = p; - *ret_start = x; + if (!GREEDY_REALLOC_APPEND(*start_array, *n_start_array, &x, 1)) + return log_oom(); + + return 1; } static int partition_hint(const Partition *p, const char *node, char **ret) { @@ -2991,9 +2997,11 @@ static int partition_hint(const Partition *p, const char *node, char **ret) { static int context_dump_partition_bar(Context *context) { _cleanup_free_ Partition **bar = NULL; _cleanup_free_ size_t *start_array = NULL; + size_t n_start_array = 0; Partition *last = NULL; bool z = false; size_t c, j = 0; + int r; assert_se((c = columns()) >= 2); c -= 2; /* We do not use the leftmost and rightmost character cell */ @@ -3002,12 +3010,11 @@ static int context_dump_partition_bar(Context *context) { if (!bar) return log_oom(); - start_array = new(size_t, context->n_partitions); - if (!start_array) - return log_oom(); - - LIST_FOREACH(partitions, p, context->partitions) - context_bar_char_process_partition(context, bar, c, p, start_array + j++); + LIST_FOREACH(partitions, p, context->partitions) { + r = context_bar_char_process_partition(context, bar, c, p, &start_array, &n_start_array); + if (r < 0) + return r; + } putc(' ', stdout); @@ -3029,7 +3036,7 @@ static int context_dump_partition_bar(Context *context) { fputs(ansi_normal(), stdout); putc('\n', stdout); - for (size_t i = 0; i < context->n_partitions; i++) { + for (size_t i = 0; i < n_start_array; i++) { _cleanup_free_ char **line = NULL; line = new0(char*, c); @@ -3039,9 +3046,13 @@ static int context_dump_partition_bar(Context *context) { j = 0; LIST_FOREACH(partitions, p, context->partitions) { _cleanup_free_ char *d = NULL; + + if (p->dropped) + continue; + j++; - if (i < context->n_partitions - j) { + if (i < n_start_array - j) { if (line[start_array[j-1]]) { const char *e; @@ -3061,7 +3072,7 @@ static int context_dump_partition_bar(Context *context) { return log_oom(); } - } else if (i == context->n_partitions - j) { + } else if (i == n_start_array - j) { _cleanup_free_ char *hint = NULL; (void) partition_hint(p, context->node, &hint); diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index dc48bc57e56..bdc6bbd8174 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -73,8 +73,8 @@ STATIC_DESTRUCTOR_REGISTER(arg_policy_path, freep); #define PCRLOCK_FIRMWARE_CONFIG_LATE_PATH "/var/lib/pcrlock.d/550-firmware-config-late.pcrlock.d/generated.pcrlock" #define PCRLOCK_GPT_PATH "/var/lib/pcrlock.d/600-gpt.pcrlock.d/generated.pcrlock" #define PCRLOCK_SECUREBOOT_AUTHORITY_PATH "/var/lib/pcrlock.d/620-secureboot-authority.pcrlock.d/generated.pcrlock" -#define PCRLOCK_KERNEL_CMDLINE_PATH "/var/lib/pcrlock.d/710-kernel-cmdline.pcrlock/generated.pcrlock" -#define PCRLOCK_KERNEL_INITRD_PATH "/var/lib/pcrlock.d/720-kernel-initrd.pcrlock/generated.pcrlock" +#define PCRLOCK_KERNEL_CMDLINE_PATH "/var/lib/pcrlock.d/710-kernel-cmdline.pcrlock.d/generated.pcrlock" +#define PCRLOCK_KERNEL_INITRD_PATH "/var/lib/pcrlock.d/720-kernel-initrd.pcrlock.d/generated.pcrlock" #define PCRLOCK_MACHINE_ID_PATH "/var/lib/pcrlock.d/820-machine-id.pcrlock" #define PCRLOCK_ROOT_FILE_SYSTEM_PATH "/var/lib/pcrlock.d/830-root-file-system.pcrlock" #define PCRLOCK_FILE_SYSTEM_PATH_PREFIX "/var/lib/pcrlock.d/840-file-system-" @@ -2801,8 +2801,8 @@ static int verb_lock_secureboot_policy(int argc, char *argv[], void *userdata) { int synthesize_empty; /* 0 → fail, > 0 → synthesize empty db, < 0 → skip */ } variables[] = { { EFI_VENDOR_GLOBAL, "SecureBoot", 0 }, - { EFI_VENDOR_GLOBAL, "PK", 0 }, - { EFI_VENDOR_GLOBAL, "KEK", 0 }, + { EFI_VENDOR_GLOBAL, "PK", 1 }, + { EFI_VENDOR_GLOBAL, "KEK", 1 }, { EFI_VENDOR_DATABASE, "db", 1 }, { EFI_VENDOR_DATABASE, "dbx", 1 }, { EFI_VENDOR_DATABASE, "dbt", -1 }, @@ -4593,7 +4593,7 @@ static int verb_make_policy(int argc, char *argv[], void *userdata) { return r; } - log_info("Written new policy to '%s' and digest to TPM2 NV index 0x%" PRIu32 ".", path, nv_index); + log_info("Written new policy to '%s' and digest to TPM2 NV index 0x%x.", path, nv_index); log_info("Overall time spent: %s", FORMAT_TIMESPAN(usec_sub_unsigned(now(CLOCK_MONOTONIC), start_usec), 1)); diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h index f0bb3be7bea..c6be19063dd 100644 --- a/src/resolve/dns-type.h +++ b/src/resolve/dns-type.h @@ -7,7 +7,7 @@ * http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml. */ enum { - /* Normal records */ + /* 0 is reserved */ DNS_TYPE_A = 0x01, DNS_TYPE_NS, DNS_TYPE_MD, @@ -60,7 +60,8 @@ enum { DNS_TYPE_NSEC3, DNS_TYPE_NSEC3PARAM, DNS_TYPE_TLSA, - + DNS_TYPE_SMIMEA, /* RFC 8162 */ + /* 0x36 (54) is not assigned */ DNS_TYPE_HIP = 0x37, DNS_TYPE_NINFO, DNS_TYPE_RKEY, @@ -68,15 +69,23 @@ enum { DNS_TYPE_CDS, DNS_TYPE_CDNSKEY, DNS_TYPE_OPENPGPKEY, - + DNS_TYPE_CSYNC, + DNS_TYPE_ZONEMD, + DNS_TYPE_SVCB, /* RFC 9460 */ + DNS_TYPE_HTTPS, /* RFC 9460 */ + /* 0x42…0x62 (66…98) are not assigned */ DNS_TYPE_SPF = 0x63, + DNS_TYPE_UINFO, + DNS_TYPE_UID, + DNS_TYPE_GID, + DNS_TYPE_UNSPEC, DNS_TYPE_NID, DNS_TYPE_L32, DNS_TYPE_L64, DNS_TYPE_LP, DNS_TYPE_EUI48, DNS_TYPE_EUI64, - + /* 0x6e…0xf8 (110…248) are not assigned */ DNS_TYPE_TKEY = 0xF9, DNS_TYPE_TSIG, DNS_TYPE_IXFR, @@ -86,15 +95,24 @@ enum { DNS_TYPE_ANY, DNS_TYPE_URI, DNS_TYPE_CAA, + DNS_TYPE_AVC, + DNS_TYPE_DOA, + DNS_TYPE_AMTRELAY, + DNS_TYPE_RESINFO, + /* 0x106…0x7fff (262…32767) are not assigned */ DNS_TYPE_TA = 0x8000, DNS_TYPE_DLV, - + /* 32770…65279 are not assigned */ + /* 65280…65534 are for private use */ + /* 65535 is reserved */ _DNS_TYPE_MAX, _DNS_TYPE_INVALID = -EINVAL, }; -assert_cc(DNS_TYPE_SSHFP == 44); -assert_cc(DNS_TYPE_TLSA == 52); +assert_cc(DNS_TYPE_SMIMEA == 53); +assert_cc(DNS_TYPE_HTTPS == 65); +assert_cc(DNS_TYPE_EUI64 == 109); +assert_cc(DNS_TYPE_RESINFO == 261); assert_cc(DNS_TYPE_ANY == 255); /* DNS record classes, see RFC 1035 */ diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 78665bc93be..a9a649242f4 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -1303,6 +1303,10 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p, usec_t ts, if (!j->shared_owner) continue; + /* Ignore cached goodby packet. See on_mdns_packet() and RFC 6762 section 10.1. */ + if (j->rr->ttl <= 1) + continue; + /* RFC6762 7.1: Don't append records with less than half the TTL remaining * as known answers. */ if (usec_sub_unsigned(j->until, ts) < j->rr->ttl * USEC_PER_SEC / 2) diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index ca1eea43463..426711b0616 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -309,9 +309,23 @@ int dns_packet_validate_query(DnsPacket *p) { switch (p->protocol) { - case DNS_PROTOCOL_LLMNR: case DNS_PROTOCOL_DNS: - if (DNS_PACKET_TC(p)) /* mDNS query may have truncation flag. */ + if (DNS_PACKET_TC(p)) + return -EBADMSG; + + if (DNS_PACKET_QDCOUNT(p) != 1) + return -EBADMSG; + + if (DNS_PACKET_ANCOUNT(p) > 0) + return -EBADMSG; + + /* Note, in most cases, DNS query packet does not have authority section. But some query + * types, e.g. IXFR, have Authority sections. Hence, unlike the check for LLMNR, we do not + * check DNS_PACKET_NSCOUNT(p) here. */ + break; + + case DNS_PROTOCOL_LLMNR: + if (DNS_PACKET_TC(p)) return -EBADMSG; /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */ @@ -329,6 +343,9 @@ int dns_packet_validate_query(DnsPacket *p) { break; case DNS_PROTOCOL_MDNS: + /* Note, mDNS query may have truncation flag. So, unlike the check for DNS and LLMNR, + * we do not check DNS_PACKET_TC(p) here. */ + /* RFC 6762, Section 18 specifies that messages with non-zero RCODE * must be silently ignored, and that we must ignore the values of * AA, RD, RA, AD, and CD bits. */ diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index fe88e502e7c..6c931d71dc4 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -74,6 +74,10 @@ static void dns_transaction_close_connection( * and the reply we might still get from the server will be eaten up instead of resulting in an ICMP * port unreachable error message. */ + /* Skip the graveyard stuff when we're shutting down, since that requires running event loop */ + if (!t->scope->manager->event || sd_event_get_state(t->scope->manager->event) == SD_EVENT_FINISHED) + use_graveyard = false; + if (use_graveyard && t->dns_udp_fd >= 0 && t->sent && !t->received) { r = manager_add_socket_to_graveyard(t->scope->manager, t->dns_udp_fd); if (r < 0) @@ -627,9 +631,20 @@ static int on_stream_complete(DnsStream *s, int error) { } } - if (error != 0) - LIST_FOREACH(transactions_by_stream, t, s->transactions) + if (error != 0) { + /* First, detach the stream from the server. Otherwise, transactions attached to this stream + * may be restarted by on_transaction_stream_error() below with this stream. */ + dns_stream_detach(s); + + /* Do not use LIST_FOREACH() here, as + * on_transaction_stream_error() + * -> dns_transaction_complete_errno() + * -> dns_transaction_free() + * may free multiple transactions in the list. */ + DnsTransaction *t; + while ((t = s->transactions)) on_transaction_stream_error(t, error); + } return 0; } diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c index 8fac351ee6d..9469bdac869 100644 --- a/src/resolve/resolved-llmnr.c +++ b/src/resolve/resolved-llmnr.c @@ -45,7 +45,7 @@ int manager_llmnr_start(Manager *m) { if (r < 0) return r; - if (socket_ipv6_is_supported()) { + if (socket_ipv6_is_enabled()) { r = manager_llmnr_ipv6_udp_fd(m); if (r == -EADDRINUSE) goto eaddrinuse; diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c index b63073af7fd..3e6e83fe625 100644 --- a/src/resolve/resolved-mdns.c +++ b/src/resolve/resolved-mdns.c @@ -36,7 +36,7 @@ int manager_mdns_start(Manager *m) { if (r < 0) return r; - if (socket_ipv6_is_supported()) { + if (socket_ipv6_is_enabled()) { r = manager_mdns_ipv6_fd(m); if (r == -EADDRINUSE) goto eaddrinuse; diff --git a/src/shared/battery-util.c b/src/shared/battery-util.c index 85cb067c841..37b3f6a6ea3 100644 --- a/src/shared/battery-util.c +++ b/src/shared/battery-util.c @@ -241,13 +241,13 @@ int battery_is_discharging_and_low(void) { r = on_ac_power(); if (r < 0) - log_debug_errno(r, "Failed to check if the system is running on AC, assuming it is not: %m"); + log_warning_errno(r, "Failed to check if the system is running on AC, assuming it is not: %m"); if (r > 0) return false; r = battery_enumerator_new(&e); if (r < 0) - return log_debug_errno(r, "Failed to initialize battery enumerator: %m"); + return log_error_errno(r, "Failed to initialize battery enumerator: %m"); FOREACH_DEVICE(e, dev) { int level; diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 348880cac88..e8f4dfbf4e7 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -1059,6 +1059,11 @@ int image_read_only(Image *i, bool b) { return 0; } +static void make_lock_dir(void) { + (void) mkdir_p("/run/systemd/nspawn", 0755); + (void) mkdir("/run/systemd/nspawn/locks", 0700); +} + int image_path_lock(const char *path, int operation, LockFile *global, LockFile *local) { _cleanup_free_ char *p = NULL; LockFile t = LOCK_FILE_INIT; @@ -1134,7 +1139,7 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile } if (p) { - (void) mkdir_p("/run/systemd/nspawn/locks", 0700); + make_lock_dir(); r = make_lock_file(p, operation, global); if (r < 0) { @@ -1309,7 +1314,7 @@ int image_name_lock(const char *name, int operation, LockFile *ret) { return 0; } - (void) mkdir_p("/run/systemd/nspawn/locks", 0700); + make_lock_dir(); p = strjoina("/run/systemd/nspawn/locks/name-", name); return make_lock_file(p, operation, ret); @@ -1347,7 +1352,6 @@ bool image_in_search_path( /* Accept trailing slashes */ if (p[strspn(p, "/")] == 0) return true; - } return false; diff --git a/src/shared/efi-loader.c b/src/shared/efi-loader.c index 0822364535e..758aaa13c16 100644 --- a/src/shared/efi-loader.c +++ b/src/shared/efi-loader.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "alloc-util.h" +#include "efi-api.h" #include "efi-loader.h" #include "env-util.h" #include "parse-util.h" @@ -247,8 +248,8 @@ int efi_measured_uki(int log_level) { if (cached >= 0) return cached; - /* Checks if we are booted on a kernel with sd-stub which measured the kernel into PCR 11. Or in - * other words, if we are running on a TPM enabled UKI. + /* Checks if we are booted on a kernel with sd-stub which measured the kernel into PCR 11 on a TPM2 + * chip. Or in other words, if we are running on a TPM enabled UKI. (TPM 1.2 situations are ignored.) * * Returns == 0 and > 0 depending on the result of the test. Returns -EREMOTE if we detected a stub * being used, but it measured things into a different PCR than we are configured for in @@ -261,7 +262,7 @@ int efi_measured_uki(int log_level) { if (r != -ENXIO) log_debug_errno(r, "Failed to parse $SYSTEMD_FORCE_MEASURE, ignoring: %m"); - if (!is_efi_boot()) + if (!efi_has_tpm2()) return (cached = 0); r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubPcrKernelImage), &pcr_string); diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c index 9b8c7f73bcd..db87084a4da 100644 --- a/src/shared/find-esp.c +++ b/src/shared/find-esp.c @@ -27,9 +27,33 @@ typedef enum VerifyESPFlags { VERIFY_ESP_SEARCHING = 1 << 0, /* Downgrade various "not found" logs to debug level */ VERIFY_ESP_UNPRIVILEGED_MODE = 1 << 1, /* Call into udev rather than blkid */ - VERIFY_ESP_RELAX_CHECKS = 1 << 2, /* Do not validate ESP partition */ + VERIFY_ESP_SKIP_FSTYPE_CHECK = 1 << 2, /* Skip filesystem check */ + VERIFY_ESP_SKIP_DEVICE_CHECK = 1 << 3, /* Skip device node check */ } VerifyESPFlags; +static VerifyESPFlags verify_esp_flags_init(int unprivileged_mode, const char *env_name_for_relaxing) { + VerifyESPFlags flags = 0; + int r; + + assert(env_name_for_relaxing); + + if (unprivileged_mode < 0) + unprivileged_mode = geteuid() != 0; + if (unprivileged_mode) + flags |= VERIFY_ESP_UNPRIVILEGED_MODE; + + r = getenv_bool(env_name_for_relaxing); + if (r < 0 && r != -ENXIO) + log_debug_errno(r, "Failed to parse $%s environment variable, assuming false.", env_name_for_relaxing); + else if (r > 0) + flags |= VERIFY_ESP_SKIP_FSTYPE_CHECK | VERIFY_ESP_SKIP_DEVICE_CHECK; + + if (detect_container() > 0) + flags |= VERIFY_ESP_SKIP_DEVICE_CHECK; + + return flags; +} + static int verify_esp_blkid( dev_t devid, VerifyESPFlags flags, @@ -326,8 +350,8 @@ static int verify_esp( dev_t *ret_devid, VerifyESPFlags flags) { - bool relax_checks, searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING), - unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE); + bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING), + unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE); _cleanup_free_ char *p = NULL; _cleanup_close_ int pfd = -EBADF; dev_t devid = 0; @@ -343,10 +367,6 @@ static int verify_esp( * -EACESS → if 'unprivileged_mode' is set, and we have trouble accessing the thing */ - relax_checks = - getenv_bool("SYSTEMD_RELAX_ESP_CHECKS") > 0 || - FLAGS_SET(flags, VERIFY_ESP_RELAX_CHECKS); - /* Non-root user can only check the status, so if an error occurred in the following, it does not cause any * issues. Let's also, silence the error messages. */ @@ -356,7 +376,7 @@ static int verify_esp( (unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR, r, "Failed to open parent directory of \"%s\": %m", path); - if (!relax_checks) { + if (!FLAGS_SET(flags, VERIFY_ESP_SKIP_FSTYPE_CHECK)) { _cleanup_free_ char *f = NULL; struct statfs sfs; @@ -383,19 +403,20 @@ static int verify_esp( "File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p); } - relax_checks = - relax_checks || - detect_container() > 0; - - r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid); + r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid); if (r < 0) return r; /* In a container we don't have access to block devices, skip this part of the verification, we trust * the container manager set everything up correctly on its own. */ - if (relax_checks) + if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK)) goto finish; + if (devnum_is_zero(devid)) + return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, + SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), + "Could not determine backing block device of directory \"%s\" (btrfs RAID?).", p); + /* If we are unprivileged we ask udev for the metadata about the partition. If we are privileged we * use blkid instead. Why? Because this code is called from 'bootctl' which is pretty much an * emergency recovery tool that should also work when udev isn't up (i.e. from the emergency shell), @@ -454,15 +475,7 @@ int find_esp_and_warn_at( assert(rfd >= 0 || rfd == AT_FDCWD); - if (unprivileged_mode < 0) - unprivileged_mode = geteuid() != 0; - flags = unprivileged_mode > 0 ? VERIFY_ESP_UNPRIVILEGED_MODE : 0; - - r = dir_fd_is_root_or_cwd(rfd); - if (r < 0) - return log_error_errno(r, "Failed to check if directory file descriptor is root: %m"); - if (r == 0) - flags |= VERIFY_ESP_RELAX_CHECKS; + flags = verify_esp_flags_init(unprivileged_mode, "SYSTEMD_RELAX_ESP_CHECKS"); if (path) return verify_esp(rfd, path, ret_path, ret_part, ret_pstart, ret_psize, ret_uuid, ret_devid, flags); @@ -742,8 +755,7 @@ static int verify_xbootldr( _cleanup_free_ char *p = NULL; _cleanup_close_ int pfd = -EBADF; bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING), - unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE), - relax_checks; + unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE); dev_t devid = 0; int r; @@ -756,17 +768,22 @@ static int verify_xbootldr( (unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR, r, "Failed to open parent directory of \"%s\": %m", path); - relax_checks = - getenv_bool("SYSTEMD_RELAX_XBOOTLDR_CHECKS") > 0 || - detect_container() > 0; - - r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid); + r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid); if (r < 0) return r; - if (relax_checks) + if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK)) goto finish; + if (devnum_is_zero(devid)) + return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, + SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), + "Could not determine backing block device of directory \"%s\" (btrfs RAID?).%s", + p, + searching ? "" : + "\nHint: set $SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes environment variable " + "to bypass this and further verifications for the directory."); + if (unprivileged_mode) r = verify_xbootldr_udev(devid, flags, ret_uuid); else @@ -800,17 +817,14 @@ int find_xbootldr_and_warn_at( sd_id128_t *ret_uuid, dev_t *ret_devid) { - VerifyESPFlags flags = 0; + VerifyESPFlags flags; int r; /* Similar to find_esp_and_warn(), but finds the XBOOTLDR partition. Returns the same errors. */ assert(rfd >= 0 || rfd == AT_FDCWD); - if (unprivileged_mode < 0) - unprivileged_mode = geteuid() != 0; - if (unprivileged_mode) - flags |= VERIFY_ESP_UNPRIVILEGED_MODE; + flags = verify_esp_flags_init(unprivileged_mode, "SYSTEMD_RELAX_XBOOTLDR_CHECKS"); if (path) return verify_xbootldr(rfd, path, flags, ret_path, ret_uuid, ret_devid); diff --git a/src/shared/hibernate-util.c b/src/shared/hibernate-util.c index 3eb13d48f68..0d215e85708 100644 --- a/src/shared/hibernate-util.c +++ b/src/shared/hibernate-util.c @@ -388,12 +388,24 @@ int find_suitable_hibernation_device_full(HibernationDevice *ret_device, uint64_ return log_debug_errno(SYNTHETIC_ERRNO(ENOSPC), "Cannot find swap entry corresponding to /sys/power/resume."); } - if (ret_device) + if (ret_device) { + char *path; + + if (entry->swapfile) { + r = device_path_make_canonical(S_IFBLK, entry->devno, &path); + if (r < 0) + return log_debug_errno(r, + "Failed to format canonical device path for devno '" DEVNUM_FORMAT_STR "': %m", + DEVNUM_FORMAT_VAL(entry->devno)); + } else + path = TAKE_PTR(entry->path); + *ret_device = (HibernationDevice) { .devno = entry->devno, .offset = entry->offset, - .path = TAKE_PTR(entry->path), + .path = path, }; + } if (ret_size) { *ret_size = entry->size; diff --git a/src/shared/killall.c b/src/shared/killall.c index 330b4c3272d..917b7732665 100644 --- a/src/shared/killall.c +++ b/src/shared/killall.c @@ -257,7 +257,7 @@ static int killall(int sig, Set *pids, bool send_sighup) { r = pidref_kill(&pidref, sig); if (r < 0) { - if (errno != -ESRCH) + if (r != -ESRCH) log_warning_errno(errno, "Could not kill " PID_FMT ", ignoring: %m", pidref.pid); } else { n_killed++; diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 5e07b88a895..30b4f57fd69 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -228,11 +228,14 @@ static int tpm2_get_capability( count, &more, &capabilities); + if (rc == TPM2_RC_VALUE) + return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), + "Requested TPM2 capability 0x%04" PRIx32 " property 0x%04" PRIx32 " apparently doesn't exist: %s", + capability, property, sym_Tss2_RC_Decode(rc)); if (rc != TSS2_RC_SUCCESS) return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get TPM2 capability 0x%04" PRIx32 " property 0x%04" PRIx32 ": %s", capability, property, sym_Tss2_RC_Decode(rc)); - if (capabilities->capability != capability) return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM provided wrong capability: 0x%04" PRIx32 " instead of 0x%04" PRIx32 ".", @@ -333,6 +336,8 @@ static int tpm2_cache_capabilities(Tpm2Context *c) { current_ecc_curve, TPM2_MAX_ECC_CURVES, &capability); + if (r == -ENXIO) /* If the TPM doesn't support ECC, it might return TPM2_RC_VALUE rather than capability.eccCurves == 0 */ + break; if (r < 0) return r; @@ -4191,6 +4196,11 @@ int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret } } +/* Be careful before changing anything in this function, as the TPM key "name" is calculated using the entire + * TPMT_PUBLIC (after marshalling), and that "name" is used (for example) to calculate the policy hash for + * the Authorize policy. So we must ensure this conversion of a PEM to TPM2B_PUBLIC does not change the + * "name", because it would break unsealing of previously-sealed objects that used (for example) + * tpm2_calculate_policy_authorize(). See bug #30546. */ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) { int key_id, r; @@ -4269,8 +4279,11 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) uint32_t exponent = 0; memcpy(&exponent, e, e_size); exponent = be32toh(exponent) >> (32 - e_size * 8); - if (exponent == TPM2_RSA_DEFAULT_EXPONENT) - exponent = 0; + + /* TPM specification Part 2 ("Structures") section for TPMS_RSA_PARAMS states "An exponent of + * zero indicates that the exponent is the default of 2^16 + 1". However, we have no reason + * to special case it in our PEM->TPM2B_PUBLIC conversion, and doing so could break backwards + * compatibility, so even if it is the "default" value of 0x10001, we do not set it to 0. */ public.parameters.rsaDetail.exponent = exponent; break; @@ -5562,10 +5575,23 @@ int tpm2_unseal(Tpm2Context *c, /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not * wait until the TPM2 tells us to go away. */ if (known_policy_hash_size > 0 && - memcmp_nn(policy_digest->buffer, policy_digest->size, known_policy_hash, known_policy_hash_size) != 0) + memcmp_nn(policy_digest->buffer, policy_digest->size, known_policy_hash, known_policy_hash_size) != 0) { + +#if HAVE_OPENSSL + if (pubkey_size > 0 && + pubkey_tpm2b.publicArea.type == TPM2_ALG_RSA && + pubkey_tpm2b.publicArea.parameters.rsaDetail.exponent == TPM2_RSA_DEFAULT_EXPONENT) { + /* Due to bug #30546, if using RSA pubkey with the default exponent, we may + * need to set the exponent to the TPM special-case value of 0 and retry. */ + log_debug("Policy hash mismatch, retrying with RSA pubkey exponent set to 0."); + pubkey_tpm2b.publicArea.parameters.rsaDetail.exponent = 0; + continue; + } else +#endif return log_debug_errno(SYNTHETIC_ERRNO(EPERM), "Current policy digest does not match stored policy digest, cancelling " "TPM2 authentication attempt."); + } log_debug("Unsealing HMAC key."); diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h index ec1e27771e9..2e04fac4047 100644 --- a/src/shared/utmp-wtmp.h +++ b/src/shared/utmp-wtmp.h @@ -23,7 +23,8 @@ static inline bool utxent_start(void) { return true; } static inline void utxent_cleanup(bool *initialized) { - if (initialized) + assert(initialized); + if (*initialized) endutxent(); } diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c index 4c1a9687183..2d79f7147a8 100644 --- a/src/shared/watchdog.c +++ b/src/shared/watchdog.c @@ -261,12 +261,15 @@ static int update_pretimeout(void) { static int update_timeout(void) { int r; + usec_t previous_timeout; assert(watchdog_timeout > 0); if (watchdog_fd < 0) return 0; + previous_timeout = watchdog_timeout; + if (watchdog_timeout != USEC_INFINITY) { r = watchdog_set_timeout(); if (r < 0) { @@ -281,8 +284,12 @@ static int update_timeout(void) { if (watchdog_timeout == USEC_INFINITY) { r = watchdog_read_timeout(); - if (r < 0) - return log_error_errno(r, "Failed to query watchdog HW timeout: %m"); + if (r < 0) { + if (!ERRNO_IS_NOT_SUPPORTED(r)) + return log_error_errno(r, "Failed to query watchdog HW timeout: %m"); + log_info("Reading watchdog timeout is not supported, reusing the configured timeout."); + watchdog_timeout = previous_timeout; + } } /* If the watchdog timeout was changed, the pretimeout could have been diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c index 21af3e9e52e..21062b24e0c 100644 --- a/src/sleep/sleep.c +++ b/src/sleep/sleep.c @@ -176,7 +176,7 @@ static int lock_all_homes(void) { /* Let's synchronously lock all home directories managed by homed that have been marked for it. This * way the key material required to access these volumes is hopefully removed from memory. */ - r = bus_connect_system_systemd(&bus); + r = sd_bus_open_system(&bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); @@ -253,10 +253,8 @@ static int execute( return r; r = write_resume_config(hibernation_device.devno, hibernation_device.offset, hibernation_device.path); - if (r < 0) { - log_error_errno(r, "Failed to write hibernation device to /sys/power/resume or /sys/power/resume_offset: %m"); + if (r < 0) goto fail; - } } r = write_mode(sleep_config->modes[operation]); diff --git a/src/storagetm/storagetm.c b/src/storagetm/storagetm.c index ae63baaf792..16d4fb07d4e 100644 --- a/src/storagetm/storagetm.c +++ b/src/storagetm/storagetm.c @@ -381,7 +381,7 @@ static int nvme_subsystem_add(const char *node, int consumed_fd, sd_device *devi return log_error_errno(errno, "Failed to fstat '%s': %m", node); if (S_ISBLK(st.st_mode)) { if (!device) { - r = sd_device_new_from_devnum(&allocated_device, 'b', st.st_dev); + r = sd_device_new_from_devnum(&allocated_device, 'b', st.st_rdev); if (r < 0) return log_error_errno(r, "Failed to get device information for device '%s': %m", node); @@ -788,9 +788,10 @@ typedef struct Context { static void device_hash_func(const struct stat *q, struct siphash *state) { assert(q); + mode_t m = q->st_mode & S_IFMT; + siphash24_compress(&m, sizeof(m), state); + if (S_ISBLK(q->st_mode) || S_ISCHR(q->st_mode)) { - mode_t m = q->st_mode & S_IFMT; - siphash24_compress(&m, sizeof(m), state); siphash24_compress(&q->st_rdev, sizeof(q->st_rdev), state); return; } diff --git a/src/systemctl/systemctl-is-system-running.c b/src/systemctl/systemctl-is-system-running.c index 6b521c93476..59be6a7a7ec 100644 --- a/src/systemctl/systemctl-is-system-running.c +++ b/src/systemctl/systemctl-is-system-running.c @@ -29,7 +29,7 @@ int verb_is_system_running(int argc, char *argv[], void *userdata) { sd_bus *bus; int r; - if (running_in_chroot() > 0 || (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted())) { + if (!isempty(arg_root) || running_in_chroot() > 0 || (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted())) { if (!arg_quiet) puts("offline"); return EXIT_FAILURE; diff --git a/src/systemctl/systemctl-start-special.c b/src/systemctl/systemctl-start-special.c index d93bffb7591..d23ce36bfce 100644 --- a/src/systemctl/systemctl-start-special.c +++ b/src/systemctl/systemctl-start-special.c @@ -121,8 +121,7 @@ static int set_exit_code(uint8_t code) { } int verb_start_special(int argc, char *argv[], void *userdata) { - bool termination_action; /* An action that terminates the manager, can be performed also by - * signal. */ + bool termination_action; /* An action that terminates the system, can be performed also by signal. */ enum action a; int r; @@ -140,17 +139,21 @@ int verb_start_special(int argc, char *argv[], void *userdata) { return r; } - r = prepare_firmware_setup(); - if (r < 0) - return r; + termination_action = IN_SET(a, ACTION_HALT, ACTION_POWEROFF, ACTION_REBOOT); - r = prepare_boot_loader_menu(); - if (r < 0) - return r; + if (termination_action) { + r = prepare_firmware_setup(); + if (r < 0) + return r; - r = prepare_boot_loader_entry(); - if (r < 0) - return r; + r = prepare_boot_loader_menu(); + if (r < 0) + return r; + + r = prepare_boot_loader_entry(); + if (r < 0) + return r; + } if (a == ACTION_REBOOT) { if (arg_reboot_argument) { @@ -181,10 +184,6 @@ int verb_start_special(int argc, char *argv[], void *userdata) { return r; } - termination_action = IN_SET(a, - ACTION_HALT, - ACTION_POWEROFF, - ACTION_REBOOT); if (termination_action && arg_force >= 2) return halt_now(a); diff --git a/src/test/test-alloc-util.c b/src/test/test-alloc-util.c index 57cb886c411..24cb5f73eb7 100644 --- a/src/test/test-alloc-util.c +++ b/src/test/test-alloc-util.c @@ -100,7 +100,7 @@ TEST(memdup_multiply_and_greedy_realloc) { size_t i; int *p; - dup = memdup_suffix0_multiply(org, sizeof(int), 3); + dup = memdup_suffix0_multiply(org, 3, sizeof(int)); assert_se(dup); assert_se(dup[0] == 1); assert_se(dup[1] == 2); @@ -108,7 +108,7 @@ TEST(memdup_multiply_and_greedy_realloc) { assert_se(((uint8_t*) dup)[sizeof(int) * 3] == 0); free(dup); - dup = memdup_multiply(org, sizeof(int), 3); + dup = memdup_multiply(org, 3, sizeof(int)); assert_se(dup); assert_se(dup[0] == 1); assert_se(dup[1] == 2); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 6d51ad7b53e..126ca14c660 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -39,6 +39,7 @@ static char *user_runtime_unit_dir = NULL; static bool can_unshare; static bool have_net_dummy; +static bool have_netns; static unsigned n_ran_tests = 0; STATIC_DESTRUCTOR_REGISTER(user_runtime_unit_dir, freep); @@ -1111,6 +1112,9 @@ static void test_exec_networknamespacepath(Manager *m) { if (!have_net_dummy) return (void)log_notice("Skipping %s, dummy network interface not available", __func__); + if (!have_netns) + return (void)log_notice("Skipping %s, network namespace not available", __func__); + r = find_executable("ip", NULL); if (r < 0) { log_notice_errno(r, "Skipping %s, could not find ip binary: %m", __func__); @@ -1452,8 +1456,8 @@ static int intro(void) { if (have_net_dummy) { /* Create a network namespace and a dummy interface in it for NetworkNamespacePath= */ - (void) system("ip netns add test-execute-netns"); - (void) system("ip netns exec test-execute-netns ip link add dummy-test-ns type dummy"); + have_netns = system("ip netns add test-execute-netns") == 0; + have_netns = have_netns && system("ip netns exec test-execute-netns ip link add dummy-test-ns type dummy") == 0; } return EXIT_SUCCESS; diff --git a/src/test/test-tpm2.c b/src/test/test-tpm2.c index 06b9800dec7..e3c7da8b08f 100644 --- a/src/test/test-tpm2.c +++ b/src/test/test-tpm2.c @@ -819,36 +819,75 @@ static void check_tpm2b_public_fingerprint(const TPM2B_PUBLIC *public, const cha assert_se(memcmp_nn(fp, fp_size, expected, expected_len) == 0); } -TEST(tpm2b_public_from_openssl_pkey) { - TPM2B_PUBLIC public; +static void check_tpm2b_public_name(const TPM2B_PUBLIC *public, const char *hexname) { + DEFINE_HEX_PTR(expected, hexname); + TPM2B_NAME name = {}; + + assert_se(tpm2_calculate_pubkey_name(&public->publicArea, &name) >= 0); + assert_se(memcmp_nn(name.name, name.size, expected, expected_len) == 0); +} + +static void check_tpm2b_public_from_ecc_pem(const char *pem, const char *hexx, const char *hexy, const char *hexfp, const char *hexname) { + TPM2B_PUBLIC public = {}; TPMT_PUBLIC *p = &public.publicArea; - DEFINE_HEX_PTR(key_ecc, "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a30444151634451674145726a6e4575424c73496c3972687068777976584e50686a346a426e500a44586e794a304b395579724e6764365335413532542b6f5376746b436a365a726c34685847337741515558706f426c532b7448717452714c35513d3d0a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a"); - get_tpm2b_public_from_pem(key_ecc, key_ecc_len, &public); + DEFINE_HEX_PTR(key, pem); + get_tpm2b_public_from_pem(key, key_len, &public); assert_se(p->type == TPM2_ALG_ECC); assert_se(p->parameters.eccDetail.curveID == TPM2_ECC_NIST_P256); - DEFINE_HEX_PTR(expected_x, "ae39c4b812ec225f6b869870caf5cd3e18f88c19cf0d79f22742bd532acd81de"); + DEFINE_HEX_PTR(expected_x, hexx); assert_se(memcmp_nn(p->unique.ecc.x.buffer, p->unique.ecc.x.size, expected_x, expected_x_len) == 0); - DEFINE_HEX_PTR(expected_y, "92e40e764fea12bed9028fa66b9788571b7c004145e9a01952fad1eab51a8be5"); + DEFINE_HEX_PTR(expected_y, hexy); assert_se(memcmp_nn(p->unique.ecc.y.buffer, p->unique.ecc.y.size, expected_y, expected_y_len) == 0); - check_tpm2b_public_fingerprint(&public, "cd3373293b62a52b48c12100e80ea9bfd806266ce76893a5ec31cb128052d97c"); + check_tpm2b_public_fingerprint(&public, hexfp); + check_tpm2b_public_name(&public, hexname); +} + +static void check_tpm2b_public_from_rsa_pem(const char *pem, const char *hexn, uint32_t exponent, const char *hexfp, const char *hexname) { + TPM2B_PUBLIC public = {}; + TPMT_PUBLIC *p = &public.publicArea; + + DEFINE_HEX_PTR(key, pem); + get_tpm2b_public_from_pem(key, key_len, &public); - DEFINE_HEX_PTR(key_rsa, "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541795639434950652f505852337a436f63787045300a6a575262546c3568585844436b472f584b79374b6d2f4439584942334b734f5a31436a5937375571372f674359363170697838697552756a73413464503165380a593445336c68556d374a332b6473766b626f4b64553243626d52494c2f6675627771694c4d587a41673342575278747234547545443533527a373634554650640a307a70304b68775231496230444c67772f344e67566f314146763378784b4d6478774d45683567676b73733038326332706c354a504e32587677426f744e6b4d0a5471526c745a4a35355244436170696e7153334577376675646c4e735851357746766c7432377a7637344b585165616d704c59433037584f6761304c676c536b0a79754774586b6a50542f735542544a705374615769674d5a6f714b7479563463515a58436b4a52684459614c47587673504233687a766d5671636e6b47654e540a65774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a"); - get_tpm2b_public_from_pem(key_rsa, key_rsa_len, &public); + assert_se(p->type == TPM2_ALG_RSA); - DEFINE_HEX_PTR(expected_n, "c95f4220f7bf3d7477cc2a1cc691348d645b4e5e615d70c2906fd72b2eca9bf0fd5c80772ac399d428d8efb52aeff80263ad698b1f22b91ba3b00e1d3f57bc638137961526ec9dfe76cbe46e829d53609b99120bfdfb9bc2a88b317cc0837056471b6be13b840f9dd1cfbeb85053ddd33a742a1c11d486f40cb830ff8360568d4016fdf1c4a31dc7030487982092cb34f36736a65e493cdd97bf0068b4d90c4ea465b59279e510c26a98a7a92dc4c3b7ee76536c5d0e7016f96ddbbcefef829741e6a6a4b602d3b5ce81ad0b8254a4cae1ad5e48cf4ffb140532694ad6968a0319a2a2adc95e1c4195c29094610d868b197bec3c1de1cef995a9c9e419e3537b"); - assert_se(p->unique.rsa.size == expected_n_len); - assert_se(memcmp(p->unique.rsa.buffer, expected_n, expected_n_len) == 0); + DEFINE_HEX_PTR(expected_n, hexn); + assert_se(memcmp_nn(p->unique.rsa.buffer, p->unique.rsa.size, expected_n, expected_n_len) == 0); assert_se(p->parameters.rsaDetail.keyBits == expected_n_len * 8); - assert_se(p->parameters.rsaDetail.exponent == 0); + assert_se(p->parameters.rsaDetail.exponent == exponent); - check_tpm2b_public_fingerprint(&public, "d9186d13a7fd5b3644cee05448f49ad3574e82a2942ff93cf89598d36cca78a9"); + check_tpm2b_public_fingerprint(&public, hexfp); + check_tpm2b_public_name(&public, hexname); +} + +TEST(tpm2b_public_from_openssl_pkey) { + /* standard ECC key */ + check_tpm2b_public_from_ecc_pem("2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a30444151634451674145726a6e4575424c73496c3972687068777976584e50686a346a426e500a44586e794a304b395579724e6764365335413532542b6f5376746b436a365a726c34685847337741515558706f426c532b7448717452714c35513d3d0a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a", + "ae39c4b812ec225f6b869870caf5cd3e18f88c19cf0d79f22742bd532acd81de", + "92e40e764fea12bed9028fa66b9788571b7c004145e9a01952fad1eab51a8be5", + "cd3373293b62a52b48c12100e80ea9bfd806266ce76893a5ec31cb128052d97c", + "000b5c127e4dbaf8fb7bac641e8db25a84a48db876ca7ee3bd317ae1a4554ff72f17"); + + /* standard RSA key */ + check_tpm2b_public_from_rsa_pem("2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541795639434950652f505852337a436f63787045300a6a575262546c3568585844436b472f584b79374b6d2f4439584942334b734f5a31436a5937375571372f674359363170697838697552756a73413464503165380a593445336c68556d374a332b6473766b626f4b64553243626d52494c2f6675627771694c4d587a41673342575278747234547545443533527a373634554650640a307a70304b68775231496230444c67772f344e67566f314146763378784b4d6478774d45683567676b73733038326332706c354a504e32587677426f744e6b4d0a5471526c745a4a35355244436170696e7153334577376675646c4e735851357746766c7432377a7637344b585165616d704c59433037584f6761304c676c536b0a79754774586b6a50542f735542544a705374615769674d5a6f714b7479563463515a58436b4a52684459614c47587673504233687a766d5671636e6b47654e540a65774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a", + "c95f4220f7bf3d7477cc2a1cc691348d645b4e5e615d70c2906fd72b2eca9bf0fd5c80772ac399d428d8efb52aeff80263ad698b1f22b91ba3b00e1d3f57bc638137961526ec9dfe76cbe46e829d53609b99120bfdfb9bc2a88b317cc0837056471b6be13b840f9dd1cfbeb85053ddd33a742a1c11d486f40cb830ff8360568d4016fdf1c4a31dc7030487982092cb34f36736a65e493cdd97bf0068b4d90c4ea465b59279e510c26a98a7a92dc4c3b7ee76536c5d0e7016f96ddbbcefef829741e6a6a4b602d3b5ce81ad0b8254a4cae1ad5e48cf4ffb140532694ad6968a0319a2a2adc95e1c4195c29094610d868b197bec3c1de1cef995a9c9e419e3537b", + 0x10001, + "d9186d13a7fd5b3644cee05448f49ad3574e82a2942ff93cf89598d36cca78a9", + "000be1bd75c7976e7a30e9e82223b81a9eff0d42c30618e588db592ed5da94455e81"); + + /* RSA key with non-default (i.e. not 0x10001) exponent */ + check_tpm2b_public_from_rsa_pem("2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b434151454179566c7551664b75565171596a5a71436a657a760a364e4a6f58654c736f702f72765375666330773769544d4f73566741557462515452505451725874397065537a4370524467634378656b6a544144577279304b0a6d59786a7a3634776c6a7030463959383068636a6b6b4b3759414d333054664c4648656c2b377574427370777142467a6e2b385a6659567353434b397354706f0a316c61376e5347514e7451576f36444a366c525a336a676d6d584f61544654416145304a432b7046584273564471736d46326438362f314e51714a755a5154520a575852636954704e58357649792f37766b6c5a6a685569526c78764e594f4e3070636476534a37364e74496e447a3048506f775a38705a454f4d2f4a454f59780a617a4c4a6a644936446b355279593578325a7949375074566a3057537242524f4d696f2b674c6556457a43343456336438315a38445138564e334c69625130330a70514944415141460a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a", + "c9596e41f2ae550a988d9a828decefe8d2685de2eca29febbd2b9f734c3b89330eb1580052d6d04d13d342b5edf69792cc2a510e0702c5e9234c00d6af2d0a998c63cfae30963a7417d63cd217239242bb600337d137cb1477a5fbbbad06ca70a811739fef197d856c4822bdb13a68d656bb9d219036d416a3a0c9ea5459de382699739a4c54c0684d090bea455c1b150eab2617677cebfd4d42a26e6504d159745c893a4d5f9bc8cbfeef925663854891971bcd60e374a5c76f489efa36d2270f3d073e8c19f2964438cfc910e6316b32c98dd23a0e4e51c98e71d99c88ecfb558f4592ac144e322a3e80b7951330b8e15dddf3567c0d0f153772e26d0d37a5", + 0x10005, + "c8ca80a687d5972e1d961aaa2cfde2ff2e7a20d85e3ea0382804e70e013d65af", + "000beb8974d36d8cf58fdc87460dda00319e10c94c1b9f222ac9ce29d1c4776246cc"); } #endif diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c index 1317bc0f764..85921975285 100644 --- a/src/timesync/timesyncd-manager.c +++ b/src/timesync/timesyncd-manager.c @@ -658,8 +658,7 @@ static int manager_listen_setup(Manager *m) { if (r < 0) return r; - if (addr.sa.sa_family == AF_INET) - (void) setsockopt_int(m->server_socket, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); + (void) socket_set_option(m->server_socket, addr.sa.sa_family, IP_TOS, IPV6_TCLASS, IPTOS_DSCP_EF); return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m); } diff --git a/src/udev/dmi_memory_id/dmi_memory_id.c b/src/udev/dmi_memory_id/dmi_memory_id.c index 37c098adc86..3f89cc7424a 100644 --- a/src/udev/dmi_memory_id/dmi_memory_id.c +++ b/src/udev/dmi_memory_id/dmi_memory_id.c @@ -7,7 +7,7 @@ * Copyright (C) 2020 Bastien Nocera * * Unless specified otherwise, all references are aimed at the "System - * Management BIOS Reference Specification, Version 3.2.0" document, + * Management BIOS Reference Specification, Version 3.7.0" document, * available from http://www.dmtf.org/standards/smbios. * * Note to contributors: @@ -145,7 +145,7 @@ static void dmi_memory_array_location(uint8_t code) { [0x01] = "PC-98/C24 Add-on Card", /* 0xA1 */ [0x02] = "PC-98/E Add-on Card", /* 0xA2 */ [0x03] = "PC-98/Local Bus Add-on Card", /* 0xA3 */ - [0x04] = "CXL Flexbus 1.0", /* 0xA4 */ + [0x04] = "CXL Add-on Card", /* 0xA4 */ }; const char *str = OUT_OF_SPEC_STR; @@ -301,6 +301,9 @@ static void dmi_memory_device_type(unsigned slot_num, uint8_t code) { [0x1F] = "Logical non-volatile device", [0x20] = "HBM", [0x21] = "HBM2", + [0x22] = "DDR5", + [0x23] = "LPDDR5", + [0x24] = "HBM3", }; printf("MEMORY_DEVICE_%u_TYPE=%s\n", slot_num, @@ -315,7 +318,7 @@ static void dmi_memory_device_type_detail(unsigned slot_num, uint16_t code) { [3] = "Fast-paged", [4] = "Static Column", [5] = "Pseudo-static", - [6] = "RAMBus", + [6] = "RAMBUS", [7] = "Synchronous", [8] = "CMOS", [9] = "EDO", @@ -358,7 +361,7 @@ static void dmi_memory_device_technology(unsigned slot_num, uint8_t code) { [0x04] = "NVDIMM-N", [0x05] = "NVDIMM-F", [0x06] = "NVDIMM-P", - [0x07] = "Intel Optane DC persistent memory", + [0x07] = "Intel Optane persistent memory", }; printf("MEMORY_DEVICE_%u_MEMORY_TECHNOLOGY=%s\n", slot_num, diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c index 5d1fafbd039..088b4da3c1a 100644 --- a/src/udev/udevadm-test-builtin.c +++ b/src/udev/udevadm-test-builtin.c @@ -78,6 +78,7 @@ int builtin_main(int argc, char *argv[], void *userdata) { int r; log_set_max_level(LOG_DEBUG); + log_parse_environment(); r = parse_argv(argc, argv); if (r <= 0) @@ -104,9 +105,12 @@ int builtin_main(int argc, char *argv[], void *userdata) { } r = udev_builtin_run(event, cmd, arg_command, true); - if (r < 0) + if (r < 0) { log_debug_errno(r, "Builtin command '%s' fails: %m", arg_command); + goto finish; + } + r = 0; finish: udev_builtin_exit(); return r; diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index 809143ede0b..e1afd7d29e6 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -95,6 +95,7 @@ int test_main(int argc, char *argv[], void *userdata) { int r; log_set_max_level(LOG_DEBUG); + log_parse_environment(); r = parse_argv(argc, argv); if (r <= 0) diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c index 51dc041a29c..687b927f721 100644 --- a/src/udev/udevadm.c +++ b/src/udev/udevadm.c @@ -137,4 +137,4 @@ static int run(int argc, char *argv[]) { return udevadm_main(argc, argv); } -DEFINE_MAIN_FUNCTION(run); +DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run); diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh index d0ec63d8708..eace3f23c03 100755 --- a/test/TEST-24-CRYPTSETUP/test.sh +++ b/test/TEST-24-CRYPTSETUP/test.sh @@ -27,7 +27,7 @@ check_result_qemu() { mount_initdir - cryptsetup luksOpen "${LOOPDEV:?}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile" + cryptsetup luksOpen "${LOOPDEV:?}p4" "${DM_NAME:?}" <"$TESTDIR/keyfile" mount "/dev/mapper/$DM_NAME" "$initdir/var" check_result_common "${initdir:?}" && ret=0 || ret=$? @@ -43,8 +43,8 @@ test_create_image() { create_empty_image_rootdir echo -n test >"${TESTDIR:?}/keyfile" - cryptsetup -q luksFormat --uuid="$PART_UUID" --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p2" "$TESTDIR/keyfile" - cryptsetup luksOpen "${LOOPDEV}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile" + cryptsetup -q luksFormat --uuid="$PART_UUID" --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p4" "$TESTDIR/keyfile" + cryptsetup luksOpen "${LOOPDEV}p4" "${DM_NAME:?}" <"$TESTDIR/keyfile" mkfs.ext4 -L var "/dev/mapper/$DM_NAME" mkdir -p "${initdir:?}/var" mount "/dev/mapper/$DM_NAME" "$initdir/var" diff --git a/test/TEST-64-UDEV-STORAGE/test.sh b/test/TEST-64-UDEV-STORAGE/test.sh index d41a4f00f9a..b9e7bdf18ad 100755 --- a/test/TEST-64-UDEV-STORAGE/test.sh +++ b/test/TEST-64-UDEV-STORAGE/test.sh @@ -24,7 +24,7 @@ _host_has_feature() {( case "${1:?}" in btrfs) - modprobe -nv btrfs && command -v mkfs.btrfs && command -v btrfs || return $? + host_has_btrfs ;; iscsi) # Client/initiator (Open-iSCSI) @@ -36,7 +36,7 @@ _host_has_feature() {( command -v lvm || return $? ;; mdadm) - command -v mdadm || return $? + host_has_mdadm ;; multipath) command -v multipath && command -v multipathd || return $? diff --git a/test/TEST-74-AUX-UTILS/test.sh b/test/TEST-74-AUX-UTILS/test.sh index f033ec469f3..e3eb62f198c 100755 --- a/test/TEST-74-AUX-UTILS/test.sh +++ b/test/TEST-74-AUX-UTILS/test.sh @@ -8,6 +8,9 @@ NSPAWN_ARGUMENTS="--private-network" # shellcheck source=test/test-functions . "${TEST_BASE_DIR:?}/test-functions" +# (Hopefully) a temporary workaround for https://github.com/systemd/systemd/issues/30573 +KERNEL_APPEND="${KERNEL_APPEND:-} SYSTEMD_DEFAULT_MOUNT_RATE_LIMIT_BURST=100" + test_append_files() { local workspace="${1:?}" @@ -16,6 +19,12 @@ test_append_files() { # the QEMU test, as nspawn refuses the invalid machine ID with -EUCLEAN printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >"$workspace/etc/machine-id" fi + + if host_has_btrfs && host_has_mdadm; then + install_btrfs + install_mdadm + generate_module_dependencies + fi } do_test "$@" diff --git a/test/test-functions b/test/test-functions index 4606745f105..17779826846 100644 --- a/test/test-functions +++ b/test/test-functions @@ -1151,7 +1151,9 @@ install_multipath() { image_install kpartx /lib/udev/kpartx_id lsmod mpathpersist multipath multipathd partx image_install "${ROOTLIBDIR:?}"/system/multipathd.{service,socket} if get_bool "$LOOKS_LIKE_DEBIAN"; then - inst_rules 56-dm-parts.rules 56-dm-mpath.rules 60-multipath.rules 68-del-part-nodes.rules 95-kpartx.rules + # Note: try both 60-kpartx.rules (as seen on Debian Sid with 0.9.4-7) and 90-kpartx.rules (as seen on + # Ubuntu Jammy with 0.8.8-1ubuntu1.22.04.4) + inst_rules 56-dm-parts.rules 56-dm-mpath.rules 60-kpartx.rules 60-multipath.rules 68-del-part-nodes.rules 90-kpartx.rules else inst_rules 11-dm-mpath.rules 11-dm-parts.rules 62-multipath.rules 66-kpartx.rules 68-del-part-nodes.rules fi @@ -1198,6 +1200,11 @@ install_lvm() { mkdir -p "${initdir:?}/etc/lvm" } +host_has_btrfs() ( + set -e + modprobe -nv btrfs && command -v mkfs.btrfs && command -v btrfs || return $? +) + install_btrfs() { instmods btrfs # Not all utilities provided by btrfs-progs are listed here; extend the list @@ -1265,6 +1272,11 @@ install_iscsi() { fi } +host_has_mdadm() ( + set -e + command -v mdadm || return $? +) + install_mdadm() { local unit local mdadm_units=( @@ -1278,6 +1290,7 @@ install_mdadm() { system-shutdown/mdadm.shutdown ) + instmods "=md" image_install mdadm mdmon inst_rules 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules 69-md-clustered-confirm-device.rules # Fedora/CentOS/RHEL ships this rule file @@ -1286,6 +1299,10 @@ install_mdadm() { for unit in "${mdadm_units[@]}"; do image_install "${ROOTLIBDIR:?}/$unit" done + + # Disable the mdmonitor service, since it fails if there's no valid email address + # configured in /etc/mdadm.conf, which just unnecessarily pollutes the logs + "${SYSTEMCTL:?}" mask --root "${initdir:?}" mdmonitor.service || : } install_compiled_systemd() { @@ -1591,6 +1608,9 @@ create_empty_image() { # Partition sizes are in MiBs local root_size=768 local data_size=100 + local esp_size=128 + local boot_size=128 + local total= if ! get_bool "$NO_BUILD"; then if meson configure "${BUILD_DIR:?}" | grep 'static-lib\|standalone-binaries' | awk '{ print $2 }' | grep -q 'true'; then root_size=$((root_size + 200)) @@ -1613,28 +1633,44 @@ create_empty_image() { data_size=$((data_size + IMAGE_ADDITIONAL_DATA_SIZE)) fi - echo "Setting up ${IMAGE_PUBLIC:?} (${root_size} MB)" + total=$((root_size + data_size + esp_size + boot_size)) + + echo "Setting up ${IMAGE_PUBLIC:?} (${total} MB)" rm -f "${IMAGE_PRIVATE:?}" "$IMAGE_PUBLIC" # Create the blank file to use as a root filesystem - truncate -s "${root_size}M" "$IMAGE_PUBLIC" + truncate -s "${total}M" "$IMAGE_PUBLIC" LOOPDEV="$(losetup --show -P -f "$IMAGE_PUBLIC")" [[ -b "$LOOPDEV" ]] || return 1 # Create two partitions - a root one and a data one (utilized by some tests) sfdisk "$LOOPDEV" </run/systemd/system/badbin_assert.socket </run/systemd/coredump.conf.d/99-storage-journal.conf cat >"${TEST_RULE}" <"$defs/10-part1.conf" + echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=1\n" >"$defs/11-dropped-first.conf" + echo -ne "[Partition]\nType=root\n" >"$defs/12-part2.conf" + echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=2\n" >"$defs/13-dropped-second.conf" + + systemd-repart --empty=allow --pretty=yes --dry-run=no --definitions="$defs" "$image" + + sfdisk -q -l "$image" + [[ "$(sfdisk -q -l "$image" | grep -c "$image")" -eq 2 ]] +} + OFFLINE="yes" run_testcases diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh index 0e598cc6b3e..65e5f6cd91f 100755 --- a/test/units/testsuite-64.sh +++ b/test/units/testsuite-64.sh @@ -396,6 +396,11 @@ EOF udevadm control --reload + # initialize partition table + for disk in {0..9}; do + echo 'label: gpt' | udevadm lock --device="${devices[$disk]}" sfdisk -q "${devices[$disk]}" + done + # Delete the partitions, immediately recreate them, wait for udev to settle # down, and then check if we have any dangling symlinks in /dev/disk/. Rinse # and repeat. @@ -1159,10 +1164,6 @@ testcase_mdadm_lvm() { helper_check_device_units } -# Disable the mdmonitor service, since it fails if there's no valid email address -# configured in /etc/mdadm.conf, which just unnecessarily pollutes the logs -systemctl list-unit-files mdmonitor.service >/dev/null && systemctl mask --runtime mdmonitor.service - udevadm settle udevadm control --log-level debug lsblk -a diff --git a/test/units/testsuite-74.bootctl.sh b/test/units/testsuite-74.bootctl.sh new file mode 100755 index 00000000000..61373b506e4 --- /dev/null +++ b/test/units/testsuite-74.bootctl.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +if systemd-detect-virt --quiet --container; then + echo "running on container, skipping." + exit 0 +fi + +if ! command -v bootctl >/dev/null; then + echo "bootctl not found, skipping." + exit 0 +fi + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +# shellcheck source=test/units/test-control.sh +. "$(dirname "$0")"/test-control.sh + +basic_tests() { + bootctl "$@" --help + bootctl "$@" --version + + bootctl "$@" install --make-entry-directory=yes + bootctl "$@" remove --make-entry-directory=yes + + bootctl "$@" install --all-architectures + bootctl "$@" remove --all-architectures + + bootctl "$@" install --make-entry-directory=yes --all-architectures + bootctl "$@" remove --make-entry-directory=yes --all-architectures + + bootctl "$@" install + (! bootctl "$@" update) + bootctl "$@" update --graceful + + bootctl "$@" is-installed + bootctl "$@" is-installed --graceful + bootctl "$@" random-seed + + bootctl "$@" + bootctl "$@" status + bootctl "$@" status --quiet + bootctl "$@" list + bootctl "$@" list --quiet + bootctl "$@" list --json=short + bootctl "$@" list --json=pretty + + bootctl "$@" remove + (! bootctl "$@" is-installed) + (! bootctl "$@" is-installed --graceful) +} + +testcase_bootctl_basic() { + assert_eq "$(bootctl --print-esp-path)" "/efi" + assert_eq "$(bootctl --print-boot-path)" "/boot" + bootctl --print-root-device + + basic_tests +} + +cleanup_image() ( + set +e + + if [[ -z "${IMAGE_DIR:-}" ]]; then + return 0 + fi + + umount "${IMAGE_DIR}/root" + + if [[ -n "${LOOPDEV:-}" ]]; then + losetup -d "${LOOPDEV}" + unset LOOPDEV + fi + + udevadm settle + + rm -rf "${IMAGE_DIR}" + unset IMAGE_DIR + + return 0 +) + +testcase_bootctl_image() { + IMAGE_DIR="$(mktemp --directory /tmp/test-bootctl.XXXXXXXXXX)" + trap cleanup_image RETURN + + truncate -s 256m "${IMAGE_DIR}/image" + + cat >"${IMAGE_DIR}/partscript" </dev/null; then + echo "mdadm not found, skipping." + return 0 + fi + + if ! command -v mkfs.btrfs >/dev/null; then + echo "mkfs.btrfs not found, skipping." + return 0 + fi + + IMAGE_DIR="$(mktemp --directory /tmp/test-bootctl.XXXXXXXXXX)" + trap cleanup_raid RETURN + + truncate -s 256m "${IMAGE_DIR}/image1" + truncate -s 256m "${IMAGE_DIR}/image2" + + cat >"${IMAGE_DIR}/partscript" < Date: Wed, 24 Jan 2024 20:02:54 +0000 Subject: [PATCH 23/29] Drop patches merged upstream --- debian/patches/series | 2 - ...socket-once-the-triggered-unit-exits.patch | 56 ------------------- ...-correct-kpartx-udev-rules-on-Debian.patch | 25 --------- 3 files changed, 83 deletions(-) delete mode 100644 debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch delete mode 100644 debian/patches/test-install-correct-kpartx-udev-rules-on-Debian.patch diff --git a/debian/patches/series b/debian/patches/series index 3f277c76cf4..c921ceca788 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -11,5 +11,3 @@ test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch test-install-empty-directories-with-NO_BUILD-1.patch test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch -test-flush-the-socket-once-the-triggered-unit-exits.patch -test-install-correct-kpartx-udev-rules-on-Debian.patch diff --git a/debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch b/debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch deleted file mode 100644 index eb32fc77be7..00000000000 --- a/debian/patches/test-flush-the-socket-once-the-triggered-unit-exits.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Frantisek Sumsal -Date: Sun, 24 Dec 2023 12:53:53 +0100 -Subject: test: flush the socket once the triggered unit exits - -Since the triggered unit intentionally fails without consuming any data -from the socket, we'd try to trigger it again and again, and we might -try to check the unit state in one of the "in-between" states, failing -the test: - -[ 165.271698] H testsuite-07.sh[1032]: + systemctl start badbin_assert.socket -[ 165.977637] H testsuite-07.sh[1032]: + socat - ABSTRACT-CONNECT:badbin_assert.socket -[ 165.983787] H systemd[1]: Cannot find unit for notify message of PID 1039, ignoring. -[ 166.817187] H testsuite-07.sh[1032]: + timeout 10 sh -c 'while systemctl is-active badbin_assert.service; do sleep .5; done' -[ 167.049218] H testsuite-07.sh[1065]: active -[ 167.146854] H systemd[1]: Listening on badbin_assert.socket. -[ 167.163473] H systemd[1]: badbin_assert.socket: Incoming traffic -[ 167.542626] H systemd[1]: Cannot find unit for notify message of PID 1065, ignoring. -[ 167.543437] H (badbin)[1062]: badbin_assert.service: Failed to execute /tmp/badbin: Exec format error -[ 167.548346] H systemd[1]: badbin_assert.service: Main process exited, code=exited, status=203/EXEC -[ 167.549482] H systemd[1]: badbin_assert.service: Failed with result 'exit-code'. -[ 167.561537] H systemd[1]: badbin_assert.socket: Incoming traffic -[ 167.933390] H systemd[1]: Started badbin_assert.service. -[ 167.950489] H (badbin)[1070]: badbin_assert.service: Failed to execute /tmp/badbin: Exec format error -[ 167.956318] H systemd[1]: badbin_assert.service: Main process exited, code=exited, status=203/EXEC -[ 167.957173] H systemd[1]: badbin_assert.service: Failed with result 'exit-code'. -[ 167.974609] H systemd[1]: badbin_assert.socket: Incoming traffic -[ 168.042838] H testsuite-07.sh[1072]: failed -[ 168.094431] H testsuite-07.sh[1075]: ++ systemctl show -P ExecMainStatus badbin_assert.service -[ 168.704022] H systemd[1]: Started badbin_assert.service. -[ 168.778680] H (badbin)[1074]: badbin_assert.service: Failed to execute /tmp/badbin: Exec format error -[ 168.826881] H systemd[1]: badbin_assert.service: Main process exited, code=exited, status=203/EXEC -[ 168.833825] H systemd[1]: badbin_assert.service: Failed with result 'exit-code'. -[ 168.923931] H testsuite-07.sh[1032]: + [[ 0 == 203 ]] -[ 168.951492] H systemd[1]: Cannot find unit for notify message of PID 1075, ignoring. -[ 168.999862] H testsuite-07.sh[615]: + echo 'Subtest /usr/lib/systemd/tests/testdata/units/testsuite-07.issue-30412.sh failed' -[ 168.999862] H testsuite-07.sh[615]: Subtest /usr/lib/systemd/tests/testdata/units/testsuite-07.issue-30412.sh failed - -Follow-up for 1eeaa93de36 and 28a2d27650c. - -(cherry picked from commit 4ddf27c57bbaaa66bed5cfa951e60a83b9f64e29) ---- - test/units/testsuite-07.issue-30412.sh | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/test/units/testsuite-07.issue-30412.sh b/test/units/testsuite-07.issue-30412.sh -index 61801c5..c1cb00e 100755 ---- a/test/units/testsuite-07.issue-30412.sh -+++ b/test/units/testsuite-07.issue-30412.sh -@@ -20,6 +20,7 @@ EOF - cat >/run/systemd/system/badbin_assert.socket < -Date: Wed, 3 Jan 2024 17:24:03 +0100 -Subject: test: install correct kpartx udev rules on Debian - -Resolves: #30703 -(cherry picked from commit 519f0074cf87391b17a82ea983daed6183d62fb6) ---- - test/test-functions | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/test/test-functions b/test/test-functions -index f887346..2c79a66 100644 ---- a/test/test-functions -+++ b/test/test-functions -@@ -1151,7 +1151,9 @@ install_multipath() { - image_install kpartx /lib/udev/kpartx_id lsmod mpathpersist multipath multipathd partx - image_install "${ROOTLIBDIR:?}"/system/multipathd.{service,socket} - if get_bool "$LOOKS_LIKE_DEBIAN"; then -- inst_rules 56-dm-parts.rules 56-dm-mpath.rules 60-multipath.rules 68-del-part-nodes.rules 95-kpartx.rules -+ # Note: try both 60-kpartx.rules (as seen on Debian Sid with 0.9.4-7) and 90-kpartx.rules (as seen on -+ # Ubuntu Jammy with 0.8.8-1ubuntu1.22.04.4) -+ inst_rules 56-dm-parts.rules 56-dm-mpath.rules 60-kpartx.rules 60-multipath.rules 68-del-part-nodes.rules 90-kpartx.rules - else - inst_rules 11-dm-mpath.rules 11-dm-parts.rules 62-multipath.rules 66-kpartx.rules 68-del-part-nodes.rules - fi From 86bbc3c96a8eed36dd65c7c3eb4d46c3e540726d Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 24 Jan 2024 20:03:09 +0000 Subject: [PATCH 24/29] Refresh patches --- .../fsckd-daemon-for-inter-fsckd-communication.patch | 4 ++-- ...eck-for-Dinstall-tests-true-with-NO_BUILD-1.patch | 4 ++-- ...t-install-empty-directories-with-NO_BUILD-1.patch | 6 +++--- ...-to-load-anchors-from-etc-bind.keys-explici.patch | 12 ++++++------ 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch b/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch index 820be23cbc1..7ec4439f4b8 100644 --- a/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch +++ b/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch @@ -241,10 +241,10 @@ index 0000000..b7ad58d + + diff --git a/meson.build b/meson.build -index 7419e2b..4efaa1b 100644 +index f1f4e7e..24f5bd2 100644 --- a/meson.build +++ b/meson.build -@@ -2149,6 +2149,7 @@ subdir('src/environment-d-generator') +@@ -2152,6 +2152,7 @@ subdir('src/environment-d-generator') subdir('src/escape') subdir('src/firstboot') subdir('src/fsck') diff --git a/debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch b/debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch index 99e161fcbb5..564fe6a600a 100644 --- a/debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch +++ b/debian/patches/test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch @@ -8,10 +8,10 @@ Subject: test: don't check for -Dinstall-tests=true with NO_BUILD=1 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/test-functions b/test/test-functions -index 6a6f624..f887346 100644 +index 8f04a37..948a00b 100644 --- a/test/test-functions +++ b/test/test-functions -@@ -3309,9 +3309,10 @@ test_create_image() { +@@ -3345,9 +3345,10 @@ test_create_image() { } test_setup() { diff --git a/debian/patches/test-install-empty-directories-with-NO_BUILD-1.patch b/debian/patches/test-install-empty-directories-with-NO_BUILD-1.patch index 14983011b4d..cda40449a8b 100644 --- a/debian/patches/test-install-empty-directories-with-NO_BUILD-1.patch +++ b/debian/patches/test-install-empty-directories-with-NO_BUILD-1.patch @@ -9,10 +9,10 @@ Resolves: #30478 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/test/test-functions b/test/test-functions -index 4606745..6a6f624 100644 +index 1777982..8f04a37 100644 --- a/test/test-functions +++ b/test/test-functions -@@ -1310,19 +1310,35 @@ install_compiled_systemd() { +@@ -1327,19 +1327,35 @@ install_compiled_systemd() { fi } @@ -55,7 +55,7 @@ index 4606745..6a6f624 100644 done < <(grep -E '^Package:' "${SOURCE_DIR}/debian/control" | cut -d ':' -f 2) } -@@ -1337,17 +1353,7 @@ install_rpm() { +@@ -1354,17 +1370,7 @@ install_rpm() { dinfo "Installing contents of RPM $rpm" while read -r file; do diff --git a/debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch b/debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch index ba928cb9a6b..e3a3b31db2e 100644 --- a/debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch +++ b/debian/patches/test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch @@ -15,7 +15,7 @@ Resolves: #30477 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/test/units/testsuite-75.sh b/test/units/testsuite-75.sh -index 5dc31f8..093fdf9 100755 +index c9cdc68..5423448 100755 --- a/test/units/testsuite-75.sh +++ b/test/units/testsuite-75.sh @@ -20,6 +20,12 @@ run() { @@ -31,7 +31,7 @@ index 5dc31f8..093fdf9 100755 disable_ipv6() { sysctl -w net.ipv6.conf.all.disable_ipv6=1 } -@@ -356,15 +362,15 @@ grep -qF "unsigned.test IN MX 15 mail.unsigned.test" "$RUN_OUT" +@@ -359,15 +365,15 @@ grep -qF "unsigned.test IN MX 15 mail.unsigned.test" "$RUN_OUT" # Check the trust chain (with and without systemd-resolved in between # Issue: https://github.com/systemd/systemd/issues/22002 # PR: https://github.com/systemd/systemd/pull/23289 @@ -51,7 +51,7 @@ index 5dc31f8..093fdf9 100755 grep -qF "; fully validated" "$RUN_OUT" done run resolvectl query mail.signed.test -@@ -402,7 +408,7 @@ grep -qF "10.0.0.123" "$RUN_OUT" +@@ -405,7 +411,7 @@ grep -qF "10.0.0.123" "$RUN_OUT" grep -qF "fd00:dead:beef:cafe::123" "$RUN_OUT" grep -qF "authenticated: yes" "$RUN_OUT" # Check OPENPGPKEY support @@ -60,7 +60,7 @@ index 5dc31f8..093fdf9 100755 grep -qF "; fully validated" "$RUN_OUT" run resolvectl openpgp mr.smith@signed.test grep -qF "5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test" "$RUN_OUT" -@@ -418,11 +424,11 @@ check_domain() { +@@ -421,11 +427,11 @@ check_domain() { local addr for addr in "${DNS_ADDRESSES[@]}"; do @@ -74,7 +74,7 @@ index 5dc31f8..093fdf9 100755 grep -qF "$message" "$RUN_OUT" run resolvectl query "$domain" -@@ -458,9 +464,9 @@ grep -qE "^follow14\.final\.signed\.test\..+IN\s+NSEC\s+" "$RUN_OUT" +@@ -461,9 +467,9 @@ grep -qE "^follow14\.final\.signed\.test\..+IN\s+NSEC\s+" "$RUN_OUT" # Check the trust chain (with and without systemd-resolved in between # Issue: https://github.com/systemd/systemd/issues/22002 # PR: https://github.com/systemd/systemd/pull/23289 @@ -86,7 +86,7 @@ index 5dc31f8..093fdf9 100755 grep -qF "; fully validated" "$RUN_OUT" run dig +short sub.onlinesign.test -@@ -474,11 +480,11 @@ run resolvectl query --legend=no -t TXT onlinesign.test +@@ -477,11 +483,11 @@ run resolvectl query --legend=no -t TXT onlinesign.test grep -qF 'onlinesign.test IN TXT "hello from onlinesign"' "$RUN_OUT" for addr in "${DNS_ADDRESSES[@]}"; do From c94992098be6b494df946c2ad8c12d0e3bd5afa1 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 24 Jan 2024 20:03:55 +0000 Subject: [PATCH 25/29] Update changelog for 255.3-1 release --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index ccfdcc23cee..8a0cc0d7760 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +systemd (255.3-1) sid; urgency=medium + + * New upstream version 255.3 + * Drop patches merged upstream + * Refresh patches + + -- Luca Boccassi Wed, 24 Jan 2024 20:03:15 +0000 + systemd (255.2-4) sid; urgency=medium * autopkgtest: add btrfs-progs Depends to upstream suite. From c2d29c1493dbeeb40cc6700210308ca96ceaeb58 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Thu, 25 Jan 2024 13:20:24 +0000 Subject: [PATCH 26/29] Backport patches to fix reproducibility issues --- debian/patches/Sort-input-file-list.patch | 28 +++++++++ ...-drop-arch-filtering-in-syscall-list.patch | 47 +++++++++++++++ debian/patches/series | 3 + ...timezone-sensitive-unit-tests-are-ru.patch | 58 +++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 debian/patches/Sort-input-file-list.patch create mode 100644 debian/patches/meson-drop-arch-filtering-in-syscall-list.patch create mode 100644 debian/patches/test-unset-TZ-before-timezone-sensitive-unit-tests-are-ru.patch diff --git a/debian/patches/Sort-input-file-list.patch b/debian/patches/Sort-input-file-list.patch new file mode 100644 index 00000000000..5a51ae0175a --- /dev/null +++ b/debian/patches/Sort-input-file-list.patch @@ -0,0 +1,28 @@ +From: "Bernhard M. Wiedemann" +Date: Thu, 25 Jan 2024 05:48:35 +0100 +Subject: Sort input file list + +so that /usr/lib/systemd/tests/unit-tests/test-libsystemd-sym +builds in a reproducible way +in spite of non-deterministic filesystem readdir order + +See https://reproducible-builds.org/ for why this is good. + +This patch was done while working on reproducible builds for openSUSE. +--- + src/test/generate-sym-test.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/generate-sym-test.py b/src/test/generate-sym-test.py +index e97b6bb..028d108 100755 +--- a/src/test/generate-sym-test.py ++++ b/src/test/generate-sym-test.py +@@ -66,7 +66,7 @@ print(''' {} + }, symbols_from_source[] = {''') + + for dirpath, _, filenames in sorted(os.walk(sys.argv[2])): +- for filename in filenames: ++ for filename in sorted(filenames): + if not filename.endswith(".c") and not filename.endswith(".h"): + continue + with open(os.path.join(dirpath, filename), "r") as f: diff --git a/debian/patches/meson-drop-arch-filtering-in-syscall-list.patch b/debian/patches/meson-drop-arch-filtering-in-syscall-list.patch new file mode 100644 index 00000000000..316fd5614da --- /dev/null +++ b/debian/patches/meson-drop-arch-filtering-in-syscall-list.patch @@ -0,0 +1,47 @@ +From: =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= +Date: Thu, 25 Jan 2024 13:26:21 +0100 +Subject: meson: drop arch filtering in syscall list + +I added the filtering in 752fedbea7c02c82287c7ff2a4139f528b3f7ba8 as a way +to reduce the number of items in the tables. I thought it's "obvious", but +it might not be so. + +One immediate problem is that the filter is broken, because on arm64, +os.uname().machine returns "aarch64", so we incorrectly filter out the arm +syscalls (there is just one: arm_fadvise64_64). Of course we could fix the +filter, but I think it's better to nuke it altogether. The filter on applies to +1 arm syscall and 5 s390 syscalls, and we have 500+ other syscalls, so this +"optimization" doesn't really matter. OTOH, if we get the filter wrong, +the result is bad. And also, the existence of the filter at all creates +problems for cross-builds. + +I wanted to get rid of 'generate-syscall-list.py', but we need to generate a +backslash in the output. https://github.com/mesonbuild/meson/issues/1564 makes +this very very hard, since any attempt to put a backslash an inline argument +results in the backslash being replaces by a forward slash, which doesn't quite +have the same meaning. So let's use a standalone script until +https://github.com/mesonbuild/meson/issues/1564 is resolved. +--- + src/shared/generate-syscall-list.py | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/src/shared/generate-syscall-list.py b/src/shared/generate-syscall-list.py +index 3ee19ff..c0975a0 100755 +--- a/src/shared/generate-syscall-list.py ++++ b/src/shared/generate-syscall-list.py +@@ -2,15 +2,6 @@ + # SPDX-License-Identifier: LGPL-2.1-or-later + + import sys +-import os +- +-s390 = 's390' in os.uname().machine +-arm = 'arm' in os.uname().machine + + for line in open(sys.argv[1]): +- if line.startswith('s390_') and not s390: +- continue +- if line.startswith('arm_') and not arm: +- continue +- + print('"{}\\0"'.format(line.strip())) diff --git a/debian/patches/series b/debian/patches/series index c921ceca788..e794f71bcce 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -11,3 +11,6 @@ test-skip-TEST-08-INITRD-if-systemd-didn-t-run-in-the-ini.patch test-install-empty-directories-with-NO_BUILD-1.patch test-don-t-check-for-Dinstall-tests-true-with-NO_BUILD-1.patch test-tell-delv-to-load-anchors-from-etc-bind.keys-explici.patch +Sort-input-file-list.patch +meson-drop-arch-filtering-in-syscall-list.patch +test-unset-TZ-before-timezone-sensitive-unit-tests-are-ru.patch diff --git a/debian/patches/test-unset-TZ-before-timezone-sensitive-unit-tests-are-ru.patch b/debian/patches/test-unset-TZ-before-timezone-sensitive-unit-tests-are-ru.patch new file mode 100644 index 00000000000..2f28995c4a3 --- /dev/null +++ b/debian/patches/test-unset-TZ-before-timezone-sensitive-unit-tests-are-ru.patch @@ -0,0 +1,58 @@ +From: Luca Boccassi +Date: Fri, 26 Jan 2024 00:22:38 +0000 +Subject: test: unset TZ before timezone-sensitive unit tests are run + +Some tests have hard-coded results that need to match, and change if +the caller has a timezone set via the TZ= environment variable, as it +is the case during reproducible build tests. Unset it. +--- + src/test/test-calendarspec.c | 9 ++++++++- + src/test/test-date.c | 3 +++ + src/test/test-time-util.c | 3 +++ + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c +index db64142..18a0f8f 100644 +--- a/src/test/test-calendarspec.c ++++ b/src/test/test-calendarspec.c +@@ -254,4 +254,11 @@ TEST(calendar_spec_from_string) { + assert_se(calendar_spec_from_string("*:4,30:*\n", &c) == -EINVAL); + } + +-DEFINE_TEST_MAIN(LOG_INFO); ++static int intro(void) { ++ /* Tests have hard-coded results that do not expect a specific timezone to be set by the caller */ ++ assert_se(unsetenv("TZ") >= 0); ++ ++ return EXIT_SUCCESS; ++} ++ ++DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); +diff --git a/src/test/test-date.c b/src/test/test-date.c +index a7058a3..162ac34 100644 +--- a/src/test/test-date.c ++++ b/src/test/test-date.c +@@ -62,6 +62,9 @@ static void test_one_noutc(const char *p) { + } + + int main(int argc, char *argv[]) { ++ /* Tests have hard-coded results that do not expect a specific timezone to be set by the caller */ ++ assert_se(unsetenv("TZ") >= 0); ++ + test_setup_logging(LOG_DEBUG); + + test_one("17:41"); +diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c +index 76931ce..53bc779 100644 +--- a/src/test/test-time-util.c ++++ b/src/test/test-time-util.c +@@ -1171,6 +1171,9 @@ TEST(timezone_offset_change) { + } + + static int intro(void) { ++ /* Tests have hard-coded results that do not expect a specific timezone to be set by the caller */ ++ assert_se(unsetenv("TZ") >= 0); ++ + log_info("realtime=" USEC_FMT "\n" + "monotonic=" USEC_FMT "\n" + "boottime=" USEC_FMT "\n", From aa02c5a5558c74c7630dc312cea93c754473b852 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Thu, 25 Jan 2024 13:20:41 +0000 Subject: [PATCH 27/29] Salsa: re-enable reprotest --- debian/salsa-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index d1f51781983..025c0aedecc 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -5,4 +5,3 @@ include: variables: # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1011649 SALSA_CI_DISABLE_PIUPARTS: 1 - SALSA_CI_DISABLE_REPROTEST: 1 From 6a8ee37a8a1960253a82777db1b58c66ee3aa19a Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Mon, 29 Jan 2024 10:46:34 +0000 Subject: [PATCH 28/29] Update changelog for 255.3-2 release --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index 8a0cc0d7760..52ca4cf0340 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +systemd (255.3-2) sid; urgency=medium + + * Backport patches to fix reproducibility issues + * Salsa: re-enable reprotest + + -- Luca Boccassi Mon, 29 Jan 2024 10:46:19 +0000 + systemd (255.3-1) sid; urgency=medium * New upstream version 255.3 From 05ffedb2d8ee87193fdb826d11ee1420ca97484a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 22:55:23 +0000 Subject: [PATCH 29/29] Bump meson from 1.3.0 to 1.3.2 in /.github/workflows Bumps [meson](https://github.com/mesonbuild/meson) from 1.3.0 to 1.3.2. - [Release notes](https://github.com/mesonbuild/meson/releases) - [Commits](https://github.com/mesonbuild/meson/compare/1.3.0...1.3.2) --- updated-dependencies: - dependency-name: meson dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/requirements.txt b/.github/workflows/requirements.txt index b42b98e98aa..167b33c19b6 100644 --- a/.github/workflows/requirements.txt +++ b/.github/workflows/requirements.txt @@ -1,6 +1,6 @@ -meson==1.3.0 \ - --hash=sha256:4ba253ef60e454e23234696119cbafa082a0aead0bd3bbf6991295054795f5dc \ - --hash=sha256:e9f54046ce5b9a1f3024f7a7d52f19f085fd57c9d26a5db0cfcf0750572a8fd8 +meson==1.3.2 \ + --hash=sha256:0ba4a71fbc060c44721c7b674807598c5af9ea51335073cae7a3e9a95b375c89 \ + --hash=sha256:492eb450c8b073024276f916f5adbb3c4bb7e90e9e6ec124efda064f3d9b5baa ninja==1.11.1.1 \ --hash=sha256:18302d96a5467ea98b68e1cae1ae4b4fb2b2a56a82b955193c637557c7273dbd \ --hash=sha256:185e0641bde601e53841525c4196278e9aaf4463758da6dd1e752c0a0f54136a \