diff --git a/0157-swap-tell-swapon-to-reinitialize-swap-if-needed.patch b/0157-swap-tell-swapon-to-reinitialize-swap-if-needed.patch new file mode 100644 index 0000000..83ff24c --- /dev/null +++ b/0157-swap-tell-swapon-to-reinitialize-swap-if-needed.patch @@ -0,0 +1,29 @@ +From 94bab389194116ab10a68bca3d72c5b06f332645 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 12 Dec 2022 16:21:30 +0100 +Subject: [PATCH] swap: tell swapon to reinitialize swap if needed + +If the page size of a swap space doesn't match the page size of the +currently running kernel, swapon will fail. Let's instruct it to +reinitialize the swap space instead. + +(cherry picked from commit cc137d53e36da5e57b060be5e621864f572b2cac) + +Resolves: #2151993 +--- + src/core/swap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/swap.c b/src/core/swap.c +index 2196793ad1..5c83c4780f 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -827,7 +827,7 @@ static void swap_enter_activating(Swap *s) { + } + } + +- r = exec_command_set(s->control_command, "/sbin/swapon", NULL); ++ r = exec_command_set(s->control_command, "/sbin/swapon", "--fixpgsz", NULL); + if (r < 0) + goto fail; + diff --git a/0158-coredump-adjust-whitespace.patch b/0158-coredump-adjust-whitespace.patch new file mode 100644 index 0000000..b6dba41 --- /dev/null +++ b/0158-coredump-adjust-whitespace.patch @@ -0,0 +1,101 @@ +From e611a79647dd2ec68b8d5553d8aa566e79cd9f6e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 29 Nov 2022 09:00:16 +0100 +Subject: [PATCH] coredump: adjust whitespace + +(cherry picked from commit 510a146634f3e095b34e2a26023b1b1f99dcb8c0) + +Related: #2155517 +--- + src/coredump/coredump.c | 56 ++++++++++++++++++++--------------------- + 1 file changed, 28 insertions(+), 28 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 98e7492811..7a181bdeeb 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -110,16 +110,16 @@ enum { + }; + + static const char * const meta_field_names[_META_MAX] = { +- [META_ARGV_PID] = "COREDUMP_PID=", +- [META_ARGV_UID] = "COREDUMP_UID=", +- [META_ARGV_GID] = "COREDUMP_GID=", +- [META_ARGV_SIGNAL] = "COREDUMP_SIGNAL=", +- [META_ARGV_TIMESTAMP] = "COREDUMP_TIMESTAMP=", +- [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=", +- [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=", +- [META_COMM] = "COREDUMP_COMM=", +- [META_EXE] = "COREDUMP_EXE=", +- [META_UNIT] = "COREDUMP_UNIT=", ++ [META_ARGV_PID] = "COREDUMP_PID=", ++ [META_ARGV_UID] = "COREDUMP_UID=", ++ [META_ARGV_GID] = "COREDUMP_GID=", ++ [META_ARGV_SIGNAL] = "COREDUMP_SIGNAL=", ++ [META_ARGV_TIMESTAMP] = "COREDUMP_TIMESTAMP=", ++ [META_ARGV_RLIMIT] = "COREDUMP_RLIMIT=", ++ [META_ARGV_HOSTNAME] = "COREDUMP_HOSTNAME=", ++ [META_COMM] = "COREDUMP_COMM=", ++ [META_EXE] = "COREDUMP_EXE=", ++ [META_UNIT] = "COREDUMP_UNIT=", + }; + + typedef struct Context { +@@ -138,9 +138,9 @@ typedef enum CoredumpStorage { + } CoredumpStorage; + + static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = { +- [COREDUMP_STORAGE_NONE] = "none", ++ [COREDUMP_STORAGE_NONE] = "none", + [COREDUMP_STORAGE_EXTERNAL] = "external", +- [COREDUMP_STORAGE_JOURNAL] = "journal", ++ [COREDUMP_STORAGE_JOURNAL] = "journal", + }; + + DEFINE_PRIVATE_STRING_TABLE_LOOKUP(coredump_storage, CoredumpStorage); +@@ -156,13 +156,13 @@ static uint64_t arg_max_use = UINT64_MAX; + + static int parse_config(void) { + static const ConfigTableItem items[] = { +- { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage }, +- { "Coredump", "Compress", config_parse_bool, 0, &arg_compress }, +- { "Coredump", "ProcessSizeMax", config_parse_iec_uint64, 0, &arg_process_size_max }, +- { "Coredump", "ExternalSizeMax", config_parse_iec_uint64_infinity, 0, &arg_external_size_max }, +- { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max }, +- { "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free }, +- { "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use }, ++ { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage }, ++ { "Coredump", "Compress", config_parse_bool, 0, &arg_compress }, ++ { "Coredump", "ProcessSizeMax", config_parse_iec_uint64, 0, &arg_process_size_max }, ++ { "Coredump", "ExternalSizeMax", config_parse_iec_uint64_infinity, 0, &arg_external_size_max }, ++ { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max }, ++ { "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free }, ++ { "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use }, + {} + }; + +@@ -208,15 +208,15 @@ static int fix_acl(int fd, uid_t uid) { + static int fix_xattr(int fd, const Context *context) { + + static const char * const xattrs[_META_MAX] = { +- [META_ARGV_PID] = "user.coredump.pid", +- [META_ARGV_UID] = "user.coredump.uid", +- [META_ARGV_GID] = "user.coredump.gid", +- [META_ARGV_SIGNAL] = "user.coredump.signal", +- [META_ARGV_TIMESTAMP] = "user.coredump.timestamp", +- [META_ARGV_RLIMIT] = "user.coredump.rlimit", +- [META_ARGV_HOSTNAME] = "user.coredump.hostname", +- [META_COMM] = "user.coredump.comm", +- [META_EXE] = "user.coredump.exe", ++ [META_ARGV_PID] = "user.coredump.pid", ++ [META_ARGV_UID] = "user.coredump.uid", ++ [META_ARGV_GID] = "user.coredump.gid", ++ [META_ARGV_SIGNAL] = "user.coredump.signal", ++ [META_ARGV_TIMESTAMP] = "user.coredump.timestamp", ++ [META_ARGV_RLIMIT] = "user.coredump.rlimit", ++ [META_ARGV_HOSTNAME] = "user.coredump.hostname", ++ [META_COMM] = "user.coredump.comm", ++ [META_EXE] = "user.coredump.exe", + }; + + int r = 0; diff --git a/0159-coredump-do-not-allow-user-to-access-coredumps-with-.patch b/0159-coredump-do-not-allow-user-to-access-coredumps-with-.patch new file mode 100644 index 0000000..6fadae5 --- /dev/null +++ b/0159-coredump-do-not-allow-user-to-access-coredumps-with-.patch @@ -0,0 +1,383 @@ +From e86a03c4f201745a683cfe1549a202d5ae636b07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 28 Nov 2022 12:12:55 +0100 +Subject: [PATCH] coredump: do not allow user to access coredumps with changed + uid/gid/capabilities + +When the user starts a program which elevates its permissions via setuid, +setgid, or capabilities set on the file, it may access additional information +which would then be visible in the coredump. We shouldn't make the the coredump +visible to the user in such cases. + +Reported-by: Matthias Gerstner + +This reads the /proc//auxv file and attaches it to the process metadata as +PROC_AUXV. Before the coredump is submitted, it is parsed and if either +at_secure was set (which the kernel will do for processes that are setuid, +setgid, or setcap), or if the effective uid/gid don't match uid/gid, the file +is not made accessible to the user. If we can't access this data, we assume the +file should not be made accessible either. In principle we could also access +the auxv data from a note in the core file, but that is much more complex and +it seems better to use the stand-alone file that is provided by the kernel. + +Attaching auxv is both convient for this patch (because this way it's passed +between the stages along with other fields), but I think it makes sense to save +it in general. + +We use the information early in the core file to figure out if the program was +32-bit or 64-bit and its endianness. This way we don't need heuristics to guess +whether the format of the auxv structure. This test might reject some cases on +fringe architecutes. But the impact would be limited: we just won't grant the +user permissions to view the coredump file. If people report that we're missing +some cases, we can always enhance this to support more architectures. + +I tested auxv parsing on amd64, 32-bit program on amd64, arm64, arm32, and +ppc64el, but not the whole coredump handling. + +(cherry picked from commit 3e4d0f6cf99f8677edd6a237382a65bfe758de03) + +Resolves: #2155517 +--- + src/basic/io-util.h | 9 ++ + src/coredump/coredump.c | 196 +++++++++++++++++++++++++++++++++++++--- + 2 files changed, 192 insertions(+), 13 deletions(-) + +diff --git a/src/basic/io-util.h b/src/basic/io-util.h +index 39728e06bc..3afb134266 100644 +--- a/src/basic/io-util.h ++++ b/src/basic/io-util.h +@@ -91,7 +91,16 @@ struct iovec_wrapper *iovw_new(void); + struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw); + struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw); + void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors); ++ + int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len); ++static inline int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) { ++ /* Move data into iovw or free on error */ ++ int r = iovw_put(iovw, data, len); ++ if (r < 0) ++ free(data); ++ return r; ++} ++ + int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value); + int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value); + void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new); +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 7a181bdeeb..ea3d8c415a 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -106,6 +107,7 @@ enum { + + META_EXE = _META_MANDATORY_MAX, + META_UNIT, ++ META_PROC_AUXV, + _META_MAX + }; + +@@ -120,10 +122,12 @@ static const char * const meta_field_names[_META_MAX] = { + [META_COMM] = "COREDUMP_COMM=", + [META_EXE] = "COREDUMP_EXE=", + [META_UNIT] = "COREDUMP_UNIT=", ++ [META_PROC_AUXV] = "COREDUMP_PROC_AUXV=", + }; + + typedef struct Context { + const char *meta[_META_MAX]; ++ size_t meta_size[_META_MAX]; + pid_t pid; + bool is_pid1; + bool is_journald; +@@ -185,13 +189,16 @@ static uint64_t storage_size_max(void) { + return 0; + } + +-static int fix_acl(int fd, uid_t uid) { ++static int fix_acl(int fd, uid_t uid, bool allow_user) { ++ assert(fd >= 0); ++ assert(uid_is_valid(uid)); + + #if HAVE_ACL + int r; + +- assert(fd >= 0); +- assert(uid_is_valid(uid)); ++ /* We don't allow users to read coredumps if the uid or capabilities were changed. */ ++ if (!allow_user) ++ return 0; + + if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY) + return 0; +@@ -251,7 +258,8 @@ static int fix_permissions( + const char *filename, + const char *target, + const Context *context, +- uid_t uid) { ++ uid_t uid, ++ bool allow_user) { + + int r; + +@@ -261,7 +269,7 @@ static int fix_permissions( + + /* Ignore errors on these */ + (void) fchmod(fd, 0640); +- (void) fix_acl(fd, uid); ++ (void) fix_acl(fd, uid, allow_user); + (void) fix_xattr(fd, context); + + r = fsync_full(fd); +@@ -331,6 +339,153 @@ static int make_filename(const Context *context, char **ret) { + return 0; + } + ++static int parse_auxv64( ++ const uint64_t *auxv, ++ size_t size_bytes, ++ int *at_secure, ++ uid_t *uid, ++ uid_t *euid, ++ gid_t *gid, ++ gid_t *egid) { ++ ++ assert(auxv || size_bytes == 0); ++ ++ if (size_bytes % (2 * sizeof(uint64_t)) != 0) ++ return log_warning_errno(SYNTHETIC_ERRNO(EIO), "Incomplete auxv structure (%zu bytes).", size_bytes); ++ ++ size_t words = size_bytes / sizeof(uint64_t); ++ ++ /* Note that we set output variables even on error. */ ++ ++ for (size_t i = 0; i + 1 < words; i += 2) ++ switch (auxv[i]) { ++ case AT_SECURE: ++ *at_secure = auxv[i + 1] != 0; ++ break; ++ case AT_UID: ++ *uid = auxv[i + 1]; ++ break; ++ case AT_EUID: ++ *euid = auxv[i + 1]; ++ break; ++ case AT_GID: ++ *gid = auxv[i + 1]; ++ break; ++ case AT_EGID: ++ *egid = auxv[i + 1]; ++ break; ++ case AT_NULL: ++ if (auxv[i + 1] != 0) ++ goto error; ++ return 0; ++ } ++ error: ++ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA), ++ "AT_NULL terminator not found, cannot parse auxv structure."); ++} ++ ++static int parse_auxv32( ++ const uint32_t *auxv, ++ size_t size_bytes, ++ int *at_secure, ++ uid_t *uid, ++ uid_t *euid, ++ gid_t *gid, ++ gid_t *egid) { ++ ++ assert(auxv || size_bytes == 0); ++ ++ size_t words = size_bytes / sizeof(uint32_t); ++ ++ if (size_bytes % (2 * sizeof(uint32_t)) != 0) ++ return log_warning_errno(SYNTHETIC_ERRNO(EIO), "Incomplete auxv structure (%zu bytes).", size_bytes); ++ ++ /* Note that we set output variables even on error. */ ++ ++ for (size_t i = 0; i + 1 < words; i += 2) ++ switch (auxv[i]) { ++ case AT_SECURE: ++ *at_secure = auxv[i + 1] != 0; ++ break; ++ case AT_UID: ++ *uid = auxv[i + 1]; ++ break; ++ case AT_EUID: ++ *euid = auxv[i + 1]; ++ break; ++ case AT_GID: ++ *gid = auxv[i + 1]; ++ break; ++ case AT_EGID: ++ *egid = auxv[i + 1]; ++ break; ++ case AT_NULL: ++ if (auxv[i + 1] != 0) ++ goto error; ++ return 0; ++ } ++ error: ++ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA), ++ "AT_NULL terminator not found, cannot parse auxv structure."); ++} ++ ++static int grant_user_access(int core_fd, const Context *context) { ++ int at_secure = -1; ++ uid_t uid = UID_INVALID, euid = UID_INVALID; ++ uid_t gid = GID_INVALID, egid = GID_INVALID; ++ int r; ++ ++ assert(core_fd >= 0); ++ assert(context); ++ ++ if (!context->meta[META_PROC_AUXV]) ++ return log_warning_errno(SYNTHETIC_ERRNO(ENODATA), "No auxv data, not adjusting permissions."); ++ ++ uint8_t elf[EI_NIDENT]; ++ errno = 0; ++ if (pread(core_fd, &elf, sizeof(elf), 0) != sizeof(elf)) ++ return log_warning_errno(errno_or_else(EIO), ++ "Failed to pread from coredump fd: %s", STRERROR_OR_EOF(errno)); ++ ++ if (elf[EI_MAG0] != ELFMAG0 || ++ elf[EI_MAG1] != ELFMAG1 || ++ elf[EI_MAG2] != ELFMAG2 || ++ elf[EI_MAG3] != ELFMAG3 || ++ elf[EI_VERSION] != EV_CURRENT) ++ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), ++ "Core file does not have ELF header, not adjusting permissions."); ++ if (!IN_SET(elf[EI_CLASS], ELFCLASS32, ELFCLASS64) || ++ !IN_SET(elf[EI_DATA], ELFDATA2LSB, ELFDATA2MSB)) ++ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), ++ "Core file has strange ELF class, not adjusting permissions."); ++ ++ if ((elf[EI_DATA] == ELFDATA2LSB) != (__BYTE_ORDER == __LITTLE_ENDIAN)) ++ return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), ++ "Core file has non-native endianness, not adjusting permissions."); ++ ++ if (elf[EI_CLASS] == ELFCLASS64) ++ r = parse_auxv64((const uint64_t*) context->meta[META_PROC_AUXV], ++ context->meta_size[META_PROC_AUXV], ++ &at_secure, &uid, &euid, &gid, &egid); ++ else ++ r = parse_auxv32((const uint32_t*) context->meta[META_PROC_AUXV], ++ context->meta_size[META_PROC_AUXV], ++ &at_secure, &uid, &euid, &gid, &egid); ++ if (r < 0) ++ return r; ++ ++ /* We allow access if we got all the data and at_secure is not set and ++ * the uid/gid matches euid/egid. */ ++ bool ret = ++ at_secure == 0 && ++ uid != UID_INVALID && euid != UID_INVALID && uid == euid && ++ gid != GID_INVALID && egid != GID_INVALID && gid == egid; ++ log_debug("Will %s access (uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)", ++ ret ? "permit" : "restrict", ++ uid, euid, gid, egid, yes_no(at_secure)); ++ return ret; ++} ++ + static int save_external_coredump( + const Context *context, + int input_fd, +@@ -453,6 +608,8 @@ static int save_external_coredump( + context->meta[META_ARGV_PID], context->meta[META_COMM]); + truncated = r == 1; + ++ bool allow_user = grant_user_access(fd, context) > 0; ++ + #if HAVE_COMPRESSION + if (arg_compress) { + _cleanup_(unlink_and_freep) char *tmp_compressed = NULL; +@@ -490,7 +647,7 @@ static int save_external_coredump( + uncompressed_size += partial_uncompressed_size; + } + +- r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid); ++ r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid, allow_user); + if (r < 0) + return r; + +@@ -517,7 +674,7 @@ static int save_external_coredump( + "SIZE_LIMIT=%"PRIu64, max_size, + "MESSAGE_ID=" SD_MESSAGE_TRUNCATED_CORE_STR); + +- r = fix_permissions(fd, tmp, fn, context, uid); ++ r = fix_permissions(fd, tmp, fn, context, uid, allow_user); + if (r < 0) + return log_error_errno(r, "Failed to fix permissions and finalize coredump %s into %s: %m", coredump_tmpfile_name(tmp), fn); + +@@ -765,7 +922,7 @@ static int change_uid_gid(const Context *context) { + } + + static int submit_coredump( +- Context *context, ++ const Context *context, + struct iovec_wrapper *iovw, + int input_fd) { + +@@ -944,16 +1101,15 @@ static int save_context(Context *context, const struct iovec_wrapper *iovw) { + struct iovec *iovec = iovw->iovec + n; + + for (size_t i = 0; i < ELEMENTSOF(meta_field_names); i++) { +- char *p; +- + /* Note that these strings are NUL terminated, because we made sure that a + * trailing NUL byte is in the buffer, though not included in the iov_len + * count (see process_socket() and gather_pid_metadata_*()) */ + assert(((char*) iovec->iov_base)[iovec->iov_len] == 0); + +- p = startswith(iovec->iov_base, meta_field_names[i]); ++ const char *p = startswith(iovec->iov_base, meta_field_names[i]); + if (p) { + context->meta[i] = p; ++ context->meta_size[i] = iovec->iov_len - strlen(meta_field_names[i]); + break; + } + } +@@ -1190,6 +1346,7 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { + uid_t owner_uid; + pid_t pid; + char *t; ++ size_t size; + const char *p; + int r; + +@@ -1254,13 +1411,26 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { + (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_LIMITS=", t); + + p = procfs_file_alloca(pid, "cgroup"); +- if (read_full_virtual_file(p, &t, NULL) >=0) ++ if (read_full_virtual_file(p, &t, NULL) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_CGROUP=", t); + + p = procfs_file_alloca(pid, "mountinfo"); +- if (read_full_virtual_file(p, &t, NULL) >=0) ++ if (read_full_virtual_file(p, &t, NULL) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_PROC_MOUNTINFO=", t); + ++ /* We attach /proc/auxv here. ELF coredumps also contain a note for this (NT_AUXV), see elf(5). */ ++ p = procfs_file_alloca(pid, "auxv"); ++ if (read_full_virtual_file(p, &t, &size) >= 0) { ++ char *buf = malloc(strlen("COREDUMP_PROC_AUXV=") + size + 1); ++ if (buf) { ++ /* Add a dummy terminator to make save_context() happy. */ ++ *((uint8_t*) mempcpy(stpcpy(buf, "COREDUMP_PROC_AUXV="), t, size)) = '\0'; ++ (void) iovw_consume(iovw, buf, size + strlen("COREDUMP_PROC_AUXV=")); ++ } ++ ++ free(t); ++ } ++ + if (get_process_cwd(pid, &t) >= 0) + (void) iovw_put_string_field_free(iovw, "COREDUMP_CWD=", t); + diff --git a/0160-Revert-basic-add-fallback-in-chase_symlinks_and_open.patch b/0160-Revert-basic-add-fallback-in-chase_symlinks_and_open.patch new file mode 100644 index 0000000..7713be9 --- /dev/null +++ b/0160-Revert-basic-add-fallback-in-chase_symlinks_and_open.patch @@ -0,0 +1,43 @@ +From eb9135c9499f6be627323929df48bc9efc93926a Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 8 Dec 2022 10:56:42 +0100 +Subject: [PATCH] Revert "basic: add fallback in chase_symlinks_and_opendir() + for cases when /proc is not mounted" + +This reverts commit 47c0c5108b39d01283ba040c41d556b160d45a55. + +Related: #2138081 +--- + src/basic/chase-symlinks.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/src/basic/chase-symlinks.c b/src/basic/chase-symlinks.c +index c09aab389e..afab54f067 100644 +--- a/src/basic/chase-symlinks.c ++++ b/src/basic/chase-symlinks.c +@@ -466,22 +466,14 @@ int chase_symlinks_and_opendir( + return 0; + } + +- r = chase_symlinks(path, root, chase_flags, &p, &path_fd); ++ r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd); + if (r < 0) + return r; + assert(path_fd >= 0); + + d = opendir(FORMAT_PROC_FD_PATH(path_fd)); +- if (!d) { +- /* Hmm, we have the fd already but we got ENOENT, most likely /proc is not mounted. +- * Let's try opendir() again on the full path. */ +- if (errno == ENOENT) { +- d = opendir(p); +- if (!d) +- return -errno; +- } else +- return -errno; +- } ++ if (!d) ++ return -errno; + + if (ret_path) + *ret_path = TAKE_PTR(p); diff --git a/0161-glyph-util-add-warning-sign-special-glyph.patch b/0161-glyph-util-add-warning-sign-special-glyph.patch new file mode 100644 index 0000000..c46d475 --- /dev/null +++ b/0161-glyph-util-add-warning-sign-special-glyph.patch @@ -0,0 +1,72 @@ +From 008cc31066925ca8ef69ad6a03d20bb4ed299a41 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 2 Dec 2022 23:50:48 +0100 +Subject: [PATCH] glyph-util: add warning sign special glyph + +(cherry picked from commit 03c16b9784151275e71db3f9a25dc42206f1b5d3) + +Related: #2138081 +--- + src/basic/glyph-util.c | 4 +++- + src/basic/glyph-util.h | 1 + + src/test/test-locale-util.c | 3 ++- + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/basic/glyph-util.c b/src/basic/glyph-util.c +index 67f2270daf..de1224f04f 100644 +--- a/src/basic/glyph-util.c ++++ b/src/basic/glyph-util.c +@@ -71,6 +71,7 @@ const char *special_glyph(SpecialGlyph code) { + [SPECIAL_GLYPH_RECYCLING] = "~", + [SPECIAL_GLYPH_DOWNLOAD] = "\\", + [SPECIAL_GLYPH_SPARKLES] = "*", ++ [SPECIAL_GLYPH_WARNING_SIGN] = "!", + }, + + /* UTF-8 */ +@@ -124,10 +125,11 @@ const char *special_glyph(SpecialGlyph code) { + /* This emoji is a single character cell glyph in Unicode, and two in ASCII */ + [SPECIAL_GLYPH_TOUCH] = u8"👆", /* actually called: BACKHAND INDEX POINTING UP */ + +- /* These three emojis are single character cell glyphs in Unicode and also in ASCII. */ ++ /* These four emojis are single character cell glyphs in Unicode and also in ASCII. */ + [SPECIAL_GLYPH_RECYCLING] = u8"♻️", /* actually called: UNIVERSAL RECYCLNG SYMBOL */ + [SPECIAL_GLYPH_DOWNLOAD] = u8"⤵️", /* actually called: RIGHT ARROW CURVING DOWN */ + [SPECIAL_GLYPH_SPARKLES] = u8"✨", ++ [SPECIAL_GLYPH_WARNING_SIGN] = u8"⚠️", + }, + }; + +diff --git a/src/basic/glyph-util.h b/src/basic/glyph-util.h +index 621d7a85b7..b64639622e 100644 +--- a/src/basic/glyph-util.h ++++ b/src/basic/glyph-util.h +@@ -44,6 +44,7 @@ typedef enum SpecialGlyph { + SPECIAL_GLYPH_RECYCLING, + SPECIAL_GLYPH_DOWNLOAD, + SPECIAL_GLYPH_SPARKLES, ++ SPECIAL_GLYPH_WARNING_SIGN, + _SPECIAL_GLYPH_MAX, + _SPECIAL_GLYPH_INVALID = -EINVAL, + } SpecialGlyph; +diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c +index 9f50c6227f..f38100401c 100644 +--- a/src/test/test-locale-util.c ++++ b/src/test/test-locale-util.c +@@ -83,7 +83,7 @@ TEST(keymaps) { + + #define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x)) + TEST(dump_special_glyphs) { +- assert_cc(SPECIAL_GLYPH_SPARKLES + 1 == _SPECIAL_GLYPH_MAX); ++ assert_cc(SPECIAL_GLYPH_WARNING_SIGN + 1 == _SPECIAL_GLYPH_MAX); + + log_info("is_locale_utf8: %s", yes_no(is_locale_utf8())); + +@@ -120,6 +120,7 @@ TEST(dump_special_glyphs) { + dump_glyph(SPECIAL_GLYPH_RECYCLING); + dump_glyph(SPECIAL_GLYPH_DOWNLOAD); + dump_glyph(SPECIAL_GLYPH_SPARKLES); ++ dump_glyph(SPECIAL_GLYPH_WARNING_SIGN); + } + + DEFINE_TEST_MAIN(LOG_INFO); diff --git a/0162-chase-symlink-when-converting-directory-O_PATH-fd-to.patch b/0162-chase-symlink-when-converting-directory-O_PATH-fd-to.patch new file mode 100644 index 0000000..3ba6254 --- /dev/null +++ b/0162-chase-symlink-when-converting-directory-O_PATH-fd-to.patch @@ -0,0 +1,27 @@ +From 2bd9f97275480842c99117123daab69cbb8f45f4 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 2 Dec 2022 23:50:57 +0100 +Subject: [PATCH] chase-symlink: when converting directory O_PATH fd to real + fd, don't bother with /proc/ + +Replaces: #25581 +(cherry picked from commit 2075b6dd394e09a0f203b9cc7e3253908397f933) + +Related: #2138081 +--- + src/basic/chase-symlinks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/basic/chase-symlinks.c b/src/basic/chase-symlinks.c +index afab54f067..ac55311f4d 100644 +--- a/src/basic/chase-symlinks.c ++++ b/src/basic/chase-symlinks.c +@@ -471,7 +471,7 @@ int chase_symlinks_and_opendir( + return r; + assert(path_fd >= 0); + +- d = opendir(FORMAT_PROC_FD_PATH(path_fd)); ++ d = xopendirat(path_fd, ".", O_NOFOLLOW); + if (!d) + return -errno; + diff --git a/0163-systemctl-print-a-clear-warning-if-people-invoke-sys.patch b/0163-systemctl-print-a-clear-warning-if-people-invoke-sys.patch new file mode 100644 index 0000000..fa43830 --- /dev/null +++ b/0163-systemctl-print-a-clear-warning-if-people-invoke-sys.patch @@ -0,0 +1,39 @@ +From d98adab06485b0da23294f8a5db4f94b40988e2a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 2 Dec 2022 23:52:12 +0100 +Subject: [PATCH] systemctl: print a clear warning if people invoke systemctl + without /proc/ + +(cherry picked from commit 0f958c8d4fc13ed1c1af928b2a7d91d31c7576eb) + +Related: #2138081 +--- + src/systemctl/systemctl.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 5858c3f6d3..91954d91e6 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -20,6 +20,7 @@ + #include "rlimit-util.h" + #include "sigbus.h" + #include "signal-util.h" ++#include "stat-util.h" + #include "string-table.h" + #include "systemctl-add-dependency.h" + #include "systemctl-cancel-job.h" +@@ -1146,6 +1147,13 @@ static int run(int argc, char *argv[]) { + if (r <= 0) + goto finish; + ++ if (proc_mounted() == 0) ++ log_warning("%s%s/proc/ is not mounted. This is not a supported mode of operation. Please fix\n" ++ "your invocation environment to mount /proc/ and /sys/ properly. Proceeding anyway.\n" ++ "Your mileage may vary.", ++ emoji_enabled() ? special_glyph(SPECIAL_GLYPH_WARNING_SIGN) : "", ++ emoji_enabled() ? " " : ""); ++ + if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) { + if (!arg_quiet) + log_info("Running in chroot, ignoring request."); diff --git a/0164-TEST-65-check-cat-config-operation-in-chroot.patch b/0164-TEST-65-check-cat-config-operation-in-chroot.patch new file mode 100644 index 0000000..52a3d4a --- /dev/null +++ b/0164-TEST-65-check-cat-config-operation-in-chroot.patch @@ -0,0 +1,48 @@ +From 3be1c0fa543f024319a03e89decedc6106cb4e02 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 5 Dec 2022 13:52:28 +0100 +Subject: [PATCH] TEST-65: check cat-config operation in chroot + +This verifies the fix in 2075b6dd394e09a0f203b9cc7e3253908397f933. + +(cherry picked from commit a7eed3eca3d7bc022d870258deb2f738b9527c6d) + +Related: #2138081 +--- + test/test-functions | 1 + + test/units/testsuite-65.sh | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/test/test-functions b/test/test-functions +index 194cd682bb..94e11a686a 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -158,6 +158,7 @@ BASICTOOLS=( + cat + chmod + chown ++ chroot + cmp + cryptsetup + cut +diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh +index 1f34308b44..ebe1f57b52 100755 +--- a/test/units/testsuite-65.sh ++++ b/test/units/testsuite-65.sh +@@ -139,6 +139,16 @@ systemd-analyze cat-config systemd/system.conf systemd/journald.conf >/dev/null + systemd-analyze cat-config systemd/system.conf foo/bar systemd/journald.conf >/dev/null + systemd-analyze cat-config foo/bar + ++if [[ ! -v ASAN_OPTIONS ]]; then ++ # check that systemd-analyze cat-config paths work in a chroot ++ mkdir -p /tmp/root ++ mount --bind / /tmp/root ++ systemd-analyze cat-config systemd/system-preset >/tmp/out1 ++ chroot /tmp/root systemd-analyze cat-config systemd/system-preset >/tmp/out2 ++ diff /tmp/out{1,2} ++fi ++ ++# verify + mkdir -p /tmp/img/usr/lib/systemd/system/ + mkdir -p /tmp/img/opt/ + diff --git a/0165-TEST-65-use-v-more.patch b/0165-TEST-65-use-v-more.patch new file mode 100644 index 0000000..5ce2ece --- /dev/null +++ b/0165-TEST-65-use-v-more.patch @@ -0,0 +1,64 @@ +From fa44b8d1e6b0d5e0ef4dfcb01e26e7907068bfa3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Dec 2022 09:52:35 +0100 +Subject: [PATCH] TEST-65: use [[ -v ]] more + +It's a bashism, but we use other bash features anyway, and it's cleaner +and much less verbose. + +(cherry picked from commit 1f9caf28cafbec89b93b8e6b641d387ac5acdd24) + +Related: #2138081 +--- + test/units/testsuite-64.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh +index 7673036335..fd1ad7c041 100755 +--- a/test/units/testsuite-64.sh ++++ b/test/units/testsuite-64.sh +@@ -192,7 +192,7 @@ testcase_nvme_subsystem() { + testcase_virtio_scsi_identically_named_partitions() { + local num + +- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then ++ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then + num=$((4 * 4)) + else + num=$((16 * 8)) +@@ -305,7 +305,7 @@ testcase_simultaneous_events() { + local -a devices symlinks + local -A running + +- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then ++ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then + num_part=2 + iterations=10 + timeout=240 +@@ -400,7 +400,7 @@ testcase_lvm_basic() { + /dev/disk/by-id/ata-foobar_deadbeeflvm{0..3} + ) + +- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then ++ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then + timeout=180 + else + timeout=30 +@@ -453,7 +453,7 @@ testcase_lvm_basic() { + helper_check_device_units + + # Same as above, but now with more "stress" +- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then ++ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then + iterations=10 + else + iterations=50 +@@ -478,7 +478,7 @@ testcase_lvm_basic() { + helper_check_device_units + + # Create & remove LVs in a loop, i.e. with more "stress" +- if [[ -n "${ASAN_OPTIONS:-}" ]]; then ++ if [[ -v ASAN_OPTIONS ]]; then + iterations=8 + partitions=16 + elif [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then diff --git a/0166-systemctl-warn-if-trying-to-disable-a-unit-with-no-i.patch b/0166-systemctl-warn-if-trying-to-disable-a-unit-with-no-i.patch new file mode 100644 index 0000000..8049f63 --- /dev/null +++ b/0166-systemctl-warn-if-trying-to-disable-a-unit-with-no-i.patch @@ -0,0 +1,227 @@ +From 201c651eaaf886064987272cc88b03995fd2715d Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Fri, 18 Nov 2022 15:43:34 +0800 +Subject: [PATCH] systemctl: warn if trying to disable a unit with no install + info + +Trying to disable a unit with no install info is mostly useless, so +adding a warning like we do for enable (with the new dbus method +'DisableUnitFilesWithFlagsAndInstallInfo()'). Note that it would +still find and remove symlinks to the unit in /etc, regardless of +whether it has install info or not, just like before. And if there are +actually files to remove, we suppress the warning. + +Fixes #17689 + +(cherry picked from commit bf1bea43f15b04152a3948702ba1695a0835c2bf) + +Related: #2141979 +--- + man/org.freedesktop.systemd1.xml | 13 ++++++++++++- + src/core/dbus-manager.c | 21 ++++++++++++++++----- + src/shared/install.c | 21 +++++++++++++++++---- + src/systemctl/systemctl-enable.c | 15 ++++++++++----- + 4 files changed, 55 insertions(+), 15 deletions(-) + +diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml +index 5e08b35234..c2f70870c7 100644 +--- a/man/org.freedesktop.systemd1.xml ++++ b/man/org.freedesktop.systemd1.xml +@@ -209,6 +209,10 @@ node /org/freedesktop/systemd1 { + DisableUnitFilesWithFlags(in as files, + in t flags, + out a(sss) changes); ++ DisableUnitFilesWithFlagsAndInstallInfo(in as files, ++ in t flags, ++ out b carries_install_info, ++ out a(sss) changes); + ReenableUnitFiles(in as files, + in b runtime, + in b force, +@@ -916,6 +920,8 @@ node /org/freedesktop/systemd1 { + + + ++ ++ + + + +@@ -1417,7 +1423,7 @@ node /org/freedesktop/systemd1 { + enabled for runtime only (true, /run/), or persistently (false, + /etc/). The second one controls whether symlinks pointing to other units shall be + replaced if necessary. This method returns one boolean and an array of the changes made. The boolean +- signals whether the unit files contained any enablement information (i.e. an [Install]) section. The ++ signals whether the unit files contained any enablement information (i.e. an [Install] section). The + changes array consists of structures with three strings: the type of the change (one of + symlink or unlink), the file name of the symlink and the + destination of the symlink. Note that most of the following calls return a changes list in the same +@@ -1440,6 +1446,11 @@ node /org/freedesktop/systemd1 { + replaced if necessary. SD_SYSTEMD_UNIT_PORTABLE will add or remove the symlinks in + /etc/systemd/system.attached and /run/systemd/system.attached. + ++ DisableUnitFilesWithFlagsAndInstallInfo() is similar to ++ DisableUnitFilesWithFlags() and takes the same arguments, but returns ++ a boolean to indicate whether the unit files contain any enablement information, like ++ EnableUnitFiles(). The changes made are still returned in an array. ++ + Similarly, ReenableUnitFiles() applies the changes to one or more units that + would result from disabling and enabling the unit quickly one after the other in an atomic + fashion. This is useful to apply updated [Install] information contained in unit files. +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 88f098ec86..2db12721a1 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -2425,6 +2425,7 @@ static int method_disable_unit_files_generic( + sd_bus_message *message, + Manager *m, + int (*call)(LookupScope scope, UnitFileFlags flags, const char *root_dir, char *files[], InstallChange **changes, size_t *n_changes), ++ bool carries_install_info, + sd_bus_error *error) { + + _cleanup_strv_free_ char **l = NULL; +@@ -2440,7 +2441,8 @@ static int method_disable_unit_files_generic( + if (r < 0) + return r; + +- if (sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlags")) { ++ if (sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlags") || ++ sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlagsAndInstallInfo")) { + uint64_t raw_flags; + + r = sd_bus_message_read(message, "t", &raw_flags); +@@ -2469,19 +2471,23 @@ static int method_disable_unit_files_generic( + if (r < 0) + return install_error(error, r, changes, n_changes); + +- return reply_install_changes_and_free(m, message, -1, changes, n_changes, error); ++ return reply_install_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error); + } + + static int method_disable_unit_files_with_flags(sd_bus_message *message, void *userdata, sd_bus_error *error) { +- return method_disable_unit_files_generic(message, userdata, unit_file_disable, error); ++ return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ false, error); ++} ++ ++static int method_disable_unit_files_with_flags_and_install_info(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ true, error); + } + + static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { +- return method_disable_unit_files_generic(message, userdata, unit_file_disable, error); ++ return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ false, error); + } + + static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { +- return method_disable_unit_files_generic(message, userdata, unit_file_unmask, error); ++ return method_disable_unit_files_generic(message, userdata, unit_file_unmask, /* carries_install_info = */ false, error); + } + + static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { +@@ -3194,6 +3200,11 @@ const sd_bus_vtable bus_manager_vtable[] = { + SD_BUS_RESULT("a(sss)", changes), + method_disable_unit_files_with_flags, + SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_ARGS("DisableUnitFilesWithFlagsAndInstallInfo", ++ SD_BUS_ARGS("as", files, "t", flags), ++ SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes), ++ method_disable_unit_files_with_flags_and_install_info, ++ SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_ARGS("ReenableUnitFiles", + SD_BUS_ARGS("as", files, "b", runtime, "b", force), + SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes), +diff --git a/src/shared/install.c b/src/shared/install.c +index 834a1c59e3..4b610b20a5 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -2790,25 +2790,38 @@ static int do_unit_file_disable( + + _cleanup_(install_context_done) InstallContext ctx = { .scope = scope }; + _cleanup_set_free_free_ Set *remove_symlinks_to = NULL; ++ InstallInfo *info; ++ bool has_install_info = false; + int r; + + STRV_FOREACH(name, names) { + if (!unit_name_is_valid(*name, UNIT_NAME_ANY)) + return install_changes_add(changes, n_changes, -EUCLEAN, *name, NULL); + +- r = install_info_add(&ctx, *name, NULL, lp->root_dir, /* auxiliary= */ false, NULL); ++ r = install_info_add(&ctx, *name, NULL, lp->root_dir, /* auxiliary= */ false, &info); ++ if (r >= 0) ++ r = install_info_traverse(&ctx, lp, info, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL); ++ + if (r < 0) +- return r; ++ return install_changes_add(changes, n_changes, r, *name, NULL); ++ ++ /* If we enable multiple units, some with install info and others without, ++ * the "empty [Install] section" warning is not shown. Let's make the behavior ++ * of disable align with that. */ ++ has_install_info = has_install_info || install_info_has_rules(info) || install_info_has_also(info); + } + + r = install_context_mark_for_removal(&ctx, lp, &remove_symlinks_to, config_path, changes, n_changes); ++ if (r >= 0) ++ r = remove_marked_symlinks(remove_symlinks_to, config_path, lp, flags & UNIT_FILE_DRY_RUN, changes, n_changes); ++ + if (r < 0) + return r; + +- return remove_marked_symlinks(remove_symlinks_to, config_path, lp, flags & UNIT_FILE_DRY_RUN, changes, n_changes); ++ /* The warning is shown only if it's a no-op */ ++ return install_changes_have_modification(*changes, *n_changes) || has_install_info; + } + +- + int unit_file_disable( + LookupScope scope, + UnitFileFlags flags, +diff --git a/src/systemctl/systemctl-enable.c b/src/systemctl/systemctl-enable.c +index 5be4c0c725..aea66872de 100644 +--- a/src/systemctl/systemctl-enable.c ++++ b/src/systemctl/systemctl-enable.c +@@ -109,9 +109,10 @@ int verb_enable(int argc, char *argv[], void *userdata) { + if (streq(verb, "enable")) { + r = unit_file_enable(arg_scope, flags, arg_root, names, &changes, &n_changes); + carries_install_info = r; +- } else if (streq(verb, "disable")) ++ } else if (streq(verb, "disable")) { + r = unit_file_disable(arg_scope, flags, arg_root, names, &changes, &n_changes); +- else if (streq(verb, "reenable")) { ++ carries_install_info = r; ++ } else if (streq(verb, "reenable")) { + r = unit_file_reenable(arg_scope, flags, arg_root, names, &changes, &n_changes); + carries_install_info = r; + } else if (streq(verb, "link")) +@@ -165,7 +166,8 @@ int verb_enable(int argc, char *argv[], void *userdata) { + method = "EnableUnitFiles"; + expect_carries_install_info = true; + } else if (streq(verb, "disable")) { +- method = "DisableUnitFiles"; ++ method = "DisableUnitFilesWithFlagsAndInstallInfo"; ++ expect_carries_install_info = true; + send_force = false; + } else if (streq(verb, "reenable")) { + method = "ReenableUnitFiles"; +@@ -208,7 +210,10 @@ int verb_enable(int argc, char *argv[], void *userdata) { + } + + if (send_runtime) { +- r = sd_bus_message_append(m, "b", arg_runtime); ++ if (streq(method, "DisableUnitFilesWithFlagsAndInstallInfo")) ++ r = sd_bus_message_append(m, "t", arg_runtime ? UNIT_FILE_RUNTIME : 0); ++ else ++ r = sd_bus_message_append(m, "b", arg_runtime); + if (r < 0) + return bus_log_create_error(r); + } +@@ -245,7 +250,7 @@ int verb_enable(int argc, char *argv[], void *userdata) { + if (carries_install_info == 0 && !ignore_carries_install_info) + log_notice("The unit files have no installation config (WantedBy=, RequiredBy=, Also=,\n" + "Alias= settings in the [Install] section, and DefaultInstance= for template\n" +- "units). This means they are not meant to be enabled using systemctl.\n" ++ "units). This means they are not meant to be enabled or disabled using systemctl.\n" + " \n" /* trick: the space is needed so that the line does not get stripped from output */ + "Possible reasons for having this kind of units are:\n" + "%1$s A unit may be statically enabled by being symlinked from another unit's\n" diff --git a/0167-systemctl-allow-suppress-the-warning-of-no-install-i.patch b/0167-systemctl-allow-suppress-the-warning-of-no-install-i.patch new file mode 100644 index 0000000..6c25260 --- /dev/null +++ b/0167-systemctl-allow-suppress-the-warning-of-no-install-i.patch @@ -0,0 +1,136 @@ +From 79c16ad7a09623b987a50a0d04a61fed41e45a77 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Sun, 27 Nov 2022 21:18:44 +0800 +Subject: [PATCH] systemctl: allow suppress the warning of no install info + using --no-warn + +In cases like packaging scripts, it might be desired to use +enable/disable on units without install info. So, adding an +option '--no-warn' to suppress the warning. + +(cherry picked from commit 108d35ac7d435b4f1378a9c0fa50858263475e09) + +Related: #2141979 +--- + man/systemctl.xml | 18 ++++++++++++++++-- + src/systemctl/systemctl-enable.c | 2 +- + src/systemctl/systemctl.c | 9 +++++++++ + src/systemctl/systemctl.h | 1 + + 4 files changed, 27 insertions(+), 3 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index f743c182fe..d909dc4db4 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -771,6 +771,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + account. + + ++ When using this operation on units without install information, a warning about it is shown. ++ can be used to suppress the warning. ++ + Enabling units should not be confused with starting (activating) units, as done by the + start command. Enabling and starting units is orthogonal: units may be enabled without + being started and started without being enabled. Enabling simply hooks the unit into various suggested +@@ -814,8 +817,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + executed. This output may be suppressed by passing . + + +- This command honors , , +- and in a similar way as enable. ++ This command honors , , , ++ and in a similar way as enable. + + + +@@ -1997,6 +2000,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + + ++ ++ ++ ++ ++ Don't generate the warning shown by default when using ++ enable or disable on units ++ without install information (i.e. don't have or have an empty ++ [Install] section). ++ ++ ++ + + + +diff --git a/src/systemctl/systemctl-enable.c b/src/systemctl/systemctl-enable.c +index aea66872de..86d9f602fa 100644 +--- a/src/systemctl/systemctl-enable.c ++++ b/src/systemctl/systemctl-enable.c +@@ -67,7 +67,7 @@ int verb_enable(int argc, char *argv[], void *userdata) { + InstallChange *changes = NULL; + size_t n_changes = 0; + int carries_install_info = -1; +- bool ignore_carries_install_info = arg_quiet; ++ bool ignore_carries_install_info = arg_quiet || arg_no_warn; + int r; + + if (!argv[1]) +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 91954d91e6..57e9966d3c 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -83,6 +83,7 @@ bool arg_show_types = false; + int arg_check_inhibitors = -1; + bool arg_dry_run = false; + bool arg_quiet = false; ++bool arg_no_warn = false; + bool arg_full = false; + bool arg_recursive = false; + bool arg_with_dependencies = false; +@@ -276,6 +277,8 @@ static int systemctl_help(void) { + " kexec, suspend, hibernate, suspend-then-hibernate,\n" + " hybrid-sleep, default, rescue, emergency, and exit.\n" + " -q --quiet Suppress output\n" ++ " --no-warn Don't generate warning when trying to enable/disable\n" ++ " units without install information\n" + " --wait For (re)start, wait until service stopped again\n" + " For is-system-running, wait until startup is completed\n" + " --no-block Do not wait until operation finished\n" +@@ -432,6 +435,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + ARG_READ_ONLY, + ARG_MKDIR, + ARG_MARKED, ++ ARG_NO_WARN, + }; + + static const struct option options[] = { +@@ -464,6 +468,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { "dry-run", no_argument, NULL, ARG_DRY_RUN }, + { "quiet", no_argument, NULL, 'q' }, ++ { "no-warn", no_argument, NULL, ARG_NO_WARN }, + { "root", required_argument, NULL, ARG_ROOT }, + { "image", required_argument, NULL, ARG_IMAGE }, + { "force", no_argument, NULL, 'f' }, +@@ -925,6 +930,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + arg_marked = true; + break; + ++ case ARG_NO_WARN: ++ arg_no_warn = true; ++ break; ++ + case '.': + /* Output an error mimicking getopt, and print a hint afterwards */ + log_error("%s: invalid option -- '.'", program_invocation_name); +diff --git a/src/systemctl/systemctl.h b/src/systemctl/systemctl.h +index 2454c4c714..1a7a6e28d3 100644 +--- a/src/systemctl/systemctl.h ++++ b/src/systemctl/systemctl.h +@@ -65,6 +65,7 @@ extern bool arg_show_types; + extern int arg_check_inhibitors; + extern bool arg_dry_run; + extern bool arg_quiet; ++extern bool arg_no_warn; + extern bool arg_full; + extern bool arg_recursive; + extern bool arg_with_dependencies; diff --git a/0168-rpm-systemd-update-helper-use-no-warn-when-disabling.patch b/0168-rpm-systemd-update-helper-use-no-warn-when-disabling.patch new file mode 100644 index 0000000..bc54cb6 --- /dev/null +++ b/0168-rpm-systemd-update-helper-use-no-warn-when-disabling.patch @@ -0,0 +1,44 @@ +From 4161593c24ea24f03bc89d74147e7209dc02ba80 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Sat, 3 Dec 2022 20:27:47 +0800 +Subject: [PATCH] rpm/systemd-update-helper: use --no-warn when disabling units + +Suppress the "empty [Install] section" warning (see #25437). + +(cherry picked from commit 0acb1459a15f5b4d3a9bd2e7bf52661ca7bdebf0) + +Related: #2141979 +--- + src/rpm/systemd-update-helper.in | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in +index ab8cdc0ff9..b35d952fab 100755 +--- a/src/rpm/systemd-update-helper.in ++++ b/src/rpm/systemd-update-helper.in +@@ -19,21 +19,21 @@ case "$command" in + + remove-system-units) + if [ -d /run/systemd/system ]; then +- systemctl --no-reload disable --now "$@" ++ systemctl --no-reload disable --now --no-warn "$@" + else +- systemctl --no-reload disable "$@" ++ systemctl --no-reload disable --no-warn "$@" + fi + ;; + + remove-user-units) +- systemctl --global disable "$@" ++ systemctl --global disable --no-warn "$@" + + [ -d /run/systemd/system ] || exit 0 + + users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') + for user in $users; do + SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ +- systemctl --user -M "$user@" disable --now "$@" & ++ systemctl --user -M "$user@" disable --now --no-warn "$@" & + done + wait + ;; diff --git a/0169-systemctl-suppress-warning-about-missing-proc-when-n.patch b/0169-systemctl-suppress-warning-about-missing-proc-when-n.patch new file mode 100644 index 0000000..2f3a8ee --- /dev/null +++ b/0169-systemctl-suppress-warning-about-missing-proc-when-n.patch @@ -0,0 +1,80 @@ +From 02fbe7d4c9bd34134c12978726b036ec1ceea839 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 7 Dec 2022 13:59:01 +0900 +Subject: [PATCH] systemctl: suppress warning about missing /proc/ when + --no-warn + +Follow-up for 0f958c8d4fc13ed1c1af928b2a7d91d31c7576eb. + +systemctl is called many times by dnf or so, and missing /proc/ is not +a user's fault, but package manager's issue. +With this commit, we can suppress the warning by updating rpm macros if +necessary. + +(cherry picked from commit 91dfb74ef5e38625dada2c2a6ae30152e64c3f5b) + +Related: #2141979 +--- + man/systemctl.xml | 16 ++++++++++++---- + src/systemctl/systemctl.c | 14 +++++++------- + 2 files changed, 19 insertions(+), 11 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index d909dc4db4..b73d4ac048 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2004,10 +2004,18 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + + +- Don't generate the warning shown by default when using +- enable or disable on units +- without install information (i.e. don't have or have an empty +- [Install] section). ++ Don't generate the warnings shown by default in the following cases: ++ ++ ++ when systemctl is invoked without procfs mounted on ++ /proc/, ++ ++ ++ when using enable or disable on units without ++ install information (i.e. don't have or have an empty [Install] section). ++ ++ ++ + + + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 57e9966d3c..3f2b0029ca 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -277,8 +277,7 @@ static int systemctl_help(void) { + " kexec, suspend, hibernate, suspend-then-hibernate,\n" + " hybrid-sleep, default, rescue, emergency, and exit.\n" + " -q --quiet Suppress output\n" +- " --no-warn Don't generate warning when trying to enable/disable\n" +- " units without install information\n" ++ " --no-warn Suppress several warnings shown by default\n" + " --wait For (re)start, wait until service stopped again\n" + " For is-system-running, wait until startup is completed\n" + " --no-block Do not wait until operation finished\n" +@@ -1157,11 +1156,12 @@ static int run(int argc, char *argv[]) { + goto finish; + + if (proc_mounted() == 0) +- log_warning("%s%s/proc/ is not mounted. This is not a supported mode of operation. Please fix\n" +- "your invocation environment to mount /proc/ and /sys/ properly. Proceeding anyway.\n" +- "Your mileage may vary.", +- emoji_enabled() ? special_glyph(SPECIAL_GLYPH_WARNING_SIGN) : "", +- emoji_enabled() ? " " : ""); ++ log_full(arg_no_warn ? LOG_DEBUG : LOG_WARNING, ++ "%s%s/proc/ is not mounted. This is not a supported mode of operation. Please fix\n" ++ "your invocation environment to mount /proc/ and /sys/ properly. Proceeding anyway.\n" ++ "Your mileage may vary.", ++ emoji_enabled() ? special_glyph(SPECIAL_GLYPH_WARNING_SIGN) : "", ++ emoji_enabled() ? " " : ""); + + if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) { + if (!arg_quiet) diff --git a/0170-shell-completion-systemctl-add-no-warn.patch b/0170-shell-completion-systemctl-add-no-warn.patch new file mode 100644 index 0000000..fc30e3e --- /dev/null +++ b/0170-shell-completion-systemctl-add-no-warn.patch @@ -0,0 +1,38 @@ +From 282bb5b70e6ff146ba81fea82d85d1e3f0cebc77 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 13 Dec 2022 09:05:11 +0900 +Subject: [PATCH] shell-completion: systemctl: add --no-warn + +(cherry picked from commit 93b0ec8bc533e8e8245560152c57e9c5dfb906bf) + +Related: #2141979 +--- + shell-completion/bash/systemctl.in | 2 +- + shell-completion/zsh/_systemctl.in | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in +index f935960c77..3c64467e2f 100644 +--- a/shell-completion/bash/systemctl.in ++++ b/shell-completion/bash/systemctl.in +@@ -128,7 +128,7 @@ _systemctl () { + [STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global + --help -h --no-ask-password --no-block --legend=no --no-pager --no-reload --no-wall --now + --quiet -q --system --user --version --runtime --recursive -r --firmware-setup +- --show-types --plain --failed --value --fail --dry-run --wait' ++ --show-types --plain --failed --value --fail --dry-run --wait --no-warn' + [ARG]='--host -H --kill-whom --property -p --signal -s --type -t --state --job-mode --root + --preset-mode -n --lines -o --output -M --machine --message --timestamp --check-inhibitors' + ) +diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in +index d471743030..2811582236 100644 +--- a/shell-completion/zsh/_systemctl.in ++++ b/shell-completion/zsh/_systemctl.in +@@ -480,6 +480,7 @@ _arguments -s \ + '--show-types[When showing sockets, show socket type]' \ + '--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \ + {-q,--quiet}'[Suppress output]' \ ++ '--no-warn[Suppress several warnings shown by default]' \ + '--no-block[Do not wait until operation finished]' \ + '--legend=no[Do not print a legend, i.e. the column headers and the footer with hints]' \ + '--no-pager[Do not pipe output into a pager]' \ diff --git a/0171-core-unit-drop-doubled-empty-line.patch b/0171-core-unit-drop-doubled-empty-line.patch new file mode 100644 index 0000000..4247ca0 --- /dev/null +++ b/0171-core-unit-drop-doubled-empty-line.patch @@ -0,0 +1,24 @@ +From bc9f6f765f772e8535325c224d2023165bc53e5c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Nov 2022 12:54:11 +0900 +Subject: [PATCH] core/unit: drop doubled empty line + +(cherry picked from commit ca1999a24c88b2460240aaff8095c2db7491f77c) + +Related: #2160477 +--- + src/core/unit.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 4bb7e2d498..4cde5c4b4e 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -720,7 +720,6 @@ Unit* unit_free(Unit *u) { + if (u->on_console) + manager_unref_console(u->manager); + +- + fdset_free(u->initial_socket_bind_link_fds); + #if BPF_FRAMEWORK + bpf_link_free(u->ipv4_socket_bind_link); diff --git a/0172-core-unit-drop-dependency-to-the-unit-being-merged.patch b/0172-core-unit-drop-dependency-to-the-unit-being-merged.patch new file mode 100644 index 0000000..3cba262 --- /dev/null +++ b/0172-core-unit-drop-dependency-to-the-unit-being-merged.patch @@ -0,0 +1,66 @@ +From 82e78c509c9eab33c1dbf2bc445f91b67b2f118f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 16 Nov 2022 03:08:22 +0900 +Subject: [PATCH] core/unit: drop dependency to the unit being merged + +Fixes a bug in 15ed3c3a188cf7fa5a60ae508fc7a3ed048d2220. + +Fixes #24990. Also, hopefully fixes #24577. + +(cherry picked from commit c8b3b524134539846917269ddd644ee93a35623f) + +Related: #2160477 +--- + src/core/unit.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 4cde5c4b4e..ae9f688ad2 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1043,10 +1043,10 @@ static int unit_add_dependency_hashmap( + return unit_per_dependency_type_hashmap_update(per_type, other, origin_mask, destination_mask); + } + +-static void unit_merge_dependencies( +- Unit *u, +- Unit *other) { +- ++static void unit_merge_dependencies(Unit *u, Unit *other) { ++ Hashmap *deps; ++ void *dt; /* Actually of type UnitDependency, except that we don't bother casting it here, ++ * since the hashmaps all want it as void pointer. */ + int r; + + assert(u); +@@ -1055,12 +1055,19 @@ static void unit_merge_dependencies( + if (u == other) + return; + ++ /* First, remove dependency to other. */ ++ HASHMAP_FOREACH_KEY(deps, dt, u->dependencies) { ++ if (hashmap_remove(deps, other)) ++ unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt)); ++ ++ if (hashmap_isempty(deps)) ++ hashmap_free(hashmap_remove(u->dependencies, dt)); ++ } ++ + for (;;) { + _cleanup_(hashmap_freep) Hashmap *other_deps = NULL; + UnitDependencyInfo di_back; + Unit *back; +- void *dt; /* Actually of type UnitDependency, except that we don't bother casting it here, +- * since the hashmaps all want it as void pointer. */ + + /* Let's focus on one dependency type at a time, that 'other' has defined. */ + other_deps = hashmap_steal_first_key_and_value(other->dependencies, &dt); +@@ -1102,8 +1109,6 @@ static void unit_merge_dependencies( + * them per type wholesale. */ + r = hashmap_put(u->dependencies, dt, other_deps); + if (r == -EEXIST) { +- Hashmap *deps; +- + /* The target unit already has dependencies of this type, let's then merge this individually. */ + + assert_se(deps = hashmap_get(u->dependencies, dt)); diff --git a/0173-core-unit-fix-logic-of-dropping-self-referencing-dep.patch b/0173-core-unit-fix-logic-of-dropping-self-referencing-dep.patch new file mode 100644 index 0000000..684c98c --- /dev/null +++ b/0173-core-unit-fix-logic-of-dropping-self-referencing-dep.patch @@ -0,0 +1,32 @@ +From 1d12983063afc64709894d80b7adcf6609aa9a43 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Nov 2022 23:08:35 +0900 +Subject: [PATCH] core/unit: fix logic of dropping self-referencing + dependencies + +Fixes a bug in 15ed3c3a188cf7fa5a60ae508fc7a3ed048d2220. + +(cherry picked from commit 53e0e6ef0eea396bb432cbfc1f2f6ea1272ff1f1) + +Related: #2160477 +--- + src/core/unit.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index ae9f688ad2..dbbf818622 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1130,10 +1130,11 @@ static void unit_merge_dependencies(Unit *u, Unit *other) { + } + } else { + assert_se(r >= 0); +- TAKE_PTR(other_deps); + + if (hashmap_remove(other_deps, u)) + unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt)); ++ ++ TAKE_PTR(other_deps); + } + } + diff --git a/0174-core-unit-merge-two-loops-into-one.patch b/0174-core-unit-merge-two-loops-into-one.patch new file mode 100644 index 0000000..a8250dc --- /dev/null +++ b/0174-core-unit-merge-two-loops-into-one.patch @@ -0,0 +1,96 @@ +From 471e4ee0b4fa9c7e9a5ea875fbf22de77fdd25d0 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 17 Nov 2022 12:46:45 +0900 +Subject: [PATCH] core/unit: merge two loops into one + +No functional change, just refactoring. + +(cherry picked from commit 4b7918a65cc2571a2b3fc166229e1b8db463e217) + +Related: #2160477 +--- + src/core/unit.c | 47 +++++++++++++++-------------------------------- + 1 file changed, 15 insertions(+), 32 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index dbbf818622..6b49edc2de 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1047,7 +1047,6 @@ static void unit_merge_dependencies(Unit *u, Unit *other) { + Hashmap *deps; + void *dt; /* Actually of type UnitDependency, except that we don't bother casting it here, + * since the hashmaps all want it as void pointer. */ +- int r; + + assert(u); + assert(other); +@@ -1074,6 +1073,8 @@ static void unit_merge_dependencies(Unit *u, Unit *other) { + if (!other_deps) + break; /* done! */ + ++ deps = hashmap_get(u->dependencies, dt); ++ + /* Now iterate through all dependencies of this dependency type, of 'other'. We refer to the + * referenced units as 'back'. */ + HASHMAP_FOREACH_KEY(di_back.data, back, other_deps) { +@@ -1084,6 +1085,7 @@ static void unit_merge_dependencies(Unit *u, Unit *other) { + /* This is a dependency pointing back to the unit we want to merge with? + * Suppress it (but warn) */ + unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt)); ++ hashmap_remove(other_deps, back); + continue; + } + +@@ -1102,40 +1104,21 @@ static void unit_merge_dependencies(Unit *u, Unit *other) { + di_move.origin_mask, + di_move.destination_mask) >= 0); + } +- } + +- /* Now all references towards 'other' of the current type 'dt' are corrected to point to +- * 'u'. Lets's now move the deps of type 'dt' from 'other' to 'u'. First, let's try to move +- * them per type wholesale. */ +- r = hashmap_put(u->dependencies, dt, other_deps); +- if (r == -EEXIST) { + /* The target unit already has dependencies of this type, let's then merge this individually. */ +- +- assert_se(deps = hashmap_get(u->dependencies, dt)); +- +- for (;;) { +- UnitDependencyInfo di_move; +- +- /* Get first dep */ +- di_move.data = hashmap_steal_first_key_and_value(other_deps, (void**) &back); +- if (!di_move.data) +- break; /* done */ +- if (back == u) { +- /* Would point back to us, ignore */ +- unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt)); +- continue; +- } +- +- assert_se(unit_per_dependency_type_hashmap_update(deps, back, di_move.origin_mask, di_move.destination_mask) >= 0); +- } +- } else { +- assert_se(r >= 0); +- +- if (hashmap_remove(other_deps, u)) +- unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt)); +- +- TAKE_PTR(other_deps); ++ if (deps) ++ assert_se(unit_per_dependency_type_hashmap_update( ++ deps, ++ back, ++ di_back.origin_mask, ++ di_back.destination_mask) >= 0); + } ++ ++ /* Now all references towards 'other' of the current type 'dt' are corrected to point to 'u'. ++ * Lets's now move the deps of type 'dt' from 'other' to 'u'. If the unit does not have ++ * dependencies of this type, let's move them per type wholesale. */ ++ if (!deps) ++ assert_se(hashmap_put(u->dependencies, dt, TAKE_PTR(other_deps)) >= 0); + } + + other->dependencies = hashmap_free(other->dependencies); diff --git a/0175-test-add-test-case-for-sysv-generator-and-invalid-de.patch b/0175-test-add-test-case-for-sysv-generator-and-invalid-de.patch new file mode 100644 index 0000000..c4c0d1a --- /dev/null +++ b/0175-test-add-test-case-for-sysv-generator-and-invalid-de.patch @@ -0,0 +1,148 @@ +From 55e11475d421f90cc5c7290c6b5d394f952ba577 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Nov 2022 21:52:10 +0900 +Subject: [PATCH] test: add test case for sysv-generator and invalid dependency + +(cherry picked from commit 5f882cc3ab32636d9242effb2cefad20d92d2ec2) + +Related: #2160477 +--- + test/units/testsuite-26.sh | 116 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 114 insertions(+), 2 deletions(-) + +diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh +index 7c7a12b1ae..a8e7a5abaa 100755 +--- a/test/units/testsuite-26.sh ++++ b/test/units/testsuite-26.sh +@@ -3,10 +3,18 @@ + set -eux + set -o pipefail + ++# shellcheck source=test/units/assert.sh ++. "$(dirname "$0")"/assert.sh ++ ++: >/failed ++ + at_exit() { + if [[ -v UNIT_NAME && -e "/usr/lib/systemd/system/$UNIT_NAME" ]]; then + rm -fv "/usr/lib/systemd/system/$UNIT_NAME" + fi ++ ++ rm -f /etc/init.d/issue-24990 ++ return 0 + } + + trap at_exit EXIT +@@ -284,6 +292,110 @@ systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO + (! systemctl show-environment | grep "^IMPORT_THIS=") + (! systemctl show-environment | grep "^IMPORT_THIS_TOO=") + +-echo OK >/testok ++# test for sysv-generator (issue #24990) ++if [[ -x /usr/lib/systemd/system-generators/systemd-sysv-generator ]]; then ++ ++ # invalid dependency ++ cat >/etc/init.d/issue-24990 <<\EOF ++#!/bin/bash ++ ++### BEGIN INIT INFO ++# Provides:test1 test2 ++# Required-Start:test1 $remote_fs $network ++# Required-Stop:test1 $remote_fs $network ++# Description:Test ++# Short-Description: Test ++### END INIT INFO ++ ++case "$1" in ++ start) ++ echo "Starting issue-24990.service" ++ sleep 1000 & ++ ;; ++ stop) ++ echo "Stopping issue-24990.service" ++ sleep 10 & ++ ;; ++ *) ++ echo "Usage: service test {start|stop|restart|status}" ++ ;; ++esac ++EOF ++ ++ chmod +x /etc/init.d/issue-24990 ++ systemctl daemon-reload ++ [[ -L /run/systemd/generator.late/test1.service ]] ++ [[ -L /run/systemd/generator.late/test2.service ]] ++ assert_eq "$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service" ++ assert_eq "$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service" ++ output=$(systemctl cat issue-24990) ++ assert_in "SourcePath=/etc/init.d/issue-24990" "$output" ++ assert_in "Description=LSB: Test" "$output" ++ assert_in "After=test1.service" "$output" ++ assert_in "After=remote-fs.target" "$output" ++ assert_in "After=network-online.target" "$output" ++ assert_in "Wants=network-online.target" "$output" ++ assert_in "ExecStart=/etc/init.d/issue-24990 start" "$output" ++ assert_in "ExecStop=/etc/init.d/issue-24990 stop" "$output" ++ systemctl status issue-24990 || : ++ systemctl show issue-24990 ++ assert_not_in "issue-24990.service" "$(systemctl show --property=After --value)" ++ assert_not_in "issue-24990.service" "$(systemctl show --property=Before --value)" ++ ++ if ! systemctl is-active network-online.target; then ++ systemctl start network-online.target ++ fi ++ ++ systemctl restart issue-24990 ++ systemctl stop issue-24990 ++ ++ # valid dependency ++ cat >/etc/init.d/issue-24990 <<\EOF ++#!/bin/bash ++ ++### BEGIN INIT INFO ++# Provides:test1 test2 ++# Required-Start:$remote_fs ++# Required-Stop:$remote_fs ++# Description:Test ++# Short-Description: Test ++### END INIT INFO ++ ++case "$1" in ++ start) ++ echo "Starting issue-24990.service" ++ sleep 1000 & ++ ;; ++ stop) ++ echo "Stopping issue-24990.service" ++ sleep 10 & ++ ;; ++ *) ++ echo "Usage: service test {start|stop|restart|status}" ++ ;; ++esac ++EOF ++ ++ chmod +x /etc/init.d/issue-24990 ++ systemctl daemon-reload ++ [[ -L /run/systemd/generator.late/test1.service ]] ++ [[ -L /run/systemd/generator.late/test2.service ]] ++ assert_eq "$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service" ++ assert_eq "$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service" ++ output=$(systemctl cat issue-24990) ++ assert_in "SourcePath=/etc/init.d/issue-24990" "$output" ++ assert_in "Description=LSB: Test" "$output" ++ assert_in "After=remote-fs.target" "$output" ++ assert_in "ExecStart=/etc/init.d/issue-24990 start" "$output" ++ assert_in "ExecStop=/etc/init.d/issue-24990 stop" "$output" ++ systemctl status issue-24990 || : ++ systemctl show issue-24990 ++ assert_not_in "issue-24990.service" "$(systemctl show --property=After --value)" ++ assert_not_in "issue-24990.service" "$(systemctl show --property=Before --value)" ++ ++ systemctl restart issue-24990 ++ systemctl stop issue-24990 ++fi + +-exit 0 ++touch /testok ++rm /failed diff --git a/0176-core-unit-merge-unit-names-after-merging-deps.patch b/0176-core-unit-merge-unit-names-after-merging-deps.patch new file mode 100644 index 0000000..75585f4 --- /dev/null +++ b/0176-core-unit-merge-unit-names-after-merging-deps.patch @@ -0,0 +1,45 @@ +From 48455fa876129bf33df06d2e758fb0fbda510d5b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 16 Nov 2022 03:18:30 +0900 +Subject: [PATCH] core/unit: merge unit names after merging deps + +Before: +systemd[1]: issue-24990.service: Dependency Before=n/a dropped, merged into issue-24990.service +After: +systemd[1]: issue-24990.service: Dependency Before=test1.service dropped, merged into issue-24990.service + +(cherry picked from commit 1d0c81a05b1605a5fc3db44d5a157a1d6876eda9) + +Related: #2160477 +--- + src/core/unit.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 6b49edc2de..d1929bbf69 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1164,11 +1164,6 @@ int unit_merge(Unit *u, Unit *other) { + if (r < 0) + return r; + +- /* Merge names */ +- r = unit_merge_names(u, other); +- if (r < 0) +- return r; +- + /* Redirect all references */ + while (other->refs_by_target) + unit_ref_set(other->refs_by_target, other->refs_by_target->source, u); +@@ -1176,6 +1171,11 @@ int unit_merge(Unit *u, Unit *other) { + /* Merge dependencies */ + unit_merge_dependencies(u, other); + ++ /* Merge names. It is better to do that after merging deps, otherwise the log message contains n/a. */ ++ r = unit_merge_names(u, other); ++ if (r < 0) ++ return r; ++ + other->load_state = UNIT_MERGED; + other->merged_into = u; + diff --git a/0177-core-unit-fix-log-message.patch b/0177-core-unit-fix-log-message.patch new file mode 100644 index 0000000..ead6ae9 --- /dev/null +++ b/0177-core-unit-fix-log-message.patch @@ -0,0 +1,113 @@ +From 883e46f2e4255b92a338c9d4004a8b4740cdbcaf Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Nov 2022 22:59:01 +0900 +Subject: [PATCH] core/unit: fix log message + +As you can see in the below, the dropped dependency Before=issue-24990.service +is not logged, but the dependency Before=test1.service which is not owned by +the units generated by the TEST-26 is logged. + +Before: +systemd[1]: issue-24990.service: Dependency After=test1.service dropped, merged into issue-24990.service +systemd[1]: issue-24990.service: Dependency Before=test1.service dropped, merged into issue-24990.service + +After: +systemd[1]: issue-24990.service: Dependency After=test1.service is dropped, as test1.service is merged into issue-24990.service. +systemd[1]: issue-24990.service: Dependency Before=issue-24990.service in test1.service is dropped, as test1.service is merged into issue-24990.service. + +(cherry picked from commit ed9911630e4bca844381d7caeb850dad9a9fa122) + +Related: #2160477 +--- + src/core/unit.c | 49 ++++++++++++++++++++++--------------------------- + 1 file changed, 22 insertions(+), 27 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index d1929bbf69..c319e99d71 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -936,29 +936,17 @@ static int unit_reserve_dependencies(Unit *u, Unit *other) { + return 0; + } + +-static void unit_maybe_warn_about_dependency( +- Unit *u, +- const char *other_id, +- UnitDependency dependency) { +- +- assert(u); +- ++static bool unit_should_warn_about_dependency(UnitDependency dependency) { + /* Only warn about some unit types */ +- if (!IN_SET(dependency, +- UNIT_CONFLICTS, +- UNIT_CONFLICTED_BY, +- UNIT_BEFORE, +- UNIT_AFTER, +- UNIT_ON_SUCCESS, +- UNIT_ON_FAILURE, +- UNIT_TRIGGERS, +- UNIT_TRIGGERED_BY)) +- return; +- +- if (streq_ptr(u->id, other_id)) +- log_unit_warning(u, "Dependency %s=%s dropped", unit_dependency_to_string(dependency), u->id); +- else +- log_unit_warning(u, "Dependency %s=%s dropped, merged into %s", unit_dependency_to_string(dependency), strna(other_id), u->id); ++ return IN_SET(dependency, ++ UNIT_CONFLICTS, ++ UNIT_CONFLICTED_BY, ++ UNIT_BEFORE, ++ UNIT_AFTER, ++ UNIT_ON_SUCCESS, ++ UNIT_ON_FAILURE, ++ UNIT_TRIGGERS, ++ UNIT_TRIGGERED_BY); + } + + static int unit_per_dependency_type_hashmap_update( +@@ -1056,8 +1044,10 @@ static void unit_merge_dependencies(Unit *u, Unit *other) { + + /* First, remove dependency to other. */ + HASHMAP_FOREACH_KEY(deps, dt, u->dependencies) { +- if (hashmap_remove(deps, other)) +- unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt)); ++ if (hashmap_remove(deps, other) && unit_should_warn_about_dependency(UNIT_DEPENDENCY_FROM_PTR(dt))) ++ log_unit_warning(u, "Dependency %s=%s is dropped, as %s is merged into %s.", ++ unit_dependency_to_string(UNIT_DEPENDENCY_FROM_PTR(dt)), ++ other->id, other->id, u->id); + + if (hashmap_isempty(deps)) + hashmap_free(hashmap_remove(u->dependencies, dt)); +@@ -1084,7 +1074,11 @@ static void unit_merge_dependencies(Unit *u, Unit *other) { + if (back == u) { + /* This is a dependency pointing back to the unit we want to merge with? + * Suppress it (but warn) */ +- unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt)); ++ if (unit_should_warn_about_dependency(UNIT_DEPENDENCY_FROM_PTR(dt))) ++ log_unit_warning(u, "Dependency %s=%s in %s is dropped, as %s is merged into %s.", ++ unit_dependency_to_string(UNIT_DEPENDENCY_FROM_PTR(dt)), ++ u->id, other->id, other->id, u->id); ++ + hashmap_remove(other_deps, back); + continue; + } +@@ -3049,7 +3043,6 @@ int unit_add_dependency( + [UNIT_IN_SLICE] = UNIT_SLICE_OF, + [UNIT_SLICE_OF] = UNIT_IN_SLICE, + }; +- Unit *original_u = u, *original_other = other; + UnitDependencyAtom a; + int r; + +@@ -3068,7 +3061,9 @@ int unit_add_dependency( + + /* We won't allow dependencies on ourselves. We will not consider them an error however. */ + if (u == other) { +- unit_maybe_warn_about_dependency(original_u, original_other->id, d); ++ if (unit_should_warn_about_dependency(d)) ++ log_unit_warning(u, "Dependency %s=%s is dropped.", ++ unit_dependency_to_string(d), u->id); + return 0; + } + diff --git a/0178-test-explicitly-create-the-etc-init.d-directory.patch b/0178-test-explicitly-create-the-etc-init.d-directory.patch new file mode 100644 index 0000000..e8becc0 --- /dev/null +++ b/0178-test-explicitly-create-the-etc-init.d-directory.patch @@ -0,0 +1,34 @@ +From 0bdf4aaa0d8cdc6b2721d09fe630bf6185903a0d Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 12 Jan 2023 19:19:28 +0100 +Subject: [PATCH] test: explicitly create the /etc/init.d directory + +On RHEL/CentOS/Fedora this directory is provided by the chkconfig or +initscripts package, which might not be installed: + +testsuite-26.sh[1225]: + [[ -x /usr/lib/systemd/system-generators/systemd-sysv-generator ]] +testsuite-26.sh[1225]: + cat +testsuite-26.sh[2330]: /usr/lib/systemd/tests/testdata/units/testsuite-26.sh: line 299: /etc/init.d/issue-24990: No such file or directory + +Follow-up to 5f882cc3ab32636d9242effb2cefad20d92d2ec2. + +(cherry picked from commit 7fcf0fab078ed92a4f6c3c3658c0a9dfd67c9601) + +Related: #2160477 +--- + test/units/testsuite-26.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh +index a8e7a5abaa..37ae6069bc 100755 +--- a/test/units/testsuite-26.sh ++++ b/test/units/testsuite-26.sh +@@ -294,7 +294,7 @@ systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO + + # test for sysv-generator (issue #24990) + if [[ -x /usr/lib/systemd/system-generators/systemd-sysv-generator ]]; then +- ++ mkdir -p /etc/init.d + # invalid dependency + cat >/etc/init.d/issue-24990 <<\EOF + #!/bin/bash diff --git a/0179-test-support-a-non-default-SysV-directory.patch b/0179-test-support-a-non-default-SysV-directory.patch new file mode 100644 index 0000000..8c9c4a3 --- /dev/null +++ b/0179-test-support-a-non-default-SysV-directory.patch @@ -0,0 +1,97 @@ +From 956944405391b5bbb8a4fee9ad93e14bf908f0a9 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 13 Jan 2023 20:10:42 +0100 +Subject: [PATCH] test: support a non-default SysV directory + +Since the directory is configurable via -Dsysvinit-path= during build, +it makes the test fail on Fedora/RHEL/CentOS, where it's set to +/etc/rc.d/init.d, instead of the default /etc/init.d. Since we can't get +the value at runtime (in a reasonable manner), let's just support the +two most common paths for now. + +Follow up to 7fcf0fab078ed92a4f6c3c3658c0a9dfd67c9601. + +(cherry picked from commit fc2a0bc05e0429e468c7eaad52998292105fe7fb) + +Related: #2160477 +--- + test/units/testsuite-26.sh | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh +index 37ae6069bc..916a6704d7 100755 +--- a/test/units/testsuite-26.sh ++++ b/test/units/testsuite-26.sh +@@ -294,9 +294,12 @@ systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO + + # test for sysv-generator (issue #24990) + if [[ -x /usr/lib/systemd/system-generators/systemd-sysv-generator ]]; then +- mkdir -p /etc/init.d ++ # This is configurable via -Dsysvinit-path=, but we can't get the value ++ # at runtime, so let's just support the two most common paths for now. ++ [[ -d /etc/rc.d/init.d ]] && SYSVINIT_PATH="/etc/rc.d/init.d" || SYSVINIT_PATH="/etc/init.d" ++ + # invalid dependency +- cat >/etc/init.d/issue-24990 <<\EOF ++ cat >"${SYSVINIT_PATH:?}/issue-24990" <<\EOF + #!/bin/bash + + ### BEGIN INIT INFO +@@ -322,21 +325,21 @@ case "$1" in + esac + EOF + +- chmod +x /etc/init.d/issue-24990 ++ chmod +x "$SYSVINIT_PATH/issue-24990" + systemctl daemon-reload + [[ -L /run/systemd/generator.late/test1.service ]] + [[ -L /run/systemd/generator.late/test2.service ]] + assert_eq "$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service" + assert_eq "$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service" + output=$(systemctl cat issue-24990) +- assert_in "SourcePath=/etc/init.d/issue-24990" "$output" ++ assert_in "SourcePath=$SYSVINIT_PATH/issue-24990" "$output" + assert_in "Description=LSB: Test" "$output" + assert_in "After=test1.service" "$output" + assert_in "After=remote-fs.target" "$output" + assert_in "After=network-online.target" "$output" + assert_in "Wants=network-online.target" "$output" +- assert_in "ExecStart=/etc/init.d/issue-24990 start" "$output" +- assert_in "ExecStop=/etc/init.d/issue-24990 stop" "$output" ++ assert_in "ExecStart=$SYSVINIT_PATH/issue-24990 start" "$output" ++ assert_in "ExecStop=$SYSVINIT_PATH/issue-24990 stop" "$output" + systemctl status issue-24990 || : + systemctl show issue-24990 + assert_not_in "issue-24990.service" "$(systemctl show --property=After --value)" +@@ -350,7 +353,7 @@ EOF + systemctl stop issue-24990 + + # valid dependency +- cat >/etc/init.d/issue-24990 <<\EOF ++ cat >"$SYSVINIT_PATH/issue-24990" <<\EOF + #!/bin/bash + + ### BEGIN INIT INFO +@@ -376,18 +379,18 @@ case "$1" in + esac + EOF + +- chmod +x /etc/init.d/issue-24990 ++ chmod +x "$SYSVINIT_PATH/issue-24990" + systemctl daemon-reload + [[ -L /run/systemd/generator.late/test1.service ]] + [[ -L /run/systemd/generator.late/test2.service ]] + assert_eq "$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service" + assert_eq "$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service" + output=$(systemctl cat issue-24990) +- assert_in "SourcePath=/etc/init.d/issue-24990" "$output" ++ assert_in "SourcePath=$SYSVINIT_PATH/issue-24990" "$output" + assert_in "Description=LSB: Test" "$output" + assert_in "After=remote-fs.target" "$output" +- assert_in "ExecStart=/etc/init.d/issue-24990 start" "$output" +- assert_in "ExecStop=/etc/init.d/issue-24990 stop" "$output" ++ assert_in "ExecStart=$SYSVINIT_PATH/issue-24990 start" "$output" ++ assert_in "ExecStop=$SYSVINIT_PATH/issue-24990 stop" "$output" + systemctl status issue-24990 || : + systemctl show issue-24990 + assert_not_in "issue-24990.service" "$(systemctl show --property=After --value)" diff --git a/systemd.spec b/systemd.spec index 5ad2828..f9ade3a 100644 --- a/systemd.spec +++ b/systemd.spec @@ -21,7 +21,7 @@ Name: systemd Url: https://www.freedesktop.org/wiki/Software/systemd Version: 252 -Release: 2%{?dist} +Release: 3%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -234,6 +234,29 @@ Patch0153: 0153-dissect-rework-DISSECT_IMAGE_ADD_PARTITION_DEVICES-D.patch Patch0154: 0154-ci-Mergify-v252-configuration-update.patch Patch0155: 0155-ci-Run-GitHub-workflows-on-rhel-branches.patch Patch0156: 0156-ci-Drop-scorecards-workflow-not-relevant.patch +Patch0157: 0157-swap-tell-swapon-to-reinitialize-swap-if-needed.patch +Patch0158: 0158-coredump-adjust-whitespace.patch +Patch0159: 0159-coredump-do-not-allow-user-to-access-coredumps-with-.patch +Patch0160: 0160-Revert-basic-add-fallback-in-chase_symlinks_and_open.patch +Patch0161: 0161-glyph-util-add-warning-sign-special-glyph.patch +Patch0162: 0162-chase-symlink-when-converting-directory-O_PATH-fd-to.patch +Patch0163: 0163-systemctl-print-a-clear-warning-if-people-invoke-sys.patch +Patch0164: 0164-TEST-65-check-cat-config-operation-in-chroot.patch +Patch0165: 0165-TEST-65-use-v-more.patch +Patch0166: 0166-systemctl-warn-if-trying-to-disable-a-unit-with-no-i.patch +Patch0167: 0167-systemctl-allow-suppress-the-warning-of-no-install-i.patch +Patch0168: 0168-rpm-systemd-update-helper-use-no-warn-when-disabling.patch +Patch0169: 0169-systemctl-suppress-warning-about-missing-proc-when-n.patch +Patch0170: 0170-shell-completion-systemctl-add-no-warn.patch +Patch0171: 0171-core-unit-drop-doubled-empty-line.patch +Patch0172: 0172-core-unit-drop-dependency-to-the-unit-being-merged.patch +Patch0173: 0173-core-unit-fix-logic-of-dropping-self-referencing-dep.patch +Patch0174: 0174-core-unit-merge-two-loops-into-one.patch +Patch0175: 0175-test-add-test-case-for-sysv-generator-and-invalid-de.patch +Patch0176: 0176-core-unit-merge-unit-names-after-merging-deps.patch +Patch0177: 0177-core-unit-fix-log-message.patch +Patch0178: 0178-test-explicitly-create-the-etc-init.d-directory.patch +Patch0179: 0179-test-support-a-non-default-SysV-directory.patch # Downstream-only patches (9000–9999) @@ -1025,6 +1048,31 @@ getent passwd systemd-oom &>/dev/null || useradd -r -l -g systemd-oom -d / -s /s %files standalone-sysusers -f .file-list-standalone-sysusers %changelog +* Mon Jan 16 2023 systemd maintenance team - 252-3 +- swap: tell swapon to reinitialize swap if needed (#2151993) +- coredump: adjust whitespace (#2155517) +- coredump: do not allow user to access coredumps with changed uid/gid/capabilities (#2155517) +- Revert "basic: add fallback in chase_symlinks_and_opendir() for cases when /proc is not mounted" (#2138081) +- glyph-util: add warning sign special glyph (#2138081) +- chase-symlink: when converting directory O_PATH fd to real fd, don't bother with /proc/ (#2138081) +- systemctl: print a clear warning if people invoke systemctl without /proc/ (#2138081) +- TEST-65: check cat-config operation in chroot (#2138081) +- TEST-65: use [[ -v ]] more (#2138081) +- systemctl: warn if trying to disable a unit with no install info (#2141979) +- systemctl: allow suppress the warning of no install info using --no-warn (#2141979) +- rpm/systemd-update-helper: use --no-warn when disabling units (#2141979) +- systemctl: suppress warning about missing /proc/ when --no-warn (#2141979) +- shell-completion: systemctl: add --no-warn (#2141979) +- core/unit: drop doubled empty line (#2160477) +- core/unit: drop dependency to the unit being merged (#2160477) +- core/unit: fix logic of dropping self-referencing dependencies (#2160477) +- core/unit: merge two loops into one (#2160477) +- test: add test case for sysv-generator and invalid dependency (#2160477) +- core/unit: merge unit names after merging deps (#2160477) +- core/unit: fix log message (#2160477) +- test: explicitly create the /etc/init.d directory (#2160477) +- test: support a non-default SysV directory (#2160477) + * Fri Dec 09 2022 systemd maintenance team - 252-2 - test: check if we can use SHA1 MD for signing before using it (#2141979) - boot: cleanups for efivar_get() and friends (#2141979)