1
0
mirror of https://github.com/systemd/systemd synced 2026-03-24 07:44:52 +01:00

Compare commits

..

No commits in common. "cac38a98033e72bb54fe23576c5418edd92e5a75" and "b34a4f0e6729de292cb3b0c03c1d48f246ad896b" have entirely different histories.

22 changed files with 809 additions and 947 deletions

View File

@ -46,7 +46,6 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| `69dad710-2ce4-4e3c-b16c-21a1d49abed3` | _Root Partition (32-bit ARM)_ | ditto | ditto | | `69dad710-2ce4-4e3c-b16c-21a1d49abed3` | _Root Partition (32-bit ARM)_ | ditto | ditto |
| `b921b045-1df0-41c3-af44-4c6f280d3fae` | _Root Partition (64-bit ARM/AArch64)_ | ditto | ditto | | `b921b045-1df0-41c3-af44-4c6f280d3fae` | _Root Partition (64-bit ARM/AArch64)_ | ditto | ditto |
| `993d8d3d-f80e-4225-855a-9daf8ed7ea97` | _Root Partition (Itanium/IA-64)_ | ditto | ditto | | `993d8d3d-f80e-4225-855a-9daf8ed7ea97` | _Root Partition (Itanium/IA-64)_ | ditto | ditto |
| `77055800-792c-4f94-b39a-98c91b762bb6` | _Root Partition (LoongArch 64-bit)_ | ditto | ditto |
| `60d5a7fe-8e7d-435c-b714-3dd8162144e1` | _Root Partition (RISC-V 32-bit)_ | ditto | ditto | | `60d5a7fe-8e7d-435c-b714-3dd8162144e1` | _Root Partition (RISC-V 32-bit)_ | ditto | ditto |
| `72ec70a6-cf74-40e6-bd49-4bda08e8f224` | _Root Partition (RISC-V 64-bit)_ | ditto | ditto | | `72ec70a6-cf74-40e6-bd49-4bda08e8f224` | _Root Partition (RISC-V 64-bit)_ | ditto | ditto |
| `d13c5d3b-b5d1-422a-b29f-9454fdc89d76` | _Root Verity Partition (x86)_ | A dm-verity superblock followed by hash data | On systems with matching architecture, contains dm-verity integrity hash data for the matching root partition. If this feature is used the partition UUID of the root partition should be the first 128bit of the root hash of the dm-verity hash data, and the partition UUID of this dm-verity partition should be the final 128bit of it, so that the root partition and its verity partition can be discovered easily, simply by specifying the root hash. | | `d13c5d3b-b5d1-422a-b29f-9454fdc89d76` | _Root Verity Partition (x86)_ | A dm-verity superblock followed by hash data | On systems with matching architecture, contains dm-verity integrity hash data for the matching root partition. If this feature is used the partition UUID of the root partition should be the first 128bit of the root hash of the dm-verity hash data, and the partition UUID of this dm-verity partition should be the final 128bit of it, so that the root partition and its verity partition can be discovered easily, simply by specifying the root hash. |
@ -54,7 +53,6 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| `7386cdf2-203c-47a9-a498-f2ecce45a2d6` | _Root Verity Partition (32-bit ARM)_ | ditto | ditto | | `7386cdf2-203c-47a9-a498-f2ecce45a2d6` | _Root Verity Partition (32-bit ARM)_ | ditto | ditto |
| `df3300ce-d69f-4c92-978c-9bfb0f38d820` | _Root Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto | | `df3300ce-d69f-4c92-978c-9bfb0f38d820` | _Root Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto |
| `86ed10d5-b607-45bb-8957-d350f23d0571` | _Root Verity Partition (Itanium/IA-64)_ | ditto | ditto | | `86ed10d5-b607-45bb-8957-d350f23d0571` | _Root Verity Partition (Itanium/IA-64)_ | ditto | ditto |
| `f3393b22-e9af-4613-a948-9d3bfbd0c535` | _Root Verity Partition (LoongArch 64-bit)_ | ditto | ditto |
| `ae0253be-1167-4007-ac68-43926c14c5de` | _Root Verity Partition (RISC-V 32-bit)_ | ditto | ditto | | `ae0253be-1167-4007-ac68-43926c14c5de` | _Root Verity Partition (RISC-V 32-bit)_ | ditto | ditto |
| `b6ed5582-440b-4209-b8da-5ff7c419ea3d` | _Root Verity Partition (RISC-V 64-bit)_ | ditto | ditto | | `b6ed5582-440b-4209-b8da-5ff7c419ea3d` | _Root Verity Partition (RISC-V 64-bit)_ | ditto | ditto |
| `75250d76-8cc6-458e-bd66-bd47cc81a812` | _`/usr/` Partition (x86)_ | Any native, optionally in LUKS | Similar semantics to root partition, but just the `/usr/` partition. | | `75250d76-8cc6-458e-bd66-bd47cc81a812` | _`/usr/` Partition (x86)_ | Any native, optionally in LUKS | Similar semantics to root partition, but just the `/usr/` partition. |
@ -62,7 +60,6 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| `7d0359a3-02b3-4f0a-865c-654403e70625` | _`/usr/` Partition (32-bit ARM)_ | ditto | ditto | | `7d0359a3-02b3-4f0a-865c-654403e70625` | _`/usr/` Partition (32-bit ARM)_ | ditto | ditto |
| `b0e01050-ee5f-4390-949a-9101b17104e9` | _`/usr/` Partition (64-bit ARM/AArch64)_ | ditto | ditto | | `b0e01050-ee5f-4390-949a-9101b17104e9` | _`/usr/` Partition (64-bit ARM/AArch64)_ | ditto | ditto |
| `4301d2a6-4e3b-4b2a-bb94-9e0b2c4225ea` | _`/usr/` Partition (Itanium/IA-64)_ | ditto | ditto | | `4301d2a6-4e3b-4b2a-bb94-9e0b2c4225ea` | _`/usr/` Partition (Itanium/IA-64)_ | ditto | ditto |
| `e611c702-575c-4cbe-9a46-434fa0bf7e3f` | _`/usr/` Partition (LoongArch 64-bit)_ | ditto | ditto |
| `b933fb22-5c3f-4f91-af90-e2bb0fa50702` | _`/usr/` Partition (RISC-V 32-bit)_ | ditto | ditto | | `b933fb22-5c3f-4f91-af90-e2bb0fa50702` | _`/usr/` Partition (RISC-V 32-bit)_ | ditto | ditto |
| `beaec34b-8442-439b-a40b-984381ed097d` | _`/usr/` Partition (RISC-V 64-bit)_ | ditto | ditto | | `beaec34b-8442-439b-a40b-984381ed097d` | _`/usr/` Partition (RISC-V 64-bit)_ | ditto | ditto |
| `8f461b0d-14ee-4e81-9aa9-049b6fb97abd` | _`/usr/` Verity Partition (x86)_ | A dm-verity superblock followed by hash data | Similar semantics to root Verity partition, but just for the `/usr/` partition. | | `8f461b0d-14ee-4e81-9aa9-049b6fb97abd` | _`/usr/` Verity Partition (x86)_ | A dm-verity superblock followed by hash data | Similar semantics to root Verity partition, but just for the `/usr/` partition. |
@ -70,7 +67,6 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| `c215d751-7bcd-4649-be90-6627490a4c05` | _`/usr/` Verity Partition (32-bit ARM)_ | ditto | ditto | | `c215d751-7bcd-4649-be90-6627490a4c05` | _`/usr/` Verity Partition (32-bit ARM)_ | ditto | ditto |
| `6e11a4e7-fbca-4ded-b9e9-e1a512bb664e` | _`/usr/` Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto | | `6e11a4e7-fbca-4ded-b9e9-e1a512bb664e` | _`/usr/` Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto |
| `6a491e03-3be7-4545-8e38-83320e0ea880` | _`/usr/` Verity Partition (Itanium/IA-64)_ | ditto | ditto | | `6a491e03-3be7-4545-8e38-83320e0ea880` | _`/usr/` Verity Partition (Itanium/IA-64)_ | ditto | ditto |
| `f46b2c26-59ae-48f0-9106-c50ed47f673d` | _`/usr/` Verity Partition (LoongArch 64-bit)_ | ditto | ditto |
| `cb1ee4e3-8cd0-4136-a0a4-aa61a32e8730` | _`/usr/` Verity Partition (RISC-V 32-bit)_ | ditto | ditto | | `cb1ee4e3-8cd0-4136-a0a4-aa61a32e8730` | _`/usr/` Verity Partition (RISC-V 32-bit)_ | ditto | ditto |
| `8f1056be-9b05-47c4-81d6-be53128e5b54` | _`/usr/` Verity Partition (RISC-V 64-bit)_ | ditto | ditto | | `8f1056be-9b05-47c4-81d6-be53128e5b54` | _`/usr/` Verity Partition (RISC-V 64-bit)_ | ditto | ditto |
| `933ac7e1-2eb4-4f13-b844-0e14e2aef915` | _Home Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/home/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/home`. | | `933ac7e1-2eb4-4f13-b844-0e14e2aef915` | _Home Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/home/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/home`. |
@ -225,13 +221,13 @@ We are not. `/etc/fstab` always overrides automatic discovery and is indeed
mentioned in the specifications. We are simply trying to make the boot and mentioned in the specifications. We are simply trying to make the boot and
installation processes of Linux a bit more robust and self-descriptive. installation processes of Linux a bit more robust and self-descriptive.
### Why did you only define the root partition for these listed architectures? ### Why did you only define the root partition for x86, x86-64, ARM, ARM64, ia64, riscv32, riscv64?
The automatic discovery of the root partition is defined to operate on the disk The automatic discovery of the root partition is defined to operate on the disk
containing the current EFI System Partition (ESP). Since EFI only exists on containing the current EFI System Partition (ESP). Since EFI only exists on
x86, x86-64, ia64, ARM, LoongArch and RISC-V so far, we only defined root x86, x86-64, ia64, ARM and RISC-V so far, we only defined root partition UUIDs for
partition UUIDs for these architectures. Should EFI become more common on these architectures. Should EFI become more common on other architectures, we
other architectures, we can define additional UUIDs for them. can define additional UUIDs for them.
### Why define distinct root partition UUIDs for the various architectures? ### Why define distinct root partition UUIDs for the various architectures?

