systemd-252-57
Resolves: RHEL-108555,RHEL-108568,RHEL-108576,RHEL-108584,RHEL-108596,RHEL-108598,RHEL-109096,RHEL-109488,RHEL-111065,RHEL-31756,RHEL-50103
This commit is contained in:
parent
531076b9fc
commit
2169d2c18c
@ -0,0 +1,96 @@
|
|||||||
|
From 3d54c58e3d4c720a9a95a39879b795e7154f0209 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Janssen <medhefgo@web.de>
|
||||||
|
Date: Fri, 23 Dec 2022 14:14:53 +0100
|
||||||
|
Subject: [PATCH] Revert "boot: Use EFI_BOOT_MANAGER_POLICY_PROTOCOL to connect
|
||||||
|
console devices"
|
||||||
|
|
||||||
|
This reverts commit b99bf5811850afdb2502ba37251c48348da63c82.
|
||||||
|
|
||||||
|
It seems that using this protocol on some firmwares to forcibly
|
||||||
|
initialize console devices may break handles (already opened file
|
||||||
|
handles and the device handle itself) that we rely on to access the
|
||||||
|
boot filesystem, making it impossible to load the selected entry.
|
||||||
|
|
||||||
|
It might be possible to get a new handle by querying for the device
|
||||||
|
handle by using its device path after calling into this protocol, but
|
||||||
|
this is untested. The firmware might also be so buggy that accessing
|
||||||
|
devices after using this protocol is impossible.
|
||||||
|
|
||||||
|
It seems prudent to revert this for now until some reliable way is found
|
||||||
|
to initialize console devices without introducing huge boot delays. Any
|
||||||
|
users on firmware where console devices cannot be accessed would have to
|
||||||
|
rely on disabling fastboot.
|
||||||
|
|
||||||
|
Fixes: #25737, #25846
|
||||||
|
(cherry picked from commit f151abb0e5fa4f820109eb0541bfdcba319d2b92)
|
||||||
|
|
||||||
|
Resolves: RHEL-108596
|
||||||
|
---
|
||||||
|
src/boot/efi/console.c | 16 ----------------
|
||||||
|
src/boot/efi/missing_efi.h | 19 -------------------
|
||||||
|
2 files changed, 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c
|
||||||
|
index 85a76e6e68..3b8b6b2e41 100644
|
||||||
|
--- a/src/boot/efi/console.c
|
||||||
|
+++ b/src/boot/efi/console.c
|
||||||
|
@@ -12,20 +12,6 @@
|
||||||
|
#define VERTICAL_MAX_OK 1080
|
||||||
|
#define VIEWPORT_RATIO 10
|
||||||
|
|
||||||
|
-static EFI_STATUS console_connect(void) {
|
||||||
|
- EFI_BOOT_MANAGER_POLICY_PROTOCOL *boot_policy;
|
||||||
|
- EFI_STATUS err;
|
||||||
|
-
|
||||||
|
- /* This should make console devices appear/fully initialize on fastboot firmware. */
|
||||||
|
-
|
||||||
|
- err = BS->LocateProtocol(
|
||||||
|
- &(EFI_GUID) EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID, NULL, (void **) &boot_policy);
|
||||||
|
- if (err != EFI_SUCCESS)
|
||||||
|
- return err;
|
||||||
|
-
|
||||||
|
- return boot_policy->ConnectDeviceClass(boot_policy, &(EFI_GUID) EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static inline void event_closep(EFI_EVENT *event) {
|
||||||
|
if (!*event)
|
||||||
|
return;
|
||||||
|
@@ -61,8 +47,6 @@ EFI_STATUS console_key_read(uint64_t *key, uint64_t timeout_usec) {
|
||||||
|
assert(key);
|
||||||
|
|
||||||
|
if (!checked) {
|
||||||
|
- console_connect();
|
||||||
|
-
|
||||||
|
/* Get the *first* TextInputEx device.*/
|
||||||
|
err = BS->LocateProtocol(
|
||||||
|
MAKE_GUID_PTR(EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL), NULL, (void **) &extraInEx);
|
||||||
|
diff --git a/src/boot/efi/missing_efi.h b/src/boot/efi/missing_efi.h
|
||||||
|
index d34dfc3379..3c35a85e46 100644
|
||||||
|
--- a/src/boot/efi/missing_efi.h
|
||||||
|
+++ b/src/boot/efi/missing_efi.h
|
||||||
|
@@ -399,25 +399,6 @@ typedef struct {
|
||||||
|
} EFI_SHELL_PARAMETERS_PROTOCOL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#ifndef EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID
|
||||||
|
-#define EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID \
|
||||||
|
- { 0xFEDF8E0C, 0xE147, 0x11E3, { 0x99, 0x03, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } }
|
||||||
|
-#define EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID \
|
||||||
|
- { 0xCAB0E94C, 0xE15F, 0x11E3, { 0x91, 0x8D, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } }
|
||||||
|
-
|
||||||
|
-typedef struct EFI_BOOT_MANAGER_POLICY_PROTOCOL EFI_BOOT_MANAGER_POLICY_PROTOCOL;
|
||||||
|
-struct EFI_BOOT_MANAGER_POLICY_PROTOCOL {
|
||||||
|
- UINT64 Revision;
|
||||||
|
- EFI_STATUS (EFIAPI *ConnectDevicePath)(
|
||||||
|
- EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,
|
||||||
|
- EFI_DEVICE_PATH *DevicePath,
|
||||||
|
- BOOLEAN Recursive);
|
||||||
|
- EFI_STATUS (EFIAPI *ConnectDeviceClass)(
|
||||||
|
- EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,
|
||||||
|
- EFI_GUID *Class);
|
||||||
|
-};
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
#ifndef EFI_WARN_UNKNOWN_GLYPH
|
||||||
|
# define EFI_WARN_UNKNOWN_GLYPH 1
|
||||||
|
#endif
|
||||||
38
1211-boot-Use-correct-memory-type-for-allocations.patch
Normal file
38
1211-boot-Use-correct-memory-type-for-allocations.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From bcb456e590fd6994a6b38e9b2d89e3ef0417d402 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Janssen <medhefgo@web.de>
|
||||||
|
Date: Tue, 2 May 2023 19:41:58 +0200
|
||||||
|
Subject: [PATCH] boot: Use correct memory type for allocations
|
||||||
|
|
||||||
|
We were using the wrong memory type when allocating pool memory. This
|
||||||
|
does not seem to cause a problem on x86, but the kernel will fail to
|
||||||
|
boot at least on ARM in QEMU.
|
||||||
|
|
||||||
|
This is caused by mixing different allocation types which ended up
|
||||||
|
breaking the kernel or EDK2 during boot services exit. Commit
|
||||||
|
2f3c3b0bee5534f2338439f04b0aa517479f8b76 appears to fix this boot
|
||||||
|
failure because it was replacing the gnu-efi xpool_print with xasprintf
|
||||||
|
thereby unifying the allocation type.
|
||||||
|
But this same issue can also happen without this fix somehow when the
|
||||||
|
random-seed logic is in use.
|
||||||
|
|
||||||
|
Fixes: #27371
|
||||||
|
(cherry picked from commit ec232e4abd7aebfec06b4814b30129532b2bcefd)
|
||||||
|
|
||||||
|
Resolves: RHEL-108555
|
||||||
|
---
|
||||||
|
src/boot/efi/util.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
|
||||||
|
index f7452e3cf5..16c9fcc3e1 100644
|
||||||
|
--- a/src/boot/efi/util.h
|
||||||
|
+++ b/src/boot/efi/util.h
|
||||||
|
@@ -47,7 +47,7 @@ static inline void freep(void *p) {
|
||||||
|
_malloc_ _alloc_(1) _returns_nonnull_ _warn_unused_result_
|
||||||
|
static inline void *xmalloc(size_t size) {
|
||||||
|
void *p;
|
||||||
|
- assert_se(BS->AllocatePool(EfiBootServicesData, size, &p) == EFI_SUCCESS);
|
||||||
|
+ assert_se(BS->AllocatePool(EfiLoaderData, size, &p) == EFI_SUCCESS);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
33
1212-meson-etc-systemd-network-is-also-used-by-udevd.patch
Normal file
33
1212-meson-etc-systemd-network-is-also-used-by-udevd.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From 7ee5909a539f7a4a65c35e86404ceecb499c54c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Thu, 2 Nov 2023 14:20:11 +0900
|
||||||
|
Subject: [PATCH] meson: /etc/systemd/network is also used by udevd
|
||||||
|
|
||||||
|
(cherry picked from commit 6256c65aad2a719ac9054961561bb26e497208ce)
|
||||||
|
|
||||||
|
Resolves: RHEL-109096
|
||||||
|
---
|
||||||
|
network/meson.build | 9 +++++----
|
||||||
|
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/network/meson.build b/network/meson.build
|
||||||
|
index 4c6de20515..499ea61086 100644
|
||||||
|
--- a/network/meson.build
|
||||||
|
+++ b/network/meson.build
|
||||||
|
@@ -12,11 +12,12 @@ if conf.get('ENABLE_NETWORKD') == 1
|
||||||
|
'80-wifi-station.network.example',
|
||||||
|
install_dir : networkdir)
|
||||||
|
|
||||||
|
- if install_sysconfdir
|
||||||
|
- meson.add_install_script('sh', '-c',
|
||||||
|
- mkdir_p.format(sysconfdir / 'systemd/network'))
|
||||||
|
- endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
install_data('99-default.link',
|
||||||
|
install_dir : networkdir)
|
||||||
|
+
|
||||||
|
+if install_sysconfdir
|
||||||
|
+ meson.add_install_script('sh', '-c',
|
||||||
|
+ mkdir_p.format(sysconfdir / 'systemd/network'))
|
||||||
|
+endif
|
||||||
207
1213-sd-bus-make-bus_add_match_full-accept-timeout.patch
Normal file
207
1213-sd-bus-make-bus_add_match_full-accept-timeout.patch
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
From 3b49b68593cbca6ee4e08a34a780fd5b5c3ab9fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: licunlong <licunlong1@huawei.com>
|
||||||
|
Date: Thu, 15 Jun 2023 16:28:28 +0800
|
||||||
|
Subject: [PATCH] sd-bus: make bus_add_match_full accept timeout
|
||||||
|
|
||||||
|
(cherry picked from commit bb30e58f644689feaa87d8136d1686b6c3a6f42a)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-bus/bus-control.c | 48 +++++++++++++++++++++-------
|
||||||
|
src/libsystemd/sd-bus/bus-control.h | 4 +--
|
||||||
|
src/libsystemd/sd-bus/bus-internal.h | 10 ++++++
|
||||||
|
src/libsystemd/sd-bus/sd-bus.c | 17 ++++++----
|
||||||
|
4 files changed, 59 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
|
||||||
|
index d96b7256a1..762656fa74 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/bus-control.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/bus-control.c
|
||||||
|
@@ -803,9 +803,10 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
|
||||||
|
int bus_add_match_internal(
|
||||||
|
sd_bus *bus,
|
||||||
|
const char *match,
|
||||||
|
+ uint64_t timeout_usec,
|
||||||
|
uint64_t *ret_counter) {
|
||||||
|
|
||||||
|
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||||
|
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
|
||||||
|
const char *e;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -816,16 +817,26 @@ int bus_add_match_internal(
|
||||||
|
|
||||||
|
e = append_eavesdrop(bus, match);
|
||||||
|
|
||||||
|
- r = sd_bus_call_method(
|
||||||
|
+ r = sd_bus_message_new_method_call(
|
||||||
|
bus,
|
||||||
|
+ &m,
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
"/org/freedesktop/DBus",
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
- "AddMatch",
|
||||||
|
+ "AddMatch");
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_message_append(m, "s", e);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_call(
|
||||||
|
+ bus,
|
||||||
|
+ m,
|
||||||
|
+ timeout_usec,
|
||||||
|
NULL,
|
||||||
|
- &reply,
|
||||||
|
- "s",
|
||||||
|
- e);
|
||||||
|
+ &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -841,9 +852,12 @@ int bus_add_match_internal_async(
|
||||||
|
sd_bus_slot **ret_slot,
|
||||||
|
const char *match,
|
||||||
|
sd_bus_message_handler_t callback,
|
||||||
|
- void *userdata) {
|
||||||
|
+ void *userdata,
|
||||||
|
+ uint64_t timeout_usec) {
|
||||||
|
|
||||||
|
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||||
|
const char *e;
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
assert(bus);
|
||||||
|
|
||||||
|
@@ -852,17 +866,27 @@ int bus_add_match_internal_async(
|
||||||
|
|
||||||
|
e = append_eavesdrop(bus, match);
|
||||||
|
|
||||||
|
- return sd_bus_call_method_async(
|
||||||
|
+ r = sd_bus_message_new_method_call(
|
||||||
|
bus,
|
||||||
|
- ret_slot,
|
||||||
|
+ &m,
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
"/org/freedesktop/DBus",
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
- "AddMatch",
|
||||||
|
+ "AddMatch");
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_message_append(m, "s", e);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return sd_bus_call_async(
|
||||||
|
+ bus,
|
||||||
|
+ ret_slot,
|
||||||
|
+ m,
|
||||||
|
callback,
|
||||||
|
userdata,
|
||||||
|
- "s",
|
||||||
|
- e);
|
||||||
|
+ timeout_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bus_remove_match_internal(
|
||||||
|
diff --git a/src/libsystemd/sd-bus/bus-control.h b/src/libsystemd/sd-bus/bus-control.h
|
||||||
|
index 8182b9cd63..1cd4fb88d9 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/bus-control.h
|
||||||
|
+++ b/src/libsystemd/sd-bus/bus-control.h
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
|
||||||
|
#include "sd-bus.h"
|
||||||
|
|
||||||
|
-int bus_add_match_internal(sd_bus *bus, const char *match, uint64_t *ret_counter);
|
||||||
|
-int bus_add_match_internal_async(sd_bus *bus, sd_bus_slot **ret, const char *match, sd_bus_message_handler_t callback, void *userdata);
|
||||||
|
+int bus_add_match_internal(sd_bus *bus, const char *match, uint64_t timeout_usec, uint64_t *ret_counter);
|
||||||
|
+int bus_add_match_internal_async(sd_bus *bus, sd_bus_slot **ret, const char *match, sd_bus_message_handler_t callback, void *userdata, uint64_t timeout_usec);
|
||||||
|
|
||||||
|
int bus_remove_match_internal(sd_bus *bus, const char *match);
|
||||||
|
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
|
||||||
|
index 51673ad1c5..603a53fb10 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/bus-internal.h
|
||||||
|
+++ b/src/libsystemd/sd-bus/bus-internal.h
|
||||||
|
@@ -386,6 +386,16 @@ int bus_attach_inotify_event(sd_bus *b);
|
||||||
|
void bus_close_inotify_fd(sd_bus *b);
|
||||||
|
void bus_close_io_fds(sd_bus *b);
|
||||||
|
|
||||||
|
+int bus_add_match_full(
|
||||||
|
+ sd_bus *bus,
|
||||||
|
+ sd_bus_slot **slot,
|
||||||
|
+ bool asynchronous,
|
||||||
|
+ const char *match,
|
||||||
|
+ sd_bus_message_handler_t callback,
|
||||||
|
+ sd_bus_message_handler_t install_callback,
|
||||||
|
+ void *userdata,
|
||||||
|
+ uint64_t timeout_usec);
|
||||||
|
+
|
||||||
|
#define OBJECT_PATH_FOREACH_PREFIX(prefix, path) \
|
||||||
|
for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \
|
||||||
|
_slash && ((_slash[(_slash) == (prefix)] = 0), true); \
|
||||||
|
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
index 10efe53a25..b8406f154b 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
@@ -3486,14 +3486,15 @@ static int add_match_callback(
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int bus_add_match_full(
|
||||||
|
+int bus_add_match_full(
|
||||||
|
sd_bus *bus,
|
||||||
|
sd_bus_slot **slot,
|
||||||
|
bool asynchronous,
|
||||||
|
const char *match,
|
||||||
|
sd_bus_message_handler_t callback,
|
||||||
|
sd_bus_message_handler_t install_callback,
|
||||||
|
- void *userdata) {
|
||||||
|
+ void *userdata,
|
||||||
|
+ uint64_t timeout_usec) {
|
||||||
|
|
||||||
|
struct bus_match_component *components = NULL;
|
||||||
|
unsigned n_components = 0;
|
||||||
|
@@ -3539,7 +3540,8 @@ static int bus_add_match_full(
|
||||||
|
&s->match_callback.install_slot,
|
||||||
|
s->match_callback.match_string,
|
||||||
|
add_match_callback,
|
||||||
|
- s);
|
||||||
|
+ s,
|
||||||
|
+ timeout_usec);
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
goto finish;
|
||||||
|
@@ -3549,7 +3551,10 @@ static int bus_add_match_full(
|
||||||
|
* then make it floating. */
|
||||||
|
r = sd_bus_slot_set_floating(s->match_callback.install_slot, true);
|
||||||
|
} else
|
||||||
|
- r = bus_add_match_internal(bus, s->match_callback.match_string, &s->match_callback.after);
|
||||||
|
+ r = bus_add_match_internal(bus,
|
||||||
|
+ s->match_callback.match_string,
|
||||||
|
+ timeout_usec,
|
||||||
|
+ &s->match_callback.after);
|
||||||
|
if (r < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
@@ -3580,7 +3585,7 @@ _public_ int sd_bus_add_match(
|
||||||
|
sd_bus_message_handler_t callback,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
- return bus_add_match_full(bus, slot, false, match, callback, NULL, userdata);
|
||||||
|
+ return bus_add_match_full(bus, slot, false, match, callback, NULL, userdata, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_public_ int sd_bus_add_match_async(
|
||||||
|
@@ -3591,7 +3596,7 @@ _public_ int sd_bus_add_match_async(
|
||||||
|
sd_bus_message_handler_t install_callback,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
- return bus_add_match_full(bus, slot, true, match, callback, install_callback, userdata);
|
||||||
|
+ return bus_add_match_full(bus, slot, true, match, callback, install_callback, userdata, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bus_pid_changed(sd_bus *bus) {
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
From 1a5720577ae6791ae64795486c5902b7c5aceb6b Mon Sep 17 00:00:00 2001
|
||||||
|
From: licunlong <licunlong1@huawei.com>
|
||||||
|
Date: Thu, 15 Jun 2023 10:47:32 +0800
|
||||||
|
Subject: [PATCH] core/unit: add get_timeout_start_usec in UnitVTable and
|
||||||
|
define it for service
|
||||||
|
|
||||||
|
(cherry picked from commit f5a9d2ee2a849aca1f2d15485d020142ff33cc30)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/service.c | 6 ++++++
|
||||||
|
src/core/unit.h | 3 +++
|
||||||
|
2 files changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index 433df0afe3..305f3b7170 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -4383,6 +4383,11 @@ static int service_get_timeout(Unit *u, usec_t *timeout) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static usec_t service_get_timeout_start_usec(Unit *u) {
|
||||||
|
+ Service *s = SERVICE(ASSERT_PTR(u));
|
||||||
|
+ return s->timeout_start_usec;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool pick_up_pid_from_bus_name(Service *s) {
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
@@ -4870,6 +4875,7 @@ const UnitVTable service_vtable = {
|
||||||
|
.bus_commit_properties = bus_service_commit_properties,
|
||||||
|
|
||||||
|
.get_timeout = service_get_timeout,
|
||||||
|
+ .get_timeout_start_usec = service_get_timeout_start_usec,
|
||||||
|
.needs_console = service_needs_console,
|
||||||
|
.exit_status = service_exit_status,
|
||||||
|
.status_text = service_status_text,
|
||||||
|
diff --git a/src/core/unit.h b/src/core/unit.h
|
||||||
|
index 4bb85b55be..fdea76458d 100644
|
||||||
|
--- a/src/core/unit.h
|
||||||
|
+++ b/src/core/unit.h
|
||||||
|
@@ -713,6 +713,9 @@ typedef struct UnitVTable {
|
||||||
|
/* Returns the next timeout of a unit */
|
||||||
|
int (*get_timeout)(Unit *u, usec_t *timeout);
|
||||||
|
|
||||||
|
+ /* Returns the start timeout of a unit */
|
||||||
|
+ usec_t (*get_timeout_start_usec)(Unit *u);
|
||||||
|
+
|
||||||
|
/* Returns the main PID if there is any defined, or 0. */
|
||||||
|
pid_t (*main_pid)(Unit *u);
|
||||||
|
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
From 6b2f0e500e6688d1b2d9ad8b9947e03bd58f27a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: licunlong <licunlong1@huawei.com>
|
||||||
|
Date: Wed, 24 May 2023 11:45:31 +0800
|
||||||
|
Subject: [PATCH] core/unit: increase the NameOwnerChanged/GetNameOwner timeout
|
||||||
|
to the unit's start timeout
|
||||||
|
|
||||||
|
When dbus is overloaded, these messages are easily timedout,
|
||||||
|
systemd may kill dbus-type service by mistake. This PR
|
||||||
|
mitigates this problem by increasing the timeout to the
|
||||||
|
unit's start timeout.
|
||||||
|
|
||||||
|
(cherry picked from commit 8df433d7cd268ae96cfe795feaa59f4d3e87b85c)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/unit.c | 39 ++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 34 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||||
|
index 0d65880ac7..dddaeb96f6 100644
|
||||||
|
--- a/src/core/unit.c
|
||||||
|
+++ b/src/core/unit.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include "bpf-foreign.h"
|
||||||
|
#include "bpf-socket-bind.h"
|
||||||
|
#include "bus-common-errors.h"
|
||||||
|
+#include "bus-internal.h"
|
||||||
|
#include "bus-util.h"
|
||||||
|
#include "cgroup-setup.h"
|
||||||
|
#include "cgroup-util.h"
|
||||||
|
@@ -3539,7 +3540,9 @@ static int get_name_owner_handler(sd_bus_message *message, void *userdata, sd_bu
|
||||||
|
}
|
||||||
|
|
||||||
|
int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
|
||||||
|
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||||
|
const char *match;
|
||||||
|
+ usec_t timeout_usec = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
@@ -3549,6 +3552,12 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
|
||||||
|
if (u->match_bus_slot || u->get_name_owner_slot)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
+ /* NameOwnerChanged and GetNameOwner is used to detect when a service finished starting up. The dbus
|
||||||
|
+ * call timeout shouldn't be earlier than that. If we couldn't get the start timeout, use the default
|
||||||
|
+ * value defined above. */
|
||||||
|
+ if (UNIT_VTABLE(u)->get_timeout_start_usec)
|
||||||
|
+ timeout_usec = UNIT_VTABLE(u)->get_timeout_start_usec(u);
|
||||||
|
+
|
||||||
|
match = strjoina("type='signal',"
|
||||||
|
"sender='org.freedesktop.DBus',"
|
||||||
|
"path='/org/freedesktop/DBus',"
|
||||||
|
@@ -3556,20 +3565,40 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
|
||||||
|
"member='NameOwnerChanged',"
|
||||||
|
"arg0='", name, "'");
|
||||||
|
|
||||||
|
- r = sd_bus_add_match_async(bus, &u->match_bus_slot, match, signal_name_owner_changed, NULL, u);
|
||||||
|
+ r = bus_add_match_full(
|
||||||
|
+ bus,
|
||||||
|
+ &u->match_bus_slot,
|
||||||
|
+ true,
|
||||||
|
+ match,
|
||||||
|
+ signal_name_owner_changed,
|
||||||
|
+ NULL,
|
||||||
|
+ u,
|
||||||
|
+ timeout_usec);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = sd_bus_call_method_async(
|
||||||
|
+ r = sd_bus_message_new_method_call(
|
||||||
|
bus,
|
||||||
|
- &u->get_name_owner_slot,
|
||||||
|
+ &m,
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
"/org/freedesktop/DBus",
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
- "GetNameOwner",
|
||||||
|
+ "GetNameOwner");
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_message_append(m, "s", name);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_call_async(
|
||||||
|
+ bus,
|
||||||
|
+ &u->get_name_owner_slot,
|
||||||
|
+ m,
|
||||||
|
get_name_owner_handler,
|
||||||
|
u,
|
||||||
|
- "s", name);
|
||||||
|
+ timeout_usec);
|
||||||
|
+
|
||||||
|
if (r < 0) {
|
||||||
|
u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
|
||||||
|
return r;
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
From 14c6c9a0a58a99d66f541cec50a5cc860303ae7e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Sun, 29 Dec 2024 15:10:53 +0900
|
||||||
|
Subject: [PATCH] core,sd-bus: drop empty lines between function call and error
|
||||||
|
check
|
||||||
|
|
||||||
|
(cherry picked from commit 7baf4d234a70f136014f9e92f00c078a55c7adba)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/unit.c | 1 -
|
||||||
|
src/libsystemd/sd-bus/sd-bus.c | 1 -
|
||||||
|
2 files changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||||
|
index dddaeb96f6..5a091b3bc4 100644
|
||||||
|
--- a/src/core/unit.c
|
||||||
|
+++ b/src/core/unit.c
|
||||||
|
@@ -3598,7 +3598,6 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
|
||||||
|
get_name_owner_handler,
|
||||||
|
u,
|
||||||
|
timeout_usec);
|
||||||
|
-
|
||||||
|
if (r < 0) {
|
||||||
|
u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
|
||||||
|
return r;
|
||||||
|
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
index b8406f154b..c2dded43ad 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
@@ -3542,7 +3542,6 @@ int bus_add_match_full(
|
||||||
|
add_match_callback,
|
||||||
|
s,
|
||||||
|
timeout_usec);
|
||||||
|
-
|
||||||
|
if (r < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
From 899e94d72119c5e5f3d0ae75f39abd376bc28b0e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Sun, 29 Dec 2024 15:50:43 +0900
|
||||||
|
Subject: [PATCH] core: do not disconnect from bus when failed to install
|
||||||
|
signal match
|
||||||
|
|
||||||
|
If bus_add_match_full() is called without install callback and we failed
|
||||||
|
to install the signal match e.g. by timeout, then add_match_callback()
|
||||||
|
will disconnect from the bus.
|
||||||
|
Let's use a custom install handler and handle failures gracefully.
|
||||||
|
|
||||||
|
This does not *solve* the root cause of issue #30573, but should improve
|
||||||
|
the situation when the issue is triggered.
|
||||||
|
|
||||||
|
(cherry picked from commit db6b214f95aa42f9a9fa3d94a3c6492cc57b58fb)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/unit.c | 30 ++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 28 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||||
|
index 5a091b3bc4..9e349402ff 100644
|
||||||
|
--- a/src/core/unit.c
|
||||||
|
+++ b/src/core/unit.c
|
||||||
|
@@ -3486,6 +3486,32 @@ int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int signal_name_owner_changed_install_handler(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
+ Unit *u = ASSERT_PTR(userdata);
|
||||||
|
+ const sd_bus_error *e;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ e = sd_bus_message_get_error(message);
|
||||||
|
+ if (!e) {
|
||||||
|
+ log_unit_trace(u, "Successfully installed NameOwnerChanged signal match.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = sd_bus_error_get_errno(e);
|
||||||
|
+ log_unit_error_errno(u, r,
|
||||||
|
+ "Unexpected error response on installing NameOwnerChanged signal match: %s",
|
||||||
|
+ bus_error_message(e, r));
|
||||||
|
+
|
||||||
|
+ /* If we failed to install NameOwnerChanged signal, also unref the bus slot of GetNameOwner(). */
|
||||||
|
+ u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
|
||||||
|
+ u->get_name_owner_slot = sd_bus_slot_unref(u->get_name_owner_slot);
|
||||||
|
+
|
||||||
|
+ if (UNIT_VTABLE(u)->bus_name_owner_change)
|
||||||
|
+ UNIT_VTABLE(u)->bus_name_owner_change(u, NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int signal_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
const char *new_owner;
|
||||||
|
Unit *u = ASSERT_PTR(userdata);
|
||||||
|
@@ -3568,10 +3594,10 @@ int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) {
|
||||||
|
r = bus_add_match_full(
|
||||||
|
bus,
|
||||||
|
&u->match_bus_slot,
|
||||||
|
- true,
|
||||||
|
+ /* asynchronous = */ true,
|
||||||
|
match,
|
||||||
|
signal_name_owner_changed,
|
||||||
|
- NULL,
|
||||||
|
+ signal_name_owner_changed_install_handler,
|
||||||
|
u,
|
||||||
|
timeout_usec);
|
||||||
|
if (r < 0)
|
||||||
180
1218-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch
Normal file
180
1218-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
From 5917dd6d4667ed4f97b63baaa3b35e2c1410f3c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ronan Pigott <ronan@rjp.ie>
|
||||||
|
Date: Thu, 28 Nov 2024 12:53:32 -0700
|
||||||
|
Subject: [PATCH] dbus: stash the subscriber list when we disconenct from the
|
||||||
|
bus
|
||||||
|
|
||||||
|
If we unexpectly disconnect from the bus, systemd would end up dropping
|
||||||
|
the list of subscribers, which breaks the ability of clients like logind
|
||||||
|
to monitor the state of units.
|
||||||
|
|
||||||
|
Stash the list of subscribers into the deserialized state in the event
|
||||||
|
of a disconnect so that when we recover we can renew the broken
|
||||||
|
subscriptions.
|
||||||
|
|
||||||
|
(cherry picked from commit 8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/dbus.c | 21 +++++++++++++++------
|
||||||
|
src/core/dbus.h | 2 +-
|
||||||
|
src/core/manager.c | 8 ++++----
|
||||||
|
src/shared/bus-util.c | 22 ++++++++++++++++++++++
|
||||||
|
src/shared/bus-util.h | 1 +
|
||||||
|
5 files changed, 43 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/dbus.c b/src/core/dbus.c
|
||||||
|
index 1431e079c2..12a6f2fa27 100644
|
||||||
|
--- a/src/core/dbus.c
|
||||||
|
+++ b/src/core/dbus.c
|
||||||
|
@@ -834,6 +834,8 @@ int bus_init_api(Manager *m) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to set up API bus: %m");
|
||||||
|
|
||||||
|
+ (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->deserialized_subscribed);
|
||||||
|
+ m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
||||||
|
m->api_bus = TAKE_PTR(bus);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -986,8 +988,17 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of tracked clients on this bus */
|
||||||
|
- if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
|
||||||
|
+ if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus) {
|
||||||
|
+ _cleanup_strv_free_ char **subscribed = NULL;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = bus_track_to_strv(m->subscribed, &subscribed);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m");
|
||||||
|
+ strv_free_and_replace(m->deserialized_subscribed, subscribed);
|
||||||
|
+
|
||||||
|
m->subscribed = sd_bus_track_unref(m->subscribed);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
HASHMAP_FOREACH(j, m->jobs)
|
||||||
|
if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus)
|
||||||
|
@@ -1046,7 +1057,6 @@ void bus_done(Manager *m) {
|
||||||
|
|
||||||
|
assert(!m->subscribed);
|
||||||
|
|
||||||
|
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
||||||
|
bus_verify_polkit_async_registry_free(m->polkit_registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1137,20 +1147,19 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l) {
|
||||||
|
+int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- assert(m);
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
if (strv_isempty(l))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!m->api_bus)
|
||||||
|
+ if (!bus)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!*t) {
|
||||||
|
- r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
|
||||||
|
+ r = sd_bus_track_new(bus, t, NULL, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
diff --git a/src/core/dbus.h b/src/core/dbus.h
|
||||||
|
index 50e7bb400e..3f0d902c89 100644
|
||||||
|
--- a/src/core/dbus.h
|
||||||
|
+++ b/src/core/dbus.h
|
||||||
|
@@ -19,7 +19,7 @@ void bus_done(Manager *m);
|
||||||
|
int bus_fdset_add_all(Manager *m, FDSet *fds);
|
||||||
|
|
||||||
|
void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix);
|
||||||
|
-int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l);
|
||||||
|
+int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l);
|
||||||
|
|
||||||
|
int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata);
|
||||||
|
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index daeaa641d7..6c67780c99 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -1560,6 +1560,9 @@ Manager* manager_free(Manager *m) {
|
||||||
|
free(m->switch_root);
|
||||||
|
free(m->switch_root_init);
|
||||||
|
|
||||||
|
+ sd_bus_track_unref(m->subscribed);
|
||||||
|
+ strv_free(m->deserialized_subscribed);
|
||||||
|
+
|
||||||
|
free(m->default_smack_process_label);
|
||||||
|
|
||||||
|
rlimit_free_all(m->rlimit);
|
||||||
|
@@ -1862,7 +1865,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
|
||||||
|
manager_setup_bus(m);
|
||||||
|
|
||||||
|
/* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
|
||||||
|
- r = bus_track_coldplug(m, &m->subscribed, false, m->deserialized_subscribed);
|
||||||
|
+ r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->deserialized_subscribed);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
|
||||||
|
m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
||||||
|
@@ -3412,9 +3415,6 @@ int manager_reload(Manager *m) {
|
||||||
|
/* Clean up runtime objects no longer referenced */
|
||||||
|
manager_vacuum(m);
|
||||||
|
|
||||||
|
- /* Clean up deserialized tracked clients */
|
||||||
|
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
||||||
|
-
|
||||||
|
/* Consider the reload process complete now. */
|
||||||
|
assert(m->n_reloading > 0);
|
||||||
|
m->n_reloading--;
|
||||||
|
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
||||||
|
index d09ec5148d..9293f10fdc 100644
|
||||||
|
--- a/src/shared/bus-util.c
|
||||||
|
+++ b/src/shared/bus-util.c
|
||||||
|
@@ -495,6 +495,28 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int bus_track_to_strv(sd_bus_track *t, char ***ret) {
|
||||||
|
+ _cleanup_strv_free_ char **subscribed = NULL;
|
||||||
|
+ int r = 0;
|
||||||
|
+
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
+ for (const char *n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) {
|
||||||
|
+ r = sd_bus_track_count_name(t, n);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ for (int j = 0; j < r; j++) {
|
||||||
|
+ r = strv_extend(&subscribed, n);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *ret = TAKE_PTR(subscribed);
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description) {
|
||||||
|
_cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
|
||||||
|
const char *e;
|
||||||
|
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
|
||||||
|
index 955cdcb57c..e1fdf2ef48 100644
|
||||||
|
--- a/src/shared/bus-util.h
|
||||||
|
+++ b/src/shared/bus-util.h
|
||||||
|
@@ -52,6 +52,7 @@ int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id,
|
||||||
|
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
|
||||||
|
|
||||||
|
int bus_track_add_name_many(sd_bus_track *t, char **l);
|
||||||
|
+int bus_track_to_strv(sd_bus_track *t, char ***ret);
|
||||||
|
|
||||||
|
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description);
|
||||||
|
static inline int bus_open_system_watch_bind(sd_bus **ret) {
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
From 435d53448b8c427dc1b61b4d27342fb593185acf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ronan Pigott <ronan@rjp.ie>
|
||||||
|
Date: Wed, 11 Dec 2024 12:47:10 -0700
|
||||||
|
Subject: [PATCH] manager: s/deserialized_subscribed/subscribed_as_strv
|
||||||
|
|
||||||
|
Now that this field may get populated at runtime, the deserialized name
|
||||||
|
is misleading. Change the name to reflect its updated purpose.
|
||||||
|
|
||||||
|
(cherry picked from commit e1315a621ae26473fcc9cd0d6013836f5f498d40)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/dbus.c | 6 +++---
|
||||||
|
src/core/manager-serialize.c | 2 +-
|
||||||
|
src/core/manager.c | 6 +++---
|
||||||
|
src/core/manager.h | 2 +-
|
||||||
|
4 files changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/dbus.c b/src/core/dbus.c
|
||||||
|
index 12a6f2fa27..7655427f38 100644
|
||||||
|
--- a/src/core/dbus.c
|
||||||
|
+++ b/src/core/dbus.c
|
||||||
|
@@ -834,8 +834,8 @@ int bus_init_api(Manager *m) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to set up API bus: %m");
|
||||||
|
|
||||||
|
- (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->deserialized_subscribed);
|
||||||
|
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
||||||
|
+ (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->subscribed_as_strv);
|
||||||
|
+ m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
|
||||||
|
m->api_bus = TAKE_PTR(bus);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -995,7 +995,7 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
|
||||||
|
r = bus_track_to_strv(m->subscribed, &subscribed);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m");
|
||||||
|
- strv_free_and_replace(m->deserialized_subscribed, subscribed);
|
||||||
|
+ strv_free_and_replace(m->subscribed_as_strv, subscribed);
|
||||||
|
|
||||||
|
m->subscribed = sd_bus_track_unref(m->subscribed);
|
||||||
|
}
|
||||||
|
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
|
||||||
|
index f3b2d7ee16..a87d490219 100644
|
||||||
|
--- a/src/core/manager-serialize.c
|
||||||
|
+++ b/src/core/manager-serialize.c
|
||||||
|
@@ -529,7 +529,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||||
|
(void) exec_runtime_deserialize_one(m, val, fds);
|
||||||
|
else if ((val = startswith(l, "subscribed="))) {
|
||||||
|
|
||||||
|
- if (strv_extend(&m->deserialized_subscribed, val) < 0)
|
||||||
|
+ if (strv_extend(&m->subscribed_as_strv, val) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
} else if ((val = startswith(l, "varlink-server-socket-address="))) {
|
||||||
|
if (!m->varlink_server && MANAGER_IS_SYSTEM(m)) {
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index 6c67780c99..45676d3def 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -1561,7 +1561,7 @@ Manager* manager_free(Manager *m) {
|
||||||
|
free(m->switch_root_init);
|
||||||
|
|
||||||
|
sd_bus_track_unref(m->subscribed);
|
||||||
|
- strv_free(m->deserialized_subscribed);
|
||||||
|
+ strv_free(m->subscribed_as_strv);
|
||||||
|
|
||||||
|
free(m->default_smack_process_label);
|
||||||
|
|
||||||
|
@@ -1865,10 +1865,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
|
||||||
|
manager_setup_bus(m);
|
||||||
|
|
||||||
|
/* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
|
||||||
|
- r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->deserialized_subscribed);
|
||||||
|
+ r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->subscribed_as_strv);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
|
||||||
|
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
||||||
|
+ m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
|
||||||
|
|
||||||
|
r = manager_varlink_init(m);
|
||||||
|
if (r < 0)
|
||||||
|
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||||
|
index 86e7e40989..a96ba7bf9d 100644
|
||||||
|
--- a/src/core/manager.h
|
||||||
|
+++ b/src/core/manager.h
|
||||||
|
@@ -276,7 +276,7 @@ struct Manager {
|
||||||
|
considered subscribes, since they last for very short only,
|
||||||
|
and it is much simpler that way. */
|
||||||
|
sd_bus_track *subscribed;
|
||||||
|
- char **deserialized_subscribed;
|
||||||
|
+ char **subscribed_as_strv;
|
||||||
|
|
||||||
|
/* This is used during reloading: before the reload we queue
|
||||||
|
* the reply message here, and afterwards we send it */
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
From da904dede254800cdbac51905db9423f8f88fefa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Sat, 11 Jan 2025 16:26:55 +0100
|
||||||
|
Subject: [PATCH] bus-util: do not reset the count returned by
|
||||||
|
sd_bus_track_count_name()
|
||||||
|
|
||||||
|
Follow-up for 8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98
|
||||||
|
|
||||||
|
While at it, turn the retval check for sd_bus_track_count_name()
|
||||||
|
into assertion, given we're working with already established tracks
|
||||||
|
(service_name_is_valid() should never yield false in this case).
|
||||||
|
|
||||||
|
Addresses https://github.com/systemd/systemd/pull/35406#discussion_r1912066774
|
||||||
|
|
||||||
|
(cherry picked from commit 33eeea4128f31df7ab4bd8866b582062d70114ae)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/shared/bus-util.c | 11 +++++------
|
||||||
|
1 file changed, 5 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
||||||
|
index 9293f10fdc..5e6d17d201 100644
|
||||||
|
--- a/src/shared/bus-util.c
|
||||||
|
+++ b/src/shared/bus-util.c
|
||||||
|
@@ -497,16 +497,15 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) {
|
||||||
|
|
||||||
|
int bus_track_to_strv(sd_bus_track *t, char ***ret) {
|
||||||
|
_cleanup_strv_free_ char **subscribed = NULL;
|
||||||
|
- int r = 0;
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
for (const char *n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) {
|
||||||
|
- r = sd_bus_track_count_name(t, n);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
+ int c = sd_bus_track_count_name(t, n);
|
||||||
|
+ assert(c >= 0);
|
||||||
|
|
||||||
|
- for (int j = 0; j < r; j++) {
|
||||||
|
+ for (int j = 0; j < c; j++) {
|
||||||
|
r = strv_extend(&subscribed, n);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
@@ -514,7 +513,7 @@ int bus_track_to_strv(sd_bus_track *t, char ***ret) {
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(subscribed);
|
||||||
|
- return r;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description) {
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
From 02e5c4076ce3981fb2b0c7830197b2f13e225efe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Mon, 13 Jan 2025 17:30:51 +0100
|
||||||
|
Subject: [PATCH] core/manager: restore bus track deserialization cleanup in
|
||||||
|
manager_reload()
|
||||||
|
|
||||||
|
There's zero explanation why it got (spuriously) removed in
|
||||||
|
8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98...
|
||||||
|
|
||||||
|
(cherry picked from commit 34f4b817f67b002eae7e2c09b19bf4b66c4791b6)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/manager.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index 45676d3def..92f283d33d 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -3409,6 +3409,10 @@ int manager_reload(Manager *m) {
|
||||||
|
(void) manager_setup_cgroups_agent(m);
|
||||||
|
(void) manager_setup_user_lookup_fd(m);
|
||||||
|
|
||||||
|
+ /* Clean up deserialized bus track information. They're never consumed during reload (as opposed to
|
||||||
|
+ * reexec) since we do not disconnect from the bus. */
|
||||||
|
+ m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
|
||||||
|
+
|
||||||
|
/* Third, fire things up! */
|
||||||
|
manager_coldplug(m);
|
||||||
|
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
From 8e451eebfe6f37bacb02543d9a38c4ddaa6f8400 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Sat, 11 Jan 2025 18:38:49 +0100
|
||||||
|
Subject: [PATCH] core/manager: drop duplicate bus track deserialization
|
||||||
|
|
||||||
|
bus_init_api() now does this internally
|
||||||
|
(after 8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98).
|
||||||
|
|
||||||
|
(cherry picked from commit af0e10354e567bfd0b9521376b2aad55f12a4e3d)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/core/manager.c | 6 ------
|
||||||
|
1 file changed, 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index 92f283d33d..653b0c2d22 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -1864,12 +1864,6 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
|
||||||
|
/* Connect to the bus if we are good for it */
|
||||||
|
manager_setup_bus(m);
|
||||||
|
|
||||||
|
- /* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
|
||||||
|
- r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->subscribed_as_strv);
|
||||||
|
- if (r < 0)
|
||||||
|
- log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
|
||||||
|
- m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
|
||||||
|
-
|
||||||
|
r = manager_varlink_init(m);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(r, "Failed to set up Varlink, ignoring: %m");
|
||||||
102
1223-sd-bus-bus-track-use-install_callback-in-sd_bus_trac.patch
Normal file
102
1223-sd-bus-bus-track-use-install_callback-in-sd_bus_trac.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
From f18c7dd568ba87c6aa9a045878c0a9ef7c23208e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Thu, 31 Jul 2025 18:26:09 +0200
|
||||||
|
Subject: [PATCH] sd-bus/bus-track: use install_callback in
|
||||||
|
sd_bus_track_add_name()
|
||||||
|
|
||||||
|
Previously we didn't provide any install_callback to
|
||||||
|
sd_bus_add_match_async() so in case AddMatch() method call timed out we
|
||||||
|
destroyed the bus connection. This seems overly aggressive and simply
|
||||||
|
updating the sd_bus_track object accordingly should be enough.
|
||||||
|
|
||||||
|
Follow-up for 37ce3fd2b7dd8f81f6f4bca2003961a92b2963dc.
|
||||||
|
|
||||||
|
Fixes #32381
|
||||||
|
|
||||||
|
(cherry picked from commit dcf42d1ee21222ee698e5e0ab3ecf3411b63da40)
|
||||||
|
|
||||||
|
Related: RHEL-31756
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-bus/bus-track.c | 32 +++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 28 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c
|
||||||
|
index f9c59a1007..276e177d2b 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/bus-track.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/bus-track.c
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
#include "sd-bus.h"
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
+#include "bus-error.h"
|
||||||
|
#include "bus-internal.h"
|
||||||
|
#include "bus-track.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
@@ -11,6 +12,7 @@ struct track_item {
|
||||||
|
unsigned n_ref;
|
||||||
|
char *name;
|
||||||
|
sd_bus_slot *slot;
|
||||||
|
+ sd_bus_track *track;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sd_bus_track {
|
||||||
|
@@ -163,18 +165,39 @@ static sd_bus_track *track_free(sd_bus_track *track) {
|
||||||
|
|
||||||
|
DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_bus_track, sd_bus_track, track_free);
|
||||||
|
|
||||||
|
-static int on_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
- sd_bus_track *track = ASSERT_PTR(userdata);
|
||||||
|
+static int on_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *reterr_error) {
|
||||||
|
+ struct track_item *item = ASSERT_PTR(userdata);
|
||||||
|
const char *name;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(message);
|
||||||
|
+ assert(item->track);
|
||||||
|
|
||||||
|
r = sd_bus_message_read(message, "sss", &name, NULL, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- bus_track_remove_name_fully(track, name);
|
||||||
|
+ bus_track_remove_name_fully(item->track, name);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int name_owner_changed_install_callback(sd_bus_message *message, void *userdata, sd_bus_error *reterr_error) {
|
||||||
|
+ struct track_item *item = ASSERT_PTR(userdata);
|
||||||
|
+ const sd_bus_error *e;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(message);
|
||||||
|
+ assert(item->track);
|
||||||
|
+ assert(item->name);
|
||||||
|
+
|
||||||
|
+ e = sd_bus_message_get_error(message);
|
||||||
|
+ if (!e)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_error_get_errno(e);
|
||||||
|
+ log_debug_errno(r, "Failed to install match for tracking name '%s': %s", item->name, bus_error_message(e, r));
|
||||||
|
+
|
||||||
|
+ bus_track_remove_name_fully(item->track, item->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -216,6 +239,7 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) {
|
||||||
|
|
||||||
|
*n = (struct track_item) {
|
||||||
|
.n_ref = 1,
|
||||||
|
+ .track = track,
|
||||||
|
};
|
||||||
|
|
||||||
|
n->name = strdup(name);
|
||||||
|
@@ -227,7 +251,7 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) {
|
||||||
|
|
||||||
|
bus_track_remove_from_queue(track); /* don't dispatch this while we work in it */
|
||||||
|
|
||||||
|
- r = sd_bus_add_match_async(track->bus, &n->slot, match, on_name_owner_changed, NULL, track);
|
||||||
|
+ r = sd_bus_add_match_async(track->bus, &n->slot, match, on_name_owner_changed, name_owner_changed_install_callback, n);
|
||||||
|
if (r < 0) {
|
||||||
|
bus_track_add_to_queue(track);
|
||||||
|
return r;
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
From 9f940102616443911fff789aae63546c1da3138e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luca Boccassi <luca.boccassi@gmail.com>
|
||||||
|
Date: Tue, 18 Feb 2025 21:15:08 +0000
|
||||||
|
Subject: [PATCH] shell completion: add kernel-identify/inspect verbs for
|
||||||
|
bootctl
|
||||||
|
|
||||||
|
Follow-up for a05255981ba5b04f1cf54ea656fbce1dfd9c3a68
|
||||||
|
Follow-up for 3e0a3a0259324b4c40a9a62c8506fe683cd0273b
|
||||||
|
|
||||||
|
(cherry picked from commit 6a6d4c3f3c123a1cbb6770f1cae8c130a48333e1)
|
||||||
|
|
||||||
|
Resolves: RHEL-108576
|
||||||
|
---
|
||||||
|
shell-completion/bash/bootctl | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/shell-completion/bash/bootctl b/shell-completion/bash/bootctl
|
||||||
|
index 0b7cef7871..328289e0cf 100644
|
||||||
|
--- a/shell-completion/bash/bootctl
|
||||||
|
+++ b/shell-completion/bash/bootctl
|
||||||
|
@@ -70,6 +70,7 @@ _bootctl() {
|
||||||
|
[STANDALONE]='help status install update remove is-installed random-seed systemd-efi-options list set-timeout set-timeout-oneshot'
|
||||||
|
[BOOTENTRY]='set-default set-oneshot'
|
||||||
|
[BOOLEAN]='reboot-to-firmware'
|
||||||
|
+ [FILE]='kernel-identify kernel-inspect'
|
||||||
|
)
|
||||||
|
|
||||||
|
for ((i=0; i < COMP_CWORD; i++)); do
|
||||||
|
@@ -100,6 +101,9 @@ _bootctl() {
|
||||||
|
fi
|
||||||
|
elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
|
||||||
|
comps="yes no"
|
||||||
|
+ elif __contains_word "$verb" ${VERBS[FILE]}; then
|
||||||
|
+ comps=$( compgen -A file -- "$cur" )
|
||||||
|
+ compopt -o filenames
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
||||||
444
1225-test-add-tests-for-format_timestamp-and-parse_timest.patch
Normal file
444
1225-test-add-tests-for-format_timestamp-and-parse_timest.patch
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
From 05b4623cb23c6f083a5bee9769e5cd22d8ff4e16 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Sun, 12 Feb 2023 05:30:49 +0900
|
||||||
|
Subject: [PATCH] test: add tests for format_timestamp() and parse_timestamp()
|
||||||
|
with various timezone
|
||||||
|
|
||||||
|
(cherry picked from commit 8b51c41fd0796b1299f3b7f2f11eaf4efae8c2db)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 378 ++++++++++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 366 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 6b546fb9f5..3fbf7bf3d0 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -1,6 +1,9 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
+#include "dirent-util.h"
|
||||||
|
#include "env-util.h"
|
||||||
|
+#include "fd-util.h"
|
||||||
|
+#include "fileio.h"
|
||||||
|
#include "random-util.h"
|
||||||
|
#include "serialize.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
@@ -8,6 +11,8 @@
|
||||||
|
#include "tests.h"
|
||||||
|
#include "time-util.h"
|
||||||
|
|
||||||
|
+#define TRIAL 100u
|
||||||
|
+
|
||||||
|
TEST(parse_sec) {
|
||||||
|
usec_t u;
|
||||||
|
|
||||||
|
@@ -334,11 +339,11 @@ TEST(usec_sub_signed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(format_timestamp) {
|
||||||
|
- for (unsigned i = 0; i < 100; i++) {
|
||||||
|
+ for (unsigned i = 0; i < TRIAL; i++) {
|
||||||
|
char buf[CONST_MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESPAN_MAX)];
|
||||||
|
usec_t x, y;
|
||||||
|
|
||||||
|
- x = random_u64_range(2147483600 * USEC_PER_SEC) + 1;
|
||||||
|
+ x = random_u64_range(USEC_TIMESTAMP_FORMATTABLE_MAX - USEC_PER_SEC) + USEC_PER_SEC;
|
||||||
|
|
||||||
|
assert_se(format_timestamp(buf, sizeof(buf), x));
|
||||||
|
log_debug("%s", buf);
|
||||||
|
@@ -377,20 +382,91 @@ TEST(format_timestamp) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_format_timestamp_impl(usec_t x) {
|
||||||
|
+ bool success;
|
||||||
|
+ const char *xx, *yy;
|
||||||
|
+ usec_t y;
|
||||||
|
+
|
||||||
|
+ xx = FORMAT_TIMESTAMP(x);
|
||||||
|
+ assert_se(xx);
|
||||||
|
+ assert_se(parse_timestamp(xx, &y) >= 0);
|
||||||
|
+ yy = FORMAT_TIMESTAMP(y);
|
||||||
|
+ assert_se(yy);
|
||||||
|
+
|
||||||
|
+ success = (x / USEC_PER_SEC == y / USEC_PER_SEC) && streq(xx, yy);
|
||||||
|
+ log_full(success ? LOG_DEBUG : LOG_ERR, "@" USEC_FMT " → %s → @" USEC_FMT " → %s", x, xx, y, yy);
|
||||||
|
+ assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
||||||
|
+ assert_se(streq(xx, yy));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_format_timestamp_loop(void) {
|
||||||
|
+ test_format_timestamp_impl(USEC_PER_SEC);
|
||||||
|
+
|
||||||
|
+ for (unsigned i = 0; i < TRIAL; i++) {
|
||||||
|
+ usec_t x;
|
||||||
|
+
|
||||||
|
+ x = random_u64_range(USEC_TIMESTAMP_FORMATTABLE_MAX - USEC_PER_SEC) + USEC_PER_SEC;
|
||||||
|
+ test_format_timestamp_impl(x);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST(FORMAT_TIMESTAMP) {
|
||||||
|
- for (unsigned i = 0; i < 100; i++) {
|
||||||
|
- _cleanup_free_ char *buf;
|
||||||
|
- usec_t x, y;
|
||||||
|
+ test_format_timestamp_loop();
|
||||||
|
+}
|
||||||
|
|
||||||
|
- x = random_u64_range(2147483600 * USEC_PER_SEC) + 1;
|
||||||
|
+static void test_format_timestamp_with_tz_one(const char *name1, const char *name2) {
|
||||||
|
+ _cleanup_free_ char *buf = NULL, *tz = NULL;
|
||||||
|
+ const char *name, *saved_tz;
|
||||||
|
|
||||||
|
- /* strbuf() is to test the macro in an argument to a function call. */
|
||||||
|
- assert_se(buf = strdup(FORMAT_TIMESTAMP(x)));
|
||||||
|
- log_debug("%s", buf);
|
||||||
|
- assert_se(parse_timestamp(buf, &y) >= 0);
|
||||||
|
- assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
||||||
|
+ if (name2)
|
||||||
|
+ assert_se(buf = path_join(name1, name2));
|
||||||
|
+ name = buf ?: name1;
|
||||||
|
+
|
||||||
|
+ if (!timezone_is_valid(name, LOG_DEBUG))
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
- assert_se(streq(FORMAT_TIMESTAMP(x), buf));
|
||||||
|
+ log_info("/* %s(%s) */", __func__, name);
|
||||||
|
+
|
||||||
|
+ saved_tz = getenv("TZ");
|
||||||
|
+
|
||||||
|
+ assert_se(tz = strjoin(":", name));
|
||||||
|
+ assert_se(setenv("TZ", tz, 1) >= 0);
|
||||||
|
+ tzset();
|
||||||
|
+ log_debug("%s: tzname[0]=%s, tzname[1]=%s", tz, strempty(tzname[0]), strempty(tzname[1]));
|
||||||
|
+
|
||||||
|
+ test_format_timestamp_loop();
|
||||||
|
+
|
||||||
|
+ assert_se(set_unset_env("TZ", saved_tz, true) == 0);
|
||||||
|
+ tzset();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST(FORMAT_TIMESTAMP_with_tz) {
|
||||||
|
+ if (!slow_tests_enabled())
|
||||||
|
+ return (void) log_tests_skipped("slow tests are disabled");
|
||||||
|
+
|
||||||
|
+ _cleanup_closedir_ DIR *dir = opendir("/usr/share/zoneinfo");
|
||||||
|
+ if (!dir)
|
||||||
|
+ return (void) log_tests_skipped_errno(errno, "Failed to open /usr/share/zoneinfo");
|
||||||
|
+
|
||||||
|
+ FOREACH_DIRENT(de, dir, break) {
|
||||||
|
+ if (de->d_type == DT_REG)
|
||||||
|
+ test_format_timestamp_with_tz_one(de->d_name, NULL);
|
||||||
|
+
|
||||||
|
+ else if (de->d_type == DT_DIR) {
|
||||||
|
+ if (streq(de->d_name, "right"))
|
||||||
|
+ /* The test does not support timezone with leap second info. */
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ _cleanup_closedir_ DIR *subdir = xopendirat(dirfd(dir), de->d_name, 0);
|
||||||
|
+ if (!subdir) {
|
||||||
|
+ log_notice_errno(errno, "Failed to open /usr/share/zoneinfo/%s, ignoring: %m", de->d_name);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ FOREACH_DIRENT(subde, subdir, break)
|
||||||
|
+ if (subde->d_type == DT_REG)
|
||||||
|
+ test_format_timestamp_with_tz_one(de->d_name, subde->d_name);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -490,6 +566,219 @@ TEST(format_timestamp_utc) {
|
||||||
|
test_format_timestamp_utc_one(USEC_INFINITY, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_parse_timestamp_one(const char *str, usec_t max_diff, usec_t expected) {
|
||||||
|
+ usec_t usec;
|
||||||
|
+
|
||||||
|
+ log_debug("/* %s(%s) */", __func__, str);
|
||||||
|
+ assert_se(parse_timestamp(str, &usec) >= 0);
|
||||||
|
+ assert_se(usec >= expected);
|
||||||
|
+ assert_se(usec_sub_unsigned(usec, expected) <= max_diff);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST(parse_timestamp) {
|
||||||
|
+ usec_t today, now_usec;
|
||||||
|
+
|
||||||
|
+ /* UTC */
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 00:01 UTC", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 00:00:01 UTC", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 00:00:01.001 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 00:00:01.0010 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 00:01 UTC", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 00:00:01 UTC", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 00:00:01.001 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 00:00:01.0010 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 00:01 UTC", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 00:00:01 UTC", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 00:00:01.001 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 00:00:01.0010 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("70-01-01 00:01 UTC", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 00:00:01 UTC", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 00:00:01.001 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 00:00:01.0010 UTC", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ if (timezone_is_valid("Asia/Tokyo", LOG_DEBUG)) {
|
||||||
|
+ /* Asia/Tokyo (+0900) */
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:01 Asia/Tokyo", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:00:01 Asia/Tokyo", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:00:01.001 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:00:01.0010 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:01 Asia/Tokyo", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:00:01 Asia/Tokyo", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:00:01.001 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:00:01.0010 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:01 Asia/Tokyo", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:00:01 Asia/Tokyo", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:00:01.001 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:00:01.0010 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:01 Asia/Tokyo", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:00:01 Asia/Tokyo", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:00:01.001 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:00:01.0010 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ const char *saved_tz = getenv("TZ");
|
||||||
|
+ assert_se(setenv("TZ", ":Asia/Tokyo", 1) >= 0);
|
||||||
|
+
|
||||||
|
+ /* JST (+0900) */
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:01 JST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:00:01 JST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:00:01.001 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Thu 1970-01-01 09:00:01.0010 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:01 JST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:00:01 JST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:00:01.001 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Thu 70-01-01 09:00:01.0010 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:01 JST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:00:01 JST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:00:01.001 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1970-01-01 09:00:01.0010 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:01 JST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:00:01 JST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:00:01.001 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("70-01-01 09:00:01.0010 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ assert_se(set_unset_env("TZ", saved_tz, true) == 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (timezone_is_valid("America/New_York", LOG_DEBUG)) {
|
||||||
|
+ /* America/New_York (-0500) */
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:01 America/New_York", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:00:01 America/New_York", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:00:01.001 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:00:01.0010 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:01 America/New_York", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:00:01 America/New_York", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:00:01.001 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:00:01.0010 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:01 America/New_York", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:00:01 America/New_York", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:00:01.001 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:00:01.0010 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:01 America/New_York", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:00:01 America/New_York", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:00:01.001 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:00:01.0010 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ const char *saved_tz = getenv("TZ");
|
||||||
|
+ assert_se(setenv("TZ", ":America/New_York", 1) >= 0);
|
||||||
|
+
|
||||||
|
+ /* EST (-0500) */
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:01 EST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:00:01 EST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:00:01.001 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 19:00:01.0010 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:01 EST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:00:01 EST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:00:01.001 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 19:00:01.0010 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:01 EST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:00:01 EST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:00:01.001 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 19:00:01.0010 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:01 EST", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:00:01 EST", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:00:01.001 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 19:00:01.0010 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ assert_se(set_unset_env("TZ", saved_tz, true) == 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* -06 */
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:01 -06", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01 -06", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01.001 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01.0010 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:01 -06", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01 -06", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01.001 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01.0010 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:01 -06", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01 -06", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01.001 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01.0010 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:01 -06", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01 -06", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01.001 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01.0010 -06", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ /* -0600 */
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:01 -0600", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01 -0600", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01.001 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01.0010 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:01 -0600", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01 -0600", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01.001 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01.0010 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:01 -0600", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01 -0600", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01.001 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01.0010 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:01 -0600", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01 -0600", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01.001 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01.0010 -0600", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ /* -06:00 */
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:01 -06:00", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01 -06:00", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01.001 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 1969-12-31 18:00:01.0010 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:01 -06:00", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01 -06:00", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01.001 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("Wed 69-12-31 18:00:01.0010 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:01 -06:00", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01 -06:00", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01.001 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("1969-12-31 18:00:01.0010 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:01 -06:00", 0, USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01 -06:00", 0, USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01.001 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("69-12-31 18:00:01.0010 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ /* without date */
|
||||||
|
+ assert_se(parse_timestamp("today", &today) == 0);
|
||||||
|
+ test_parse_timestamp_one("00:01", 0, today + USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("00:00:01", 0, today + USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("00:00:01.001", 0, today + USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("00:00:01.0010", 0, today + USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("tomorrow", 0, today + USEC_PER_DAY);
|
||||||
|
+ test_parse_timestamp_one("yesterday", 0, today - USEC_PER_DAY);
|
||||||
|
+
|
||||||
|
+ /* relative */
|
||||||
|
+ assert_se(parse_timestamp("now", &now_usec) == 0);
|
||||||
|
+ test_parse_timestamp_one("+5hours", USEC_PER_MINUTE, now_usec + 5 * USEC_PER_HOUR);
|
||||||
|
+ if (now_usec >= 10 * USEC_PER_DAY)
|
||||||
|
+ test_parse_timestamp_one("-10days", USEC_PER_MINUTE, now_usec - 10 * USEC_PER_DAY);
|
||||||
|
+ test_parse_timestamp_one("2weeks left", USEC_PER_MINUTE, now_usec + 2 * USEC_PER_WEEK);
|
||||||
|
+ if (now_usec >= 30 * USEC_PER_MINUTE)
|
||||||
|
+ test_parse_timestamp_one("30minutes ago", USEC_PER_MINUTE, now_usec - 30 * USEC_PER_MINUTE);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST(deserialize_dual_timestamp) {
|
||||||
|
int r;
|
||||||
|
dual_timestamp t;
|
||||||
|
@@ -613,6 +902,71 @@ TEST(map_clock_usec) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_timezone_offset_change_one(const char *utc, const char *pretty) {
|
||||||
|
+ usec_t x, y, z;
|
||||||
|
+ char *s;
|
||||||
|
+
|
||||||
|
+ assert_se(parse_timestamp(utc, &x) >= 0);
|
||||||
|
+
|
||||||
|
+ s = FORMAT_TIMESTAMP_STYLE(x, TIMESTAMP_UTC);
|
||||||
|
+ assert_se(parse_timestamp(s, &y) >= 0);
|
||||||
|
+ log_debug("%s -> " USEC_FMT " -> %s -> " USEC_FMT, utc, x, s, y);
|
||||||
|
+ assert_se(streq(s, utc));
|
||||||
|
+ assert_se(x == y);
|
||||||
|
+
|
||||||
|
+ assert_se(parse_timestamp(pretty, &y) >= 0);
|
||||||
|
+ s = FORMAT_TIMESTAMP_STYLE(y, TIMESTAMP_PRETTY);
|
||||||
|
+ assert_se(parse_timestamp(s, &z) >= 0);
|
||||||
|
+ log_debug("%s -> " USEC_FMT " -> %s -> " USEC_FMT, pretty, y, s, z);
|
||||||
|
+ assert_se(streq(s, pretty));
|
||||||
|
+ assert_se(x == y);
|
||||||
|
+ assert_se(x == z);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST(timezone_offset_change) {
|
||||||
|
+ const char *tz = getenv("TZ");
|
||||||
|
+
|
||||||
|
+ /* See issue #26370. */
|
||||||
|
+
|
||||||
|
+ if (timezone_is_valid("Africa/Casablanca", LOG_DEBUG)) {
|
||||||
|
+ assert_se(setenv("TZ", ":Africa/Casablanca", 1) >= 0);
|
||||||
|
+ tzset();
|
||||||
|
+ log_debug("Africa/Casablanca: tzname[0]=%s, tzname[1]=%s", strempty(tzname[0]), strempty(tzname[1]));
|
||||||
|
+
|
||||||
|
+ test_timezone_offset_change_one("Sun 2015-10-25 01:59:59 UTC", "Sun 2015-10-25 02:59:59 +01");
|
||||||
|
+ test_timezone_offset_change_one("Sun 2015-10-25 02:00:00 UTC", "Sun 2015-10-25 02:00:00 +00");
|
||||||
|
+ test_timezone_offset_change_one("Sun 2018-06-17 01:59:59 UTC", "Sun 2018-06-17 01:59:59 +00");
|
||||||
|
+ test_timezone_offset_change_one("Sun 2018-06-17 02:00:00 UTC", "Sun 2018-06-17 03:00:00 +01");
|
||||||
|
+ test_timezone_offset_change_one("Sun 2018-10-28 01:59:59 UTC", "Sun 2018-10-28 02:59:59 +01");
|
||||||
|
+ test_timezone_offset_change_one("Sun 2018-10-28 02:00:00 UTC", "Sun 2018-10-28 03:00:00 +01");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (timezone_is_valid("Asia/Atyrau", LOG_DEBUG)) {
|
||||||
|
+ assert_se(setenv("TZ", ":Asia/Atyrau", 1) >= 0);
|
||||||
|
+ tzset();
|
||||||
|
+ log_debug("Asia/Atyrau: tzname[0]=%s, tzname[1]=%s", strempty(tzname[0]), strempty(tzname[1]));
|
||||||
|
+
|
||||||
|
+ test_timezone_offset_change_one("Sat 2004-03-27 21:59:59 UTC", "Sun 2004-03-28 01:59:59 +04");
|
||||||
|
+ test_timezone_offset_change_one("Sat 2004-03-27 22:00:00 UTC", "Sun 2004-03-28 03:00:00 +05");
|
||||||
|
+ test_timezone_offset_change_one("Sat 2004-10-30 21:59:59 UTC", "Sun 2004-10-31 02:59:59 +05");
|
||||||
|
+ test_timezone_offset_change_one("Sat 2004-10-30 22:00:00 UTC", "Sun 2004-10-31 03:00:00 +05");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (timezone_is_valid("Chile/EasterIsland", LOG_DEBUG)) {
|
||||||
|
+ assert_se(setenv("TZ", ":Chile/EasterIsland", 1) >= 0);
|
||||||
|
+ tzset();
|
||||||
|
+ log_debug("Chile/EasterIsland: tzname[0]=%s, tzname[1]=%s", strempty(tzname[0]), strempty(tzname[1]));
|
||||||
|
+
|
||||||
|
+ test_timezone_offset_change_one("Sun 1981-10-11 03:59:59 UTC", "Sat 1981-10-10 20:59:59 -07");
|
||||||
|
+ test_timezone_offset_change_one("Sun 1981-10-11 04:00:00 UTC", "Sat 1981-10-10 22:00:00 -06");
|
||||||
|
+ test_timezone_offset_change_one("Sun 1982-03-14 02:59:59 UTC", "Sat 1982-03-13 20:59:59 -06");
|
||||||
|
+ test_timezone_offset_change_one("Sun 1982-03-14 03:00:00 UTC", "Sat 1982-03-13 21:00:00 -06");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ assert_se(set_unset_env("TZ", tz, true) == 0);
|
||||||
|
+ tzset();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int intro(void) {
|
||||||
|
log_info("realtime=" USEC_FMT "\n"
|
||||||
|
"monotonic=" USEC_FMT "\n"
|
||||||
52
1226-test-time-util-disable-failing-tests.patch
Normal file
52
1226-test-time-util-disable-failing-tests.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
From c7a62e108ffbe41ccf1bb5fba4b5a37daf317939 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Tardon <dtardon@redhat.com>
|
||||||
|
Date: Fri, 15 Aug 2025 15:12:14 +0200
|
||||||
|
Subject: [PATCH] test-time-util: disable failing tests
|
||||||
|
|
||||||
|
Presumably they depend on fixes that we don't have yet. And I don't want
|
||||||
|
to backport stuff not relevant to the "--when" feature as a part of this
|
||||||
|
PR.
|
||||||
|
|
||||||
|
RHEL-only: ci
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 3fbf7bf3d0..f2acb6159a 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -697,6 +697,7 @@ TEST(parse_timestamp) {
|
||||||
|
assert_se(set_unset_env("TZ", saved_tz, true) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
/* -06 */
|
||||||
|
test_parse_timestamp_one("Wed 1969-12-31 18:01 -06", 0, USEC_PER_MINUTE);
|
||||||
|
test_parse_timestamp_one("Wed 1969-12-31 18:00:01 -06", 0, USEC_PER_SEC);
|
||||||
|
@@ -759,6 +760,7 @@ TEST(parse_timestamp) {
|
||||||
|
test_parse_timestamp_one("69-12-31 18:00:01 -06:00", 0, USEC_PER_SEC);
|
||||||
|
test_parse_timestamp_one("69-12-31 18:00:01.001 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
test_parse_timestamp_one("69-12-31 18:00:01.0010 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/* without date */
|
||||||
|
assert_se(parse_timestamp("today", &today) == 0);
|
||||||
|
@@ -941,6 +943,7 @@ TEST(timezone_offset_change) {
|
||||||
|
test_timezone_offset_change_one("Sun 2018-10-28 02:00:00 UTC", "Sun 2018-10-28 03:00:00 +01");
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
if (timezone_is_valid("Asia/Atyrau", LOG_DEBUG)) {
|
||||||
|
assert_se(setenv("TZ", ":Asia/Atyrau", 1) >= 0);
|
||||||
|
tzset();
|
||||||
|
@@ -962,6 +965,7 @@ TEST(timezone_offset_change) {
|
||||||
|
test_timezone_offset_change_one("Sun 1982-03-14 02:59:59 UTC", "Sat 1982-03-13 20:59:59 -06");
|
||||||
|
test_timezone_offset_change_one("Sun 1982-03-14 03:00:00 UTC", "Sat 1982-03-13 21:00:00 -06");
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
assert_se(set_unset_env("TZ", tz, true) == 0);
|
||||||
|
tzset();
|
||||||
122
1227-test-test-parse_timestamp-in-various-timezone.patch
Normal file
122
1227-test-test-parse_timestamp-in-various-timezone.patch
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
From 9010f2b16067fbe974cd1922b596bcd526de07bc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 3 Mar 2023 12:09:59 +0900
|
||||||
|
Subject: [PATCH] test: test parse_timestamp() in various timezone
|
||||||
|
|
||||||
|
(cherry picked from commit d8f3ad627c9a857d46d442f8ab722c1efab30d5c)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 57 +++++++++++++++++++++++++++++----------
|
||||||
|
1 file changed, 43 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index f2acb6159a..ee861135c2 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -567,15 +567,17 @@ TEST(format_timestamp_utc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parse_timestamp_one(const char *str, usec_t max_diff, usec_t expected) {
|
||||||
|
- usec_t usec;
|
||||||
|
+ usec_t usec = USEC_INFINITY;
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
- log_debug("/* %s(%s) */", __func__, str);
|
||||||
|
- assert_se(parse_timestamp(str, &usec) >= 0);
|
||||||
|
+ r = parse_timestamp(str, &usec);
|
||||||
|
+ log_debug("/* %s(%s): max_diff="USEC_FMT", expected="USEC_FMT", result="USEC_FMT"*/", __func__, str, max_diff, expected, usec);
|
||||||
|
+ assert_se(r >= 0);
|
||||||
|
assert_se(usec >= expected);
|
||||||
|
assert_se(usec_sub_unsigned(usec, expected) <= max_diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
-TEST(parse_timestamp) {
|
||||||
|
+static void test_parse_timestamp_impl(const char *tz) {
|
||||||
|
usec_t today, now_usec;
|
||||||
|
|
||||||
|
/* UTC */
|
||||||
|
@@ -620,10 +622,9 @@ TEST(parse_timestamp) {
|
||||||
|
test_parse_timestamp_one("70-01-01 09:00:01 Asia/Tokyo", 0, USEC_PER_SEC);
|
||||||
|
test_parse_timestamp_one("70-01-01 09:00:01.001 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
test_parse_timestamp_one("70-01-01 09:00:01.0010 Asia/Tokyo", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- const char *saved_tz = getenv("TZ");
|
||||||
|
- assert_se(setenv("TZ", ":Asia/Tokyo", 1) >= 0);
|
||||||
|
-
|
||||||
|
+ if (streq_ptr(tz, "Asia/Tokyo")) {
|
||||||
|
/* JST (+0900) */
|
||||||
|
test_parse_timestamp_one("Thu 1970-01-01 09:01 JST", 0, USEC_PER_MINUTE);
|
||||||
|
test_parse_timestamp_one("Thu 1970-01-01 09:00:01 JST", 0, USEC_PER_SEC);
|
||||||
|
@@ -644,8 +645,6 @@ TEST(parse_timestamp) {
|
||||||
|
test_parse_timestamp_one("70-01-01 09:00:01 JST", 0, USEC_PER_SEC);
|
||||||
|
test_parse_timestamp_one("70-01-01 09:00:01.001 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
test_parse_timestamp_one("70-01-01 09:00:01.0010 JST", 0, USEC_PER_SEC + 1000);
|
||||||
|
-
|
||||||
|
- assert_se(set_unset_env("TZ", saved_tz, true) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timezone_is_valid("America/New_York", LOG_DEBUG)) {
|
||||||
|
@@ -669,10 +668,9 @@ TEST(parse_timestamp) {
|
||||||
|
test_parse_timestamp_one("69-12-31 19:00:01 America/New_York", 0, USEC_PER_SEC);
|
||||||
|
test_parse_timestamp_one("69-12-31 19:00:01.001 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
test_parse_timestamp_one("69-12-31 19:00:01.0010 America/New_York", 0, USEC_PER_SEC + 1000);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- const char *saved_tz = getenv("TZ");
|
||||||
|
- assert_se(setenv("TZ", ":America/New_York", 1) >= 0);
|
||||||
|
-
|
||||||
|
+ if (streq_ptr(tz, "America/New_York")) {
|
||||||
|
/* EST (-0500) */
|
||||||
|
test_parse_timestamp_one("Wed 1969-12-31 19:01 EST", 0, USEC_PER_MINUTE);
|
||||||
|
test_parse_timestamp_one("Wed 1969-12-31 19:00:01 EST", 0, USEC_PER_SEC);
|
||||||
|
@@ -693,8 +691,6 @@ TEST(parse_timestamp) {
|
||||||
|
test_parse_timestamp_one("69-12-31 19:00:01 EST", 0, USEC_PER_SEC);
|
||||||
|
test_parse_timestamp_one("69-12-31 19:00:01.001 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
test_parse_timestamp_one("69-12-31 19:00:01.0010 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
-
|
||||||
|
- assert_se(set_unset_env("TZ", saved_tz, true) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
@@ -781,6 +777,39 @@ TEST(parse_timestamp) {
|
||||||
|
test_parse_timestamp_one("30minutes ago", USEC_PER_MINUTE, now_usec - 30 * USEC_PER_MINUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
+TEST(parse_timestamp) {
|
||||||
|
+ test_parse_timestamp_impl(NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_parse_timestamp_with_tz_one(const char *tz) {
|
||||||
|
+ const char *saved_tz, *colon_tz;
|
||||||
|
+
|
||||||
|
+ if (!timezone_is_valid(tz, LOG_DEBUG))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ log_info("/* %s(%s) */", __func__, tz);
|
||||||
|
+
|
||||||
|
+ saved_tz = getenv("TZ");
|
||||||
|
+
|
||||||
|
+ assert_se(colon_tz = strjoina(":", tz));
|
||||||
|
+ assert_se(setenv("TZ", colon_tz, 1) >= 0);
|
||||||
|
+ tzset();
|
||||||
|
+ log_debug("%s: tzname[0]=%s, tzname[1]=%s", tz, strempty(tzname[0]), strempty(tzname[1]));
|
||||||
|
+
|
||||||
|
+ test_parse_timestamp_impl(tz);
|
||||||
|
+
|
||||||
|
+ assert_se(set_unset_env("TZ", saved_tz, true) == 0);
|
||||||
|
+ tzset();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST(parse_timestamp_with_tz) {
|
||||||
|
+ _cleanup_strv_free_ char **timezones = NULL;
|
||||||
|
+
|
||||||
|
+ assert_se(get_timezones(&timezones) >= 0);
|
||||||
|
+ STRV_FOREACH(tz, timezones)
|
||||||
|
+ test_parse_timestamp_with_tz_one(*tz);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST(deserialize_dual_timestamp) {
|
||||||
|
int r;
|
||||||
|
dual_timestamp t;
|
||||||
47
1228-systemctl-logind-add-missing-asserts.patch
Normal file
47
1228-systemctl-logind-add-missing-asserts.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
From 41b7fedf9ed75f6dfa9fec03a70964b897fbf9ba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Tue, 14 Mar 2023 06:56:17 +0800
|
||||||
|
Subject: [PATCH] systemctl: logind: add missing asserts
|
||||||
|
|
||||||
|
(cherry picked from commit 9071eea01bd26d838bfd793db497efd849ad44da)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/systemctl/systemctl-logind.c | 10 +++++++++-
|
||||||
|
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/systemctl/systemctl-logind.c b/src/systemctl/systemctl-logind.c
|
||||||
|
index 1c3b68f09f..f910fe6675 100644
|
||||||
|
--- a/src/systemctl/systemctl-logind.c
|
||||||
|
+++ b/src/systemctl/systemctl-logind.c
|
||||||
|
@@ -21,6 +21,8 @@ static int logind_set_wall_message(sd_bus *bus) {
|
||||||
|
_cleanup_free_ char *m = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ assert(bus);
|
||||||
|
+
|
||||||
|
m = strv_join(arg_wall, " ");
|
||||||
|
if (!m)
|
||||||
|
return log_oom();
|
||||||
|
@@ -55,7 +57,10 @@ int logind_reboot(enum action a) {
|
||||||
|
sd_bus *bus;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- if (a < 0 || a >= _ACTION_MAX || !actions[a])
|
||||||
|
+ assert(a >= 0);
|
||||||
|
+ assert(a < _ACTION_MAX);
|
||||||
|
+
|
||||||
|
+ if (!actions[a])
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = acquire_bus(BUS_FULL, &bus);
|
||||||
|
@@ -106,6 +111,9 @@ int logind_check_inhibitors(enum action a) {
|
||||||
|
unsigned c = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ assert(a >= 0);
|
||||||
|
+ assert(a < _ACTION_MAX);
|
||||||
|
+
|
||||||
|
if (arg_check_inhibitors == 0 || arg_force > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
From 5085c1c72a52d6c4e8b47d91a6cd08ceec9c49cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Sun, 5 Mar 2023 23:11:48 +0800
|
||||||
|
Subject: [PATCH] systemctl: logind: make logind_schedule_shutdown accept
|
||||||
|
action as param
|
||||||
|
|
||||||
|
(cherry picked from commit 92b00e867844948bdf559758739343c4308570c0)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/systemctl/systemctl-compat-halt.c | 2 +-
|
||||||
|
src/systemctl/systemctl-logind.c | 8 +++++---
|
||||||
|
src/systemctl/systemctl-logind.h | 2 +-
|
||||||
|
3 files changed, 7 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/systemctl/systemctl-compat-halt.c b/src/systemctl/systemctl-compat-halt.c
|
||||||
|
index 8a0e4e6294..b9164c27ab 100644
|
||||||
|
--- a/src/systemctl/systemctl-compat-halt.c
|
||||||
|
+++ b/src/systemctl/systemctl-compat-halt.c
|
||||||
|
@@ -149,7 +149,7 @@ int halt_main(void) {
|
||||||
|
if (arg_force == 0) {
|
||||||
|
/* always try logind first */
|
||||||
|
if (arg_when > 0)
|
||||||
|
- r = logind_schedule_shutdown();
|
||||||
|
+ r = logind_schedule_shutdown(arg_action);
|
||||||
|
else {
|
||||||
|
r = logind_check_inhibitors(arg_action);
|
||||||
|
if (r < 0)
|
||||||
|
diff --git a/src/systemctl/systemctl-logind.c b/src/systemctl/systemctl-logind.c
|
||||||
|
index f910fe6675..068f54e18b 100644
|
||||||
|
--- a/src/systemctl/systemctl-logind.c
|
||||||
|
+++ b/src/systemctl/systemctl-logind.c
|
||||||
|
@@ -291,19 +291,21 @@ int prepare_boot_loader_entry(void) {
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
-int logind_schedule_shutdown(void) {
|
||||||
|
-
|
||||||
|
+int logind_schedule_shutdown(enum action a) {
|
||||||
|
#if ENABLE_LOGIND
|
||||||
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
const char *action;
|
||||||
|
sd_bus *bus;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ assert(a >= 0);
|
||||||
|
+ assert(a < _ACTION_MAX);
|
||||||
|
+
|
||||||
|
r = acquire_bus(BUS_FULL, &bus);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- action = action_table[arg_action].verb;
|
||||||
|
+ action = action_table[a].verb;
|
||||||
|
if (!action)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Scheduling not supported for this action.");
|
||||||
|
|
||||||
|
diff --git a/src/systemctl/systemctl-logind.h b/src/systemctl/systemctl-logind.h
|
||||||
|
index 925f4559c1..516f74952f 100644
|
||||||
|
--- a/src/systemctl/systemctl-logind.h
|
||||||
|
+++ b/src/systemctl/systemctl-logind.h
|
||||||
|
@@ -10,7 +10,7 @@ int prepare_firmware_setup(void);
|
||||||
|
int prepare_boot_loader_menu(void);
|
||||||
|
int prepare_boot_loader_entry(void);
|
||||||
|
|
||||||
|
-int logind_schedule_shutdown(void);
|
||||||
|
+int logind_schedule_shutdown(enum action a);
|
||||||
|
int logind_cancel_shutdown(void);
|
||||||
|
int logind_show_shutdown(void);
|
||||||
|
|
||||||
262
1230-systemctl-add-option-when-for-scheduled-shutdown.patch
Normal file
262
1230-systemctl-add-option-when-for-scheduled-shutdown.patch
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
From 87f8db36eb01b805e7000aeb69ebfaf1c8c323b8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Sun, 5 Mar 2023 23:27:44 +0800
|
||||||
|
Subject: [PATCH] systemctl: add option --when for scheduled shutdown
|
||||||
|
|
||||||
|
Pass an empty string or "cancel" will cancel the action.
|
||||||
|
Pass "show" will show the scheduled actions.
|
||||||
|
|
||||||
|
Replaces #17258
|
||||||
|
|
||||||
|
(cherry picked from commit 1433e1f998465b7acf472c73d58c14e7e2eb3f13)
|
||||||
|
|
||||||
|
Resolves: RHEL-109488
|
||||||
|
---
|
||||||
|
man/systemctl.xml | 41 ++++++++++++++-----------
|
||||||
|
src/systemctl/systemctl-logind.c | 26 ++++++++++------
|
||||||
|
src/systemctl/systemctl-start-special.c | 33 +++++++++++++-------
|
||||||
|
src/systemctl/systemctl.c | 28 +++++++++++++++++
|
||||||
|
4 files changed, 89 insertions(+), 39 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemctl.xml b/man/systemctl.xml
|
||||||
|
index 1df0b158bd..cea6192224 100644
|
||||||
|
--- a/man/systemctl.xml
|
||||||
|
+++ b/man/systemctl.xml
|
||||||
|
@@ -1448,6 +1448,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
<option>--force</option> is specified twice the halt operation is executed by <command>systemctl</command>
|
||||||
|
itself, and the system manager is not contacted. This means the command should succeed even when the system
|
||||||
|
manager has crashed.</para>
|
||||||
|
+
|
||||||
|
+ <para>If combined with <option>--when=</option>, shutdown will be scheduled after the given timestamp.
|
||||||
|
+ And <option>--when=cancel</option> will cancel the shutdown.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
@@ -1459,13 +1462,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
users. This command is asynchronous; it will return after the power-off operation is enqueued, without
|
||||||
|
waiting for it to complete.</para>
|
||||||
|
|
||||||
|
- <para>If combined with <option>--force</option>, shutdown of all running services is skipped, however all
|
||||||
|
- processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the
|
||||||
|
- powering off. If <option>--force</option> is specified twice, the operation is immediately executed without
|
||||||
|
- terminating any processes or unmounting any file systems. This may result in data loss. Note that when
|
||||||
|
- <option>--force</option> is specified twice the power-off operation is executed by
|
||||||
|
- <command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
||||||
|
- succeed even when the system manager has crashed.</para>
|
||||||
|
+ <para>This command honors <option>--force</option> and <option>--when=</option> in a similar way
|
||||||
|
+ as <command>halt</command>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
@@ -1479,14 +1477,6 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
users. This command is asynchronous; it will return after the reboot operation is enqueued,
|
||||||
|
without waiting for it to complete.</para>
|
||||||
|
|
||||||
|
- <para>If combined with <option>--force</option>, shutdown of all running services is skipped, however all
|
||||||
|
- processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the
|
||||||
|
- reboot. If <option>--force</option> is specified twice, the operation is immediately executed without
|
||||||
|
- terminating any processes or unmounting any file systems. This may result in data loss. Note that when
|
||||||
|
- <option>--force</option> is specified twice the reboot operation is executed by
|
||||||
|
- <command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
||||||
|
- succeed even when the system manager has crashed.</para>
|
||||||
|
-
|
||||||
|
<para>If the switch <option>--reboot-argument=</option> is given, it will be passed as the optional
|
||||||
|
argument to the <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
|
system call.</para>
|
||||||
|
@@ -1494,6 +1484,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
<para>Options <option>--boot-loader-entry=</option>, <option>--boot-loader-menu=</option>, and
|
||||||
|
<option>--firmware-setup</option> can be used to select what to do <emphasis>after</emphasis> the
|
||||||
|
reboot. See the descriptions of those options for details.</para>
|
||||||
|
+
|
||||||
|
+ <para>This command honors <option>--force</option> and <option>--when=</option> in a similar way
|
||||||
|
+ as <command>halt</command>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
@@ -1506,9 +1499,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
asynchronous; it will return after the reboot operation is enqueued, without waiting for it to
|
||||||
|
complete.</para>
|
||||||
|
|
||||||
|
- <para>If combined with <option>--force</option>, shutdown of all running services is skipped, however all
|
||||||
|
- processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the
|
||||||
|
- reboot.</para>
|
||||||
|
+ <para>This command honors <option>--force</option> and <option>--when=</option> in a similar way
|
||||||
|
+ as <command>halt</command>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
@@ -2420,6 +2412,19 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
<listitem><para>When used with <command>bind</command>, creates a read-only bind mount.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--when=</option></term>
|
||||||
|
+
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>When used with <command>halt</command>, <command>poweroff</command>, <command>reboot</command>
|
||||||
|
+ or <command>kexec</command>, schedule the action to be performed at the given timestamp,
|
||||||
|
+ which should adhere to the syntax documented in <citerefentry
|
||||||
|
+ project='man-pages'><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||||
|
+ section "PARSING TIMESTAMPS". Specially, if <literal>show</literal> is given, the currently scheduled
|
||||||
|
+ action will be shown, which can be canceled by passing an empty string or <literal>cancel</literal>.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
<xi:include href="user-system-options.xml" xpointer="host" />
|
||||||
|
<xi:include href="user-system-options.xml" xpointer="machine" />
|
||||||
|
|
||||||
|
diff --git a/src/systemctl/systemctl-logind.c b/src/systemctl/systemctl-logind.c
|
||||||
|
index 068f54e18b..fd8ca09de8 100644
|
||||||
|
--- a/src/systemctl/systemctl-logind.c
|
||||||
|
+++ b/src/systemctl/systemctl-logind.c
|
||||||
|
@@ -356,7 +356,7 @@ int logind_show_shutdown(void) {
|
||||||
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||||
|
sd_bus *bus;
|
||||||
|
- const char *action = NULL;
|
||||||
|
+ const char *action, *pretty_action;
|
||||||
|
uint64_t elapse;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -376,17 +376,23 @@ int logind_show_shutdown(void) {
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(ENODATA), "No scheduled shutdown.");
|
||||||
|
|
||||||
|
if (STR_IN_SET(action, "halt", "poweroff", "exit"))
|
||||||
|
- action = "Shutdown";
|
||||||
|
+ pretty_action = "Shutdown";
|
||||||
|
else if (streq(action, "kexec"))
|
||||||
|
- action = "Reboot via kexec";
|
||||||
|
+ pretty_action = "Reboot via kexec";
|
||||||
|
else if (streq(action, "reboot"))
|
||||||
|
- action = "Reboot";
|
||||||
|
-
|
||||||
|
- /* If we don't recognize the action string, we'll show it as-is */
|
||||||
|
-
|
||||||
|
- log_info("%s scheduled for %s, use 'shutdown -c' to cancel.",
|
||||||
|
- action,
|
||||||
|
- FORMAT_TIMESTAMP_STYLE(elapse, arg_timestamp_style));
|
||||||
|
+ pretty_action = "Reboot";
|
||||||
|
+ else /* If we don't recognize the action string, we'll show it as-is */
|
||||||
|
+ pretty_action = action;
|
||||||
|
+
|
||||||
|
+ if (arg_action == ACTION_SYSTEMCTL)
|
||||||
|
+ log_info("%s scheduled for %s, use 'systemctl %s --when=cancel' to cancel.",
|
||||||
|
+ pretty_action,
|
||||||
|
+ FORMAT_TIMESTAMP_STYLE(elapse, arg_timestamp_style),
|
||||||
|
+ action);
|
||||||
|
+ else
|
||||||
|
+ log_info("%s scheduled for %s, use 'shutdown -c' to cancel.",
|
||||||
|
+ pretty_action,
|
||||||
|
+ FORMAT_TIMESTAMP_STYLE(elapse, arg_timestamp_style));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
diff --git a/src/systemctl/systemctl-start-special.c b/src/systemctl/systemctl-start-special.c
|
||||||
|
index 9363764cd7..4dee3028b0 100644
|
||||||
|
--- a/src/systemctl/systemctl-start-special.c
|
||||||
|
+++ b/src/systemctl/systemctl-start-special.c
|
||||||
|
@@ -208,22 +208,33 @@ int verb_start_special(int argc, char *argv[], void *userdata) {
|
||||||
|
ACTION_POWEROFF,
|
||||||
|
ACTION_REBOOT,
|
||||||
|
ACTION_KEXEC,
|
||||||
|
- ACTION_HALT,
|
||||||
|
- ACTION_SUSPEND,
|
||||||
|
- ACTION_HIBERNATE,
|
||||||
|
- ACTION_HYBRID_SLEEP,
|
||||||
|
- ACTION_SUSPEND_THEN_HIBERNATE)) {
|
||||||
|
-
|
||||||
|
- r = logind_reboot(a);
|
||||||
|
- if (r >= 0)
|
||||||
|
- return r;
|
||||||
|
- if (IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS))
|
||||||
|
- /* Requested operation requires auth, is not supported or already in progress */
|
||||||
|
+ ACTION_HALT)) {
|
||||||
|
+
|
||||||
|
+ if (arg_when == 0)
|
||||||
|
+ r = logind_reboot(a);
|
||||||
|
+ else if (arg_when != USEC_INFINITY)
|
||||||
|
+ r = logind_schedule_shutdown(a);
|
||||||
|
+ else /* arg_when == USEC_INFINITY */
|
||||||
|
+ r = logind_cancel_shutdown();
|
||||||
|
+ if (r >= 0 || IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS))
|
||||||
|
+ /* The latter indicates that the requested operation requires auth,
|
||||||
|
+ * is not supported or already in progress, in which cases we ignore the error. */
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* On all other errors, try low-level operation. In order to minimize the difference
|
||||||
|
* between operation with and without logind, we explicitly enable non-blocking mode
|
||||||
|
* for this, as logind's shutdown operations are always non-blocking. */
|
||||||
|
+ arg_no_block = true;
|
||||||
|
+
|
||||||
|
+ } else if (IN_SET(a,
|
||||||
|
+ ACTION_SUSPEND,
|
||||||
|
+ ACTION_HIBERNATE,
|
||||||
|
+ ACTION_HYBRID_SLEEP,
|
||||||
|
+ ACTION_SUSPEND_THEN_HIBERNATE)) {
|
||||||
|
+
|
||||||
|
+ r = logind_reboot(a);
|
||||||
|
+ if (r >= 0 || IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS))
|
||||||
|
+ return r;
|
||||||
|
|
||||||
|
arg_no_block = true;
|
||||||
|
|
||||||
|
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
||||||
|
index 883a5b75f4..9dfde28426 100644
|
||||||
|
--- a/src/systemctl/systemctl.c
|
||||||
|
+++ b/src/systemctl/systemctl.c
|
||||||
|
@@ -313,6 +313,8 @@ static int systemctl_help(void) {
|
||||||
|
" --read-only Create read-only bind mount\n"
|
||||||
|
" --mkdir Create directory before mounting, if missing\n"
|
||||||
|
" --marked Restart/reload previously marked units\n"
|
||||||
|
+ " --when=TIME Schedule halt/power-off/reboot/kexec action after\n"
|
||||||
|
+ " a certain timestamp\n"
|
||||||
|
"\nSee the %2$s for details.\n",
|
||||||
|
program_invocation_short_name,
|
||||||
|
link,
|
||||||
|
@@ -435,6 +437,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
||||||
|
ARG_MKDIR,
|
||||||
|
ARG_MARKED,
|
||||||
|
ARG_NO_WARN,
|
||||||
|
+ ARG_WHEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct option options[] = {
|
||||||
|
@@ -497,6 +500,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
||||||
|
{ "read-only", no_argument, NULL, ARG_READ_ONLY },
|
||||||
|
{ "mkdir", no_argument, NULL, ARG_MKDIR },
|
||||||
|
{ "marked", no_argument, NULL, ARG_MARKED },
|
||||||
|
+ { "when", required_argument, NULL, ARG_WHEN },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -933,6 +937,30 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
||||||
|
arg_no_warn = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case ARG_WHEN:
|
||||||
|
+ if (streq(optarg, "show")) {
|
||||||
|
+ r = logind_show_shutdown();
|
||||||
|
+ if (r < 0 && r != -ENODATA)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (STR_IN_SET(optarg, "", "cancel")) {
|
||||||
|
+ arg_when = USEC_INFINITY;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = parse_timestamp(optarg, &arg_when);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to parse --when= argument '%s': %m", optarg);
|
||||||
|
+
|
||||||
|
+ if (!timestamp_is_set(arg_when))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
+ "Invalid timestamp '%s' specified for --when=.", optarg);
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case '.':
|
||||||
|
/* Output an error mimicking getopt, and print a hint afterwards */
|
||||||
|
log_error("%s: invalid option -- '.'", program_invocation_name);
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
From e8f66d4c6570765fd60111ec7e3b5dbdb7d14c69 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Tue, 14 Mar 2023 07:16:18 +0800
|
||||||
|
Subject: [PATCH] test-time-util: add test cases to invalidate "show" and
|
||||||
|
"cancel"
|
||||||
|
|
||||||
|
Ensure that systemctl reboot --when=show and --when=cancel will not result in ambiguities
|
||||||
|
|
||||||
|
(cherry picked from commit 165655cb1de2e79d954d9165459143140e52c53b)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index ee861135c2..379f55ff2f 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -580,6 +580,11 @@ static void test_parse_timestamp_one(const char *str, usec_t max_diff, usec_t ex
|
||||||
|
static void test_parse_timestamp_impl(const char *tz) {
|
||||||
|
usec_t today, now_usec;
|
||||||
|
|
||||||
|
+ /* Invalid: Ensure that systemctl reboot --when=show and --when=cancel
|
||||||
|
+ * will not result in ambiguities */
|
||||||
|
+ assert_se(parse_timestamp("show", NULL) == -EINVAL);
|
||||||
|
+ assert_se(parse_timestamp("cancel", NULL) == -EINVAL);
|
||||||
|
+
|
||||||
|
/* UTC */
|
||||||
|
test_parse_timestamp_one("Thu 1970-01-01 00:01 UTC", 0, USEC_PER_MINUTE);
|
||||||
|
test_parse_timestamp_one("Thu 1970-01-01 00:00:01 UTC", 0, USEC_PER_SEC);
|
||||||
128
1232-Introduce-RET_GATHER-and-use-it-in-src-shared.patch
Normal file
128
1232-Introduce-RET_GATHER-and-use-it-in-src-shared.patch
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
From 5bec9826a14483e7e612879fe2630f1b517e37be Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Sun, 9 Jul 2023 13:25:42 -0600
|
||||||
|
Subject: [PATCH] Introduce RET_GATHER and use it in src/shared/
|
||||||
|
|
||||||
|
The idea is to make it easier to implement the common pattern of
|
||||||
|
accumulating errors (negative values) in an accumulator to return
|
||||||
|
the first error.
|
||||||
|
|
||||||
|
(cherry picked from commit 809c3a84e1a572ccaaa7eca5394c0b842118c22f)
|
||||||
|
|
||||||
|
Resolves: RHEL-108598
|
||||||
|
---
|
||||||
|
src/basic/errno-util.h | 10 ++++++++++
|
||||||
|
src/shared/bus-util.c | 10 ++--------
|
||||||
|
src/shared/devnode-acl.c | 4 ++--
|
||||||
|
src/shared/nscd-flush.c | 16 +++++-----------
|
||||||
|
src/test/test-errno-util.c | 11 +++++++++++
|
||||||
|
5 files changed, 30 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h
|
||||||
|
index b10dd755c9..27804e6382 100644
|
||||||
|
--- a/src/basic/errno-util.h
|
||||||
|
+++ b/src/basic/errno-util.h
|
||||||
|
@@ -74,6 +74,16 @@ static inline int RET_NERRNO(int ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Collect possible errors in <acc>, so that the first error can be returned.
|
||||||
|
+ * Returns (possibly updated) <acc>. */
|
||||||
|
+#define RET_GATHER(acc, err) \
|
||||||
|
+ ({ \
|
||||||
|
+ int *__a = &(acc), __e = (err); \
|
||||||
|
+ if (*__a >= 0 && __e < 0) \
|
||||||
|
+ *__a = __e; \
|
||||||
|
+ *__a; \
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
static inline int errno_or_else(int fallback) {
|
||||||
|
/* To be used when invoking library calls where errno handling is not defined clearly: we return
|
||||||
|
* errno if it is set, and the specified error otherwise. The idea is that the caller initializes
|
||||||
|
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
||||||
|
index 5e6d17d201..7c8d2aa6f5 100644
|
||||||
|
--- a/src/shared/bus-util.c
|
||||||
|
+++ b/src/shared/bus-util.c
|
||||||
|
@@ -484,14 +484,8 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) {
|
||||||
|
|
||||||
|
/* Continues adding after failure, and returns the first failure. */
|
||||||
|
|
||||||
|
- STRV_FOREACH(i, l) {
|
||||||
|
- int k;
|
||||||
|
-
|
||||||
|
- k = sd_bus_track_add_name(t, *i);
|
||||||
|
- if (k < 0 && r >= 0)
|
||||||
|
- r = k;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ STRV_FOREACH(i, l)
|
||||||
|
+ RET_GATHER(r, sd_bus_track_add_name(t, *i));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/shared/devnode-acl.c b/src/shared/devnode-acl.c
|
||||||
|
index 66e3a40f2f..8c961061cf 100644
|
||||||
|
--- a/src/shared/devnode-acl.c
|
||||||
|
+++ b/src/shared/devnode-acl.c
|
||||||
|
@@ -220,8 +220,8 @@ int devnode_acl_all(const char *seat,
|
||||||
|
k = devnode_acl(n, flush, del, old_uid, add, new_uid);
|
||||||
|
if (k == -ENOENT)
|
||||||
|
log_debug("Device %s disappeared while setting ACLs", n);
|
||||||
|
- else if (k < 0 && r == 0)
|
||||||
|
- r = k;
|
||||||
|
+ else
|
||||||
|
+ RET_GATHER(r, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
diff --git a/src/shared/nscd-flush.c b/src/shared/nscd-flush.c
|
||||||
|
index 9b0ba2d67a..d2b41f2b4d 100644
|
||||||
|
--- a/src/shared/nscd-flush.c
|
||||||
|
+++ b/src/shared/nscd-flush.c
|
||||||
|
@@ -128,21 +128,15 @@ static int nscd_flush_cache_one(const char *database, usec_t end) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int nscd_flush_cache(char **databases) {
|
||||||
|
- usec_t end;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
- /* Tries to invalidate the specified database in nscd. We do this carefully, with a 5s timeout, so that we
|
||||||
|
- * don't block indefinitely on another service. */
|
||||||
|
+ /* Tries to invalidate the specified database in nscd. We do this carefully, with a 5s timeout,
|
||||||
|
+ * so that we don't block indefinitely on another service. */
|
||||||
|
|
||||||
|
- end = usec_add(now(CLOCK_MONOTONIC), NSCD_FLUSH_CACHE_TIMEOUT_USEC);
|
||||||
|
+ usec_t end = usec_add(now(CLOCK_MONOTONIC), NSCD_FLUSH_CACHE_TIMEOUT_USEC);
|
||||||
|
|
||||||
|
- STRV_FOREACH(i, databases) {
|
||||||
|
- int k;
|
||||||
|
-
|
||||||
|
- k = nscd_flush_cache_one(*i, end);
|
||||||
|
- if (k < 0 && r >= 0)
|
||||||
|
- r = k;
|
||||||
|
- }
|
||||||
|
+ STRV_FOREACH(i, databases)
|
||||||
|
+ RET_GATHER(r, nscd_flush_cache_one(*i, end));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
diff --git a/src/test/test-errno-util.c b/src/test/test-errno-util.c
|
||||||
|
index cac0d5402b..77fb7d0011 100644
|
||||||
|
--- a/src/test/test-errno-util.c
|
||||||
|
+++ b/src/test/test-errno-util.c
|
||||||
|
@@ -67,4 +67,15 @@ TEST(ERRNO_IS_TRANSIENT) {
|
||||||
|
assert_se(!ERRNO_IS_NEG_TRANSIENT(INTMAX_MIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
+TEST(RET_GATHER) {
|
||||||
|
+ int x = 0, y = 2;
|
||||||
|
+
|
||||||
|
+ assert_se(RET_GATHER(x, 5) == 0);
|
||||||
|
+ assert_se(RET_GATHER(x, -5) == -5);
|
||||||
|
+ assert_se(RET_GATHER(x, -1) == -5);
|
||||||
|
+
|
||||||
|
+ assert_se(RET_GATHER(x, y++) == -5);
|
||||||
|
+ assert_se(y == 3);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
DEFINE_TEST_MAIN(LOG_INFO);
|
||||||
50
1233-fd-util-don-t-eat-up-errors-in-fd_cloexec_many.patch
Normal file
50
1233-fd-util-don-t-eat-up-errors-in-fd_cloexec_many.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
From c2dc44abd4014f13a40dde350af92e2d74201359 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Yuan <me@yhndnzj.com>
|
||||||
|
Date: Fri, 29 Dec 2023 17:57:59 +0800
|
||||||
|
Subject: [PATCH] fd-util: don't eat up errors in fd_cloexec_many
|
||||||
|
|
||||||
|
Follow-up for ed18c22c989495aab36512f03449222cfcf79aa7
|
||||||
|
|
||||||
|
Before this commit, a successful fd_cloexec() call would
|
||||||
|
discard all previously gathered errors.
|
||||||
|
|
||||||
|
(cherry picked from commit 6b9cac874c33f4fa27aa4b4b5b980f60c28ee043)
|
||||||
|
|
||||||
|
Resolves: RHEL-108598
|
||||||
|
---
|
||||||
|
src/basic/fd-util.c | 13 ++++++-------
|
||||||
|
1 file changed, 6 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
|
||||||
|
index 66bb7569bb..932c5a8d80 100644
|
||||||
|
--- a/src/basic/fd-util.c
|
||||||
|
+++ b/src/basic/fd-util.c
|
||||||
|
@@ -175,7 +175,7 @@ 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);
|
||||||
|
|
||||||
|
@@ -183,14 +183,13 @@ int fd_cloexec_many(const int fds[], size_t n_fds, bool cloexec) {
|
||||||
|
if (fds[i] < 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(fds[i], cloexec));
|
||||||
|
+
|
||||||
|
+ if (r >= 0)
|
||||||
|
+ r = 1; /* report if we did anything */
|
||||||
|
}
|
||||||
|
|
||||||
|
- return ret;
|
||||||
|
+ return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pure_ static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) {
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
From 762a8dc0c328e256847b111249bbff8e70f98942 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 19 May 2023 04:33:39 +0900
|
||||||
|
Subject: [PATCH] sd-bus: refuse to send messages with an invalid string
|
||||||
|
|
||||||
|
Prompted by aaf7b0e41105d7b7cf30912cdac32820f011a219 and
|
||||||
|
4804da58536ab7ad46178a03f4d2da49fd8e4ba2.
|
||||||
|
|
||||||
|
(cherry picked from commit 26a9dd6f55bb757e0033995cbb16bca12986b7cd)
|
||||||
|
|
||||||
|
Resolves: RHEL-108584
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-bus/bus-message.c | 14 +++++++++++++-
|
||||||
|
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
|
||||||
|
index 213b276e33..c51af56dda 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/bus-message.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/bus-message.c
|
||||||
|
@@ -1324,12 +1324,21 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
|
||||||
|
* into the empty string */
|
||||||
|
p = strempty(p);
|
||||||
|
|
||||||
|
- _fallthrough_;
|
||||||
|
+ if (!utf8_is_valid(p))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ align = 4;
|
||||||
|
+ sz = 4 + strlen(p) + 1;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case SD_BUS_TYPE_OBJECT_PATH:
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
+ if (!object_path_is_valid(p))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
align = 4;
|
||||||
|
sz = 4 + strlen(p) + 1;
|
||||||
|
break;
|
||||||
|
@@ -1338,6 +1347,9 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
|
||||||
|
|
||||||
|
p = strempty(p);
|
||||||
|
|
||||||
|
+ if (!signature_is_valid(p, /* allow_dict_entry = */ true))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
align = 1;
|
||||||
|
sz = 1 + strlen(p) + 1;
|
||||||
|
break;
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
From f3f939b236636fdca38e89ca564a669f0da4fd4d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||||
|
Date: Fri, 19 May 2023 18:42:36 +0200
|
||||||
|
Subject: [PATCH] test: check if we correctly handle invalid UTF-8 in mount
|
||||||
|
stuff
|
||||||
|
|
||||||
|
Provides coverage for #27611.
|
||||||
|
|
||||||
|
(cherry picked from commit b74df879fc81d4668ce14532a76c23b85e651170)
|
||||||
|
|
||||||
|
Resolves: RHEL-108584
|
||||||
|
---
|
||||||
|
.../units/testsuite-07.mount-invalid-chars.sh | 70 +++++++++++++++++++
|
||||||
|
1 file changed, 70 insertions(+)
|
||||||
|
create mode 100755 test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-07.mount-invalid-chars.sh b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000000..617ea697c8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
@@ -0,0 +1,70 @@
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
+set -eux
|
||||||
|
+set -o pipefail
|
||||||
|
+
|
||||||
|
+# Don't send invalid characters over dbus if a mount contains them
|
||||||
|
+
|
||||||
|
+at_exit() {
|
||||||
|
+ mountpoint -q /proc/1/mountinfo && umount /proc/1/mountinfo
|
||||||
|
+ [[ -e /tmp/fstab.bak ]] && mv -f /tmp/fstab /etc/fstab
|
||||||
|
+ rm -f /run/systemd/system/foo-*.mount
|
||||||
|
+ systemctl daemon-reload
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap at_exit EXIT
|
||||||
|
+
|
||||||
|
+# Check invalid characters directly in /proc/mountinfo
|
||||||
|
+#
|
||||||
|
+# This is a bit tricky (and hacky), since we have to temporarily replace
|
||||||
|
+# PID 1's /proc/mountinfo, but we have to keep the original mounts intact,
|
||||||
|
+# otherwise systemd would unmount them on reload
|
||||||
|
+TMP_MOUNTINFO="$(mktemp)"
|
||||||
|
+
|
||||||
|
+cp /proc/1/mountinfo "$TMP_MOUNTINFO"
|
||||||
|
+# Add a mount entry with a "Unicode non-character" in it
|
||||||
|
+echo -ne '69 1 252:2 / /foo/mountinfo rw,relatime shared:1 - cifs //foo\ufffebar rw,seclabel\n' >>"$TMP_MOUNTINFO"
|
||||||
|
+mount --bind "$TMP_MOUNTINFO" /proc/1/mountinfo
|
||||||
|
+systemctl daemon-reload
|
||||||
|
+# On affected versions this would throw an error:
|
||||||
|
+# Failed to get properties: Bad message
|
||||||
|
+systemctl status foo-mountinfo.mount
|
||||||
|
+
|
||||||
|
+umount /proc/1/mountinfo
|
||||||
|
+systemctl daemon-reload
|
||||||
|
+rm -f "$TMP_MOUNTINFO"
|
||||||
|
+
|
||||||
|
+# Check invalid characters in a mount unit
|
||||||
|
+#
|
||||||
|
+# systemd already handles this and refuses to load the invalid string, e.g.:
|
||||||
|
+# foo-fstab.mount:9: String is not UTF-8 clean, ignoring assignment: What=//localhost/foo<6F><6F><EFBFBD>bar
|
||||||
|
+#
|
||||||
|
+# a) Unit generated from /etc/fstab
|
||||||
|
+[[ -e /etc/fstab ]] && cp -f /etc/fstab /tmp/fstab.bak
|
||||||
|
+
|
||||||
|
+echo -ne '//localhost/foo\ufffebar /foo/fstab cifs defaults 0 0\n' >/etc/fstab
|
||||||
|
+systemctl daemon-reload
|
||||||
|
+[[ "$(systemctl show -P UnitFileState foo-fstab.mount)" == bad ]]
|
||||||
|
+
|
||||||
|
+# b) Unit generated from /etc/fstab (but the invalid character is in options)
|
||||||
|
+echo -ne '//localhost/foobar /foo/fstab/opt cifs nosuid,a\ufffeb,noexec 0 0\n' >/etc/fstab
|
||||||
|
+systemctl daemon-reload
|
||||||
|
+[[ "$(systemctl show -P UnitFileState foo-fstab-opt.mount)" == bad ]]
|
||||||
|
+rm -f /etc/fstab
|
||||||
|
+
|
||||||
|
+[[ -e /tmp/fstab.bak ]] && mv -f /tmp/fstab /etc/fstab
|
||||||
|
+systemctl daemon-reload
|
||||||
|
+
|
||||||
|
+# c) Mount unit
|
||||||
|
+mkdir -p /run/systemd/system
|
||||||
|
+echo -ne '[Mount]\nWhat=//localhost/foo\ufffebar\nWhere=/foo/unit\nType=cifs\nOptions=noexec\n' >/run/systemd/system/foo-unit.mount
|
||||||
|
+systemctl daemon-reload
|
||||||
|
+[[ "$(systemctl show -P UnitFileState foo-unit.mount)" == bad ]]
|
||||||
|
+rm -f /run/systemd/system/foo-unit.mount
|
||||||
|
+
|
||||||
|
+# d) Mount unit (but the invalid character is in Options=)
|
||||||
|
+mkdir -p /run/systemd/system
|
||||||
|
+echo -ne '[Mount]\nWhat=//localhost/foobar\nWhere=/foo/unit/opt\nType=cifs\nOptions=noexec,a\ufffeb,nosuid\n' >/run/systemd/system/foo-unit-opt.mount
|
||||||
|
+systemctl daemon-reload
|
||||||
|
+[[ "$(systemctl show -P UnitFileState foo-unit-opt.mount)" == bad ]]
|
||||||
|
+rm -f /run/systemd/system/foo-unit-opt.mount
|
||||||
25
1236-test-fix-a-typo-in-the-cleanup-stuff.patch
Normal file
25
1236-test-fix-a-typo-in-the-cleanup-stuff.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From e882eabc5c9115413db1e6d83f4542ad618fec23 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||||
|
Date: Mon, 22 May 2023 12:06:16 +0200
|
||||||
|
Subject: [PATCH] test: fix a typo in the cleanup stuff
|
||||||
|
|
||||||
|
(cherry picked from commit 7942811255f3d6973b246ebf6b26b690bbceab37)
|
||||||
|
|
||||||
|
Resolves: RHEL-108584
|
||||||
|
---
|
||||||
|
test/units/testsuite-07.mount-invalid-chars.sh | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-07.mount-invalid-chars.sh b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
index 617ea697c8..b70e621126 100755
|
||||||
|
--- a/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
+++ b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
@@ -7,7 +7,7 @@ set -o pipefail
|
||||||
|
|
||||||
|
at_exit() {
|
||||||
|
mountpoint -q /proc/1/mountinfo && umount /proc/1/mountinfo
|
||||||
|
- [[ -e /tmp/fstab.bak ]] && mv -f /tmp/fstab /etc/fstab
|
||||||
|
+ [[ -e /tmp/fstab.bak ]] && mv -f /tmp/fstab.bak /etc/fstab
|
||||||
|
rm -f /run/systemd/system/foo-*.mount
|
||||||
|
systemctl daemon-reload
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
From 78641d8a552eb95dd85cad9686d829af48478727 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||||
|
Date: Mon, 14 Aug 2023 20:09:31 +0200
|
||||||
|
Subject: [PATCH] test: explicitly specify a UTF-8 locale for UTF-8 shenanigans
|
||||||
|
|
||||||
|
As things don't work well without it:
|
||||||
|
|
||||||
|
$ LANG=C printf "\ufffe\n"
|
||||||
|
\uFFFE
|
||||||
|
|
||||||
|
(cherry picked from commit 01febfcdce0326aa1888d085c1009c9399f6a930)
|
||||||
|
|
||||||
|
Resolves: RHEL-108584
|
||||||
|
---
|
||||||
|
test/units/testsuite-07.mount-invalid-chars.sh | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-07.mount-invalid-chars.sh b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
index b70e621126..5a07d14d04 100755
|
||||||
|
--- a/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
+++ b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
@@ -23,7 +23,7 @@ TMP_MOUNTINFO="$(mktemp)"
|
||||||
|
|
||||||
|
cp /proc/1/mountinfo "$TMP_MOUNTINFO"
|
||||||
|
# Add a mount entry with a "Unicode non-character" in it
|
||||||
|
-echo -ne '69 1 252:2 / /foo/mountinfo rw,relatime shared:1 - cifs //foo\ufffebar rw,seclabel\n' >>"$TMP_MOUNTINFO"
|
||||||
|
+LANG="C.UTF-8" printf '69 1 252:2 / /foo/mountinfo rw,relatime shared:1 - cifs //foo\ufffebar rw,seclabel\n' >>"$TMP_MOUNTINFO"
|
||||||
|
mount --bind "$TMP_MOUNTINFO" /proc/1/mountinfo
|
||||||
|
systemctl daemon-reload
|
||||||
|
# On affected versions this would throw an error:
|
||||||
|
@@ -42,12 +42,12 @@ rm -f "$TMP_MOUNTINFO"
|
||||||
|
# a) Unit generated from /etc/fstab
|
||||||
|
[[ -e /etc/fstab ]] && cp -f /etc/fstab /tmp/fstab.bak
|
||||||
|
|
||||||
|
-echo -ne '//localhost/foo\ufffebar /foo/fstab cifs defaults 0 0\n' >/etc/fstab
|
||||||
|
+LANG="C.UTF-8" printf '//localhost/foo\ufffebar /foo/fstab cifs defaults 0 0\n' >/etc/fstab
|
||||||
|
systemctl daemon-reload
|
||||||
|
[[ "$(systemctl show -P UnitFileState foo-fstab.mount)" == bad ]]
|
||||||
|
|
||||||
|
# b) Unit generated from /etc/fstab (but the invalid character is in options)
|
||||||
|
-echo -ne '//localhost/foobar /foo/fstab/opt cifs nosuid,a\ufffeb,noexec 0 0\n' >/etc/fstab
|
||||||
|
+LANG="C.UTF-8" printf '//localhost/foobar /foo/fstab/opt cifs nosuid,a\ufffeb,noexec 0 0\n' >/etc/fstab
|
||||||
|
systemctl daemon-reload
|
||||||
|
[[ "$(systemctl show -P UnitFileState foo-fstab-opt.mount)" == bad ]]
|
||||||
|
rm -f /etc/fstab
|
||||||
|
@@ -57,14 +57,14 @@ systemctl daemon-reload
|
||||||
|
|
||||||
|
# c) Mount unit
|
||||||
|
mkdir -p /run/systemd/system
|
||||||
|
-echo -ne '[Mount]\nWhat=//localhost/foo\ufffebar\nWhere=/foo/unit\nType=cifs\nOptions=noexec\n' >/run/systemd/system/foo-unit.mount
|
||||||
|
+LANG="C.UTF-8" printf '[Mount]\nWhat=//localhost/foo\ufffebar\nWhere=/foo/unit\nType=cifs\nOptions=noexec\n' >/run/systemd/system/foo-unit.mount
|
||||||
|
systemctl daemon-reload
|
||||||
|
[[ "$(systemctl show -P UnitFileState foo-unit.mount)" == bad ]]
|
||||||
|
rm -f /run/systemd/system/foo-unit.mount
|
||||||
|
|
||||||
|
# d) Mount unit (but the invalid character is in Options=)
|
||||||
|
mkdir -p /run/systemd/system
|
||||||
|
-echo -ne '[Mount]\nWhat=//localhost/foobar\nWhere=/foo/unit/opt\nType=cifs\nOptions=noexec,a\ufffeb,nosuid\n' >/run/systemd/system/foo-unit-opt.mount
|
||||||
|
+LANG="C.UTF-8" printf '[Mount]\nWhat=//localhost/foobar\nWhere=/foo/unit/opt\nType=cifs\nOptions=noexec,a\ufffeb,nosuid\n' >/run/systemd/system/foo-unit-opt.mount
|
||||||
|
systemctl daemon-reload
|
||||||
|
[[ "$(systemctl show -P UnitFileState foo-unit-opt.mount)" == bad ]]
|
||||||
|
rm -f /run/systemd/system/foo-unit-opt.mount
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
From 15ad0f0a0145640ee290d805030338f8c01051f4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||||
|
Date: Wed, 23 Aug 2023 15:10:23 +0200
|
||||||
|
Subject: [PATCH] test: use the correct file name when restoring the original
|
||||||
|
fstab
|
||||||
|
|
||||||
|
(cherry picked from commit 9541addff028b56724df79fcf5b88e1544403957)
|
||||||
|
|
||||||
|
Resolves: RHEL-108584
|
||||||
|
---
|
||||||
|
test/units/testsuite-07.mount-invalid-chars.sh | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-07.mount-invalid-chars.sh b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
index 5a07d14d04..a879334869 100755
|
||||||
|
--- a/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
+++ b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
@@ -52,7 +52,7 @@ systemctl daemon-reload
|
||||||
|
[[ "$(systemctl show -P UnitFileState foo-fstab-opt.mount)" == bad ]]
|
||||||
|
rm -f /etc/fstab
|
||||||
|
|
||||||
|
-[[ -e /tmp/fstab.bak ]] && mv -f /tmp/fstab /etc/fstab
|
||||||
|
+[[ -e /tmp/fstab.bak ]] && mv -f /tmp/fstab.bak /etc/fstab
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
# c) Mount unit
|
||||||
134
1239-core-escape-UTF-8-in-mount-unit-Where-field-before-s.patch
Normal file
134
1239-core-escape-UTF-8-in-mount-unit-Where-field-before-s.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
From b280191167ddc52a77da5b4047297d288f9ce73b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 20 Jun 2025 13:16:10 +0200
|
||||||
|
Subject: [PATCH] core: escape UTF-8 in mount unit Where field before sending
|
||||||
|
to clients
|
||||||
|
|
||||||
|
Followup for: 4804da58536ab7ad46178a03f4d2da49fd8e4ba2 #27541
|
||||||
|
|
||||||
|
Fixes: #36206
|
||||||
|
(cherry picked from commit 222b0b05ce9ac29283cd89cf98444c4da3373568)
|
||||||
|
|
||||||
|
Resolves: RHEL-108584
|
||||||
|
---
|
||||||
|
src/core/dbus-mount.c | 23 ++++++++++++++++++-
|
||||||
|
src/core/mount.c | 16 ++++++++++++-
|
||||||
|
src/core/mount.h | 2 ++
|
||||||
|
.../units/testsuite-07.mount-invalid-chars.sh | 5 ++--
|
||||||
|
4 files changed, 42 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c
|
||||||
|
index 55ad4f2c98..7006ebbbba 100644
|
||||||
|
--- a/src/core/dbus-mount.c
|
||||||
|
+++ b/src/core/dbus-mount.c
|
||||||
|
@@ -11,6 +11,27 @@
|
||||||
|
#include "unit.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
+static int property_get_where(
|
||||||
|
+ sd_bus *bus,
|
||||||
|
+ const char *path,
|
||||||
|
+ const char *interface,
|
||||||
|
+ const char *property,
|
||||||
|
+ sd_bus_message *reply,
|
||||||
|
+ void *userdata,
|
||||||
|
+ sd_bus_error *error) {
|
||||||
|
+
|
||||||
|
+ Mount *m = ASSERT_PTR(userdata);
|
||||||
|
+
|
||||||
|
+ assert(bus);
|
||||||
|
+ assert(reply);
|
||||||
|
+
|
||||||
|
+ _cleanup_free_ char *escaped = mount_get_where_escaped(m);
|
||||||
|
+ if (!escaped)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ return sd_bus_message_append_basic(reply, 's', escaped);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int property_get_what(
|
||||||
|
sd_bus *bus,
|
||||||
|
const char *path,
|
||||||
|
@@ -84,7 +105,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResu
|
||||||
|
|
||||||
|
const sd_bus_vtable bus_mount_vtable[] = {
|
||||||
|
SD_BUS_VTABLE_START(0),
|
||||||
|
- SD_BUS_PROPERTY("Where", "s", NULL, offsetof(Mount, where), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
+ SD_BUS_PROPERTY("Where", "s", property_get_where, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("What", "s", property_get_what, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("Options","s", property_get_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("Type", "s", property_get_type, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
diff --git a/src/core/mount.c b/src/core/mount.c
|
||||||
|
index cfe3f40302..79772fb6f1 100644
|
||||||
|
--- a/src/core/mount.c
|
||||||
|
+++ b/src/core/mount.c
|
||||||
|
@@ -31,6 +31,7 @@
|
||||||
|
#include "strv.h"
|
||||||
|
#include "unit-name.h"
|
||||||
|
#include "unit.h"
|
||||||
|
+#include "utf8.h"
|
||||||
|
|
||||||
|
#define RETRY_UMOUNT_MAX 32
|
||||||
|
|
||||||
|
@@ -657,7 +658,11 @@ static int mount_add_extras(Mount *m) {
|
||||||
|
path_simplify(m->where);
|
||||||
|
|
||||||
|
if (!u->description) {
|
||||||
|
- r = unit_set_description(u, m->where);
|
||||||
|
+ _cleanup_free_ char *w = mount_get_where_escaped(m);
|
||||||
|
+ if (!w)
|
||||||
|
+ return log_oom();
|
||||||
|
+
|
||||||
|
+ r = unit_set_description(u, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
@@ -2207,6 +2212,15 @@ static int mount_can_start(Unit *u) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+char* mount_get_where_escaped(const Mount *m) {
|
||||||
|
+ assert(m);
|
||||||
|
+
|
||||||
|
+ if (!m->where)
|
||||||
|
+ return strdup("");
|
||||||
|
+
|
||||||
|
+ return utf8_escape_invalid(m->where);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
|
||||||
|
[MOUNT_EXEC_MOUNT] = "ExecMount",
|
||||||
|
[MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
|
||||||
|
diff --git a/src/core/mount.h b/src/core/mount.h
|
||||||
|
index 1a0d9fc5e5..db4a915202 100644
|
||||||
|
--- a/src/core/mount.h
|
||||||
|
+++ b/src/core/mount.h
|
||||||
|
@@ -93,6 +93,8 @@ extern const UnitVTable mount_vtable;
|
||||||
|
|
||||||
|
void mount_fd_event(Manager *m, int events);
|
||||||
|
|
||||||
|
+char* mount_get_where_escaped(const Mount *m);
|
||||||
|
+
|
||||||
|
const char* mount_exec_command_to_string(MountExecCommand i) _const_;
|
||||||
|
MountExecCommand mount_exec_command_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-07.mount-invalid-chars.sh b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
index a879334869..cd2ca78fdf 100755
|
||||||
|
--- a/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
+++ b/test/units/testsuite-07.mount-invalid-chars.sh
|
||||||
|
@@ -23,12 +23,13 @@ TMP_MOUNTINFO="$(mktemp)"
|
||||||
|
|
||||||
|
cp /proc/1/mountinfo "$TMP_MOUNTINFO"
|
||||||
|
# Add a mount entry with a "Unicode non-character" in it
|
||||||
|
-LANG="C.UTF-8" printf '69 1 252:2 / /foo/mountinfo rw,relatime shared:1 - cifs //foo\ufffebar rw,seclabel\n' >>"$TMP_MOUNTINFO"
|
||||||
|
+LANG="C.UTF-8" printf '69 1 252:2 / /foo/mount\ufffeinfo rw,relatime shared:1 - cifs //foo\ufffebar rw,seclabel\n' >>"$TMP_MOUNTINFO"
|
||||||
|
mount --bind "$TMP_MOUNTINFO" /proc/1/mountinfo
|
||||||
|
systemctl daemon-reload
|
||||||
|
# On affected versions this would throw an error:
|
||||||
|
# Failed to get properties: Bad message
|
||||||
|
-systemctl status foo-mountinfo.mount
|
||||||
|
+systemctl list-units -t mount
|
||||||
|
+systemctl status foo-mount\\xef\\xbf\\xbeinfo.mount
|
||||||
|
|
||||||
|
umount /proc/1/mountinfo
|
||||||
|
systemctl daemon-reload
|
||||||
51
1240-Revert-test-time-util-disable-failing-tests.patch
Normal file
51
1240-Revert-test-time-util-disable-failing-tests.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
From 4d4f5e617bb467be81274dc32b7066fc5ce52b75 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Wed, 3 Sep 2025 13:55:00 +0200
|
||||||
|
Subject: [PATCH] Revert "test-time-util: disable failing tests"
|
||||||
|
|
||||||
|
This won't be needed anymore.
|
||||||
|
|
||||||
|
This reverts commit c7a62e108ffbe41ccf1bb5fba4b5a37daf317939.
|
||||||
|
|
||||||
|
rhel-only: ci
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 4 ----
|
||||||
|
1 file changed, 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 379f55ff2f..56a71ecfba 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -698,7 +698,6 @@ static void test_parse_timestamp_impl(const char *tz) {
|
||||||
|
test_parse_timestamp_one("69-12-31 19:00:01.0010 EST", 0, USEC_PER_SEC + 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if 0
|
||||||
|
/* -06 */
|
||||||
|
test_parse_timestamp_one("Wed 1969-12-31 18:01 -06", 0, USEC_PER_MINUTE);
|
||||||
|
test_parse_timestamp_one("Wed 1969-12-31 18:00:01 -06", 0, USEC_PER_SEC);
|
||||||
|
@@ -761,7 +760,6 @@ static void test_parse_timestamp_impl(const char *tz) {
|
||||||
|
test_parse_timestamp_one("69-12-31 18:00:01 -06:00", 0, USEC_PER_SEC);
|
||||||
|
test_parse_timestamp_one("69-12-31 18:00:01.001 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
test_parse_timestamp_one("69-12-31 18:00:01.0010 -06:00", 0, USEC_PER_SEC + 1000);
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
/* without date */
|
||||||
|
assert_se(parse_timestamp("today", &today) == 0);
|
||||||
|
@@ -977,7 +975,6 @@ TEST(timezone_offset_change) {
|
||||||
|
test_timezone_offset_change_one("Sun 2018-10-28 02:00:00 UTC", "Sun 2018-10-28 03:00:00 +01");
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if 0
|
||||||
|
if (timezone_is_valid("Asia/Atyrau", LOG_DEBUG)) {
|
||||||
|
assert_se(setenv("TZ", ":Asia/Atyrau", 1) >= 0);
|
||||||
|
tzset();
|
||||||
|
@@ -999,7 +996,6 @@ TEST(timezone_offset_change) {
|
||||||
|
test_timezone_offset_change_one("Sun 1982-03-14 02:59:59 UTC", "Sat 1982-03-13 20:59:59 -06");
|
||||||
|
test_timezone_offset_change_one("Sun 1982-03-14 03:00:00 UTC", "Sat 1982-03-13 21:00:00 -06");
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
assert_se(set_unset_env("TZ", tz, true) == 0);
|
||||||
|
tzset();
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
From 03dff755efde1a311969636e11fe95c398b7d878 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 3 Mar 2023 19:40:40 +0900
|
||||||
|
Subject: [PATCH] test: use get_timezones() to iterate all known timezones
|
||||||
|
|
||||||
|
(cherry picked from commit 0b20d70d1c7c190fb943dd4d1f28e6f456d2193e)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 50 +++++++++------------------------------
|
||||||
|
1 file changed, 11 insertions(+), 39 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 56a71ecfba..eb8cc538c0 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -1,6 +1,5 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
-#include "dirent-util.h"
|
||||||
|
#include "env-util.h"
|
||||||
|
#include "fd-util.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
@@ -414,23 +413,18 @@ TEST(FORMAT_TIMESTAMP) {
|
||||||
|
test_format_timestamp_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_format_timestamp_with_tz_one(const char *name1, const char *name2) {
|
||||||
|
- _cleanup_free_ char *buf = NULL, *tz = NULL;
|
||||||
|
- const char *name, *saved_tz;
|
||||||
|
-
|
||||||
|
- if (name2)
|
||||||
|
- assert_se(buf = path_join(name1, name2));
|
||||||
|
- name = buf ?: name1;
|
||||||
|
+static void test_format_timestamp_with_tz_one(const char *tz) {
|
||||||
|
+ const char *saved_tz, *colon_tz;
|
||||||
|
|
||||||
|
- if (!timezone_is_valid(name, LOG_DEBUG))
|
||||||
|
+ if (!timezone_is_valid(tz, LOG_DEBUG))
|
||||||
|
return;
|
||||||
|
|
||||||
|
- log_info("/* %s(%s) */", __func__, name);
|
||||||
|
+ log_info("/* %s(%s) */", __func__, tz);
|
||||||
|
|
||||||
|
saved_tz = getenv("TZ");
|
||||||
|
|
||||||
|
- assert_se(tz = strjoin(":", name));
|
||||||
|
- assert_se(setenv("TZ", tz, 1) >= 0);
|
||||||
|
+ assert_se(colon_tz = strjoina(":", tz));
|
||||||
|
+ assert_se(setenv("TZ", colon_tz, 1) >= 0);
|
||||||
|
tzset();
|
||||||
|
log_debug("%s: tzname[0]=%s, tzname[1]=%s", tz, strempty(tzname[0]), strempty(tzname[1]));
|
||||||
|
|
||||||
|
@@ -441,33 +435,11 @@ static void test_format_timestamp_with_tz_one(const char *name1, const char *nam
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FORMAT_TIMESTAMP_with_tz) {
|
||||||
|
- if (!slow_tests_enabled())
|
||||||
|
- return (void) log_tests_skipped("slow tests are disabled");
|
||||||
|
-
|
||||||
|
- _cleanup_closedir_ DIR *dir = opendir("/usr/share/zoneinfo");
|
||||||
|
- if (!dir)
|
||||||
|
- return (void) log_tests_skipped_errno(errno, "Failed to open /usr/share/zoneinfo");
|
||||||
|
-
|
||||||
|
- FOREACH_DIRENT(de, dir, break) {
|
||||||
|
- if (de->d_type == DT_REG)
|
||||||
|
- test_format_timestamp_with_tz_one(de->d_name, NULL);
|
||||||
|
-
|
||||||
|
- else if (de->d_type == DT_DIR) {
|
||||||
|
- if (streq(de->d_name, "right"))
|
||||||
|
- /* The test does not support timezone with leap second info. */
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- _cleanup_closedir_ DIR *subdir = xopendirat(dirfd(dir), de->d_name, 0);
|
||||||
|
- if (!subdir) {
|
||||||
|
- log_notice_errno(errno, "Failed to open /usr/share/zoneinfo/%s, ignoring: %m", de->d_name);
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- FOREACH_DIRENT(subde, subdir, break)
|
||||||
|
- if (subde->d_type == DT_REG)
|
||||||
|
- test_format_timestamp_with_tz_one(de->d_name, subde->d_name);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _cleanup_strv_free_ char **timezones = NULL;
|
||||||
|
+
|
||||||
|
+ assert_se(get_timezones(&timezones) >= 0);
|
||||||
|
+ STRV_FOREACH(tz, timezones)
|
||||||
|
+ test_format_timestamp_with_tz_one(*tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(format_timestamp_relative) {
|
||||||
72
1242-test-time-util-do-not-fail-on-DST-change.patch
Normal file
72
1242-test-time-util-do-not-fail-on-DST-change.patch
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
From c1e4badeadf75e75b6059a6d644d28414013c102 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 13 Mar 2023 03:47:45 +0900
|
||||||
|
Subject: [PATCH] test-time-util: do not fail on DST change
|
||||||
|
|
||||||
|
(cherry picked from commit cfacd245e798282fcb9b3231bd6e857abfe124fc)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 37 ++++++++++++++++++++++++++++++-------
|
||||||
|
1 file changed, 30 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index eb8cc538c0..775e6bb84a 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -543,12 +543,30 @@ static void test_parse_timestamp_one(const char *str, usec_t max_diff, usec_t ex
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = parse_timestamp(str, &usec);
|
||||||
|
- log_debug("/* %s(%s): max_diff="USEC_FMT", expected="USEC_FMT", result="USEC_FMT"*/", __func__, str, max_diff, expected, usec);
|
||||||
|
+ log_debug("/* %s(%s): max_diff="USEC_FMT", expected="USEC_FMT", result="USEC_FMT" */", __func__, str, max_diff, expected, usec);
|
||||||
|
assert_se(r >= 0);
|
||||||
|
assert_se(usec >= expected);
|
||||||
|
assert_se(usec_sub_unsigned(usec, expected) <= max_diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool time_is_zero(usec_t usec) {
|
||||||
|
+ const char *s;
|
||||||
|
+
|
||||||
|
+ s = FORMAT_TIMESTAMP(usec);
|
||||||
|
+ return strstr(s, " 00:00:00 ");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool timezone_equal(usec_t today, usec_t target) {
|
||||||
|
+ const char *s, *t, *sz, *tz;
|
||||||
|
+
|
||||||
|
+ s = FORMAT_TIMESTAMP(today);
|
||||||
|
+ t = FORMAT_TIMESTAMP(target);
|
||||||
|
+ assert_se(sz = strrchr(s, ' '));
|
||||||
|
+ assert_se(tz = strrchr(t, ' '));
|
||||||
|
+ log_debug("%s("USEC_FMT", "USEC_FMT") -> %s, %s", __func__, today, target, s, t);
|
||||||
|
+ return streq(sz, tz);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void test_parse_timestamp_impl(const char *tz) {
|
||||||
|
usec_t today, now_usec;
|
||||||
|
|
||||||
|
@@ -735,12 +753,17 @@ static void test_parse_timestamp_impl(const char *tz) {
|
||||||
|
|
||||||
|
/* without date */
|
||||||
|
assert_se(parse_timestamp("today", &today) == 0);
|
||||||
|
- test_parse_timestamp_one("00:01", 0, today + USEC_PER_MINUTE);
|
||||||
|
- test_parse_timestamp_one("00:00:01", 0, today + USEC_PER_SEC);
|
||||||
|
- test_parse_timestamp_one("00:00:01.001", 0, today + USEC_PER_SEC + 1000);
|
||||||
|
- test_parse_timestamp_one("00:00:01.0010", 0, today + USEC_PER_SEC + 1000);
|
||||||
|
- test_parse_timestamp_one("tomorrow", 0, today + USEC_PER_DAY);
|
||||||
|
- test_parse_timestamp_one("yesterday", 0, today - USEC_PER_DAY);
|
||||||
|
+ if (time_is_zero(today)) {
|
||||||
|
+ test_parse_timestamp_one("00:01", 0, today + USEC_PER_MINUTE);
|
||||||
|
+ test_parse_timestamp_one("00:00:01", 0, today + USEC_PER_SEC);
|
||||||
|
+ test_parse_timestamp_one("00:00:01.001", 0, today + USEC_PER_SEC + 1000);
|
||||||
|
+ test_parse_timestamp_one("00:00:01.0010", 0, today + USEC_PER_SEC + 1000);
|
||||||
|
+
|
||||||
|
+ if (timezone_equal(today, today + USEC_PER_DAY) && time_is_zero(today + USEC_PER_DAY))
|
||||||
|
+ test_parse_timestamp_one("tomorrow", 0, today + USEC_PER_DAY);
|
||||||
|
+ if (timezone_equal(today, today - USEC_PER_DAY) && time_is_zero(today - USEC_PER_DAY))
|
||||||
|
+ test_parse_timestamp_one("yesterday", 0, today - USEC_PER_DAY);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* relative */
|
||||||
|
assert_se(parse_timestamp("now", &now_usec) == 0);
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
From 8e8569467616ee982df2cc73ac39240482c92d36 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Sun, 26 Nov 2023 20:58:43 +0100
|
||||||
|
Subject: [PATCH] test-time-util: suppress timestamp conversion failures for
|
||||||
|
Africa/Khartoum timezone
|
||||||
|
|
||||||
|
Our timestamp conversion roundtrip test was failing. But I think that this
|
||||||
|
is not our bug:
|
||||||
|
|
||||||
|
$ TZ='Africa/Khartoum' date --date='@1509482094'
|
||||||
|
Tue Oct 31 23:34:54 EAT 2017
|
||||||
|
$ TZ='Africa/Khartoum' date --date='Tue Oct 31 23:34:54 EAT 2017' +%s
|
||||||
|
1509485694
|
||||||
|
$ TZ='Africa/Khartoum' date --date='@1509485694'
|
||||||
|
Tue Oct 31 23:34:54 CAT 2017
|
||||||
|
$ echo $[1509485694 - 1509482094]
|
||||||
|
3600
|
||||||
|
|
||||||
|
This is essentially the same as what happens in our test. After a round-trip, we
|
||||||
|
end up one hour ahead.
|
||||||
|
|
||||||
|
> For 1509482094632752, from the change log of tzdata:
|
||||||
|
>
|
||||||
|
> Release 2017c - 2017-10-20 14:49:34 -0700
|
||||||
|
>
|
||||||
|
> Changes to future timestamps
|
||||||
|
> Sudan will switch from +03 to +02 on 2017-11-01.
|
||||||
|
|
||||||
|
Fixes https://github.com/systemd/systemd/issues/28472.
|
||||||
|
|
||||||
|
(cherry picked from commit 78b95ccad864e1f993fe0776841dd8f39856581b)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 22 ++++++++++++++++++----
|
||||||
|
1 file changed, 18 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 775e6bb84a..2550ffdba2 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -382,7 +382,7 @@ TEST(format_timestamp) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_format_timestamp_impl(usec_t x) {
|
||||||
|
- bool success;
|
||||||
|
+ bool success, override;
|
||||||
|
const char *xx, *yy;
|
||||||
|
usec_t y;
|
||||||
|
|
||||||
|
@@ -393,14 +393,28 @@ static void test_format_timestamp_impl(usec_t x) {
|
||||||
|
assert_se(yy);
|
||||||
|
|
||||||
|
success = (x / USEC_PER_SEC == y / USEC_PER_SEC) && streq(xx, yy);
|
||||||
|
- log_full(success ? LOG_DEBUG : LOG_ERR, "@" USEC_FMT " → %s → @" USEC_FMT " → %s", x, xx, y, yy);
|
||||||
|
- assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
||||||
|
- assert_se(streq(xx, yy));
|
||||||
|
+ /* Workaround for https://github.com/systemd/systemd/issues/28472 */
|
||||||
|
+ override = !success &&
|
||||||
|
+ (STRPTR_IN_SET(tzname[0], "CAT", "EAT") ||
|
||||||
|
+ STRPTR_IN_SET(tzname[1], "CAT", "EAT")) &&
|
||||||
|
+ DIV_ROUND_UP(y - x, USEC_PER_SEC) == 3600; /* 1 hour, ignore fractional second */
|
||||||
|
+ log_full(success ? LOG_DEBUG : override ? LOG_WARNING : LOG_ERR,
|
||||||
|
+ "@" USEC_FMT " → %s → @" USEC_FMT " → %s%s",
|
||||||
|
+ x, xx, y, yy,
|
||||||
|
+ override ? ", ignoring." : "");
|
||||||
|
+ if (!override) {
|
||||||
|
+ assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
||||||
|
+ assert_se(streq(xx, yy));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_format_timestamp_loop(void) {
|
||||||
|
test_format_timestamp_impl(USEC_PER_SEC);
|
||||||
|
|
||||||
|
+ /* Two cases which trigger https://github.com/systemd/systemd/issues/28472 */
|
||||||
|
+ test_format_timestamp_impl(1504938962980066);
|
||||||
|
+ test_format_timestamp_impl(1509482094632752);
|
||||||
|
+
|
||||||
|
for (unsigned i = 0; i < TRIAL; i++) {
|
||||||
|
usec_t x;
|
||||||
|
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
From 846cb844c3e8b5621745798f62bfbfb4275735f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Thu, 5 Dec 2024 13:32:19 +0100
|
||||||
|
Subject: [PATCH] test-time-util: do more suppression of time zone checks
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The issue is directly triggered by tzdata-2024b, where the setting of timezone
|
||||||
|
started to fail and the tests stopped passing. But those timestamps in 1/1/1970
|
||||||
|
appear to have some problems already before:
|
||||||
|
|
||||||
|
$ sudo date -s 'Thu 1970-01-01 13:00:01 WET'
|
||||||
|
Thu Jan 1 03:00:01 PM EET 1970
|
||||||
|
$ sudo date -s 'Thu 1970-01-01 12:00:01 WET'
|
||||||
|
date: cannot set date: Invalid argument
|
||||||
|
Thu Jan 1 02:00:01 PM EET 1970
|
||||||
|
$ rpm -q tzdata
|
||||||
|
tzdata-2024a-9.fc41.noarch
|
||||||
|
|
||||||
|
The same issue appears with other timezones. So move the first timestamp one
|
||||||
|
day forward to avoid the issue.
|
||||||
|
|
||||||
|
After the previous problem is solved, we also get the problem already seen
|
||||||
|
previously where the roundtrip returns a time that is off by one hour:
|
||||||
|
|
||||||
|
@86401000000 → Fri 1970-01-02 00:00:01 WET → @82801000000 → Thu 1970-01-01 23:00:01 WET
|
||||||
|
Assertion 'x / USEC_PER_SEC == y / USEC_PER_SEC' failed at src/test/test-time-util.c:415, function test_format_timestamp_impl(). Aborting.
|
||||||
|
|
||||||
|
Extend the override to suppress this.
|
||||||
|
|
||||||
|
(cherry picked from commit 3cf362f6f57b7d0b5f6b86a49316303b0dda7599)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 11 ++++++-----
|
||||||
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 2550ffdba2..45d7541415 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -393,11 +393,12 @@ static void test_format_timestamp_impl(usec_t x) {
|
||||||
|
assert_se(yy);
|
||||||
|
|
||||||
|
success = (x / USEC_PER_SEC == y / USEC_PER_SEC) && streq(xx, yy);
|
||||||
|
- /* Workaround for https://github.com/systemd/systemd/issues/28472 */
|
||||||
|
+ /* Workaround for https://github.com/systemd/systemd/issues/28472
|
||||||
|
+ * and https://github.com/systemd/systemd/pull/35471. */
|
||||||
|
override = !success &&
|
||||||
|
- (STRPTR_IN_SET(tzname[0], "CAT", "EAT") ||
|
||||||
|
- STRPTR_IN_SET(tzname[1], "CAT", "EAT")) &&
|
||||||
|
- DIV_ROUND_UP(y - x, USEC_PER_SEC) == 3600; /* 1 hour, ignore fractional second */
|
||||||
|
+ (STRPTR_IN_SET(tzname[0], "CAT", "EAT", "WET") ||
|
||||||
|
+ STRPTR_IN_SET(tzname[1], "CAT", "EAT", "WET")) &&
|
||||||
|
+ DIV_ROUND_UP(x > y ? x - y : y - x, USEC_PER_SEC) == 3600; /* 1 hour, ignore fractional second */
|
||||||
|
log_full(success ? LOG_DEBUG : override ? LOG_WARNING : LOG_ERR,
|
||||||
|
"@" USEC_FMT " → %s → @" USEC_FMT " → %s%s",
|
||||||
|
x, xx, y, yy,
|
||||||
|
@@ -409,7 +410,7 @@ static void test_format_timestamp_impl(usec_t x) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_format_timestamp_loop(void) {
|
||||||
|
- test_format_timestamp_impl(USEC_PER_SEC);
|
||||||
|
+ test_format_timestamp_impl(USEC_PER_DAY + USEC_PER_SEC);
|
||||||
|
|
||||||
|
/* Two cases which trigger https://github.com/systemd/systemd/issues/28472 */
|
||||||
|
test_format_timestamp_impl(1504938962980066);
|
||||||
61
1245-test-time-util-fix-truncation-of-usec-to-sec.patch
Normal file
61
1245-test-time-util-fix-truncation-of-usec-to-sec.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
From cb442eb90085aae9db3bdf0cd7a4730912dba3ef Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Sat, 14 Dec 2024 16:49:54 +0900
|
||||||
|
Subject: [PATCH] test-time-util: fix truncation of usec to sec
|
||||||
|
|
||||||
|
Also
|
||||||
|
- use ASSERT_XYZ() macros,
|
||||||
|
- log tzname[] on failure.
|
||||||
|
|
||||||
|
(cherry picked from commit 3f1d499964abb6a4c0141d7ea8f852829880adff)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/test-time-util.c | 20 ++++++++++++--------
|
||||||
|
1 file changed, 12 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 45d7541415..a5443ad7d7 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -384,28 +384,32 @@ TEST(format_timestamp) {
|
||||||
|
static void test_format_timestamp_impl(usec_t x) {
|
||||||
|
bool success, override;
|
||||||
|
const char *xx, *yy;
|
||||||
|
- usec_t y;
|
||||||
|
+ usec_t y, x_sec, y_sec;
|
||||||
|
|
||||||
|
xx = FORMAT_TIMESTAMP(x);
|
||||||
|
- assert_se(xx);
|
||||||
|
- assert_se(parse_timestamp(xx, &y) >= 0);
|
||||||
|
+ ASSERT_NOT_NULL(xx);
|
||||||
|
+ ASSERT_OK(parse_timestamp(xx, &y));
|
||||||
|
yy = FORMAT_TIMESTAMP(y);
|
||||||
|
- assert_se(yy);
|
||||||
|
+ ASSERT_NOT_NULL(yy);
|
||||||
|
|
||||||
|
- success = (x / USEC_PER_SEC == y / USEC_PER_SEC) && streq(xx, yy);
|
||||||
|
+ x_sec = x / USEC_PER_SEC;
|
||||||
|
+ y_sec = y / USEC_PER_SEC;
|
||||||
|
+ success = (x_sec == y_sec) && streq(xx, yy);
|
||||||
|
/* Workaround for https://github.com/systemd/systemd/issues/28472
|
||||||
|
* and https://github.com/systemd/systemd/pull/35471. */
|
||||||
|
override = !success &&
|
||||||
|
(STRPTR_IN_SET(tzname[0], "CAT", "EAT", "WET") ||
|
||||||
|
STRPTR_IN_SET(tzname[1], "CAT", "EAT", "WET")) &&
|
||||||
|
- DIV_ROUND_UP(x > y ? x - y : y - x, USEC_PER_SEC) == 3600; /* 1 hour, ignore fractional second */
|
||||||
|
+ (x_sec > y_sec ? x_sec - y_sec : y_sec - x_sec) == 3600; /* 1 hour, ignore fractional second */
|
||||||
|
log_full(success ? LOG_DEBUG : override ? LOG_WARNING : LOG_ERR,
|
||||||
|
"@" USEC_FMT " → %s → @" USEC_FMT " → %s%s",
|
||||||
|
x, xx, y, yy,
|
||||||
|
override ? ", ignoring." : "");
|
||||||
|
if (!override) {
|
||||||
|
- assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
|
||||||
|
- assert_se(streq(xx, yy));
|
||||||
|
+ if (!success)
|
||||||
|
+ log_warning("tzname[0]=\"%s\", tzname[1]=\"%s\"", tzname[0], tzname[1]);
|
||||||
|
+ ASSERT_EQ(x_sec, y_sec);
|
||||||
|
+ ASSERT_STREQ(xx, yy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
From e0ac4a4632c99750ad63476c3ae62a1988b2883b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luca Boccassi <bluca@debian.org>
|
||||||
|
Date: Fri, 26 Jan 2024 00:22:38 +0000
|
||||||
|
Subject: [PATCH] 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.
|
||||||
|
|
||||||
|
(cherry picked from commit 1e902c3463024bb328bf0d01a5d58a69e1ccf739)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
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 564983b699..4699991535 100644
|
||||||
|
--- a/src/test/test-calendarspec.c
|
||||||
|
+++ b/src/test/test-calendarspec.c
|
||||||
|
@@ -260,4 +260,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 097066b61a..cc11bd999e 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 a5443ad7d7..21b05a3010 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -1016,6 +1016,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",
|
||||||
30
1247-meson-extend-timeout-for-test-time-util.patch
Normal file
30
1247-meson-extend-timeout-for-test-time-util.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From bef180f6ddc06bc6e669024b5d1fb9b97a1e3f4d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Tue, 2 Sep 2025 17:33:35 +0200
|
||||||
|
Subject: [PATCH] meson: extend timeout for test-time-util
|
||||||
|
|
||||||
|
As it runs through many timezones and hits the default timeout when
|
||||||
|
running under sanitizers.
|
||||||
|
|
||||||
|
Based on upstream's b66b3c409900a77b3da7b366ae5a0179abacea99.
|
||||||
|
|
||||||
|
rhel-only: ci
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/test/meson.build | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/meson.build b/src/test/meson.build
|
||||||
|
index 5547271ee7..9de487ced5 100644
|
||||||
|
--- a/src/test/meson.build
|
||||||
|
+++ b/src/test/meson.build
|
||||||
|
@@ -459,7 +459,8 @@ tests += [
|
||||||
|
|
||||||
|
[files('test-fileio.c')],
|
||||||
|
|
||||||
|
- [files('test-time-util.c')],
|
||||||
|
+ [files('test-time-util.c'),
|
||||||
|
+ [], [], [], '', 'timeout=120'],
|
||||||
|
|
||||||
|
[files('test-clock.c')],
|
||||||
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
From c5bdf8c148fc9ab18d3412756ada7317caece6fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 01:40:56 +0900
|
||||||
|
Subject: [PATCH] time-util: use DEFINE_STRING_TABLE_LOOKUP_TO_STRING() macro
|
||||||
|
|
||||||
|
(cherry picked from commit d227a42aadf04c23c668ac3089bc7b4a9baaf7e1)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index f5e10bba1a..6eee8a48a7 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -1616,7 +1616,7 @@ static const char* const timestamp_style_table[_TIMESTAMP_STYLE_MAX] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Use the macro for enum → string to allow for aliases */
|
||||||
|
-_DEFINE_STRING_TABLE_LOOKUP_TO_STRING(timestamp_style, TimestampStyle,);
|
||||||
|
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(timestamp_style, TimestampStyle);
|
||||||
|
|
||||||
|
/* For the string → enum mapping we use the generic implementation, but also support two aliases */
|
||||||
|
TimestampStyle timestamp_style_from_string(const char *s) {
|
||||||
30
1249-time-util-align-string-table.patch
Normal file
30
1249-time-util-align-string-table.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 243ecafd63c2c0f8cbdecee770626143bf4def62 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 01:41:38 +0900
|
||||||
|
Subject: [PATCH] time-util: align string table
|
||||||
|
|
||||||
|
(cherry picked from commit e01a8fdd2645c06cdb9057bd5b8a45ab02c0d6ee)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 6eee8a48a7..404fde01db 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -1609,10 +1609,10 @@ int time_change_fd(void) {
|
||||||
|
|
||||||
|
static const char* const timestamp_style_table[_TIMESTAMP_STYLE_MAX] = {
|
||||||
|
[TIMESTAMP_PRETTY] = "pretty",
|
||||||
|
- [TIMESTAMP_US] = "us",
|
||||||
|
- [TIMESTAMP_UTC] = "utc",
|
||||||
|
+ [TIMESTAMP_US] = "us",
|
||||||
|
+ [TIMESTAMP_UTC] = "utc",
|
||||||
|
[TIMESTAMP_US_UTC] = "us+utc",
|
||||||
|
- [TIMESTAMP_UNIX] = "unix",
|
||||||
|
+ [TIMESTAMP_UNIX] = "unix",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Use the macro for enum → string to allow for aliases */
|
||||||
316
1250-time-util-rename-variables.patch
Normal file
316
1250-time-util-rename-variables.patch
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
From 753dd2e5f28a9b5a552efda75bcbec20ad501e69 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 02:04:31 +0900
|
||||||
|
Subject: [PATCH] time-util: rename variables
|
||||||
|
|
||||||
|
(cherry picked from commit cf98b66d1ad0ff0e9ee0444861069ebade038dbb)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 86 +++++++++++++++++++++----------------------
|
||||||
|
src/basic/time-util.h | 16 ++++----
|
||||||
|
2 files changed, 51 insertions(+), 51 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 404fde01db..7dbd3af20a 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -604,7 +604,7 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
|
||||||
|
+static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
static const struct {
|
||||||
|
const char *name;
|
||||||
|
const int nr;
|
||||||
|
@@ -628,7 +628,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
|
||||||
|
const char *k, *utc = NULL, *tzn = NULL;
|
||||||
|
struct tm tm, copy;
|
||||||
|
time_t x;
|
||||||
|
- usec_t x_usec, plus = 0, minus = 0, ret;
|
||||||
|
+ usec_t usec, x_usec, plus = 0, minus = 0;
|
||||||
|
int r, weekday = -1, dst = -1;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
@@ -651,9 +651,9 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
if (t[0] == '@' && !with_tz)
|
||||||
|
- return parse_sec(t + 1, usec);
|
||||||
|
+ return parse_sec(t + 1, ret);
|
||||||
|
|
||||||
|
- ret = now(CLOCK_REALTIME);
|
||||||
|
+ usec = now(CLOCK_REALTIME);
|
||||||
|
|
||||||
|
if (!with_tz) {
|
||||||
|
if (streq(t, "now"))
|
||||||
|
@@ -734,7 +734,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- x = (time_t) (ret / USEC_PER_SEC);
|
||||||
|
+ x = (time_t) (usec / USEC_PER_SEC);
|
||||||
|
x_usec = 0;
|
||||||
|
|
||||||
|
if (!localtime_or_gmtime_r(&x, &tm, utc))
|
||||||
|
@@ -871,24 +871,24 @@ from_tm:
|
||||||
|
if (x < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- ret = (usec_t) x * USEC_PER_SEC + x_usec;
|
||||||
|
- if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||||
|
+ usec = (usec_t) x * USEC_PER_SEC + x_usec;
|
||||||
|
+ if (usec > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
finish:
|
||||||
|
- if (ret + plus < ret) /* overflow? */
|
||||||
|
+ if (usec + plus < usec) /* overflow? */
|
||||||
|
return -EINVAL;
|
||||||
|
- ret += plus;
|
||||||
|
- if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||||
|
+ usec += plus;
|
||||||
|
+ if (usec > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- if (ret >= minus)
|
||||||
|
- ret -= minus;
|
||||||
|
+ if (usec >= minus)
|
||||||
|
+ usec -= minus;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- if (usec)
|
||||||
|
- *usec = ret;
|
||||||
|
+ if (ret)
|
||||||
|
+ *ret = usec;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -897,7 +897,7 @@ typedef struct ParseTimestampResult {
|
||||||
|
int return_value;
|
||||||
|
} ParseTimestampResult;
|
||||||
|
|
||||||
|
-int parse_timestamp(const char *t, usec_t *usec) {
|
||||||
|
+int parse_timestamp(const char *t, usec_t *ret) {
|
||||||
|
char *last_space, *tz = NULL;
|
||||||
|
ParseTimestampResult *shared, tmp;
|
||||||
|
int r;
|
||||||
|
@@ -907,7 +907,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
|
||||||
|
tz = last_space + 1;
|
||||||
|
|
||||||
|
if (!tz || endswith_no_case(t, " UTC"))
|
||||||
|
- return parse_timestamp_impl(t, usec, false);
|
||||||
|
+ return parse_timestamp_impl(t, ret, false);
|
||||||
|
|
||||||
|
shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (shared == MAP_FAILED)
|
||||||
|
@@ -949,13 +949,13 @@ int parse_timestamp(const char *t, usec_t *usec) {
|
||||||
|
if (munmap(shared, sizeof *shared) != 0)
|
||||||
|
return negative_errno();
|
||||||
|
|
||||||
|
- if (tmp.return_value == 0 && usec)
|
||||||
|
- *usec = tmp.usec;
|
||||||
|
+ if (tmp.return_value == 0 && ret)
|
||||||
|
+ *ret = tmp.usec;
|
||||||
|
|
||||||
|
return tmp.return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static const char* extract_multiplier(const char *p, usec_t *multiplier) {
|
||||||
|
+static const char* extract_multiplier(const char *p, usec_t *ret) {
|
||||||
|
static const struct {
|
||||||
|
const char *suffix;
|
||||||
|
usec_t usec;
|
||||||
|
@@ -996,7 +996,7 @@ static const char* extract_multiplier(const char *p, usec_t *multiplier) {
|
||||||
|
|
||||||
|
e = startswith(p, table[i].suffix);
|
||||||
|
if (e) {
|
||||||
|
- *multiplier = table[i].usec;
|
||||||
|
+ *ret = table[i].usec;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1004,9 +1004,9 @@ static const char* extract_multiplier(const char *p, usec_t *multiplier) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
||||||
|
+int parse_time(const char *t, usec_t *ret, usec_t default_unit) {
|
||||||
|
const char *p, *s;
|
||||||
|
- usec_t r = 0;
|
||||||
|
+ usec_t usec = 0;
|
||||||
|
bool something = false;
|
||||||
|
|
||||||
|
assert(t);
|
||||||
|
@@ -1021,8 +1021,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
||||||
|
if (*s != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- if (usec)
|
||||||
|
- *usec = USEC_INFINITY;
|
||||||
|
+ if (ret)
|
||||||
|
+ *ret = USEC_INFINITY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1069,10 +1069,10 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
k = (usec_t) l * multiplier;
|
||||||
|
- if (k >= USEC_INFINITY - r)
|
||||||
|
+ if (k >= USEC_INFINITY - usec)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
- r += k;
|
||||||
|
+ usec += k;
|
||||||
|
|
||||||
|
something = true;
|
||||||
|
|
||||||
|
@@ -1082,10 +1082,10 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
||||||
|
|
||||||
|
for (b = e + 1; *b >= '0' && *b <= '9'; b++, m /= 10) {
|
||||||
|
k = (usec_t) (*b - '0') * m;
|
||||||
|
- if (k >= USEC_INFINITY - r)
|
||||||
|
+ if (k >= USEC_INFINITY - usec)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
- r += k;
|
||||||
|
+ usec += k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't allow "0.-0", "3.+1", "3. 1", "3.sec" or "3.hoge" */
|
||||||
|
@@ -1094,13 +1094,13 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (usec)
|
||||||
|
- *usec = r;
|
||||||
|
+ if (ret)
|
||||||
|
+ *ret = usec;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int parse_sec(const char *t, usec_t *usec) {
|
||||||
|
- return parse_time(t, usec, USEC_PER_SEC);
|
||||||
|
+int parse_sec(const char *t, usec_t *ret) {
|
||||||
|
+ return parse_time(t, ret, USEC_PER_SEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_sec_fix_0(const char *t, usec_t *ret) {
|
||||||
|
@@ -1127,7 +1127,7 @@ int parse_sec_def_infinity(const char *t, usec_t *ret) {
|
||||||
|
return parse_sec(t, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static const char* extract_nsec_multiplier(const char *p, nsec_t *multiplier) {
|
||||||
|
+static const char* extract_nsec_multiplier(const char *p, nsec_t *ret) {
|
||||||
|
static const struct {
|
||||||
|
const char *suffix;
|
||||||
|
nsec_t nsec;
|
||||||
|
@@ -1172,7 +1172,7 @@ static const char* extract_nsec_multiplier(const char *p, nsec_t *multiplier) {
|
||||||
|
|
||||||
|
e = startswith(p, table[i].suffix);
|
||||||
|
if (e) {
|
||||||
|
- *multiplier = table[i].nsec;
|
||||||
|
+ *ret = table[i].nsec;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1180,13 +1180,13 @@ static const char* extract_nsec_multiplier(const char *p, nsec_t *multiplier) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int parse_nsec(const char *t, nsec_t *nsec) {
|
||||||
|
+int parse_nsec(const char *t, nsec_t *ret) {
|
||||||
|
const char *p, *s;
|
||||||
|
- nsec_t r = 0;
|
||||||
|
+ nsec_t nsec = 0;
|
||||||
|
bool something = false;
|
||||||
|
|
||||||
|
assert(t);
|
||||||
|
- assert(nsec);
|
||||||
|
+ assert(ret);
|
||||||
|
|
||||||
|
p = t;
|
||||||
|
|
||||||
|
@@ -1197,7 +1197,7 @@ int parse_nsec(const char *t, nsec_t *nsec) {
|
||||||
|
if (*s != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- *nsec = NSEC_INFINITY;
|
||||||
|
+ *ret = NSEC_INFINITY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1244,10 +1244,10 @@ int parse_nsec(const char *t, nsec_t *nsec) {
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
k = (nsec_t) l * multiplier;
|
||||||
|
- if (k >= NSEC_INFINITY - r)
|
||||||
|
+ if (k >= NSEC_INFINITY - nsec)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
- r += k;
|
||||||
|
+ nsec += k;
|
||||||
|
|
||||||
|
something = true;
|
||||||
|
|
||||||
|
@@ -1257,10 +1257,10 @@ int parse_nsec(const char *t, nsec_t *nsec) {
|
||||||
|
|
||||||
|
for (b = e + 1; *b >= '0' && *b <= '9'; b++, m /= 10) {
|
||||||
|
k = (nsec_t) (*b - '0') * m;
|
||||||
|
- if (k >= NSEC_INFINITY - r)
|
||||||
|
+ if (k >= NSEC_INFINITY - nsec)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
- r += k;
|
||||||
|
+ nsec += k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't allow "0.-0", "3.+1", "3. 1", "3.sec" or "3.hoge" */
|
||||||
|
@@ -1269,7 +1269,7 @@ int parse_nsec(const char *t, nsec_t *nsec) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- *nsec = r;
|
||||||
|
+ *ret = nsec;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
|
||||||
|
index c98f95a530..9d44cac747 100644
|
||||||
|
--- a/src/basic/time-util.h
|
||||||
|
+++ b/src/basic/time-util.h
|
||||||
|
@@ -141,15 +141,15 @@ static inline char* format_timestamp(char *buf, size_t l, usec_t t) {
|
||||||
|
#define FORMAT_TIMESTAMP_STYLE(t, style) \
|
||||||
|
format_timestamp_style((char[FORMAT_TIMESTAMP_MAX]){}, FORMAT_TIMESTAMP_MAX, t, style)
|
||||||
|
|
||||||
|
-int parse_timestamp(const char *t, usec_t *usec);
|
||||||
|
+int parse_timestamp(const char *t, usec_t *ret);
|
||||||
|
|
||||||
|
-int parse_sec(const char *t, usec_t *usec);
|
||||||
|
-int parse_sec_fix_0(const char *t, usec_t *usec);
|
||||||
|
-int parse_sec_def_infinity(const char *t, usec_t *usec);
|
||||||
|
-int parse_time(const char *t, usec_t *usec, usec_t default_unit);
|
||||||
|
-int parse_nsec(const char *t, nsec_t *nsec);
|
||||||
|
+int parse_sec(const char *t, usec_t *ret);
|
||||||
|
+int parse_sec_fix_0(const char *t, usec_t *ret);
|
||||||
|
+int parse_sec_def_infinity(const char *t, usec_t *ret);
|
||||||
|
+int parse_time(const char *t, usec_t *ret, usec_t default_unit);
|
||||||
|
+int parse_nsec(const char *t, nsec_t *ret);
|
||||||
|
|
||||||
|
-int get_timezones(char ***l);
|
||||||
|
+int get_timezones(char ***ret);
|
||||||
|
int verify_timezone(const char *name, int log_level);
|
||||||
|
static inline bool timezone_is_valid(const char *name, int log_level) {
|
||||||
|
return verify_timezone(name, log_level) >= 0;
|
||||||
|
@@ -159,7 +159,7 @@ bool clock_supported(clockid_t clock);
|
||||||
|
|
||||||
|
usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to);
|
||||||
|
|
||||||
|
-int get_timezone(char **timezone);
|
||||||
|
+int get_timezone(char **ret);
|
||||||
|
|
||||||
|
time_t mktime_or_timegm(struct tm *tm, bool utc);
|
||||||
|
struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
|
||||||
115
1251-time-util-add-assertions.patch
Normal file
115
1251-time-util-add-assertions.patch
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
From 23f6608ffa05ce80ebfbca9a28369ff858e9d42e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 02:06:13 +0900
|
||||||
|
Subject: [PATCH] time-util: add assertions
|
||||||
|
|
||||||
|
(cherry picked from commit dff3bddc5416834d42cc682cb544732a4b91db3b)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 25 +++++++++++++++++++++++++
|
||||||
|
1 file changed, 25 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 7dbd3af20a..ac28dc9be6 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -172,6 +172,8 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
|
||||||
|
dual_timestamp* dual_timestamp_from_boottime(dual_timestamp *ts, usec_t u) {
|
||||||
|
usec_t nowm;
|
||||||
|
|
||||||
|
+ assert(ts);
|
||||||
|
+
|
||||||
|
if (u == USEC_INFINITY) {
|
||||||
|
ts->realtime = ts->monotonic = USEC_INFINITY;
|
||||||
|
return ts;
|
||||||
|
@@ -184,6 +186,7 @@ dual_timestamp* dual_timestamp_from_boottime(dual_timestamp *ts, usec_t u) {
|
||||||
|
}
|
||||||
|
|
||||||
|
usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock) {
|
||||||
|
+ assert(ts);
|
||||||
|
|
||||||
|
switch (clock) {
|
||||||
|
|
||||||
|
@@ -421,6 +424,8 @@ char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
|
||||||
|
const char *s;
|
||||||
|
usec_t n, d;
|
||||||
|
|
||||||
|
+ assert(buf);
|
||||||
|
+
|
||||||
|
if (!timestamp_is_set(t))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
@@ -902,6 +907,8 @@ int parse_timestamp(const char *t, usec_t *ret) {
|
||||||
|
ParseTimestampResult *shared, tmp;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ assert(t);
|
||||||
|
+
|
||||||
|
last_space = strrchr(t, ' ');
|
||||||
|
if (last_space != NULL && timezone_is_valid(last_space + 1, LOG_DEBUG))
|
||||||
|
tz = last_space + 1;
|
||||||
|
@@ -991,6 +998,9 @@ static const char* extract_multiplier(const char *p, usec_t *ret) {
|
||||||
|
{ "µs", 1ULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
+ assert(p);
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
for (size_t i = 0; i < ELEMENTSOF(table); i++) {
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
@@ -1119,6 +1129,9 @@ int parse_sec_fix_0(const char *t, usec_t *ret) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_sec_def_infinity(const char *t, usec_t *ret) {
|
||||||
|
+ assert(t);
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
t += strspn(t, WHITESPACE);
|
||||||
|
if (isempty(t)) {
|
||||||
|
*ret = USEC_INFINITY;
|
||||||
|
@@ -1167,6 +1180,9 @@ static const char* extract_nsec_multiplier(const char *p, nsec_t *ret) {
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
+ assert(p);
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
for (i = 0; i < ELEMENTSOF(table); i++) {
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
@@ -1320,6 +1336,8 @@ static int get_timezones_from_tzdata_zi(char ***ret) {
|
||||||
|
_cleanup_strv_free_ char **zones = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
f = fopen("/usr/share/zoneinfo/tzdata.zi", "re");
|
||||||
|
if (!f)
|
||||||
|
return -errno;
|
||||||
|
@@ -1477,6 +1495,8 @@ int get_timezone(char **ret) {
|
||||||
|
char *z;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
r = readlink_malloc("/etc/localtime", &t);
|
||||||
|
if (r == -ENOENT) {
|
||||||
|
/* If the symlink does not exist, assume "UTC", like glibc does */
|
||||||
|
@@ -1506,10 +1526,15 @@ int get_timezone(char **ret) {
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t mktime_or_timegm(struct tm *tm, bool utc) {
|
||||||
|
+ assert(tm);
|
||||||
|
+
|
||||||
|
return utc ? timegm(tm) : mktime(tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) {
|
||||||
|
+ assert(t);
|
||||||
|
+ assert(tm);
|
||||||
|
+
|
||||||
|
return utc ? gmtime_r(t, tm) : localtime_r(t, tm);
|
||||||
|
}
|
||||||
|
|
||||||
54
1252-time-util-drop-redundant-else.patch
Normal file
54
1252-time-util-drop-redundant-else.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From a3c08667c9abaf60793ed35e93123bc5f89981f3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 03:43:58 +0900
|
||||||
|
Subject: [PATCH] time-util: drop redundant else
|
||||||
|
|
||||||
|
(cherry picked from commit 17d1ebfc43c3b971d20ff2806acc634ee153eef6)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 11 +++++++----
|
||||||
|
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index ac28dc9be6..c5b91fde66 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -664,21 +664,23 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
if (streq(t, "now"))
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
- else if (t[0] == '+') {
|
||||||
|
+ if (t[0] == '+') {
|
||||||
|
r = parse_sec(t+1, &plus);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
goto finish;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- } else if (t[0] == '-') {
|
||||||
|
+ if (t[0] == '-') {
|
||||||
|
r = parse_sec(t+1, &minus);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
goto finish;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- } else if ((k = endswith(t, " ago"))) {
|
||||||
|
+ if ((k = endswith(t, " ago"))) {
|
||||||
|
t = strndupa_safe(t, k - t);
|
||||||
|
|
||||||
|
r = parse_sec(t, &minus);
|
||||||
|
@@ -686,8 +688,9 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
return r;
|
||||||
|
|
||||||
|
goto finish;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- } else if ((k = endswith(t, " left"))) {
|
||||||
|
+ if ((k = endswith(t, " left"))) {
|
||||||
|
t = strndupa_safe(t, k - t);
|
||||||
|
|
||||||
|
r = parse_sec(t, &plus);
|
||||||
50
1253-time-util-do-not-use-strdupa.patch
Normal file
50
1253-time-util-do-not-use-strdupa.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
From 50a7d58a24a381e265436c14303e7bb368a4b147 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 03:41:26 +0900
|
||||||
|
Subject: [PATCH] time-util: do not use strdupa()
|
||||||
|
|
||||||
|
The input string may come from command line, config files.
|
||||||
|
|
||||||
|
(cherry picked from commit 804537bdc420bb82e54b455b7a10d542c8f029dd)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 16 ++++++++++++----
|
||||||
|
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index c5b91fde66..64cdcea594 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -681,9 +681,13 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((k = endswith(t, " ago"))) {
|
||||||
|
- t = strndupa_safe(t, k - t);
|
||||||
|
+ _cleanup_free_ char *buf = NULL;
|
||||||
|
|
||||||
|
- r = parse_sec(t, &minus);
|
||||||
|
+ buf = strndup(t, k - t);
|
||||||
|
+ if (!buf)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ r = parse_sec(buf, &minus);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -691,9 +695,13 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((k = endswith(t, " left"))) {
|
||||||
|
- t = strndupa_safe(t, k - t);
|
||||||
|
+ _cleanup_free_ char *buf = NULL;
|
||||||
|
+
|
||||||
|
+ buf = strndup(t, k - t);
|
||||||
|
+ if (!buf)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
|
||||||
|
- r = parse_sec(t, &plus);
|
||||||
|
+ r = parse_sec(buf, &plus);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
49
1254-time-util-use-result-from-startswith_no_case.patch
Normal file
49
1254-time-util-use-result-from-startswith_no_case.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
From eabf4db441c885a78d5726838004bbb9436dbf91 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 04:14:24 +0900
|
||||||
|
Subject: [PATCH] time-util: use result from startswith_no_case()
|
||||||
|
|
||||||
|
No functional change, just refactoring.
|
||||||
|
|
||||||
|
(cherry picked from commit f2ecfd8bc1e6d09173e9f98c5ac1b19b755a3c25)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 14 ++++----------
|
||||||
|
1 file changed, 4 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 64cdcea594..047dad0fec 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -635,7 +635,6 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
time_t x;
|
||||||
|
usec_t usec, x_usec, plus = 0, minus = 0;
|
||||||
|
int r, weekday = -1, dst = -1;
|
||||||
|
- size_t i;
|
||||||
|
|
||||||
|
/* Allowed syntaxes:
|
||||||
|
*
|
||||||
|
@@ -775,18 +774,13 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
goto from_tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < ELEMENTSOF(day_nr); i++) {
|
||||||
|
- size_t skip;
|
||||||
|
-
|
||||||
|
- if (!startswith_no_case(t, day_nr[i].name))
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- skip = strlen(day_nr[i].name);
|
||||||
|
- if (t[skip] != ' ')
|
||||||
|
+ for (size_t i = 0; i < ELEMENTSOF(day_nr); i++) {
|
||||||
|
+ k = startswith_no_case(t, day_nr[i].name);
|
||||||
|
+ if (!k || *k != ' ')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
weekday = day_nr[i].nr;
|
||||||
|
- t += skip + 1;
|
||||||
|
+ t = k + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
47
1255-time-util-use-usec_add-and-usec_sub_unsigned.patch
Normal file
47
1255-time-util-use-usec_add-and-usec_sub_unsigned.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
From 9f7d490b1c16f0444987dab7ce70287b59d98cf9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 04:27:27 +0900
|
||||||
|
Subject: [PATCH] time-util: use usec_add() and usec_sub_unsigned()
|
||||||
|
|
||||||
|
And move the check with USEC_TIMESTAMP_FORMATTABLE_MAX at the end,
|
||||||
|
as usec_add() can handle overflow correctly.
|
||||||
|
|
||||||
|
(cherry picked from commit db43717e982e1361eee4bdcd92167d6c47eb627c)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 17 +++++++----------
|
||||||
|
1 file changed, 7 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 047dad0fec..ba5e17bd9d 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -881,20 +881,17 @@ from_tm:
|
||||||
|
if (x < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- usec = (usec_t) x * USEC_PER_SEC + x_usec;
|
||||||
|
- if (usec > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||||
|
- return -EINVAL;
|
||||||
|
+ usec = usec_add(x * USEC_PER_SEC, x_usec);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
- if (usec + plus < usec) /* overflow? */
|
||||||
|
- return -EINVAL;
|
||||||
|
- usec += plus;
|
||||||
|
- if (usec > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||||
|
+ usec = usec_add(usec, plus);
|
||||||
|
+
|
||||||
|
+ if (usec < minus)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- if (usec >= minus)
|
||||||
|
- usec -= minus;
|
||||||
|
- else
|
||||||
|
+ usec = usec_sub_unsigned(usec, minus);
|
||||||
|
+
|
||||||
|
+ if (usec > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
72
1256-time-util-shorten-code-a-bit.patch
Normal file
72
1256-time-util-shorten-code-a-bit.patch
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
From 2dafd8e6be624f93c757ca9c739d502ed73d79c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 04:27:52 +0900
|
||||||
|
Subject: [PATCH] time-util: shorten code a bit
|
||||||
|
|
||||||
|
No functional change, just refactoring.
|
||||||
|
|
||||||
|
(cherry picked from commit 1d2c42c5dc765c57b4fba6b7c629093aa20685a8)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 25 +++++++++----------------
|
||||||
|
1 file changed, 9 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index ba5e17bd9d..6e1b34b025 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -633,8 +633,9 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
const char *k, *utc = NULL, *tzn = NULL;
|
||||||
|
struct tm tm, copy;
|
||||||
|
time_t x;
|
||||||
|
- usec_t usec, x_usec, plus = 0, minus = 0;
|
||||||
|
+ usec_t usec, plus = 0, minus = 0;
|
||||||
|
int r, weekday = -1, dst = -1;
|
||||||
|
+ unsigned fractional = 0;
|
||||||
|
|
||||||
|
/* Allowed syntaxes:
|
||||||
|
*
|
||||||
|
@@ -750,7 +751,6 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
}
|
||||||
|
|
||||||
|
x = (time_t) (usec / USEC_PER_SEC);
|
||||||
|
- x_usec = 0;
|
||||||
|
|
||||||
|
if (!localtime_or_gmtime_r(&x, &tm, utc))
|
||||||
|
return -EINVAL;
|
||||||
|
@@ -859,19 +859,12 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
parse_usec:
|
||||||
|
- {
|
||||||
|
- unsigned add;
|
||||||
|
-
|
||||||
|
- k++;
|
||||||
|
- r = parse_fractional_part_u(&k, 6, &add);
|
||||||
|
- if (r < 0)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- if (*k)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- x_usec = add;
|
||||||
|
- }
|
||||||
|
+ k++;
|
||||||
|
+ r = parse_fractional_part_u(&k, 6, &fractional);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ if (*k != '\0')
|
||||||
|
+ return -EINVAL;
|
||||||
|
|
||||||
|
from_tm:
|
||||||
|
if (weekday >= 0 && tm.tm_wday != weekday)
|
||||||
|
@@ -881,7 +874,7 @@ from_tm:
|
||||||
|
if (x < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- usec = usec_add(x * USEC_PER_SEC, x_usec);
|
||||||
|
+ usec = usec_add(x * USEC_PER_SEC, fractional);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
usec = usec_add(usec, plus);
|
||||||
69
1257-time-util-rename-variables.patch
Normal file
69
1257-time-util-rename-variables.patch
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
From 5bfcf206bd16079ae8030a2c912ee8377a3f6d5f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Wed, 15 Feb 2023 13:46:50 +0900
|
||||||
|
Subject: [PATCH] time-util: rename variables
|
||||||
|
|
||||||
|
No functional changes, just refactoring.
|
||||||
|
|
||||||
|
(cherry picked from commit a83c1baaeb510f1916d2d8cf0324d100708c7073)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 18 +++++++++---------
|
||||||
|
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 6e1b34b025..d468848d09 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -632,10 +632,10 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
|
||||||
|
const char *k, *utc = NULL, *tzn = NULL;
|
||||||
|
struct tm tm, copy;
|
||||||
|
- time_t x;
|
||||||
|
usec_t usec, plus = 0, minus = 0;
|
||||||
|
- int r, weekday = -1, dst = -1;
|
||||||
|
+ int r, weekday = -1, isdst = -1;
|
||||||
|
unsigned fractional = 0;
|
||||||
|
+ time_t sec;
|
||||||
|
|
||||||
|
/* Allowed syntaxes:
|
||||||
|
*
|
||||||
|
@@ -744,18 +744,18 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
if (IN_SET(j, 0, 1)) {
|
||||||
|
/* Found one of the two timezones specified. */
|
||||||
|
t = strndupa_safe(t, e - t - 1);
|
||||||
|
- dst = j;
|
||||||
|
+ isdst = j;
|
||||||
|
tzn = tzname[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- x = (time_t) (usec / USEC_PER_SEC);
|
||||||
|
+ sec = (time_t) (usec / USEC_PER_SEC);
|
||||||
|
|
||||||
|
- if (!localtime_or_gmtime_r(&x, &tm, utc))
|
||||||
|
+ if (!localtime_or_gmtime_r(&sec, &tm, utc))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- tm.tm_isdst = dst;
|
||||||
|
+ tm.tm_isdst = isdst;
|
||||||
|
if (!with_tz && tzn)
|
||||||
|
tm.tm_zone = tzn;
|
||||||
|
|
||||||
|
@@ -870,11 +870,11 @@ from_tm:
|
||||||
|
if (weekday >= 0 && tm.tm_wday != weekday)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- x = mktime_or_timegm(&tm, utc);
|
||||||
|
- if (x < 0)
|
||||||
|
+ sec = mktime_or_timegm(&tm, utc);
|
||||||
|
+ if (sec < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- usec = usec_add(x * USEC_PER_SEC, fractional);
|
||||||
|
+ usec = usec_add(sec * USEC_PER_SEC, fractional);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
usec = usec_add(usec, plus);
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
From a1a7ab09cf96e30cfd0c89efaf8d03a5dc81e928 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Wed, 15 Feb 2023 13:51:15 +0900
|
||||||
|
Subject: [PATCH] time-util: drop unnecessary assignment of timezone name
|
||||||
|
|
||||||
|
As mktime() does not use timezone neme.
|
||||||
|
|
||||||
|
(cherry picked from commit 97c5f7ba1f50fcd7b982b995b46692c8cad4afaa)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 5 +----
|
||||||
|
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index d468848d09..92928e88a4 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -630,7 +630,7 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
{ "Sat", 6 },
|
||||||
|
};
|
||||||
|
|
||||||
|
- const char *k, *utc = NULL, *tzn = NULL;
|
||||||
|
+ const char *k, *utc = NULL;
|
||||||
|
struct tm tm, copy;
|
||||||
|
usec_t usec, plus = 0, minus = 0;
|
||||||
|
int r, weekday = -1, isdst = -1;
|
||||||
|
@@ -745,7 +745,6 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
/* Found one of the two timezones specified. */
|
||||||
|
t = strndupa_safe(t, e - t - 1);
|
||||||
|
isdst = j;
|
||||||
|
- tzn = tzname[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -756,8 +755,6 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
tm.tm_isdst = isdst;
|
||||||
|
- if (!with_tz && tzn)
|
||||||
|
- tm.tm_zone = tzn;
|
||||||
|
|
||||||
|
if (streq(t, "today")) {
|
||||||
|
tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
|
||||||
275
1259-time-util-make-parse_timestamp-use-the-RFC-822-ISO-8.patch
Normal file
275
1259-time-util-make-parse_timestamp-use-the-RFC-822-ISO-8.patch
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
From e4b1932cd1c0ad2d42a6271cb651e6979b5962ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 14 Feb 2023 03:39:15 +0900
|
||||||
|
Subject: [PATCH] time-util: make parse_timestamp() use the RFC-822/ISO 8601
|
||||||
|
standard timezone spec
|
||||||
|
|
||||||
|
If the timezone is specified with a number e.g. +0900 or so, then
|
||||||
|
let's parse the time as a UTC, and adjust it with the specified time
|
||||||
|
shift.
|
||||||
|
|
||||||
|
Otherwise, if an area has timezone change, e.g.
|
||||||
|
---
|
||||||
|
Africa/Casablanca Sun Jun 17 01:59:59 2018 UT = Sun Jun 17 01:59:59 2018 +00 isdst=0 gmtoff=0
|
||||||
|
Africa/Casablanca Sun Jun 17 02:00:00 2018 UT = Sun Jun 17 03:00:00 2018 +01 isdst=1 gmtoff=3600
|
||||||
|
Africa/Casablanca Sun Oct 28 01:59:59 2018 UT = Sun Oct 28 02:59:59 2018 +01 isdst=1 gmtoff=3600
|
||||||
|
Africa/Casablanca Sun Oct 28 02:00:00 2018 UT = Sun Oct 28 03:00:00 2018 +01 isdst=0 gmtoff=3600
|
||||||
|
---
|
||||||
|
then we could not determine isdst from the timezone (+01 in the above)
|
||||||
|
and mktime() will provide wrong results.
|
||||||
|
|
||||||
|
Fixes #26370.
|
||||||
|
|
||||||
|
(cherry picked from commit 7a9afae6040af0417d893328cb44b622dcdcb94f)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 174 +++++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 112 insertions(+), 62 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 92928e88a4..6fbbc2f655 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -609,7 +609,14 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
+static int parse_timestamp_impl(
|
||||||
|
+ const char *t,
|
||||||
|
+ bool with_tz,
|
||||||
|
+ bool utc,
|
||||||
|
+ int isdst,
|
||||||
|
+ long gmtoff,
|
||||||
|
+ usec_t *ret) {
|
||||||
|
+
|
||||||
|
static const struct {
|
||||||
|
const char *name;
|
||||||
|
const int nr;
|
||||||
|
@@ -630,11 +637,11 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
{ "Sat", 6 },
|
||||||
|
};
|
||||||
|
|
||||||
|
- const char *k, *utc = NULL;
|
||||||
|
- struct tm tm, copy;
|
||||||
|
usec_t usec, plus = 0, minus = 0;
|
||||||
|
- int r, weekday = -1, isdst = -1;
|
||||||
|
+ int r, weekday = -1;
|
||||||
|
unsigned fractional = 0;
|
||||||
|
+ const char *k;
|
||||||
|
+ struct tm tm, copy;
|
||||||
|
time_t sec;
|
||||||
|
|
||||||
|
/* Allowed syntaxes:
|
||||||
|
@@ -707,46 +714,6 @@ static int parse_timestamp_impl(const char *t, usec_t *ret, bool with_tz) {
|
||||||
|
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- /* See if the timestamp is suffixed with UTC */
|
||||||
|
- utc = endswith_no_case(t, " UTC");
|
||||||
|
- if (utc)
|
||||||
|
- t = strndupa_safe(t, utc - t);
|
||||||
|
- else {
|
||||||
|
- const char *e = NULL;
|
||||||
|
- int j;
|
||||||
|
-
|
||||||
|
- tzset();
|
||||||
|
-
|
||||||
|
- /* See if the timestamp is suffixed by either the DST or non-DST local timezone. Note
|
||||||
|
- * that we only support the local timezones here, nothing else. Not because we
|
||||||
|
- * wouldn't want to, but simply because there are no nice APIs available to cover
|
||||||
|
- * this. By accepting the local time zone strings, we make sure that all timestamps
|
||||||
|
- * written by format_timestamp() can be parsed correctly, even though we don't
|
||||||
|
- * support arbitrary timezone specifications. */
|
||||||
|
-
|
||||||
|
- for (j = 0; j <= 1; j++) {
|
||||||
|
-
|
||||||
|
- if (isempty(tzname[j]))
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- e = endswith_no_case(t, tzname[j]);
|
||||||
|
- if (!e)
|
||||||
|
- continue;
|
||||||
|
- if (e == t)
|
||||||
|
- continue;
|
||||||
|
- if (e[-1] != ' ')
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (IN_SET(j, 0, 1)) {
|
||||||
|
- /* Found one of the two timezones specified. */
|
||||||
|
- t = strndupa_safe(t, e - t - 1);
|
||||||
|
- isdst = j;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
sec = (time_t) (usec / USEC_PER_SEC);
|
||||||
|
@@ -864,9 +831,32 @@ parse_usec:
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
from_tm:
|
||||||
|
+ assert(plus == 0);
|
||||||
|
+ assert(minus == 0);
|
||||||
|
+
|
||||||
|
if (weekday >= 0 && tm.tm_wday != weekday)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
+ if (gmtoff < 0) {
|
||||||
|
+ plus = -gmtoff * USEC_PER_SEC;
|
||||||
|
+
|
||||||
|
+ /* If gmtoff is negative, the string maye be too old to be parsed as UTC.
|
||||||
|
+ * E.g. 1969-12-31 23:00:00 -06 == 1970-01-01 05:00:00 UTC
|
||||||
|
+ * We assumed that gmtoff is in the range of -24:00…+24:00, hence the only date we need to
|
||||||
|
+ * handle here is 1969-12-31. So, let's shift the date with one day, then subtract the shift
|
||||||
|
+ * later. */
|
||||||
|
+ if (tm.tm_year == 69 && tm.tm_mon == 11 && tm.tm_mday == 31) {
|
||||||
|
+ /* Thu 1970-01-01-00:00:00 */
|
||||||
|
+ tm.tm_year = 70;
|
||||||
|
+ tm.tm_mon = 0;
|
||||||
|
+ tm.tm_mday = 1;
|
||||||
|
+ tm.tm_wday = 4;
|
||||||
|
+ tm.tm_yday = 0;
|
||||||
|
+ minus = USEC_PER_DAY;
|
||||||
|
+ }
|
||||||
|
+ } else
|
||||||
|
+ minus = gmtoff * USEC_PER_SEC;
|
||||||
|
+
|
||||||
|
sec = mktime_or_timegm(&tm, utc);
|
||||||
|
if (sec < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
@@ -889,24 +879,93 @@ finish:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int parse_timestamp_with_tz(const char *t, size_t len, bool utc, int isdst, long gmtoff, usec_t *ret) {
|
||||||
|
+ _cleanup_free_ char *buf = NULL;
|
||||||
|
+
|
||||||
|
+ assert(t);
|
||||||
|
+ assert(len > 0);
|
||||||
|
+
|
||||||
|
+ buf = strndup(t, len);
|
||||||
|
+ if (!buf)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ return parse_timestamp_impl(buf, /* with_tz = */ true, utc, isdst, gmtoff, ret);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int parse_timestamp_maybe_with_tz(const char *t, size_t len, bool valid_tz, usec_t *ret) {
|
||||||
|
+ assert(t);
|
||||||
|
+ assert(len > 0);
|
||||||
|
+
|
||||||
|
+ tzset();
|
||||||
|
+
|
||||||
|
+ for (int j = 0; j <= 1; j++) {
|
||||||
|
+ if (isempty(tzname[j]))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!streq(t + len + 1, tzname[j]))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ /* The specified timezone matches tzname[] of the local timezone. */
|
||||||
|
+ return parse_timestamp_with_tz(t, len, /* utc = */ false, /* isdst = */ j, /* gmtoff = */ 0, ret);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (valid_tz)
|
||||||
|
+ /* We know that the specified timezone is a valid zoneinfo (e.g. Asia/Tokyo). So, simply drop
|
||||||
|
+ * the timezone and parse the remaining string as a local time. */
|
||||||
|
+ return parse_timestamp_with_tz(t, len, /* utc = */ false, /* isdst = */ -1, /* gmtoff = */ 0, ret);
|
||||||
|
+
|
||||||
|
+ return parse_timestamp_impl(t, /* with_tz = */ false, /* utc = */ false, /* isdst = */ -1, /* gmtoff = */ 0, ret);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
typedef struct ParseTimestampResult {
|
||||||
|
usec_t usec;
|
||||||
|
int return_value;
|
||||||
|
} ParseTimestampResult;
|
||||||
|
|
||||||
|
int parse_timestamp(const char *t, usec_t *ret) {
|
||||||
|
- char *last_space, *tz = NULL;
|
||||||
|
ParseTimestampResult *shared, tmp;
|
||||||
|
+ const char *k, *tz, *space;
|
||||||
|
+ struct tm tm;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
- last_space = strrchr(t, ' ');
|
||||||
|
- if (last_space != NULL && timezone_is_valid(last_space + 1, LOG_DEBUG))
|
||||||
|
- tz = last_space + 1;
|
||||||
|
+ space = strrchr(t, ' ');
|
||||||
|
+ if (!space)
|
||||||
|
+ return parse_timestamp_impl(t, /* with_tz = */ false, /* utc = */ false, /* isdst = */ -1, /* gmtoff = */ 0, ret);
|
||||||
|
|
||||||
|
- if (!tz || endswith_no_case(t, " UTC"))
|
||||||
|
- return parse_timestamp_impl(t, ret, false);
|
||||||
|
+ /* The string starts with space. */
|
||||||
|
+ if (space == t)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ /* Shortcut, parse the string as UTC. */
|
||||||
|
+ if (streq(space + 1, "UTC"))
|
||||||
|
+ return parse_timestamp_with_tz(t, space - t, /* utc = */ true, /* isdst = */ -1, /* gmtoff = */ 0, ret);
|
||||||
|
+
|
||||||
|
+ /* If the timezone is compatible with RFC-822/ISO 8601 (e.g. +06, or -03:00) then parse the string as
|
||||||
|
+ * UTC and shift the result. */
|
||||||
|
+ k = strptime(space + 1, "%z", &tm);
|
||||||
|
+ if (k && *k == '\0') {
|
||||||
|
+ /* glibc accepts gmtoff more than 24 hours, but we refuse it. */
|
||||||
|
+ if ((usec_t) labs(tm.tm_gmtoff) > USEC_PER_DAY / USEC_PER_SEC)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ return parse_timestamp_with_tz(t, space - t, /* utc = */ true, /* isdst = */ -1, /* gmtoff = */ tm.tm_gmtoff, ret);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* If the last word is not a timezone file (e.g. Asia/Tokyo), then let's check if it matches
|
||||||
|
+ * tzname[] of the local timezone, e.g. JST or CEST. */
|
||||||
|
+ if (!timezone_is_valid(space + 1, LOG_DEBUG))
|
||||||
|
+ return parse_timestamp_maybe_with_tz(t, space - t, /* valid_tz = */ false, ret);
|
||||||
|
+
|
||||||
|
+ /* Shortcut. If the current $TZ is equivalent to the specified timezone, it is not necessary to fork
|
||||||
|
+ * the process. */
|
||||||
|
+ tz = getenv("TZ");
|
||||||
|
+ if (tz && *tz == ':' && streq(tz + 1, space + 1))
|
||||||
|
+ return parse_timestamp_maybe_with_tz(t, space - t, /* valid_tz = */ true, ret);
|
||||||
|
+
|
||||||
|
+ /* Otherwise, to avoid polluting the current environment variables, let's fork the process and set
|
||||||
|
+ * the specified timezone in the child process. */
|
||||||
|
|
||||||
|
shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (shared == MAP_FAILED)
|
||||||
|
@@ -918,11 +977,10 @@ int parse_timestamp(const char *t, usec_t *ret) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (r == 0) {
|
||||||
|
- bool with_tz = true;
|
||||||
|
- char *colon_tz;
|
||||||
|
+ const char *colon_tz;
|
||||||
|
|
||||||
|
/* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */
|
||||||
|
- colon_tz = strjoina(":", tz);
|
||||||
|
+ colon_tz = strjoina(":", space + 1);
|
||||||
|
|
||||||
|
if (setenv("TZ", colon_tz, 1) != 0) {
|
||||||
|
shared->return_value = negative_errno();
|
||||||
|
@@ -931,15 +989,7 @@ int parse_timestamp(const char *t, usec_t *ret) {
|
||||||
|
|
||||||
|
tzset();
|
||||||
|
|
||||||
|
- /* If there is a timezone that matches the tzname fields, leave the parsing to the implementation.
|
||||||
|
- * Otherwise just cut it off. */
|
||||||
|
- with_tz = !STR_IN_SET(tz, tzname[0], tzname[1]);
|
||||||
|
-
|
||||||
|
- /* Cut off the timezone if we don't need it. */
|
||||||
|
- if (with_tz)
|
||||||
|
- t = strndupa_safe(t, last_space - t);
|
||||||
|
-
|
||||||
|
- shared->return_value = parse_timestamp_impl(t, &shared->usec, with_tz);
|
||||||
|
+ shared->return_value = parse_timestamp_maybe_with_tz(t, space - t, /* valid_tz = */ true, &shared->usec);
|
||||||
|
|
||||||
|
_exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
27
1260-time-util-fix-typo.patch
Normal file
27
1260-time-util-fix-typo.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 008aed2736dac288700f1c177690904da9c5137d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 3 Mar 2023 15:24:23 +0900
|
||||||
|
Subject: [PATCH] time-util: fix typo
|
||||||
|
|
||||||
|
Follow-up for 7a9afae6040af0417d893328cb44b622dcdcb94f.
|
||||||
|
|
||||||
|
(cherry picked from commit ca9c9d8d8e999fd80fc43d002c8d5b20c4c1a0a4)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||||
|
index 6fbbc2f655..66bf4c17bb 100644
|
||||||
|
--- a/src/basic/time-util.c
|
||||||
|
+++ b/src/basic/time-util.c
|
||||||
|
@@ -840,7 +840,7 @@ from_tm:
|
||||||
|
if (gmtoff < 0) {
|
||||||
|
plus = -gmtoff * USEC_PER_SEC;
|
||||||
|
|
||||||
|
- /* If gmtoff is negative, the string maye be too old to be parsed as UTC.
|
||||||
|
+ /* If gmtoff is negative, the string may be too old to be parsed as UTC.
|
||||||
|
* E.g. 1969-12-31 23:00:00 -06 == 1970-01-01 05:00:00 UTC
|
||||||
|
* We assumed that gmtoff is in the range of -24:00…+24:00, hence the only date we need to
|
||||||
|
* handle here is 1969-12-31. So, let's shift the date with one day, then subtract the shift
|
||||||
36
1261-ci-bump-the-tools-tree-to-F42.patch
Normal file
36
1261-ci-bump-the-tools-tree-to-F42.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From 5e10617a3a450a2bb6fbe031d1861559192bc85c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Thu, 4 Sep 2025 15:31:27 +0200
|
||||||
|
Subject: [PATCH] ci: bump the tools tree to F42
|
||||||
|
|
||||||
|
To fix the failing SB key enrollment:
|
||||||
|
|
||||||
|
3h3hBdsDxe: loading Boot0001 "UEFI QEMU QEMU HARDDISK " from PciRoot(0x0)/Pci(0x4,0x0)/Scsi(0x1,0x0)
|
||||||
|
BdsDxe: starting Boot0001 "UEFI QEMU QEMU HARDDISK " from PciRoot(0x0)/Pci(0x4,0x0)/Scsi(0x1,0x0)
|
||||||
|
systemd-boot@0x7d189000,0x7d1a6000
|
||||||
|
Enrolling secure boot keys from directory: \loader\keys\auto
|
||||||
|
Failed to write PK secure boot variable: Security violation
|
||||||
|
systemd-stub@0x670fd000,0x67115000
|
||||||
|
Overlapping PE sections detected. Boot may fail due to image memory corruption!
|
||||||
|
EFI stub: Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path
|
||||||
|
EFI stub: Measured initrd data into PCR 9
|
||||||
|
|
||||||
|
rhel-only: ci
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
.github/workflows/mkosi.yml | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml
|
||||||
|
index 808ae0148e..2694ba14ec 100644
|
||||||
|
--- a/.github/workflows/mkosi.yml
|
||||||
|
+++ b/.github/workflows/mkosi.yml
|
||||||
|
@@ -83,7 +83,7 @@ jobs:
|
||||||
|
[Host]
|
||||||
|
ToolsTree=default
|
||||||
|
ToolsTreeDistribution=fedora
|
||||||
|
- ToolsTreeRelease=41
|
||||||
|
+ ToolsTreeRelease=42
|
||||||
|
# Sometimes we run on a host with /dev/kvm, but it is broken, so explicitly disable it
|
||||||
|
QemuKvm=no
|
||||||
|
EOF
|
||||||
27
1262-journald-extend-STDOUT_STREAMS_MAX-to-64k.patch
Normal file
27
1262-journald-extend-STDOUT_STREAMS_MAX-to-64k.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 8cec69eb3fe332ac618c34780dd5275d931d9bf8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Sun, 1 Dec 2024 14:46:40 +0900
|
||||||
|
Subject: [PATCH] journald: extend STDOUT_STREAMS_MAX to 64k
|
||||||
|
|
||||||
|
Closes #35390.
|
||||||
|
|
||||||
|
(cherry picked from commit c576ba7182f54f352c03f0768c9178b173fb8bcb)
|
||||||
|
|
||||||
|
Resolves: RHEL-111065
|
||||||
|
---
|
||||||
|
src/journal/journald-stream.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
|
||||||
|
index 8bdcd8c2ae..3ec6e7fcf3 100644
|
||||||
|
--- a/src/journal/journald-stream.c
|
||||||
|
+++ b/src/journal/journald-stream.c
|
||||||
|
@@ -38,7 +38,7 @@
|
||||||
|
#include "unit-name.h"
|
||||||
|
#include "user-util.h"
|
||||||
|
|
||||||
|
-#define STDOUT_STREAMS_MAX 4096
|
||||||
|
+#define STDOUT_STREAMS_MAX (64*1024)
|
||||||
|
|
||||||
|
/* During the "setup" protocol phase of the stream logic let's define a different maximum line length than
|
||||||
|
* during the actual operational phase. We want to allow users to specify very short line lengths after all,
|
||||||
163
1263-Revert-Revert-udev-builtin-net_id-use-firmware_node-.patch
Normal file
163
1263-Revert-Revert-udev-builtin-net_id-use-firmware_node-.patch
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
From fa27bab14e2ede08dcac41ab78901ab3b653e556 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Tue, 26 Aug 2025 15:30:49 +0200
|
||||||
|
Subject: [PATCH] Revert "Revert "udev-builtin-net_id: use firmware_node/sun
|
||||||
|
for ID_NET_NAME_SLOT""
|
||||||
|
|
||||||
|
This reverts commit ae92c09f0ddfea2ff6042e152eec9af86013da38.
|
||||||
|
|
||||||
|
Also introduce rhel-9.8 naming scheme.
|
||||||
|
|
||||||
|
rhel-only: policy
|
||||||
|
|
||||||
|
Resolves: RHEL-50103
|
||||||
|
---
|
||||||
|
man/systemd.net-naming-scheme.xml | 9 ++++-
|
||||||
|
src/shared/netif-naming-scheme.c | 1 +
|
||||||
|
src/shared/netif-naming-scheme.h | 2 +
|
||||||
|
src/udev/udev-builtin-net_id.c | 66 +++++++++++++++++++++++++++----
|
||||||
|
4 files changed, 70 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||||
|
index 34e8e46459..c6ee7b4b6e 100644
|
||||||
|
--- a/man/systemd.net-naming-scheme.xml
|
||||||
|
+++ b/man/systemd.net-naming-scheme.xml
|
||||||
|
@@ -526,6 +526,13 @@
|
||||||
|
<listitem><para>Same as naming scheme <constant>rhel-9.5</constant>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-9.8</constant></term>
|
||||||
|
+
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>PCI slot number is now read from <constant>firmware_node/sun</constant> sysfs file.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<para>By default <constant>rhel-9.0</constant> is used.</para>
|
||||||
|
@@ -679,7 +686,7 @@ ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
- <title>PCI Ethernet card in hotplug slot with firmware index number</title>
|
||||||
|
+ <title>PCI Ethernet card in slot with firmware index number</title>
|
||||||
|
|
||||||
|
<programlisting># /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
|
||||||
|
ID_NET_NAME_MAC=enx000000000466
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
|
||||||
|
index a38c3f1e2f..4ed866491e 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.c
|
||||||
|
+++ b/src/shared/netif-naming-scheme.c
|
||||||
|
@@ -47,6 +47,7 @@ static const NamingScheme naming_schemes[] = {
|
||||||
|
{ "rhel-9.5", NAMING_RHEL_9_5 },
|
||||||
|
{ "rhel-9.6", NAMING_RHEL_9_6 },
|
||||||
|
{ "rhel-9.7", NAMING_RHEL_9_7 },
|
||||||
|
+ { "rhel-9.8", NAMING_RHEL_9_8 },
|
||||||
|
/* … add more schemes here, as the logic to name devices is updated … */
|
||||||
|
|
||||||
|
EXTRA_NET_NAMING_MAP
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
|
||||||
|
index 3cba656707..c16476522a 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.h
|
||||||
|
+++ b/src/shared/netif-naming-scheme.h
|
||||||
|
@@ -42,6 +42,7 @@ typedef enum NamingSchemeFlags {
|
||||||
|
* This is disabled since rhel-9.5, as it seems not to work at least for some setups. See upstream issue #28929. */
|
||||||
|
NAMING_DEVICETREE_ALIASES = 1 << 15, /* Generate names from devicetree aliases */
|
||||||
|
NAMING_SR_IOV_R = 1 << 17, /* Use "r" suffix for SR-IOV VF representors */
|
||||||
|
+ NAMING_FIRMWARE_NODE_SUN = 1 << 18, /* Use firmware_node/sun to get PCI slot number */
|
||||||
|
|
||||||
|
/* And now the masks that combine the features above */
|
||||||
|
NAMING_V238 = 0,
|
||||||
|
@@ -76,6 +77,7 @@ typedef enum NamingSchemeFlags {
|
||||||
|
NAMING_RHEL_9_5 = NAMING_RHEL_9_4 & ~NAMING_BRIDGE_MULTIFUNCTION_SLOT,
|
||||||
|
NAMING_RHEL_9_6 = NAMING_RHEL_9_5,
|
||||||
|
NAMING_RHEL_9_7 = NAMING_RHEL_9_5,
|
||||||
|
+ NAMING_RHEL_9_8 = NAMING_RHEL_9_5 | NAMING_FIRMWARE_NODE_SUN,
|
||||||
|
|
||||||
|
EXTRA_NET_NAMING_SCHEMES
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||||
|
index 16c9971876..291fb4ba36 100644
|
||||||
|
--- a/src/udev/udev-builtin-net_id.c
|
||||||
|
+++ b/src/udev/udev-builtin-net_id.c
|
||||||
|
@@ -442,6 +442,51 @@ static int pci_get_hotplug_slot(sd_device *dev, uint32_t *ret) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int get_device_firmware_node_sun(sd_device *dev, uint32_t *ret) {
|
||||||
|
+ const char *attr;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(dev);
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
+ r = device_get_sysattr_value_filtered(dev, "firmware_node/sun", &attr);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_debug_errno(dev, r, "Failed to read firmware_node/sun, ignoring: %m");
|
||||||
|
+
|
||||||
|
+ r = safe_atou32(attr, ret);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to parse firmware_node/sun '%s', ignoring: %m", attr);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int pci_get_slot_from_firmware_node_sun(sd_device *dev, uint32_t *ret) {
|
||||||
|
+ int r;
|
||||||
|
+ sd_device *slot_dev;
|
||||||
|
+
|
||||||
|
+ assert(dev);
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
+ /* Try getting the ACPI _SUN for the device */
|
||||||
|
+ if (get_device_firmware_node_sun(dev, ret) >= 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_parent_with_subsystem_devtype(dev, "pci", NULL, &slot_dev);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_debug_errno(dev, r, "Failed to find pci parent, ignoring: %m");
|
||||||
|
+
|
||||||
|
+ if (is_pci_bridge(slot_dev) && is_pci_multifunction(dev) <= 0)
|
||||||
|
+ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ESTALE),
|
||||||
|
+ "Not using slot information because the parent pcieport "
|
||||||
|
+ "is a bridge and the PCI device is not multifunction.");
|
||||||
|
+
|
||||||
|
+ /* Try getting the ACPI _SUN from the parent pcieport */
|
||||||
|
+ if (get_device_firmware_node_sun(slot_dev, ret) >= 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ return -ENOENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||||
|
const char *sysname, *attr;
|
||||||
|
unsigned domain, bus, slot, func;
|
||||||
|
@@ -517,13 +562,20 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||||
|
domain, bus, slot, func, strempty(info->phys_port_name), dev_port,
|
||||||
|
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), empty_to_na(names->pci_path));
|
||||||
|
|
||||||
|
- r = pci_get_hotplug_slot(names->pcidev, &hotplug_slot);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
- if (r > 0)
|
||||||
|
- /* If the hotplug slot is found through the function ID, then drop the domain from the name.
|
||||||
|
- * See comments in parse_hotplug_slot_from_function_id(). */
|
||||||
|
- domain = 0;
|
||||||
|
+ if (naming_scheme_has(NAMING_FIRMWARE_NODE_SUN))
|
||||||
|
+ r = pci_get_slot_from_firmware_node_sun(names->pcidev, &hotplug_slot);
|
||||||
|
+ else
|
||||||
|
+ r = -1;
|
||||||
|
+ /* If we don't find a slot using firmware_node/sun, fallback to hotplug_slot */
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ r = pci_get_hotplug_slot(names->pcidev, &hotplug_slot);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r > 0)
|
||||||
|
+ /* If the hotplug slot is found through the function ID, then drop the domain from the name.
|
||||||
|
+ * See comments in parse_hotplug_slot_from_function_id(). */
|
||||||
|
+ domain = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
s = names->pci_slot;
|
||||||
|
l = sizeof(names->pci_slot);
|
||||||
43
1264-udev-builtin-net_id-ignore-firmware_node-sun-0.patch
Normal file
43
1264-udev-builtin-net_id-ignore-firmware_node-sun-0.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 743c0fbd5ea56f926b36d6bbfc2d609bacd4353e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Etienne Champetier <e.champetier@ateme.com>
|
||||||
|
Date: Thu, 22 Aug 2024 16:30:56 -0400
|
||||||
|
Subject: [PATCH] udev-builtin-net_id: ignore firmware_node/sun == 0
|
||||||
|
|
||||||
|
Since ID_NET_NAME_SLOT was introduced we ignore slot == 0
|
||||||
|
https://github.com/systemd/systemd/blob/0035597a30d120f70df2dd7da3d6128fb8ba6051/src/udev/udev-builtin-net_id.c#L139
|
||||||
|
|
||||||
|
Qemu sets _SUN to PCI_SLOT() for all NICs, so _SUN is not unique.
|
||||||
|
https://gitlab.com/qemu-project/qemu/-/issues/2530
|
||||||
|
|
||||||
|
In my tests with libvirt I can only set 'slot="0x00"' in interface definition,
|
||||||
|
so all NICs end up with _SUN == 0, and this commit is enough to avoid the issue.
|
||||||
|
|
||||||
|
Fixes 0a4ecc54cb9f2d3418b970c51bfadb69c34ae9eb
|
||||||
|
|
||||||
|
(cherry picked from commit 448f9f81fd32f8658449101ada2eadd853f6b06b)
|
||||||
|
|
||||||
|
Resolves: RHEL-50103
|
||||||
|
---
|
||||||
|
src/udev/udev-builtin-net_id.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||||
|
index 291fb4ba36..e1895a38c0 100644
|
||||||
|
--- a/src/udev/udev-builtin-net_id.c
|
||||||
|
+++ b/src/udev/udev-builtin-net_id.c
|
||||||
|
@@ -453,10 +453,14 @@ static int get_device_firmware_node_sun(sd_device *dev, uint32_t *ret) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_debug_errno(dev, r, "Failed to read firmware_node/sun, ignoring: %m");
|
||||||
|
|
||||||
|
- r = safe_atou32(attr, ret);
|
||||||
|
+ uint32_t sun;
|
||||||
|
+ r = safe_atou32(attr, &sun);
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_warning_errno(dev, r, "Failed to parse firmware_node/sun '%s', ignoring: %m", attr);
|
||||||
|
+ if (sun == 0)
|
||||||
|
+ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "firmware_node/sun == 0, ignoring: %m");
|
||||||
|
|
||||||
|
+ *ret = sun;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
36
1265-fundamental-fix-compile-check-for-explicit_bzero.patch
Normal file
36
1265-fundamental-fix-compile-check-for-explicit_bzero.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From c14ed0d0bf700b9959359004d5eef50d4d2db951 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 10 Jan 2023 14:08:41 +0100
|
||||||
|
Subject: [PATCH] fundamental: fix compile check for explicit_bzero
|
||||||
|
|
||||||
|
Our HAVE_* variables are defined to 0 or 1, so '#if defined(HAVE_*)' is always true.
|
||||||
|
The variable is not defined when compiling for EFI though, so we need the
|
||||||
|
additional guard.
|
||||||
|
|
||||||
|
Fixup for 3f92dc2fd4070b213e6bc85263a9bef06ec9a486.
|
||||||
|
|
||||||
|
(I don't want to do something like add -DHAVE_EXPLICIT_BZERO=0 to the commandline
|
||||||
|
in src/efi/boot/meson.build, because this quite verbose. Our compilation commandlines
|
||||||
|
are very long already. Let's instead keep this localized in this one spot in the
|
||||||
|
source file.)x
|
||||||
|
|
||||||
|
(cherry picked from commit 5deb391c6e6d2b8fd7b94234efea49cd6bee0d76)
|
||||||
|
|
||||||
|
Resolves: RHEL-108568
|
||||||
|
---
|
||||||
|
src/fundamental/memory-util-fundamental.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/fundamental/memory-util-fundamental.h b/src/fundamental/memory-util-fundamental.h
|
||||||
|
index 8f50d8b8e1..e0ae33dc0d 100644
|
||||||
|
--- a/src/fundamental/memory-util-fundamental.h
|
||||||
|
+++ b/src/fundamental/memory-util-fundamental.h
|
||||||
|
@@ -11,7 +11,7 @@
|
||||||
|
|
||||||
|
#include "macro-fundamental.h"
|
||||||
|
|
||||||
|
-#if defined(HAVE_EXPLICIT_BZERO)
|
||||||
|
+#if !defined(SD_BOOT) && HAVE_EXPLICIT_BZERO
|
||||||
|
static inline void *explicit_bzero_safe(void *p, size_t l) {
|
||||||
|
if (p && l > 0)
|
||||||
|
explicit_bzero(p, l);
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
From 9906687d228f71768ddf115799ebb39272d1f655 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Sun, 12 Mar 2023 20:57:16 +0900
|
||||||
|
Subject: [PATCH] time-util: make USEC_TIMESTAMP_FORMATTABLE_MAX for 32bit
|
||||||
|
system off by one day
|
||||||
|
|
||||||
|
As the same reason why we take one day off for 64bit case.
|
||||||
|
|
||||||
|
This also makes both upper bounds always defined for testing.
|
||||||
|
|
||||||
|
(cherry picked from commit bd5770da76ee157d3b31323ed2d22f5d9082bb36)
|
||||||
|
|
||||||
|
Related: RHEL-109488
|
||||||
|
---
|
||||||
|
src/basic/time-util.h | 14 +++++++++-----
|
||||||
|
src/test/test-date.c | 4 ++--
|
||||||
|
src/test/test-time-util.c | 2 +-
|
||||||
|
3 files changed, 12 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
|
||||||
|
index 9d44cac747..7f8bda0948 100644
|
||||||
|
--- a/src/basic/time-util.h
|
||||||
|
+++ b/src/basic/time-util.h
|
||||||
|
@@ -200,13 +200,17 @@ static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
|
||||||
|
return usec_sub_unsigned(timestamp, (usec_t) delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit
|
||||||
|
+ * year territory. However, since we want to stay away from this in all timezones we take one day off. */
|
||||||
|
+#define USEC_TIMESTAMP_FORMATTABLE_MAX_64BIT ((usec_t) 253402214399000000) /* Thu 9999-12-30 23:59:59 UTC */
|
||||||
|
+/* With a 32bit time_t we can't go beyond 2038...
|
||||||
|
+ * We parse timestamp with RFC-822/ISO 8601 (e.g. +06, or -03:00) as UTC, hence the upper bound must be off
|
||||||
|
+ * by USEC_PER_DAY. See parse_timestamp() for more details. */
|
||||||
|
+#define USEC_TIMESTAMP_FORMATTABLE_MAX_32BIT (((usec_t) INT32_MAX) * USEC_PER_SEC - USEC_PER_DAY)
|
||||||
|
#if SIZEOF_TIME_T == 8
|
||||||
|
- /* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit
|
||||||
|
- * year territory. However, since we want to stay away from this in all timezones we take one day off. */
|
||||||
|
-# define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 253402214399000000)
|
||||||
|
+# define USEC_TIMESTAMP_FORMATTABLE_MAX USEC_TIMESTAMP_FORMATTABLE_MAX_64BIT
|
||||||
|
#elif SIZEOF_TIME_T == 4
|
||||||
|
-/* With a 32bit time_t we can't go beyond 2038... */
|
||||||
|
-# define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 2147483647000000)
|
||||||
|
+# define USEC_TIMESTAMP_FORMATTABLE_MAX USEC_TIMESTAMP_FORMATTABLE_MAX_32BIT
|
||||||
|
#else
|
||||||
|
# error "Yuck, time_t is neither 4 nor 8 bytes wide?"
|
||||||
|
#endif
|
||||||
|
diff --git a/src/test/test-date.c b/src/test/test-date.c
|
||||||
|
index cc11bd999e..ef316eeca7 100644
|
||||||
|
--- a/src/test/test-date.c
|
||||||
|
+++ b/src/test/test-date.c
|
||||||
|
@@ -104,8 +104,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
test_should_fail("9999-12-31 00:00:00 UTC");
|
||||||
|
test_should_fail("10000-01-01 00:00:00 UTC");
|
||||||
|
#elif SIZEOF_TIME_T == 4
|
||||||
|
- test_should_pass("2038-01-19 03:14:07 UTC");
|
||||||
|
- test_should_fail("2038-01-19 03:14:08 UTC");
|
||||||
|
+ test_should_pass("2038-01-18 03:14:07 UTC");
|
||||||
|
+ test_should_fail("2038-01-18 03:14:08 UTC");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||||
|
index 21b05a3010..71ef5906ba 100644
|
||||||
|
--- a/src/test/test-time-util.c
|
||||||
|
+++ b/src/test/test-time-util.c
|
||||||
|
@@ -550,7 +550,7 @@ TEST(format_timestamp_utc) {
|
||||||
|
test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX, "Thu 9999-12-30 23:59:59 UTC");
|
||||||
|
test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, "--- XXXX-XX-XX XX:XX:XX");
|
||||||
|
#elif SIZEOF_TIME_T == 4
|
||||||
|
- test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX, "Tue 2038-01-19 03:14:07 UTC");
|
||||||
|
+ test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX, "Mon 2038-01-18 03:14:07 UTC");
|
||||||
|
test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, "--- XXXX-XX-XX XX:XX:XX");
|
||||||
|
#endif
|
||||||
|
|
||||||
118
systemd.spec
118
systemd.spec
@ -21,7 +21,7 @@
|
|||||||
Name: systemd
|
Name: systemd
|
||||||
Url: https://systemd.io
|
Url: https://systemd.io
|
||||||
Version: 252
|
Version: 252
|
||||||
Release: 55%{?dist}
|
Release: 57%{?dist}
|
||||||
# For a breakdown of the licensing, see README
|
# For a breakdown of the licensing, see README
|
||||||
License: LGPLv2+ and MIT and GPLv2+
|
License: LGPLv2+ and MIT and GPLv2+
|
||||||
Summary: System and Service Manager
|
Summary: System and Service Manager
|
||||||
@ -1292,6 +1292,63 @@ Patch1206: 1206-core-when-removing-a-job-from-a-transaction-include-.patch
|
|||||||
Patch1207: 1207-catalog-add-entries-for-the-order-cycle-log-messages.patch
|
Patch1207: 1207-catalog-add-entries-for-the-order-cycle-log-messages.patch
|
||||||
Patch1208: 1208-tree-wide-check-more-log-message-format-in-log_struc.patch
|
Patch1208: 1208-tree-wide-check-more-log-message-format-in-log_struc.patch
|
||||||
Patch1209: 1209-core-transaction-do-not-attempt-to-log-n-a-as-a-jour.patch
|
Patch1209: 1209-core-transaction-do-not-attempt-to-log-n-a-as-a-jour.patch
|
||||||
|
Patch1210: 1210-Revert-boot-Use-EFI_BOOT_MANAGER_POLICY_PROTOCOL-to-.patch
|
||||||
|
Patch1211: 1211-boot-Use-correct-memory-type-for-allocations.patch
|
||||||
|
Patch1212: 1212-meson-etc-systemd-network-is-also-used-by-udevd.patch
|
||||||
|
Patch1213: 1213-sd-bus-make-bus_add_match_full-accept-timeout.patch
|
||||||
|
Patch1214: 1214-core-unit-add-get_timeout_start_usec-in-UnitVTable-a.patch
|
||||||
|
Patch1215: 1215-core-unit-increase-the-NameOwnerChanged-GetNameOwner.patch
|
||||||
|
Patch1216: 1216-core-sd-bus-drop-empty-lines-between-function-call-a.patch
|
||||||
|
Patch1217: 1217-core-do-not-disconnect-from-bus-when-failed-to-insta.patch
|
||||||
|
Patch1218: 1218-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch
|
||||||
|
Patch1219: 1219-manager-s-deserialized_subscribed-subscribed_as_strv.patch
|
||||||
|
Patch1220: 1220-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch
|
||||||
|
Patch1221: 1221-core-manager-restore-bus-track-deserialization-clean.patch
|
||||||
|
Patch1222: 1222-core-manager-drop-duplicate-bus-track-deserializatio.patch
|
||||||
|
Patch1223: 1223-sd-bus-bus-track-use-install_callback-in-sd_bus_trac.patch
|
||||||
|
Patch1224: 1224-shell-completion-add-kernel-identify-inspect-verbs-f.patch
|
||||||
|
Patch1225: 1225-test-add-tests-for-format_timestamp-and-parse_timest.patch
|
||||||
|
Patch1226: 1226-test-time-util-disable-failing-tests.patch
|
||||||
|
Patch1227: 1227-test-test-parse_timestamp-in-various-timezone.patch
|
||||||
|
Patch1228: 1228-systemctl-logind-add-missing-asserts.patch
|
||||||
|
Patch1229: 1229-systemctl-logind-make-logind_schedule_shutdown-accep.patch
|
||||||
|
Patch1230: 1230-systemctl-add-option-when-for-scheduled-shutdown.patch
|
||||||
|
Patch1231: 1231-test-time-util-add-test-cases-to-invalidate-show-and.patch
|
||||||
|
Patch1232: 1232-Introduce-RET_GATHER-and-use-it-in-src-shared.patch
|
||||||
|
Patch1233: 1233-fd-util-don-t-eat-up-errors-in-fd_cloexec_many.patch
|
||||||
|
Patch1234: 1234-sd-bus-refuse-to-send-messages-with-an-invalid-strin.patch
|
||||||
|
Patch1235: 1235-test-check-if-we-correctly-handle-invalid-UTF-8-in-m.patch
|
||||||
|
Patch1236: 1236-test-fix-a-typo-in-the-cleanup-stuff.patch
|
||||||
|
Patch1237: 1237-test-explicitly-specify-a-UTF-8-locale-for-UTF-8-she.patch
|
||||||
|
Patch1238: 1238-test-use-the-correct-file-name-when-restoring-the-or.patch
|
||||||
|
Patch1239: 1239-core-escape-UTF-8-in-mount-unit-Where-field-before-s.patch
|
||||||
|
Patch1240: 1240-Revert-test-time-util-disable-failing-tests.patch
|
||||||
|
Patch1241: 1241-test-use-get_timezones-to-iterate-all-known-timezone.patch
|
||||||
|
Patch1242: 1242-test-time-util-do-not-fail-on-DST-change.patch
|
||||||
|
Patch1243: 1243-test-time-util-suppress-timestamp-conversion-failure.patch
|
||||||
|
Patch1244: 1244-test-time-util-do-more-suppression-of-time-zone-chec.patch
|
||||||
|
Patch1245: 1245-test-time-util-fix-truncation-of-usec-to-sec.patch
|
||||||
|
Patch1246: 1246-test-unset-TZ-before-timezone-sensitive-unit-tests-a.patch
|
||||||
|
Patch1247: 1247-meson-extend-timeout-for-test-time-util.patch
|
||||||
|
Patch1248: 1248-time-util-use-DEFINE_STRING_TABLE_LOOKUP_TO_STRING-m.patch
|
||||||
|
Patch1249: 1249-time-util-align-string-table.patch
|
||||||
|
Patch1250: 1250-time-util-rename-variables.patch
|
||||||
|
Patch1251: 1251-time-util-add-assertions.patch
|
||||||
|
Patch1252: 1252-time-util-drop-redundant-else.patch
|
||||||
|
Patch1253: 1253-time-util-do-not-use-strdupa.patch
|
||||||
|
Patch1254: 1254-time-util-use-result-from-startswith_no_case.patch
|
||||||
|
Patch1255: 1255-time-util-use-usec_add-and-usec_sub_unsigned.patch
|
||||||
|
Patch1256: 1256-time-util-shorten-code-a-bit.patch
|
||||||
|
Patch1257: 1257-time-util-rename-variables.patch
|
||||||
|
Patch1258: 1258-time-util-drop-unnecessary-assignment-of-timezone-na.patch
|
||||||
|
Patch1259: 1259-time-util-make-parse_timestamp-use-the-RFC-822-ISO-8.patch
|
||||||
|
Patch1260: 1260-time-util-fix-typo.patch
|
||||||
|
Patch1261: 1261-ci-bump-the-tools-tree-to-F42.patch
|
||||||
|
Patch1262: 1262-journald-extend-STDOUT_STREAMS_MAX-to-64k.patch
|
||||||
|
Patch1263: 1263-Revert-Revert-udev-builtin-net_id-use-firmware_node-.patch
|
||||||
|
Patch1264: 1264-udev-builtin-net_id-ignore-firmware_node-sun-0.patch
|
||||||
|
Patch1265: 1265-fundamental-fix-compile-check-for-explicit_bzero.patch
|
||||||
|
Patch1266: 1266-time-util-make-USEC_TIMESTAMP_FORMATTABLE_MAX-for-32.patch
|
||||||
|
|
||||||
# Downstream-only patches (9000–9999)
|
# Downstream-only patches (9000–9999)
|
||||||
|
|
||||||
@ -2169,6 +2226,65 @@ systemd-hwdb update &>/dev/null || :
|
|||||||
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
|
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Sep 16 2025 systemd maintenance team <systemd-maint@redhat.com> - 252-57
|
||||||
|
- Revert "boot: Use EFI_BOOT_MANAGER_POLICY_PROTOCOL to connect console devices" (RHEL-108596)
|
||||||
|
- boot: Use correct memory type for allocations (RHEL-108555)
|
||||||
|
- meson: /etc/systemd/network is also used by udevd (RHEL-109096)
|
||||||
|
- sd-bus: make bus_add_match_full accept timeout (RHEL-31756)
|
||||||
|
- core/unit: add get_timeout_start_usec in UnitVTable and define it for service (RHEL-31756)
|
||||||
|
- core/unit: increase the NameOwnerChanged/GetNameOwner timeout to the unit's start timeout (RHEL-31756)
|
||||||
|
- core,sd-bus: drop empty lines between function call and error check (RHEL-31756)
|
||||||
|
- core: do not disconnect from bus when failed to install signal match (RHEL-31756)
|
||||||
|
- dbus: stash the subscriber list when we disconenct from the bus (RHEL-31756)
|
||||||
|
- manager: s/deserialized_subscribed/subscribed_as_strv (RHEL-31756)
|
||||||
|
- bus-util: do not reset the count returned by sd_bus_track_count_name() (RHEL-31756)
|
||||||
|
- core/manager: restore bus track deserialization cleanup in manager_reload() (RHEL-31756)
|
||||||
|
- core/manager: drop duplicate bus track deserialization (RHEL-31756)
|
||||||
|
- sd-bus/bus-track: use install_callback in sd_bus_track_add_name() (RHEL-31756)
|
||||||
|
- shell completion: add kernel-identify/inspect verbs for bootctl (RHEL-108576)
|
||||||
|
- test: add tests for format_timestamp() and parse_timestamp() with various timezone (RHEL-109488)
|
||||||
|
- test-time-util: disable failing tests (RHEL-109488)
|
||||||
|
- test: test parse_timestamp() in various timezone (RHEL-109488)
|
||||||
|
- systemctl: logind: add missing asserts (RHEL-109488)
|
||||||
|
- systemctl: logind: make logind_schedule_shutdown accept action as param (RHEL-109488)
|
||||||
|
- systemctl: add option --when for scheduled shutdown (RHEL-109488)
|
||||||
|
- test-time-util: add test cases to invalidate "show" and "cancel" (RHEL-109488)
|
||||||
|
- Introduce RET_GATHER and use it in src/shared/ (RHEL-108598)
|
||||||
|
- fd-util: don't eat up errors in fd_cloexec_many (RHEL-108598)
|
||||||
|
- sd-bus: refuse to send messages with an invalid string (RHEL-108584)
|
||||||
|
- test: check if we correctly handle invalid UTF-8 in mount stuff (RHEL-108584)
|
||||||
|
- test: fix a typo in the cleanup stuff (RHEL-108584)
|
||||||
|
- test: explicitly specify a UTF-8 locale for UTF-8 shenanigans (RHEL-108584)
|
||||||
|
- test: use the correct file name when restoring the original fstab (RHEL-108584)
|
||||||
|
- core: escape UTF-8 in mount unit Where field before sending to clients (RHEL-108584)
|
||||||
|
- Revert "test-time-util: disable failing tests" (RHEL-109488)
|
||||||
|
- test: use get_timezones() to iterate all known timezones (RHEL-109488)
|
||||||
|
- test-time-util: do not fail on DST change (RHEL-109488)
|
||||||
|
- test-time-util: suppress timestamp conversion failures for Africa/Khartoum timezone (RHEL-109488)
|
||||||
|
- test-time-util: do more suppression of time zone checks (RHEL-109488)
|
||||||
|
- test-time-util: fix truncation of usec to sec (RHEL-109488)
|
||||||
|
- test: unset TZ before timezone-sensitive unit tests are run (RHEL-109488)
|
||||||
|
- meson: extend timeout for test-time-util (RHEL-109488)
|
||||||
|
- time-util: use DEFINE_STRING_TABLE_LOOKUP_TO_STRING() macro (RHEL-109488)
|
||||||
|
- time-util: align string table (RHEL-109488)
|
||||||
|
- time-util: rename variables (RHEL-109488)
|
||||||
|
- time-util: add assertions (RHEL-109488)
|
||||||
|
- time-util: drop redundant else (RHEL-109488)
|
||||||
|
- time-util: do not use strdupa() (RHEL-109488)
|
||||||
|
- time-util: use result from startswith_no_case() (RHEL-109488)
|
||||||
|
- time-util: use usec_add() and usec_sub_unsigned() (RHEL-109488)
|
||||||
|
- time-util: shorten code a bit (RHEL-109488)
|
||||||
|
- time-util: rename variables (RHEL-109488)
|
||||||
|
- time-util: drop unnecessary assignment of timezone name (RHEL-109488)
|
||||||
|
- time-util: make parse_timestamp() use the RFC-822/ISO 8601 standard timezone spec (RHEL-109488)
|
||||||
|
- time-util: fix typo (RHEL-109488)
|
||||||
|
- ci: bump the tools tree to F42 (RHEL-109488)
|
||||||
|
- journald: extend STDOUT_STREAMS_MAX to 64k (RHEL-111065)
|
||||||
|
- Revert "Revert "udev-builtin-net_id: use firmware_node/sun for ID_NET_NAME_SLOT"" (RHEL-50103)
|
||||||
|
- udev-builtin-net_id: ignore firmware_node/sun == 0 (RHEL-50103)
|
||||||
|
- fundamental: fix compile check for explicit_bzero (RHEL-108568)
|
||||||
|
- time-util: make USEC_TIMESTAMP_FORMATTABLE_MAX for 32bit system off by one day (RHEL-109488)
|
||||||
|
|
||||||
* Fri Aug 15 2025 systemd maintenance team <systemd-maint@redhat.com> - 252-55
|
* Fri Aug 15 2025 systemd maintenance team <systemd-maint@redhat.com> - 252-55
|
||||||
- tree-wide: check more log message format in log_struct() and friends (RHEL-100353)
|
- tree-wide: check more log message format in log_struct() and friends (RHEL-100353)
|
||||||
- build: add some coloring to --version output (RHEL-100353)
|
- build: add some coloring to --version output (RHEL-100353)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user