View File

@ -200,16 +200,6 @@
<entry>Verity data for the ia64 root file system partition</entry> <entry>Verity data for the ia64 root file system partition</entry>
</row> </row>
<row>
<entry><constant>root-loongarch64</constant></entry>
<entry>Root file system partition for the LoongArch 64-bit architecture</entry>
</row>
<row>
<entry><constant>root-loongarch64-verity</constant></entry>
<entry>Verity data for the LoongArch 64-bit root file system partition</entry>
</row>
<row> <row>
<entry><constant>root-riscv32</constant></entry> <entry><constant>root-riscv32</constant></entry>
<entry>Root file system partition for the RISC-V 32-bit architecture</entry> <entry>Root file system partition for the RISC-V 32-bit architecture</entry>
@ -300,16 +290,6 @@
<entry>Verity data for the ia64 <filename>/usr/</filename> file system partition</entry> <entry>Verity data for the ia64 <filename>/usr/</filename> file system partition</entry>
</row> </row>
<row>
<entry><constant>usr-loongarch64</constant></entry>
<entry><filename>/usr/</filename> file system partition for the LoongArch 64-bit architecture</entry>
</row>
<row>
<entry><constant>usr-loongarch64-verity</constant></entry>
<entry>Verity data for the LoongArch 64-bit <filename>/usr/</filename> file system partition</entry>
</row>
<row> <row>
<entry><constant>usr-riscv32</constant></entry> <entry><constant>usr-riscv32</constant></entry>
<entry><filename>/usr/</filename> file system partition for the RISC-V 32-bit architecture</entry> <entry><filename>/usr/</filename> file system partition for the RISC-V 32-bit architecture</entry>

View File

@ -109,12 +109,6 @@
<entry><filename>/</filename></entry> <entry><filename>/</filename></entry>
<entry>On Itanium systems, the first Itanium root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry> <entry>On Itanium systems, the first Itanium root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
</row> </row>
<row>
<entry>77055800-792c-4f94-b39a-98c91b762bb6</entry>
<entry><filename>Root Partition (LoongArch 64)</filename></entry>
<entry><filename>/</filename></entry>
<entry>On LoongArch 64-bit systems, the first LoongArch 64-bit root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
</row>
<row> <row>
<entry>60d5a7fe-8e7d-435c-b714-3dd8162144e1</entry> <entry>60d5a7fe-8e7d-435c-b714-3dd8162144e1</entry>
<entry><filename>Root Partition (RISCV-V 32)</filename></entry> <entry><filename>Root Partition (RISCV-V 32)</filename></entry>

View File

@ -55,7 +55,6 @@
#include "machine-id-setup.h" #include "machine-id-setup.h"
#include "manager.h" #include "manager.h"
#include "manager-dump.h" #include "manager-dump.h"
#include "manager-serialize.h"
#include "mkdir.h" #include "mkdir.h"
#include "mount-setup.h" #include "mount-setup.h"
#include "os-util.h" #include "os-util.h"

View File

@ -1,536 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "clean-ipc.h"
#include "dbus.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "macro.h"
#include "manager-serialize.h"
#include "manager.h"
#include "parse-util.h"
#include "serialize.h"
#include "syslog-util.h"
#include "unit-serialize.h"
#include "user-util.h"
int manager_open_serialization(Manager *m, FILE **ret_f) {
_cleanup_close_ int fd = -1;
FILE *f;
assert(ret_f);
fd = open_serialization_fd("systemd-state");
if (fd < 0)
return fd;
f = take_fdopen(&fd, "w+");
if (!f)
return -errno;
*ret_f = f;
return 0;
}
static bool manager_timestamp_shall_serialize(ManagerTimestamp t) {
if (!in_initrd())
return true;
/* The following timestamps only apply to the host system, hence only serialize them there */
return !IN_SET(t,
MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH,
MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH,
MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH,
MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
}
static void manager_serialize_uid_refs_internal(
FILE *f,
Hashmap *uid_refs,
const char *field_name) {
void *p, *k;
assert(f);
assert(field_name);
/* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as
* the actual counter of it is better rebuild after a reload/reexec. */
HASHMAP_FOREACH_KEY(p, k, uid_refs) {
uint32_t c;
uid_t uid;
uid = PTR_TO_UID(k);
c = PTR_TO_UINT32(p);
if (!(c & DESTROY_IPC_FLAG))
continue;
(void) serialize_item_format(f, field_name, UID_FMT, uid);
}
}
static void manager_serialize_uid_refs(Manager *m, FILE *f) {
manager_serialize_uid_refs_internal(f, m->uid_refs, "destroy-ipc-uid");
}
static void manager_serialize_gid_refs(Manager *m, FILE *f) {
manager_serialize_uid_refs_internal(f, m->gid_refs, "destroy-ipc-gid");
}
int manager_serialize(
Manager *m,
FILE *f,
FDSet *fds,
bool switching_root) {
const char *t;
Unit *u;
int r;
assert(m);
assert(f);
assert(fds);
_cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
(void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
(void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
(void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
(void) serialize_bool(f, "taint-usr", m->taint_usr);
(void) serialize_bool(f, "ready-sent", m->ready_sent);
(void) serialize_bool(f, "taint-logged", m->taint_logged);
(void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
/* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
(void) serialize_bool(f, "honor-device-enumeration", !switching_root);
if (m->show_status_overridden != _SHOW_STATUS_INVALID)
(void) serialize_item(f, "show-status-overridden",
show_status_to_string(m->show_status_overridden));
if (m->log_level_overridden)
(void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
if (m->log_target_overridden)
(void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
(void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]);
(void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]);
(void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]);
for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
_cleanup_free_ char *joined = NULL;
if (!manager_timestamp_shall_serialize(q))
continue;
joined = strjoin(manager_timestamp_to_string(q), "-timestamp");
if (!joined)
return log_oom();
(void) serialize_dual_timestamp(f, joined, m->timestamps + q);
}
if (!switching_root)
(void) serialize_strv(f, "env", m->client_environment);
if (m->notify_fd >= 0) {
r = serialize_fd(f, fds, "notify-fd", m->notify_fd);
if (r < 0)
return r;
(void) serialize_item(f, "notify-socket", m->notify_socket);
}
if (m->cgroups_agent_fd >= 0) {
r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd);
if (r < 0)
return r;
}
if (m->user_lookup_fds[0] >= 0) {
int copy0, copy1;
copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
if (copy0 < 0)
return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m");
copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
if (copy1 < 0)
return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m");
(void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
}
bus_track_serialize(m->subscribed, f, "subscribed");
r = dynamic_user_serialize(m, f, fds);
if (r < 0)
return r;
manager_serialize_uid_refs(m, f);
manager_serialize_gid_refs(m, f);
r = exec_runtime_serialize(m, f, fds);
if (r < 0)
return r;
(void) fputc('\n', f);
HASHMAP_FOREACH_KEY(u, t, m->units) {
if (u->id != t)
continue;
r = unit_serialize(u, f, fds, switching_root);
if (r < 0)
return r;
}
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to flush serialization: %m");
r = bus_fdset_add_all(m, fds);
if (r < 0)
return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
return 0;
}
static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) {
Unit *u;
int r;
r = manager_load_unit(m, name, NULL, NULL, &u);
if (r < 0) {
if (r == -ENOMEM)
return r;
return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name);
}
r = unit_deserialize(u, f, fds);
if (r < 0) {
if (r == -ENOMEM)
return r;
return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name);
}
return 0;
}
static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
const char *unit_name;
int r;
for (;;) {
_cleanup_free_ char *line = NULL;
/* Start marker */
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read serialization line: %m");
if (r == 0)
break;
unit_name = strstrip(line);
r = manager_deserialize_one_unit(m, unit_name, f, fds);
if (r == -ENOMEM)
return r;
if (r < 0) {
r = unit_deserialize_skip(f);
if (r < 0)
return r;
}
}
return 0;
}
static void manager_deserialize_uid_refs_one_internal(
Hashmap** uid_refs,
const char *value) {
uid_t uid;
uint32_t c;
int r;
assert(uid_refs);
assert(value);
r = parse_uid(value, &uid);
if (r < 0 || uid == 0) {
log_debug("Unable to parse UID/GID reference serialization: " UID_FMT, uid);
return;
}
if (hashmap_ensure_allocated(uid_refs, &trivial_hash_ops) < 0) {
log_oom();
return;
}
c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
if (c & DESTROY_IPC_FLAG)
return;
c |= DESTROY_IPC_FLAG;
r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
if (r < 0) {
log_debug_errno(r, "Failed to add UID/GID reference entry: %m");
return;
}
}
static void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
manager_deserialize_uid_refs_one_internal(&m->uid_refs, value);
}
static void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
manager_deserialize_uid_refs_one_internal(&m->gid_refs, value);
}
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
int r = 0;
assert(m);
assert(f);
if (DEBUG_LOGGING) {
if (fdset_isempty(fds))
log_debug("No file descriptors passed");
else {
int fd;
FDSET_FOREACH(fd, fds) {
_cleanup_free_ char *fn = NULL;
r = fd_get_path(fd, &fn);
if (r < 0)
log_debug_errno(r, "Received serialized fd %i → %m", fd);
else
log_debug("Received serialized fd %i → %s", fd, strna(fn));
}
}
}
log_debug("Deserializing state...");
/* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
* increased it to non-zero, which is why we just increase it by one here and down again at the end of this
* call. */
_cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
for (;;) {
_cleanup_free_ char *line = NULL;
const char *val, *l;
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read serialization line: %m");
if (r == 0)
break;
l = strstrip(line);
if (isempty(l)) /* end marker */
break;
if ((val = startswith(l, "current-job-id="))) {
uint32_t id;
if (safe_atou32(val, &id) < 0)
log_notice("Failed to parse current job id value '%s', ignoring.", val);
else
m->current_job_id = MAX(m->current_job_id, id);
} else if ((val = startswith(l, "n-installed-jobs="))) {
uint32_t n;
if (safe_atou32(val, &n) < 0)
log_notice("Failed to parse installed jobs counter '%s', ignoring.", val);
else
m->n_installed_jobs += n;
} else if ((val = startswith(l, "n-failed-jobs="))) {
uint32_t n;
if (safe_atou32(val, &n) < 0)
log_notice("Failed to parse failed jobs counter '%s', ignoring.", val);
else
m->n_failed_jobs += n;
} else if ((val = startswith(l, "taint-usr="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse taint /usr flag '%s', ignoring.", val);
else
m->taint_usr = m->taint_usr || b;
} else if ((val = startswith(l, "ready-sent="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse ready-sent flag '%s', ignoring.", val);
else
m->ready_sent = m->ready_sent || b;
} else if ((val = startswith(l, "taint-logged="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
else
m->taint_logged = m->taint_logged || b;
} else if ((val = startswith(l, "service-watchdogs="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
else
m->service_watchdogs = b;
} else if ((val = startswith(l, "honor-device-enumeration="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
else
m->honor_device_enumeration = b;
} else if ((val = startswith(l, "show-status-overridden="))) {
ShowStatus s;
s = show_status_from_string(val);
if (s < 0)
log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
else
manager_override_show_status(m, s, "deserialize");
} else if ((val = startswith(l, "log-level-override="))) {
int level;
level = log_level_from_string(val);
if (level < 0)
log_notice("Failed to parse log-level-override value '%s', ignoring.", val);
else
manager_override_log_level(m, level);
} else if ((val = startswith(l, "log-target-override="))) {
LogTarget target;
target = log_target_from_string(val);
if (target < 0)
log_notice("Failed to parse log-target-override value '%s', ignoring.", val);
else
manager_override_log_target(m, target);
} else if ((val = startswith(l, "runtime-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
else
manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
} else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
else
manager_override_watchdog(m, WATCHDOG_REBOOT, t);
} else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
else
manager_override_watchdog(m, WATCHDOG_KEXEC, t);
} else if (startswith(l, "env=")) {
r = deserialize_environment(l + 4, &m->client_environment);
if (r < 0)
log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
} else if ((val = startswith(l, "notify-fd="))) {
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
else {
m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source);
safe_close(m->notify_fd);
m->notify_fd = fdset_remove(fds, fd);
}
} else if ((val = startswith(l, "notify-socket="))) {
r = free_and_strdup(&m->notify_socket, val);
if (r < 0)
return r;
} else if ((val = startswith(l, "cgroups-agent-fd="))) {
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
else {
m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source);
safe_close(m->cgroups_agent_fd);
m->cgroups_agent_fd = fdset_remove(fds, fd);
}
} else if ((val = startswith(l, "user-lookup="))) {
int fd0, fd1;
if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
log_notice("Failed to parse user lookup fd, ignoring: %s", val);
else {
m->user_lookup_event_source = sd_event_source_disable_unref(m->user_lookup_event_source);
safe_close_pair(m->user_lookup_fds);
m->user_lookup_fds[0] = fdset_remove(fds, fd0);
m->user_lookup_fds[1] = fdset_remove(fds, fd1);
}
} else if ((val = startswith(l, "dynamic-user=")))
dynamic_user_deserialize_one(m, val, fds);
else if ((val = startswith(l, "destroy-ipc-uid=")))
manager_deserialize_uid_refs_one(m, val);
else if ((val = startswith(l, "destroy-ipc-gid=")))
manager_deserialize_gid_refs_one(m, val);
else if ((val = startswith(l, "exec-runtime=")))
(void) exec_runtime_deserialize_one(m, val, fds);
else if ((val = startswith(l, "subscribed="))) {
if (strv_extend(&m->deserialized_subscribed, val) < 0)
return -ENOMEM;
} else {
ManagerTimestamp q;
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
val = startswith(l, manager_timestamp_to_string(q));
if (!val)
continue;
val = startswith(val, "-timestamp=");
if (val)
break;
}
if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
(void) deserialize_dual_timestamp(val, m->timestamps + q);
else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
log_notice("Unknown serialization item '%s', ignoring.", l);
}
}
return manager_deserialize_units(m, f, fds);
}

View File

@ -1,13 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
#include "manager.h"
#include "fdset.h"
#define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
int manager_open_serialization(Manager *m, FILE **ret_f);
int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
int manager_deserialize(Manager *m, FILE *f, FDSet *fds);

View File

@ -56,7 +56,6 @@
#include "macro.h" #include "macro.h"
#include "manager.h" #include "manager.h"
#include "manager-dump.h" #include "manager-dump.h"
#include "manager-serialize.h"
#include "memory-util.h" #include "memory-util.h"
#include "mkdir.h" #include "mkdir.h"
#include "parse-util.h" #include "parse-util.h"
@ -67,6 +66,7 @@
#include "rlimit-util.h" #include "rlimit-util.h"
#include "rm-rf.h" #include "rm-rf.h"
#include "selinux-util.h" #include "selinux-util.h"
#include "serialize.h"
#include "signal-util.h" #include "signal-util.h"
#include "socket-util.h" #include "socket-util.h"
#include "special.h" #include "special.h"
@ -82,6 +82,7 @@
#include "transaction.h" #include "transaction.h"
#include "umask-util.h" #include "umask-util.h"
#include "unit-name.h" #include "unit-name.h"
#include "unit-serialize.h"
#include "user-util.h" #include "user-util.h"
#include "virt.h" #include "virt.h"
#include "watchdog.h" #include "watchdog.h"
@ -117,19 +118,9 @@ static int manager_run_generators(Manager *m);
static void manager_vacuum(Manager *m); static void manager_vacuum(Manager *m);
static usec_t manager_watch_jobs_next_time(Manager *m) { static usec_t manager_watch_jobs_next_time(Manager *m) {
usec_t timeout; return usec_add(now(CLOCK_MONOTONIC),
show_status_on(m->show_status) ? JOBS_IN_PROGRESS_WAIT_USEC :
if (MANAGER_IS_USER(m)) JOBS_IN_PROGRESS_QUIET_WAIT_USEC);
/* Let the user manager without a timeout show status quickly, so the system manager can make
* use of it, if it wants to. */
timeout = JOBS_IN_PROGRESS_WAIT_USEC * 2 / 3;
else if (show_status_on(m->show_status))
/* When status is on, just use the usual timeout. */
timeout = JOBS_IN_PROGRESS_WAIT_USEC;
else
timeout = JOBS_IN_PROGRESS_QUIET_WAIT_USEC;
return usec_add(now(CLOCK_MONOTONIC), timeout);
} }
static void manager_watch_jobs_in_progress(Manager *m) { static void manager_watch_jobs_in_progress(Manager *m) {
@ -209,6 +200,7 @@ static void manager_flip_auto_status(Manager *m, bool enable, const char *reason
} }
static void manager_print_jobs_in_progress(Manager *m) { static void manager_print_jobs_in_progress(Manager *m) {
_cleanup_free_ char *job_of_n = NULL;
Job *j; Job *j;
unsigned counter = 0, print_nr; unsigned counter = 0, print_nr;
char cylon[6 + CYLON_BUFFER_EXTRA + 1]; char cylon[6 + CYLON_BUFFER_EXTRA + 1];
@ -238,51 +230,26 @@ static void manager_print_jobs_in_progress(Manager *m) {
m->jobs_in_progress_iteration++; m->jobs_in_progress_iteration++;
char job_of_n[STRLEN("( of ) ") + DECIMAL_STR_MAX(unsigned)*2] = "";
if (m->n_running_jobs > 1) if (m->n_running_jobs > 1)
xsprintf(job_of_n, "(%u of %u) ", counter, m->n_running_jobs); if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
job_of_n = NULL;
bool have_timeout = job_get_timeout(j, &x) > 0; bool have_timeout = job_get_timeout(j, &x) > 0;
/* We want to use enough information for the user to identify previous lines talking about the same /* We want to use enough information for the user to identify previous lines talking about the same
* unit, but keep the message as short as possible. So if 'Starting foo.service' or 'Starting * unit, but keep the message as short as possible. So if 'Starting foo.service' or 'Starting
* foo.service - Description' were used, 'foo.service' is enough here. On the other hand, if we used * foo.service (Description)' were used, 'foo.service' is enough here. On the other hand, if we used
* 'Starting Description' before, then we shall also use 'Description' here. So we pass NULL as the * 'Starting Description' before, then we shall also use 'Description' here. So we pass NULL as the
* second argument to unit_status_string(). */ * second argument to unit_status_string(). */
const char *ident = unit_status_string(j->unit, NULL); const char *ident = unit_status_string(j->unit, NULL);
const char *time = FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
const char *limit = have_timeout ? FORMAT_TIMESPAN(x - j->begin_usec, 1*USEC_PER_SEC) : "no limit";
if (m->status_unit_format == STATUS_UNIT_FORMAT_DESCRIPTION)
/* When using 'Description', we effectively don't have enough space to show the nested status
* without ellipsization, so let's not even try. */
manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon, manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
"%sA %s job is running for %s (%s / %s)", "%sA %s job is running for %s (%s / %s)",
job_of_n, strempty(job_of_n),
job_type_to_string(j->type), job_type_to_string(j->type),
ident, ident,
time, limit); FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC),
else { have_timeout ? FORMAT_TIMESPAN(x - j->begin_usec, 1*USEC_PER_SEC) : "no limit");
const char *status_text = unit_status_text(j->unit);
manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
"%sJob %s/%s running (%s / %s)%s%s",
job_of_n,
ident,
job_type_to_string(j->type),
time, limit,
status_text ? ": " : "",
strempty(status_text));
}
sd_notifyf(false,
"STATUS=%sUser job %s/%s running (%s / %s)...",
job_of_n,
ident,
job_type_to_string(j->type),
time, limit);
m->status_ready = false;
} }
static int have_ask_password(void) { static int have_ask_password(void) {
@ -654,7 +621,9 @@ static char** sanitize_environment(char **l) {
NULL); NULL);
/* Let's order the environment alphabetically, just to make it pretty */ /* Let's order the environment alphabetically, just to make it pretty */
return strv_sort(l); strv_sort(l);
return l;
} }
int manager_default_environment(Manager *m) { int manager_default_environment(Manager *m) {
@ -1717,11 +1686,11 @@ static void manager_ready(Manager *m) {
m->honor_device_enumeration = true; m->honor_device_enumeration = true;
} }
Manager* manager_reloading_start(Manager *m) { static Manager* manager_reloading_start(Manager *m) {
m->n_reloading++; m->n_reloading++;
return m; return m;
} }
void manager_reloading_stopp(Manager **m) { static void manager_reloading_stopp(Manager **m) {
if (*m) { if (*m) {
assert((*m)->n_reloading > 0); assert((*m)->n_reloading > 0);
(*m)->n_reloading--; (*m)->n_reloading--;
@ -2647,19 +2616,15 @@ turn_off:
return 0; return 0;
} }
static void manager_start_special(Manager *m, const char *name, JobMode mode) { static void manager_start_target(Manager *m, const char *name, JobMode mode) {
Job *job; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
if (manager_add_job_by_name_and_warn(m, JOB_START, name, mode, NULL, &job) < 0) log_debug("Activating special unit %s", name);
return;
const char *s = unit_status_string(job->unit, NULL); r = manager_add_job_by_name(m, JOB_START, name, mode, NULL, &error, NULL);
if (r < 0)
log_info("Activating special unit %s...", s); log_error("Failed to enqueue %s job: %s", name, bus_error_message(&error, r));
sd_notifyf(false,
"STATUS=Activating special unit %s...", s);
m->status_ready = false;
} }
static void manager_handle_ctrl_alt_del(Manager *m) { static void manager_handle_ctrl_alt_del(Manager *m) {
@ -2668,7 +2633,7 @@ static void manager_handle_ctrl_alt_del(Manager *m) {
* unless it was disabled in system.conf */ * unless it was disabled in system.conf */
if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE) if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE)
manager_start_special(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
else else
emergency_action(m, m->cad_burst_action, EMERGENCY_ACTION_WARN, NULL, -1, emergency_action(m, m->cad_burst_action, EMERGENCY_ACTION_WARN, NULL, -1,
"Ctrl-Alt-Del was pressed more than 7 times within 2s"); "Ctrl-Alt-Del was pressed more than 7 times within 2s");
@ -2732,20 +2697,21 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
if (MANAGER_IS_SYSTEM(m)) if (MANAGER_IS_SYSTEM(m))
manager_handle_ctrl_alt_del(m); manager_handle_ctrl_alt_del(m);
else else
manager_start_special(m, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY); manager_start_target(m, SPECIAL_EXIT_TARGET,
JOB_REPLACE_IRREVERSIBLY);
break; break;
case SIGWINCH: case SIGWINCH:
/* This is a nop on non-init */ /* This is a nop on non-init */
if (MANAGER_IS_SYSTEM(m)) if (MANAGER_IS_SYSTEM(m))
manager_start_special(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE); manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
break; break;
case SIGPWR: case SIGPWR:
/* This is a nop on non-init */ /* This is a nop on non-init */
if (MANAGER_IS_SYSTEM(m)) if (MANAGER_IS_SYSTEM(m))
manager_start_special(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE); manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
break; break;
@ -2757,8 +2723,10 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
if (MANAGER_IS_SYSTEM(m)) if (MANAGER_IS_SYSTEM(m))
(void) bus_init_system(m); (void) bus_init_system(m);
} else } else {
manager_start_special(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE); log_info("Starting D-Bus service...");
manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
}
break; break;
@ -2809,7 +2777,8 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 && if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) { (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
int idx = (int) sfsi.ssi_signo - SIGRTMIN; int idx = (int) sfsi.ssi_signo - SIGRTMIN;
manager_start_special(m, target_table[idx].target, target_table[idx].mode); manager_start_target(m, target_table[idx].target,
target_table[idx].mode);
break; break;
} }
@ -3174,8 +3143,10 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
return; return;
} }
if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
return (void) log_oom(); log_oom();
return;
}
errno = 0; errno = 0;
if (write(fd, message, n + 1) != n + 1) if (write(fd, message, n + 1) != n + 1)
@ -3183,6 +3154,242 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
log_error_errno(errno, "Failed to write Plymouth message: %m"); log_error_errno(errno, "Failed to write Plymouth message: %m");
} }
int manager_open_serialization(Manager *m, FILE **_f) {
_cleanup_close_ int fd = -1;
FILE *f;
assert(_f);
fd = open_serialization_fd("systemd-state");
if (fd < 0)
return fd;
f = take_fdopen(&fd, "w+");
if (!f)
return -errno;
*_f = f;
return 0;
}
static bool manager_timestamp_shall_serialize(ManagerTimestamp t) {
if (!in_initrd())
return true;
/* The following timestamps only apply to the host system, hence only serialize them there */
return !IN_SET(t,
MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH,
MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH,
MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH,
MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
}
#define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
static void manager_serialize_uid_refs_internal(
FILE *f,
Hashmap *uid_refs,
const char *field_name) {
void *p, *k;
assert(f);
assert(field_name);
/* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as
* the actual counter of it is better rebuild after a reload/reexec. */
HASHMAP_FOREACH_KEY(p, k, uid_refs) {
uint32_t c;
uid_t uid;
uid = PTR_TO_UID(k);
c = PTR_TO_UINT32(p);
if (!(c & DESTROY_IPC_FLAG))
continue;
(void) serialize_item_format(f, field_name, UID_FMT, uid);
}
}
static void manager_serialize_uid_refs(Manager *m, FILE *f) {
manager_serialize_uid_refs_internal(f, m->uid_refs, "destroy-ipc-uid");
}
static void manager_serialize_gid_refs(Manager *m, FILE *f) {
manager_serialize_uid_refs_internal(f, m->gid_refs, "destroy-ipc-gid");
}
int manager_serialize(
Manager *m,
FILE *f,
FDSet *fds,
bool switching_root) {
const char *t;
Unit *u;
int r;
assert(m);
assert(f);
assert(fds);
_cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
(void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
(void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
(void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
(void) serialize_bool(f, "taint-usr", m->taint_usr);
(void) serialize_bool(f, "ready-sent", m->ready_sent);
(void) serialize_bool(f, "taint-logged", m->taint_logged);
(void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
/* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
(void) serialize_bool(f, "honor-device-enumeration", !switching_root);
if (m->show_status_overridden != _SHOW_STATUS_INVALID)
(void) serialize_item(f, "show-status-overridden",
show_status_to_string(m->show_status_overridden));
if (m->log_level_overridden)
(void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
if (m->log_target_overridden)
(void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
(void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]);
(void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]);
(void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]);
for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
_cleanup_free_ char *joined = NULL;
if (!manager_timestamp_shall_serialize(q))
continue;
joined = strjoin(manager_timestamp_to_string(q), "-timestamp");
if (!joined)
return log_oom();
(void) serialize_dual_timestamp(f, joined, m->timestamps + q);
}
if (!switching_root)
(void) serialize_strv(f, "env", m->client_environment);
if (m->notify_fd >= 0) {
r = serialize_fd(f, fds, "notify-fd", m->notify_fd);
if (r < 0)
return r;
(void) serialize_item(f, "notify-socket", m->notify_socket);
}
if (m->cgroups_agent_fd >= 0) {
r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd);
if (r < 0)
return r;
}
if (m->user_lookup_fds[0] >= 0) {
int copy0, copy1;
copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
if (copy0 < 0)
return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m");
copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
if (copy1 < 0)
return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m");
(void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
}
bus_track_serialize(m->subscribed, f, "subscribed");
r = dynamic_user_serialize(m, f, fds);
if (r < 0)
return r;
manager_serialize_uid_refs(m, f);
manager_serialize_gid_refs(m, f);
r = exec_runtime_serialize(m, f, fds);
if (r < 0)
return r;
(void) fputc('\n', f);
HASHMAP_FOREACH_KEY(u, t, m->units) {
if (u->id != t)
continue;
r = unit_serialize(u, f, fds, switching_root);
if (r < 0)
return r;
}
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to flush serialization: %m");
r = bus_fdset_add_all(m, fds);
if (r < 0)
return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
return 0;
}
static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) {
Unit *u;
int r;
r = manager_load_unit(m, name, NULL, NULL, &u);
if (r < 0) {
if (r == -ENOMEM)
return r;
return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name);
}
r = unit_deserialize(u, f, fds);
if (r < 0) {
if (r == -ENOMEM)
return r;
return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name);
}
return 0;
}
static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
const char *unit_name;
int r;
for (;;) {
_cleanup_free_ char *line = NULL;
/* Start marker */
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read serialization line: %m");
if (r == 0)
break;
unit_name = strstrip(line);
r = manager_deserialize_one_unit(m, unit_name, f, fds);
if (r == -ENOMEM)
return r;
if (r < 0) {
r = unit_deserialize_skip(f);
if (r < 0)
return r;
}
}
return 0;
}
usec_t manager_get_watchdog(Manager *m, WatchdogType t) { usec_t manager_get_watchdog(Manager *m, WatchdogType t) {
assert(m); assert(m);
@ -3267,6 +3474,294 @@ void manager_retry_runtime_watchdog(Manager *m) {
m->runtime_watchdog_running = true; m->runtime_watchdog_running = true;
} }
static void manager_deserialize_uid_refs_one_internal(
Hashmap** uid_refs,
const char *value) {
uid_t uid;
uint32_t c;
int r;
assert(uid_refs);
assert(value);
r = parse_uid(value, &uid);
if (r < 0 || uid == 0) {
log_debug("Unable to parse UID/GID reference serialization: " UID_FMT, uid);
return;
}
if (hashmap_ensure_allocated(uid_refs, &trivial_hash_ops) < 0) {
log_oom();
return;
}
c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
if (c & DESTROY_IPC_FLAG)
return;
c |= DESTROY_IPC_FLAG;
r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
if (r < 0) {
log_debug_errno(r, "Failed to add UID/GID reference entry: %m");
return;
}
}
static void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
manager_deserialize_uid_refs_one_internal(&m->uid_refs, value);
}
static void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
manager_deserialize_uid_refs_one_internal(&m->gid_refs, value);
}
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
int r = 0;
assert(m);
assert(f);
if (DEBUG_LOGGING) {
if (fdset_isempty(fds))
log_debug("No file descriptors passed");
else {
int fd;
FDSET_FOREACH(fd, fds) {
_cleanup_free_ char *fn = NULL;
r = fd_get_path(fd, &fn);
if (r < 0)
log_debug_errno(r, "Received serialized fd %i → %m", fd);
else
log_debug("Received serialized fd %i → %s", fd, strna(fn));
}
}
}
log_debug("Deserializing state...");
/* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
* increased it to non-zero, which is why we just increase it by one here and down again at the end of this
* call. */
_cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
for (;;) {
_cleanup_free_ char *line = NULL;
const char *val, *l;
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read serialization line: %m");
if (r == 0)
break;
l = strstrip(line);
if (isempty(l)) /* end marker */
break;
if ((val = startswith(l, "current-job-id="))) {
uint32_t id;
if (safe_atou32(val, &id) < 0)
log_notice("Failed to parse current job id value '%s', ignoring.", val);
else
m->current_job_id = MAX(m->current_job_id, id);
} else if ((val = startswith(l, "n-installed-jobs="))) {
uint32_t n;
if (safe_atou32(val, &n) < 0)
log_notice("Failed to parse installed jobs counter '%s', ignoring.", val);
else
m->n_installed_jobs += n;
} else if ((val = startswith(l, "n-failed-jobs="))) {
uint32_t n;
if (safe_atou32(val, &n) < 0)
log_notice("Failed to parse failed jobs counter '%s', ignoring.", val);
else
m->n_failed_jobs += n;
} else if ((val = startswith(l, "taint-usr="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse taint /usr flag '%s', ignoring.", val);
else
m->taint_usr = m->taint_usr || b;
} else if ((val = startswith(l, "ready-sent="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse ready-sent flag '%s', ignoring.", val);
else
m->ready_sent = m->ready_sent || b;
} else if ((val = startswith(l, "taint-logged="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
else
m->taint_logged = m->taint_logged || b;
} else if ((val = startswith(l, "service-watchdogs="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
else
m->service_watchdogs = b;
} else if ((val = startswith(l, "honor-device-enumeration="))) {
int b;
b = parse_boolean(val);
if (b < 0)
log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
else
m->honor_device_enumeration = b;
} else if ((val = startswith(l, "show-status-overridden="))) {
ShowStatus s;
s = show_status_from_string(val);
if (s < 0)
log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
else
manager_override_show_status(m, s, "deserialize");
} else if ((val = startswith(l, "log-level-override="))) {
int level;
level = log_level_from_string(val);
if (level < 0)
log_notice("Failed to parse log-level-override value '%s', ignoring.", val);
else
manager_override_log_level(m, level);
} else if ((val = startswith(l, "log-target-override="))) {
LogTarget target;
target = log_target_from_string(val);
if (target < 0)
log_notice("Failed to parse log-target-override value '%s', ignoring.", val);
else
manager_override_log_target(m, target);
} else if ((val = startswith(l, "runtime-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
else
manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
} else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
else
manager_override_watchdog(m, WATCHDOG_REBOOT, t);
} else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
usec_t t;
if (deserialize_usec(val, &t) < 0)
log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
else
manager_override_watchdog(m, WATCHDOG_KEXEC, t);
} else if (startswith(l, "env=")) {
r = deserialize_environment(l + 4, &m->client_environment);
if (r < 0)
log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
} else if ((val = startswith(l, "notify-fd="))) {
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
else {
m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source);
safe_close(m->notify_fd);
m->notify_fd = fdset_remove(fds, fd);
}
} else if ((val = startswith(l, "notify-socket="))) {
r = free_and_strdup(&m->notify_socket, val);
if (r < 0)
return r;
} else if ((val = startswith(l, "cgroups-agent-fd="))) {
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
else {
m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source);
safe_close(m->cgroups_agent_fd);
m->cgroups_agent_fd = fdset_remove(fds, fd);
}
} else if ((val = startswith(l, "user-lookup="))) {
int fd0, fd1;
if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
log_notice("Failed to parse user lookup fd, ignoring: %s", val);
else {
m->user_lookup_event_source = sd_event_source_disable_unref(m->user_lookup_event_source);
safe_close_pair(m->user_lookup_fds);
m->user_lookup_fds[0] = fdset_remove(fds, fd0);
m->user_lookup_fds[1] = fdset_remove(fds, fd1);
}
} else if ((val = startswith(l, "dynamic-user=")))
dynamic_user_deserialize_one(m, val, fds);
else if ((val = startswith(l, "destroy-ipc-uid=")))
manager_deserialize_uid_refs_one(m, val);
else if ((val = startswith(l, "destroy-ipc-gid=")))
manager_deserialize_gid_refs_one(m, val);
else if ((val = startswith(l, "exec-runtime=")))
(void) exec_runtime_deserialize_one(m, val, fds);
else if ((val = startswith(l, "subscribed="))) {
if (strv_extend(&m->deserialized_subscribed, val) < 0)
return -ENOMEM;
} else {
ManagerTimestamp q;
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
val = startswith(l, manager_timestamp_to_string(q));
if (!val)
continue;
val = startswith(val, "-timestamp=");
if (val)
break;
}
if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
(void) deserialize_dual_timestamp(val, m->timestamps + q);
else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
log_notice("Unknown serialization item '%s', ignoring.", l);
}
}
return manager_deserialize_units(m, f, fds);
}
int manager_reload(Manager *m) { int manager_reload(Manager *m) {
_cleanup_(manager_reloading_stopp) Manager *reloading = NULL; _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
_cleanup_fdset_free_ FDSet *fds = NULL; _cleanup_fdset_free_ FDSet *fds = NULL;
@ -3479,32 +3974,28 @@ static void manager_notify_finished(Manager *m) {
bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec); bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
sd_notifyf(false,
m->ready_sent ? "STATUS=Startup finished in %s."
: "READY=1\n"
"STATUS=Startup finished in %s.",
FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC));
m->ready_sent = true;
log_taint_string(m); log_taint_string(m);
} }
static void user_manager_send_ready(Manager *m) { static void manager_send_ready(Manager *m) {
assert(m); assert(m);
/* We send READY=1 on reaching basic.target only when running in --user mode. */ /* We send READY=1 on reaching basic.target only when running in --user mode. */
if (!MANAGER_IS_USER(m) || m->ready_sent) if (!MANAGER_IS_USER(m) || m->ready_sent)
return; return;
m->ready_sent = true;
sd_notifyf(false, sd_notifyf(false,
"READY=1\n" "READY=1\n"
"STATUS=Reached " SPECIAL_BASIC_TARGET "."); "STATUS=Reached " SPECIAL_BASIC_TARGET ".");
m->ready_sent = true;
m->status_ready = false;
}
static void manager_send_ready(Manager *m) {
if (m->ready_sent && m->status_ready)
/* Skip the notification if nothing changed. */
return;
sd_notifyf(false,
"%sSTATUS=Ready.",
m->ready_sent ? "READY=1\n" : "");
m->ready_sent = m->status_ready = true;
} }
static void manager_check_basic_target(Manager *m) { static void manager_check_basic_target(Manager *m) {
@ -3521,7 +4012,7 @@ static void manager_check_basic_target(Manager *m) {
return; return;
/* For user managers, send out READY=1 as soon as we reach basic.target */ /* For user managers, send out READY=1 as soon as we reach basic.target */
user_manager_send_ready(m); manager_send_ready(m);
/* Log the taint string as soon as we reach basic.target */ /* Log the taint string as soon as we reach basic.target */
log_taint_string(m); log_taint_string(m);
@ -3552,11 +4043,6 @@ void manager_check_finished(Manager *m) {
if (hashmap_buckets(m->jobs) > hashmap_size(m->units) / 10) if (hashmap_buckets(m->jobs) > hashmap_size(m->units) / 10)
m->jobs = hashmap_free(m->jobs); m->jobs = hashmap_free(m->jobs);
manager_send_ready(m);
if (MANAGER_IS_FINISHED(m))
return;
manager_flip_auto_status(m, false, "boot finished"); manager_flip_auto_status(m, false, "boot finished");
/* Notify Type=idle units that we are done now */ /* Notify Type=idle units that we are done now */
@ -3571,6 +4057,9 @@ void manager_check_finished(Manager *m) {
/* This is no longer the first boot */ /* This is no longer the first boot */
manager_set_first_boot(m, false); manager_set_first_boot(m, false);
if (MANAGER_IS_FINISHED(m))
return;
dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH); dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH);
manager_notify_finished(m); manager_notify_finished(m);

View File

@ -329,9 +329,6 @@ struct Manager {
/* Have we already sent out the READY=1 notification? */ /* Have we already sent out the READY=1 notification? */
bool ready_sent; bool ready_sent;
/* Was the last status sent "STATUS=Ready."? */
bool status_ready;
/* Have we already printed the taint line if necessary? */ /* Have we already printed the taint line if necessary? */
bool taint_logged; bool taint_logged;
@ -503,9 +500,12 @@ int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
int manager_loop(Manager *m); int manager_loop(Manager *m);
int manager_open_serialization(Manager *m, FILE **_f);
int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
int manager_reload(Manager *m); int manager_reload(Manager *m);
Manager* manager_reloading_start(Manager *m);
void manager_reloading_stopp(Manager **m);
void manager_reset_failed(Manager *m); void manager_reset_failed(Manager *m);

View File

@ -87,8 +87,6 @@ libcore_sources = '''
locale-setup.h locale-setup.h
manager-dump.c manager-dump.c
manager-dump.h manager-dump.h
manager-serialize.c
manager-serialize.h
manager.c manager.c
manager.h manager.h
mount.c mount.c

View File

@ -4379,14 +4379,6 @@ static int service_exit_status(Unit *u) {
return s->main_exec_status.status; return s->main_exec_status.status;
} }
static const char* service_status_text(Unit *u) {
Service *s = SERVICE(u);
assert(s);
return s->status_text;
}
static int service_clean(Unit *u, ExecCleanMask mask) { static int service_clean(Unit *u, ExecCleanMask mask) {
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
Service *s = SERVICE(u); Service *s = SERVICE(u);
@ -4598,7 +4590,6 @@ const UnitVTable service_vtable = {
.get_timeout = service_get_timeout, .get_timeout = service_get_timeout,
.needs_console = service_needs_console, .needs_console = service_needs_console,
.exit_status = service_exit_status, .exit_status = service_exit_status,
.status_text = service_status_text,
.status_message_formats = { .status_message_formats = {
.finished_start_job = { .finished_start_job = {

View File

@ -631,9 +631,6 @@ typedef struct UnitVTable {
* exit code of the "main" process of the service or similar. */ * exit code of the "main" process of the service or similar. */
int (*exit_status)(Unit *u); int (*exit_status)(Unit *u);
/* Return a copy of the status string pointer. */
const char* (*status_text)(Unit *u);
/* Like the enumerate() callback further down, but only enumerates the perpetual units, i.e. all units that /* Like the enumerate() callback further down, but only enumerates the perpetual units, i.e. all units that
* unconditionally exist and are always active. The main reason to keep both enumeration functions separate is * unconditionally exist and are always active. The main reason to keep both enumeration functions separate is
* philosophical: the state of perpetual units should be put in place by coldplug(), while the state of those * philosophical: the state of perpetual units should be put in place by coldplug(), while the state of those
@ -747,12 +744,6 @@ static inline bool unit_is_extrinsic(Unit *u) {
(UNIT_VTABLE(u)->is_extrinsic && UNIT_VTABLE(u)->is_extrinsic(u)); (UNIT_VTABLE(u)->is_extrinsic && UNIT_VTABLE(u)->is_extrinsic(u));
} }
static inline const char* unit_status_text(Unit *u) {
if (u && UNIT_VTABLE(u)->status_text)
return UNIT_VTABLE(u)->status_text(u);
return NULL;
}
void unit_add_to_load_queue(Unit *u); void unit_add_to_load_queue(Unit *u);
void unit_add_to_dbus_queue(Unit *u); void unit_add_to_dbus_queue(Unit *u);
void unit_add_to_cleanup_queue(Unit *u); void unit_add_to_cleanup_queue(Unit *u);

View File

@ -15,8 +15,6 @@ const GptPartitionType gpt_partition_type_table[] = {
{ GPT_ROOT_ARM_64_VERITY, "root-arm64-verity" }, { GPT_ROOT_ARM_64_VERITY, "root-arm64-verity" },
{ GPT_ROOT_IA64, "root-ia64" }, { GPT_ROOT_IA64, "root-ia64" },
{ GPT_ROOT_IA64_VERITY, "root-ia64-verity" }, { GPT_ROOT_IA64_VERITY, "root-ia64-verity" },
{ GPT_ROOT_LOONGARCH64, "root-loongarch64" },
{ GPT_ROOT_LOONGARCH64_VERITY, "root-loongarch64-verity" },
{ GPT_ROOT_RISCV32, "root-riscv32" }, { GPT_ROOT_RISCV32, "root-riscv32" },
{ GPT_ROOT_RISCV32_VERITY, "root-riscv32-verity" }, { GPT_ROOT_RISCV32_VERITY, "root-riscv32-verity" },
{ GPT_ROOT_RISCV64, "root-riscv64" }, { GPT_ROOT_RISCV64, "root-riscv64" },
@ -39,8 +37,6 @@ const GptPartitionType gpt_partition_type_table[] = {
{ GPT_USR_ARM_64_VERITY, "usr-arm64-verity" }, { GPT_USR_ARM_64_VERITY, "usr-arm64-verity" },
{ GPT_USR_IA64, "usr-ia64" }, { GPT_USR_IA64, "usr-ia64" },
{ GPT_USR_IA64_VERITY, "usr-ia64-verity" }, { GPT_USR_IA64_VERITY, "usr-ia64-verity" },
{ GPT_USR_LOONGARCH64, "usr-loongarch64" },
{ GPT_USR_LOONGARCH64_VERITY, "usr-loongarch64-verity" },
{ GPT_USR_RISCV32, "usr-riscv32" }, { GPT_USR_RISCV32, "usr-riscv32" },
{ GPT_USR_RISCV32_VERITY, "usr-riscv32-verity" }, { GPT_USR_RISCV32_VERITY, "usr-riscv32-verity" },
{ GPT_USR_RISCV64, "usr-riscv64" }, { GPT_USR_RISCV64, "usr-riscv64" },
@ -118,7 +114,6 @@ bool gpt_partition_type_is_root(sd_id128_t id) {
GPT_ROOT_ARM, GPT_ROOT_ARM,
GPT_ROOT_ARM_64, GPT_ROOT_ARM_64,
GPT_ROOT_IA64, GPT_ROOT_IA64,
GPT_ROOT_LOONGARCH64,
GPT_ROOT_RISCV32, GPT_ROOT_RISCV32,
GPT_ROOT_RISCV64); GPT_ROOT_RISCV64);
} }
@ -130,7 +125,6 @@ bool gpt_partition_type_is_root_verity(sd_id128_t id) {
GPT_ROOT_ARM_VERITY, GPT_ROOT_ARM_VERITY,
GPT_ROOT_ARM_64_VERITY, GPT_ROOT_ARM_64_VERITY,
GPT_ROOT_IA64_VERITY, GPT_ROOT_IA64_VERITY,
GPT_ROOT_LOONGARCH64_VERITY,
GPT_ROOT_RISCV32_VERITY, GPT_ROOT_RISCV32_VERITY,
GPT_ROOT_RISCV64_VERITY); GPT_ROOT_RISCV64_VERITY);
} }
@ -142,7 +136,6 @@ bool gpt_partition_type_is_usr(sd_id128_t id) {
GPT_USR_ARM, GPT_USR_ARM,
GPT_USR_ARM_64, GPT_USR_ARM_64,
GPT_USR_IA64, GPT_USR_IA64,
GPT_USR_LOONGARCH64,
GPT_USR_RISCV32, GPT_USR_RISCV32,
GPT_USR_RISCV64); GPT_USR_RISCV64);
} }
@ -154,7 +147,6 @@ bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
GPT_USR_ARM_VERITY, GPT_USR_ARM_VERITY,
GPT_USR_ARM_64_VERITY, GPT_USR_ARM_64_VERITY,
GPT_USR_IA64_VERITY, GPT_USR_IA64_VERITY,
GPT_USR_LOONGARCH64_VERITY,
GPT_USR_RISCV32_VERITY, GPT_USR_RISCV32_VERITY,
GPT_USR_RISCV64_VERITY); GPT_USR_RISCV64_VERITY);
} }

View File

@ -7,16 +7,14 @@
#include "id128-util.h" #include "id128-util.h"
/* We only support root disk discovery for x86, x86-64, Itanium, ARM and LoongArch for now, /* We only support root disk discovery for x86, x86-64, Itanium and ARM for now, since EFI for anything else
* since EFI for anything else doesn't really exist, and we only care for root partitions * doesn't really exist, and we only care for root partitions on the same disk as the EFI ESP. */
* on the same disk as the EFI ESP. */
#define GPT_ROOT_X86 SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a) #define GPT_ROOT_X86 SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
#define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09) #define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
#define GPT_ROOT_ARM SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3) #define GPT_ROOT_ARM SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3)
#define GPT_ROOT_ARM_64 SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae) #define GPT_ROOT_ARM_64 SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae)
#define GPT_ROOT_IA64 SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97) #define GPT_ROOT_IA64 SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97)
#define GPT_ROOT_LOONGARCH64 SD_ID128_MAKE(77,05,58,00,79,2c,4f,94,b3,9a,99,c9,1b,76,2b,b6)
#define GPT_ROOT_RISCV32 SD_ID128_MAKE(60,d5,a7,fe,8e,7d,43,5c,b7,14,3d,d8,16,21,44,e1) #define GPT_ROOT_RISCV32 SD_ID128_MAKE(60,d5,a7,fe,8e,7d,43,5c,b7,14,3d,d8,16,21,44,e1)
#define GPT_ROOT_RISCV64 SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24) #define GPT_ROOT_RISCV64 SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24)
#define GPT_USR_X86 SD_ID128_MAKE(75,25,0d,76,8c,c6,45,8e,bd,66,bd,47,cc,81,a8,12) #define GPT_USR_X86 SD_ID128_MAKE(75,25,0d,76,8c,c6,45,8e,bd,66,bd,47,cc,81,a8,12)
@ -24,7 +22,6 @@
#define GPT_USR_ARM SD_ID128_MAKE(7d,03,59,a3,02,b3,4f,0a,86,5c,65,44,03,e7,06,25) #define GPT_USR_ARM SD_ID128_MAKE(7d,03,59,a3,02,b3,4f,0a,86,5c,65,44,03,e7,06,25)
#define GPT_USR_ARM_64 SD_ID128_MAKE(b0,e0,10,50,ee,5f,43,90,94,9a,91,01,b1,71,04,e9) #define GPT_USR_ARM_64 SD_ID128_MAKE(b0,e0,10,50,ee,5f,43,90,94,9a,91,01,b1,71,04,e9)
#define GPT_USR_IA64 SD_ID128_MAKE(43,01,d2,a6,4e,3b,4b,2a,bb,94,9e,0b,2c,42,25,ea) #define GPT_USR_IA64 SD_ID128_MAKE(43,01,d2,a6,4e,3b,4b,2a,bb,94,9e,0b,2c,42,25,ea)
#define GPT_USR_LOONGARCH64 SD_ID128_MAKE(e6,11,c7,02,57,5c,4c,be,9a,46,43,4f,a0,bf,7e,3f)
#define GPT_USR_RISCV32 SD_ID128_MAKE(b9,33,fb,22,5c,3f,4f,91,af,90,e2,bb,0f,a5,07,02) #define GPT_USR_RISCV32 SD_ID128_MAKE(b9,33,fb,22,5c,3f,4f,91,af,90,e2,bb,0f,a5,07,02)
#define GPT_USR_RISCV64 SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d) #define GPT_USR_RISCV64 SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d)
#define GPT_ESP SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b) #define GPT_ESP SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
@ -44,7 +41,6 @@
#define GPT_ROOT_ARM_VERITY SD_ID128_MAKE(73,86,cd,f2,20,3c,47,a9,a4,98,f2,ec,ce,45,a2,d6) #define GPT_ROOT_ARM_VERITY SD_ID128_MAKE(73,86,cd,f2,20,3c,47,a9,a4,98,f2,ec,ce,45,a2,d6)
#define GPT_ROOT_ARM_64_VERITY SD_ID128_MAKE(df,33,00,ce,d6,9f,4c,92,97,8c,9b,fb,0f,38,d8,20) #define GPT_ROOT_ARM_64_VERITY SD_ID128_MAKE(df,33,00,ce,d6,9f,4c,92,97,8c,9b,fb,0f,38,d8,20)
#define GPT_ROOT_IA64_VERITY SD_ID128_MAKE(86,ed,10,d5,b6,07,45,bb,89,57,d3,50,f2,3d,05,71) #define GPT_ROOT_IA64_VERITY SD_ID128_MAKE(86,ed,10,d5,b6,07,45,bb,89,57,d3,50,f2,3d,05,71)
#define GPT_ROOT_LOONGARCH64_VERITY SD_ID128_MAKE(f3,39,3b,22,e9,af,46,13,a9,48,9d,3b,fb,d0,c5,35)
#define GPT_ROOT_RISCV32_VERITY SD_ID128_MAKE(ae,02,53,be,11,67,40,07,ac,68,43,92,6c,14,c5,de) #define GPT_ROOT_RISCV32_VERITY SD_ID128_MAKE(ae,02,53,be,11,67,40,07,ac,68,43,92,6c,14,c5,de)
#define GPT_ROOT_RISCV64_VERITY SD_ID128_MAKE(b6,ed,55,82,44,0b,42,09,b8,da,5f,f7,c4,19,ea,3d) #define GPT_ROOT_RISCV64_VERITY SD_ID128_MAKE(b6,ed,55,82,44,0b,42,09,b8,da,5f,f7,c4,19,ea,3d)
#define GPT_USR_X86_VERITY SD_ID128_MAKE(8f,46,1b,0d,14,ee,4e,81,9a,a9,04,9b,6f,b9,7a,bd) #define GPT_USR_X86_VERITY SD_ID128_MAKE(8f,46,1b,0d,14,ee,4e,81,9a,a9,04,9b,6f,b9,7a,bd)
@ -52,7 +48,6 @@
#define GPT_USR_ARM_VERITY SD_ID128_MAKE(c2,15,d7,51,7b,cd,46,49,be,90,66,27,49,0a,4c,05) #define GPT_USR_ARM_VERITY SD_ID128_MAKE(c2,15,d7,51,7b,cd,46,49,be,90,66,27,49,0a,4c,05)
#define GPT_USR_ARM_64_VERITY SD_ID128_MAKE(6e,11,a4,e7,fb,ca,4d,ed,b9,e9,e1,a5,12,bb,66,4e) #define GPT_USR_ARM_64_VERITY SD_ID128_MAKE(6e,11,a4,e7,fb,ca,4d,ed,b9,e9,e1,a5,12,bb,66,4e)
#define GPT_USR_IA64_VERITY SD_ID128_MAKE(6a,49,1e,03,3b,e7,45,45,8e,38,83,32,0e,0e,a8,80) #define GPT_USR_IA64_VERITY SD_ID128_MAKE(6a,49,1e,03,3b,e7,45,45,8e,38,83,32,0e,0e,a8,80)
#define GPT_USR_LOONGARCH64_VERITY SD_ID128_MAKE(f4,6b,2c,26,59,ae,48,f0,91,06,c5,0e,d4,7f,67,3d)
#define GPT_USR_RISCV32_VERITY SD_ID128_MAKE(cb,1e,e4,e3,8c,d0,41,36,a0,a4,aa,61,a3,2e,87,30) #define GPT_USR_RISCV32_VERITY SD_ID128_MAKE(cb,1e,e4,e3,8c,d0,41,36,a0,a4,aa,61,a3,2e,87,30)
#define GPT_USR_RISCV64_VERITY SD_ID128_MAKE(8f,10,56,be,9b,05,47,c4,81,d6,be,53,12,8e,5b,54) #define GPT_USR_RISCV64_VERITY SD_ID128_MAKE(8f,10,56,be,9b,05,47,c4,81,d6,be,53,12,8e,5b,54)
@ -95,13 +90,6 @@
# define GPT_USR_NATIVE_VERITY GPT_USR_ARM_VERITY # define GPT_USR_NATIVE_VERITY GPT_USR_ARM_VERITY
#endif #endif
#if defined(__loongarch64)
# define GPT_ROOT_NATIVE GPT_ROOT_LOONGARCH64
# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_LOONGARCH64_VERITY
# define GPT_USR_NATIVE GPT_USR_LOONGARCH64
# define GPT_USR_NATIVE_VERITY GPT_USR_LOONGARCH64_VERITY
#endif
#if defined(__riscv) #if defined(__riscv)
#if (__riscv_xlen == 32) #if (__riscv_xlen == 32)
# define GPT_ROOT_NATIVE GPT_ROOT_RISCV32 # define GPT_ROOT_NATIVE GPT_ROOT_RISCV32

View File

@ -75,9 +75,6 @@ struct sd_bus_vtable {
uint64_t features; uint64_t features;
const unsigned *vtable_format_reference; const unsigned *vtable_format_reference;
} start; } start;
struct {
size_t reserved;
} end;
struct { struct {
const char *member; const char *member;
const char *signature; const char *signature;
@ -188,11 +185,7 @@ struct sd_bus_vtable {
{ \ { \
.type = _SD_BUS_VTABLE_END, \ .type = _SD_BUS_VTABLE_END, \
.flags = 0, \ .flags = 0, \
.x = { \ .x = { { 0 } }, \
.end = { \
.reserved = 0, \
}, \
}, \
} }
#define _SD_ECHO(X) X #define _SD_ECHO(X) X