mirror of
https://github.com/systemd/systemd.git
synced 2025-03-08 08:58:27 +03:00
Merge pull request #3777 from poettering/id128-rework
uuid/id128 code rework
This commit is contained in:
commit
31b14fdb6f
@ -242,6 +242,7 @@ AM_CPPFLAGS = \
|
||||
-I $(top_srcdir)/src/libsystemd/sd-network \
|
||||
-I $(top_srcdir)/src/libsystemd/sd-hwdb \
|
||||
-I $(top_srcdir)/src/libsystemd/sd-device \
|
||||
-I $(top_srcdir)/src/libsystemd/sd-id128 \
|
||||
-I $(top_srcdir)/src/libsystemd-network \
|
||||
$(OUR_CPPFLAGS)
|
||||
|
||||
@ -3074,9 +3075,7 @@ systemd_nspawn_SOURCES = \
|
||||
src/core/mount-setup.c \
|
||||
src/core/mount-setup.h \
|
||||
src/core/loopback-setup.c \
|
||||
src/core/loopback-setup.h \
|
||||
src/core/machine-id-setup.c \
|
||||
src/core/machine-id-setup.h
|
||||
src/core/loopback-setup.h
|
||||
|
||||
nodist_systemd_nspawn_SOURCES = \
|
||||
src/nspawn/nspawn-gperf.c
|
||||
@ -3213,6 +3212,8 @@ libsystemd_internal_la_SOURCES = \
|
||||
src/libsystemd/sd-netlink/local-addresses.h \
|
||||
src/libsystemd/sd-netlink/local-addresses.c \
|
||||
src/libsystemd/sd-id128/sd-id128.c \
|
||||
src/libsystemd/sd-id128/id128-util.h \
|
||||
src/libsystemd/sd-id128/id128-util.c \
|
||||
src/libsystemd/sd-daemon/sd-daemon.c \
|
||||
src/libsystemd/sd-login/sd-login.c \
|
||||
src/libsystemd/sd-path/sd-path.c \
|
||||
|
@ -74,13 +74,11 @@
|
||||
lowercase hexadecimal digits and be terminated by a
|
||||
<constant>NUL</constant> byte.</para>
|
||||
|
||||
<para><function>sd_id128_from_string()</function> implements the
|
||||
reverse operation: it takes a 33 character string with 32
|
||||
hexadecimal digits (either lowercase or uppercase, terminated by
|
||||
<constant>NUL</constant>) and parses them back into a 128-bit ID
|
||||
returned in <parameter>ret</parameter>. Alternatively, this call
|
||||
can also parse a 37-character string with a 128-bit ID formatted
|
||||
as RFC UUID.</para>
|
||||
<para><function>sd_id128_from_string()</function> implements the reverse operation: it takes a 33 character string
|
||||
with 32 hexadecimal digits (either lowercase or uppercase, terminated by <constant>NUL</constant>) and parses them
|
||||
back into a 128-bit ID returned in <parameter>ret</parameter>. Alternatively, this call can also parse a
|
||||
37-character string with a 128-bit ID formatted as RFC UUID. If <parameter>ret</parameter> is passed as NULL the
|
||||
function will validate the passed ID string, but not actually return it in parsed form.</para>
|
||||
|
||||
<para>For more information about the <literal>sd_id128_t</literal>
|
||||
type see
|
||||
|
@ -151,6 +151,12 @@
|
||||
early boot service.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--print</option></term>
|
||||
|
||||
<listitem><para>Print the machine ID generated or commited after the operation is complete.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
@ -581,47 +581,6 @@ int on_ac_power(void) {
|
||||
return found_online || !found_offline;
|
||||
}
|
||||
|
||||
bool id128_is_valid(const char *s) {
|
||||
size_t i, l;
|
||||
|
||||
l = strlen(s);
|
||||
if (l == 32) {
|
||||
|
||||
/* Simple formatted 128bit hex string */
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
char c = s[i];
|
||||
|
||||
if (!(c >= '0' && c <= '9') &&
|
||||
!(c >= 'a' && c <= 'z') &&
|
||||
!(c >= 'A' && c <= 'Z'))
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (l == 36) {
|
||||
|
||||
/* Formatted UUID */
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
char c = s[i];
|
||||
|
||||
if ((i == 8 || i == 13 || i == 18 || i == 23)) {
|
||||
if (c != '-')
|
||||
return false;
|
||||
} else {
|
||||
if (!(c >= '0' && c <= '9') &&
|
||||
!(c >= 'a' && c <= 'z') &&
|
||||
!(c >= 'A' && c <= 'Z'))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int container_get_leader(const char *machine, pid_t *pid) {
|
||||
_cleanup_free_ char *s = NULL, *class = NULL;
|
||||
const char *p;
|
||||
|
@ -176,8 +176,6 @@ static inline unsigned log2u_round_up(unsigned x) {
|
||||
return log2u(x - 1) + 1;
|
||||
}
|
||||
|
||||
bool id128_is_valid(const char *s) _pure_;
|
||||
|
||||
int container_get_leader(const char *machine, pid_t *pid);
|
||||
|
||||
int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
|
||||
|
@ -311,7 +311,7 @@ static int print_efi_option(uint16_t id, bool in_order) {
|
||||
return r;
|
||||
|
||||
/* print only configured entries with partition information */
|
||||
if (!path || sd_id128_equal(partition, SD_ID128_NULL))
|
||||
if (!path || sd_id128_is_null(partition))
|
||||
return 0;
|
||||
|
||||
efi_tilt_backslashes(path);
|
||||
@ -1072,7 +1072,7 @@ static int bootctl_main(int argc, char*argv[]) {
|
||||
|
||||
printf("Loader:\n");
|
||||
printf(" Product: %s\n", strna(loader));
|
||||
if (!sd_id128_equal(loader_part_uuid, SD_ID128_NULL))
|
||||
if (!sd_id128_is_null(loader_part_uuid))
|
||||
printf(" Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
|
||||
SD_ID128_FORMAT_VAL(loader_part_uuid));
|
||||
else
|
||||
|
@ -17,11 +17,8 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/mount.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -29,10 +26,8 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "io-util.h"
|
||||
#include "id128-util.h"
|
||||
#include "log.h"
|
||||
#include "machine-id-setup.h"
|
||||
#include "macro.h"
|
||||
@ -46,101 +41,23 @@
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
|
||||
static int shorten_uuid(char destination[34], const char source[36]) {
|
||||
unsigned i, j;
|
||||
|
||||
assert(destination);
|
||||
assert(source);
|
||||
|
||||
/* Converts a UUID into a machine ID, by lowercasing it and
|
||||
* removing dashes. Validates everything. */
|
||||
|
||||
for (i = 0, j = 0; i < 36 && j < 32; i++) {
|
||||
int t;
|
||||
|
||||
t = unhexchar(source[i]);
|
||||
if (t < 0)
|
||||
continue;
|
||||
|
||||
destination[j++] = hexchar(t);
|
||||
}
|
||||
|
||||
if (i != 36 || j != 32)
|
||||
return -EINVAL;
|
||||
|
||||
destination[32] = '\n';
|
||||
destination[33] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_machine_id(int fd, char id[34]) {
|
||||
char id_to_validate[34];
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(id);
|
||||
|
||||
/* Reads a machine ID from a file, validates it, and returns
|
||||
* it. The returned ID ends in a newline. */
|
||||
|
||||
r = loop_read_exact(fd, id_to_validate, 33, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (id_to_validate[32] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
id_to_validate[32] = 0;
|
||||
|
||||
if (!id128_is_valid(id_to_validate))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(id, id_to_validate, 32);
|
||||
id[32] = '\n';
|
||||
id[33] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_machine_id(int fd, const char id[34]) {
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(id);
|
||||
|
||||
if (lseek(fd, 0, SEEK_SET) < 0)
|
||||
return -errno;
|
||||
|
||||
r = loop_write(fd, id, 33, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (fsync(fd) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generate_machine_id(char id[34], const char *root) {
|
||||
int fd, r;
|
||||
unsigned char *p;
|
||||
sd_id128_t buf;
|
||||
char *q;
|
||||
static int generate_machine_id(const char *root, sd_id128_t *ret) {
|
||||
const char *dbus_machine_id;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
assert(id);
|
||||
|
||||
dbus_machine_id = prefix_roota(root, "/var/lib/dbus/machine-id");
|
||||
assert(ret);
|
||||
|
||||
/* First, try reading the D-Bus machine id, unless it is a symlink */
|
||||
dbus_machine_id = prefix_roota(root, "/var/lib/dbus/machine-id");
|
||||
fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||
if (fd >= 0) {
|
||||
r = read_machine_id(fd, id);
|
||||
safe_close(fd);
|
||||
|
||||
if (r >= 0) {
|
||||
if (id128_read_fd(fd, ID128_PLAIN, ret) >= 0) {
|
||||
log_info("Initializing machine ID from D-Bus machine ID.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = safe_close(fd);
|
||||
}
|
||||
|
||||
if (isempty(root)) {
|
||||
@ -151,13 +68,10 @@ static int generate_machine_id(char id[34], const char *root) {
|
||||
if (detect_container() > 0) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
|
||||
r = getenv_for_pid(1, "container_uuid", &e);
|
||||
if (r > 0) {
|
||||
r = shorten_uuid(id, e);
|
||||
if (r >= 0) {
|
||||
log_info("Initializing machine ID from container UUID.");
|
||||
return 0;
|
||||
}
|
||||
if (getenv_for_pid(1, "container_uuid", &e) > 0 &&
|
||||
sd_id128_from_string(e, ret) >= 0) {
|
||||
log_info("Initializing machine ID from container UUID.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else if (detect_vm() == VIRTUALIZATION_KVM) {
|
||||
@ -166,51 +80,29 @@ static int generate_machine_id(char id[34], const char *root) {
|
||||
* running in qemu/kvm and a machine ID was passed in
|
||||
* via -uuid on the qemu/kvm command line */
|
||||
|
||||
char uuid[36];
|
||||
|
||||
fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||
if (fd >= 0) {
|
||||
r = loop_read_exact(fd, uuid, 36, false);
|
||||
safe_close(fd);
|
||||
|
||||
if (r >= 0) {
|
||||
r = shorten_uuid(id, uuid);
|
||||
if (r >= 0) {
|
||||
log_info("Initializing machine ID from KVM UUID.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, ret) >= 0) {
|
||||
log_info("Initializing machine ID from KVM UUID.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If that didn't work, generate a random machine id */
|
||||
r = sd_id128_randomize(&buf);
|
||||
r = sd_id128_randomize(ret);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open /dev/urandom: %m");
|
||||
|
||||
for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) {
|
||||
q[0] = hexchar(*p >> 4);
|
||||
q[1] = hexchar(*p & 15);
|
||||
}
|
||||
|
||||
id[32] = '\n';
|
||||
id[33] = 0;
|
||||
return log_error_errno(r, "Failed to generate randomized : %m");
|
||||
|
||||
log_info("Initializing machine ID from random generator.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int machine_id_setup(const char *root, sd_id128_t machine_id) {
|
||||
int machine_id_setup(const char *root, sd_id128_t machine_id, sd_id128_t *ret) {
|
||||
const char *etc_machine_id, *run_machine_id;
|
||||
_cleanup_close_ int fd = -1;
|
||||
bool writable = true;
|
||||
char id[34]; /* 32 + \n + \0 */
|
||||
bool writable;
|
||||
int r;
|
||||
|
||||
etc_machine_id = prefix_roota(root, "/etc/machine-id");
|
||||
run_machine_id = prefix_roota(root, "/run/machine-id");
|
||||
|
||||
RUN_WITH_UMASK(0000) {
|
||||
/* We create this 0444, to indicate that this isn't really
|
||||
@ -218,7 +110,7 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) {
|
||||
* will be owned by root it doesn't matter much, but maybe
|
||||
* people look. */
|
||||
|
||||
mkdir_parents(etc_machine_id, 0755);
|
||||
(void) mkdir_parents(etc_machine_id, 0755);
|
||||
fd = open(etc_machine_id, O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
|
||||
if (fd < 0) {
|
||||
int old_errno = errno;
|
||||
@ -239,41 +131,41 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) {
|
||||
}
|
||||
|
||||
writable = false;
|
||||
}
|
||||
} else
|
||||
writable = true;
|
||||
}
|
||||
|
||||
/* A machine id argument overrides all other machined-ids */
|
||||
if (!sd_id128_is_null(machine_id)) {
|
||||
sd_id128_to_string(machine_id, id);
|
||||
id[32] = '\n';
|
||||
id[33] = 0;
|
||||
} else {
|
||||
if (read_machine_id(fd, id) >= 0)
|
||||
/* A we got a valid machine ID argument, that's what counts */
|
||||
if (sd_id128_is_null(machine_id)) {
|
||||
|
||||
/* Try to read any existing machine ID */
|
||||
if (id128_read_fd(fd, ID128_PLAIN, ret) >= 0)
|
||||
return 0;
|
||||
|
||||
/* Hmm, so, the id currently stored is not useful, then let's
|
||||
* generate one */
|
||||
|
||||
r = generate_machine_id(id, root);
|
||||
/* Hmm, so, the id currently stored is not useful, then let's generate one */
|
||||
r = generate_machine_id(root, &machine_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
|
||||
return log_error_errno(errno, "Failed to seek: %m");
|
||||
}
|
||||
|
||||
if (writable)
|
||||
if (write_machine_id(fd, id) >= 0)
|
||||
return 0;
|
||||
if (id128_write_fd(fd, ID128_PLAIN, machine_id, true) >= 0)
|
||||
goto finish;
|
||||
|
||||
fd = safe_close(fd);
|
||||
|
||||
/* Hmm, we couldn't write it? So let's write it to
|
||||
* /run/machine-id as a replacement */
|
||||
/* Hmm, we couldn't write it? So let's write it to /run/machine-id as a replacement */
|
||||
|
||||
RUN_WITH_UMASK(0022) {
|
||||
r = write_string_file(run_machine_id, id, WRITE_STRING_FILE_CREATE);
|
||||
if (r < 0) {
|
||||
(void) unlink(run_machine_id);
|
||||
return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
|
||||
}
|
||||
run_machine_id = prefix_roota(root, "/run/machine-id");
|
||||
|
||||
RUN_WITH_UMASK(0022)
|
||||
r = id128_write(run_machine_id, ID128_PLAIN, machine_id, false);
|
||||
if (r < 0) {
|
||||
(void) unlink(run_machine_id);
|
||||
return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
|
||||
}
|
||||
|
||||
/* And now, let's mount it over */
|
||||
@ -286,7 +178,11 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) {
|
||||
|
||||
/* Mark the mount read-only */
|
||||
if (mount(NULL, etc_machine_id, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL) < 0)
|
||||
log_warning_errno(errno, "Failed to make transient %s read-only: %m", etc_machine_id);
|
||||
log_warning_errno(errno, "Failed to make transient %s read-only, ignoring: %m", etc_machine_id);
|
||||
|
||||
finish:
|
||||
if (ret)
|
||||
*ret = machine_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -294,9 +190,13 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) {
|
||||
int machine_id_commit(const char *root) {
|
||||
_cleanup_close_ int fd = -1, initial_mntns_fd = -1;
|
||||
const char *etc_machine_id;
|
||||
char id[34]; /* 32 + \n + \0 */
|
||||
sd_id128_t id;
|
||||
int r;
|
||||
|
||||
/* Replaces a tmpfs bind mount of /etc/machine-id by a proper file, atomically. For this, the umount is removed
|
||||
* in a mount namespace, a new file is created at the right place. Afterwards the mount is also removed in the
|
||||
* original mount namespace, thus revealing the file that was just created. */
|
||||
|
||||
etc_machine_id = prefix_roota(root, "/etc/machine-id");
|
||||
|
||||
r = path_is_mount_point(etc_machine_id, 0);
|
||||
@ -312,10 +212,6 @@ int machine_id_commit(const char *root) {
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Cannot open %s: %m", etc_machine_id);
|
||||
|
||||
r = read_machine_id(fd, id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "We didn't find a valid machine ID in %s.", etc_machine_id);
|
||||
|
||||
r = fd_is_temporary_fs(fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine whether %s is on a temporary file system: %m", etc_machine_id);
|
||||
@ -324,6 +220,10 @@ int machine_id_commit(const char *root) {
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
r = id128_read_fd(fd, ID128_PLAIN, &id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "We didn't find a valid machine ID in %s.", etc_machine_id);
|
||||
|
||||
fd = safe_close(fd);
|
||||
|
||||
/* Store current mount namespace */
|
||||
@ -342,15 +242,9 @@ int machine_id_commit(const char *root) {
|
||||
return log_error_errno(errno, "Failed to unmount transient %s file in our private namespace: %m", etc_machine_id);
|
||||
|
||||
/* Update a persistent version of etc_machine_id */
|
||||
fd = open(etc_machine_id, O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Cannot open for writing %s. This is mandatory to get a persistent machine-id: %m", etc_machine_id);
|
||||
|
||||
r = write_machine_id(fd, id);
|
||||
r = id128_write(etc_machine_id, ID128_PLAIN, id, true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Cannot write %s: %m", etc_machine_id);
|
||||
|
||||
fd = safe_close(fd);
|
||||
return log_error_errno(r, "Cannot write %s. This is mandatory to get a persistent machine ID: %m", etc_machine_id);
|
||||
|
||||
/* Return to initial namespace and proceed a lazy tmpfs unmount */
|
||||
r = namespace_enter(-1, initial_mntns_fd, -1, -1, -1);
|
||||
|
@ -20,4 +20,4 @@
|
||||
***/
|
||||
|
||||
int machine_id_commit(const char *root);
|
||||
int machine_id_setup(const char *root, sd_id128_t machine_id);
|
||||
int machine_id_setup(const char *root, sd_id128_t requested, sd_id128_t *ret);
|
||||
|
@ -291,14 +291,16 @@ static int parse_crash_chvt(const char *value) {
|
||||
}
|
||||
|
||||
static int set_machine_id(const char *m) {
|
||||
sd_id128_t t;
|
||||
assert(m);
|
||||
|
||||
if (sd_id128_from_string(m, &arg_machine_id) < 0)
|
||||
if (sd_id128_from_string(m, &t) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (sd_id128_is_null(arg_machine_id))
|
||||
if (sd_id128_is_null(t))
|
||||
return -EINVAL;
|
||||
|
||||
arg_machine_id = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1721,7 +1723,7 @@ int main(int argc, char *argv[]) {
|
||||
status_welcome();
|
||||
|
||||
hostname_setup();
|
||||
machine_id_setup(NULL, arg_machine_id);
|
||||
machine_id_setup(NULL, arg_machine_id, NULL);
|
||||
loopback_setup();
|
||||
bump_unix_max_dgram_qlen();
|
||||
|
||||
|
@ -427,7 +427,7 @@ static int process_machine_id(void) {
|
||||
if (laccess(etc_machine_id, F_OK) >= 0)
|
||||
return 0;
|
||||
|
||||
if (sd_id128_equal(arg_machine_id, SD_ID128_NULL))
|
||||
if (sd_id128_is_null(arg_machine_id))
|
||||
return 0;
|
||||
|
||||
mkdir_parents(etc_machine_id, 0755);
|
||||
|
@ -1266,7 +1266,7 @@ static int add_boot(sd_journal *j) {
|
||||
/* Take a shortcut and use the current boot_id, which we can do very quickly.
|
||||
* We can do this only when we logs are coming from the current machine,
|
||||
* so take the slow path if log location is specified. */
|
||||
if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL) &&
|
||||
if (arg_boot_offset == 0 && sd_id128_is_null(arg_boot_id) &&
|
||||
!arg_directory && !arg_file)
|
||||
|
||||
return add_match_this_boot(j, arg_machine);
|
||||
|
@ -877,7 +877,7 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format,
|
||||
assert_cc(6 == LOG_INFO);
|
||||
IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
|
||||
|
||||
if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
|
||||
if (!sd_id128_is_null(message_id)) {
|
||||
snprintf(mid, sizeof(mid), LOG_MESSAGE_ID(message_id));
|
||||
IOVEC_SET_STRING(iovec[n++], mid);
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ static int bus_socket_auth_verify_client(sd_bus *b) {
|
||||
peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
|
||||
}
|
||||
|
||||
if (!sd_id128_equal(b->server_id, SD_ID128_NULL) &&
|
||||
if (!sd_id128_is_null(b->server_id) &&
|
||||
!sd_id128_equal(b->server_id, peer))
|
||||
return -EPERM;
|
||||
|
||||
|
182
src/libsystemd/sd-id128/id128-util.c
Normal file
182
src/libsystemd/sd-id128/id128-util.c
Normal file
@ -0,0 +1,182 @@
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2016 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "id128-util.h"
|
||||
#include "io-util.h"
|
||||
#include "stdio-util.h"
|
||||
|
||||
char *id128_to_uuid_string(sd_id128_t id, char s[37]) {
|
||||
unsigned n, k = 0;
|
||||
|
||||
assert(s);
|
||||
|
||||
/* Similar to sd_id128_to_string() but formats the result as UUID instead of plain hex chars */
|
||||
|
||||
for (n = 0; n < 16; n++) {
|
||||
|
||||
if (IN_SET(n, 4, 6, 8, 10))
|
||||
s[k++] = '-';
|
||||
|
||||
s[k++] = hexchar(id.bytes[n] >> 4);
|
||||
s[k++] = hexchar(id.bytes[n] & 0xF);
|
||||
}
|
||||
|
||||
assert(k == 36);
|
||||
|
||||
s[k] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool id128_is_valid(const char *s) {
|
||||
size_t i, l;
|
||||
|
||||
assert(s);
|
||||
|
||||
l = strlen(s);
|
||||
if (l == 32) {
|
||||
|
||||
/* Plain formatted 128bit hex string */
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
char c = s[i];
|
||||
|
||||
if (!(c >= '0' && c <= '9') &&
|
||||
!(c >= 'a' && c <= 'z') &&
|
||||
!(c >= 'A' && c <= 'Z'))
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (l == 36) {
|
||||
|
||||
/* Formatted UUID */
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
char c = s[i];
|
||||
|
||||
if ((i == 8 || i == 13 || i == 18 || i == 23)) {
|
||||
if (c != '-')
|
||||
return false;
|
||||
} else {
|
||||
if (!(c >= '0' && c <= '9') &&
|
||||
!(c >= 'a' && c <= 'z') &&
|
||||
!(c >= 'A' && c <= 'Z'))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
char buffer[36 + 2];
|
||||
ssize_t l;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(f < _ID128_FORMAT_MAX);
|
||||
|
||||
/* Reads an 128bit ID from a file, which may either be in plain format (32 hex digits), or in UUID format, both
|
||||
* followed by a newline and nothing else. */
|
||||
|
||||
l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 33 or 37 chars */
|
||||
if (l < 0)
|
||||
return (int) l;
|
||||
if (l == 0) /* empty? */
|
||||
return -ENOMEDIUM;
|
||||
|
||||
if (l == 33) {
|
||||
if (f == ID128_UUID)
|
||||
return -EINVAL;
|
||||
|
||||
if (buffer[32] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
buffer[32] = 0;
|
||||
|
||||
} else if (l == 37) {
|
||||
if (f == ID128_PLAIN)
|
||||
return -EINVAL;
|
||||
|
||||
if (buffer[36] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
buffer[36] = 0;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
return sd_id128_from_string(buffer, ret);
|
||||
}
|
||||
|
||||
int id128_read(const char *p, Id128Format f, sd_id128_t *ret) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
return id128_read_fd(fd, f, ret);
|
||||
}
|
||||
|
||||
int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
|
||||
char buffer[36 + 2];
|
||||
size_t sz;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(f < _ID128_FORMAT_MAX);
|
||||
|
||||
if (f != ID128_UUID) {
|
||||
sd_id128_to_string(id, buffer);
|
||||
buffer[32] = '\n';
|
||||
sz = 33;
|
||||
} else {
|
||||
id128_to_uuid_string(id, buffer);
|
||||
buffer[36] = '\n';
|
||||
sz = 37;
|
||||
}
|
||||
|
||||
r = loop_write(fd, buffer, sz, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (do_sync) {
|
||||
if (fsync(fd) < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
return id128_write_fd(fd, f, id, do_sync);
|
||||
}
|
45
src/libsystemd/sd-id128/id128-util.h
Normal file
45
src/libsystemd/sd-id128/id128-util.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2016 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "sd-id128.h"
|
||||
#include "macro.h"
|
||||
|
||||
char *id128_to_uuid_string(sd_id128_t id, char s[37]);
|
||||
|
||||
/* Like SD_ID128_FORMAT_STR, but formats as UUID, not in plain format */
|
||||
#define ID128_UUID_FORMAT_STR "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
|
||||
|
||||
bool id128_is_valid(const char *s) _pure_;
|
||||
|
||||
typedef enum Id128Format {
|
||||
ID128_ANY,
|
||||
ID128_PLAIN, /* formatted as 32 hex chars as-is */
|
||||
ID128_UUID, /* formatted as 36 character uuid string */
|
||||
_ID128_FORMAT_MAX,
|
||||
} Id128Format;
|
||||
|
||||
int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret);
|
||||
int id128_read(const char *p, Id128Format f, sd_id128_t *ret);
|
||||
|
||||
int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync);
|
||||
int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync);
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "id128-util.h"
|
||||
#include "io-util.h"
|
||||
#include "macro.h"
|
||||
#include "random-util.h"
|
||||
@ -51,7 +52,6 @@ _public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) {
|
||||
bool is_guid = false;
|
||||
|
||||
assert_return(s, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
for (n = 0, i = 0; n < 16;) {
|
||||
int a, b;
|
||||
@ -89,7 +89,43 @@ _public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) {
|
||||
if (s[i] != 0)
|
||||
return -EINVAL;
|
||||
|
||||
*ret = t;
|
||||
if (ret)
|
||||
*ret = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
static thread_local sd_id128_t saved_machine_id = {};
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (sd_id128_is_null(saved_machine_id)) {
|
||||
r = id128_read("/etc/machine-id", ID128_PLAIN, &saved_machine_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (sd_id128_is_null(saved_machine_id))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*ret = saved_machine_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
static thread_local sd_id128_t saved_boot_id = {};
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (sd_id128_is_null(saved_boot_id)) {
|
||||
r = id128_read("/proc/sys/kernel/random/boot_id", ID128_UUID, &saved_boot_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = saved_boot_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -106,106 +142,6 @@ static sd_id128_t make_v4_uuid(sd_id128_t id) {
|
||||
return id;
|
||||
}
|
||||
|
||||
_public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
static thread_local sd_id128_t saved_machine_id;
|
||||
static thread_local bool saved_machine_id_valid = false;
|
||||
_cleanup_close_ int fd = -1;
|
||||
char buf[33];
|
||||
unsigned j;
|
||||
sd_id128_t t;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (saved_machine_id_valid) {
|
||||
*ret = saved_machine_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
r = loop_read_exact(fd, buf, 33, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (buf[32] !='\n')
|
||||
return -EIO;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
int a, b;
|
||||
|
||||
a = unhexchar(buf[j*2]);
|
||||
b = unhexchar(buf[j*2+1]);
|
||||
|
||||
if (a < 0 || b < 0)
|
||||
return -EIO;
|
||||
|
||||
t.bytes[j] = a << 4 | b;
|
||||
}
|
||||
|
||||
saved_machine_id = t;
|
||||
saved_machine_id_valid = true;
|
||||
|
||||
*ret = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
static thread_local sd_id128_t saved_boot_id;
|
||||
static thread_local bool saved_boot_id_valid = false;
|
||||
_cleanup_close_ int fd = -1;
|
||||
char buf[36];
|
||||
unsigned j;
|
||||
sd_id128_t t;
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (saved_boot_id_valid) {
|
||||
*ret = saved_boot_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
r = loop_read_exact(fd, buf, 36, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (j = 0, p = buf; j < 16; j++) {
|
||||
int a, b;
|
||||
|
||||
if (p >= buf + 35)
|
||||
return -EIO;
|
||||
|
||||
if (*p == '-') {
|
||||
p++;
|
||||
if (p >= buf + 35)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
a = unhexchar(p[0]);
|
||||
b = unhexchar(p[1]);
|
||||
|
||||
if (a < 0 || b < 0)
|
||||
return -EIO;
|
||||
|
||||
t.bytes[j] = a << 4 | b;
|
||||
|
||||
p += 2;
|
||||
}
|
||||
|
||||
saved_boot_id = t;
|
||||
saved_boot_id_valid = true;
|
||||
|
||||
*ret = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_id128_randomize(sd_id128_t *ret) {
|
||||
sd_id128_t t;
|
||||
int r;
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
static char *arg_root = NULL;
|
||||
static bool arg_commit = false;
|
||||
static bool arg_print = false;
|
||||
|
||||
static void help(void) {
|
||||
printf("%s [OPTIONS...]\n\n"
|
||||
@ -37,6 +38,7 @@ static void help(void) {
|
||||
" --version Show package version\n"
|
||||
" --root=ROOT Filesystem root\n"
|
||||
" --commit Commit transient ID\n"
|
||||
" --print Print used machine ID\n"
|
||||
, program_invocation_short_name);
|
||||
}
|
||||
|
||||
@ -46,6 +48,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_ROOT,
|
||||
ARG_COMMIT,
|
||||
ARG_PRINT,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -53,6 +56,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "commit", no_argument, NULL, ARG_COMMIT },
|
||||
{ "print", no_argument, NULL, ARG_PRINT },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -82,6 +86,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_commit = true;
|
||||
break;
|
||||
|
||||
case ARG_PRINT:
|
||||
arg_print = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -98,6 +106,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char buf[SD_ID128_STRING_MAX];
|
||||
sd_id128_t id;
|
||||
int r;
|
||||
|
||||
log_parse_environment();
|
||||
@ -107,10 +117,24 @@ int main(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
goto finish;
|
||||
|
||||
if (arg_commit)
|
||||
if (arg_commit) {
|
||||
r = machine_id_commit(arg_root);
|
||||
else
|
||||
r = machine_id_setup(arg_root, SD_ID128_NULL);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = sd_id128_get_machine(&id);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to read machine ID back: %m");
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
r = machine_id_setup(arg_root, SD_ID128_NULL, &id);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_print)
|
||||
puts(sd_id128_to_string(id, buf));
|
||||
|
||||
finish:
|
||||
free(arg_root);
|
||||
|
@ -181,7 +181,7 @@ int machine_save(Machine *m) {
|
||||
fprintf(f, "ROOT=%s\n", escaped);
|
||||
}
|
||||
|
||||
if (!sd_id128_equal(m->id, SD_ID128_NULL))
|
||||
if (!sd_id128_is_null(m->id))
|
||||
fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id));
|
||||
|
||||
if (m->leader != 0)
|
||||
|
@ -528,7 +528,7 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
|
||||
|
||||
fputs(strna(i->name), stdout);
|
||||
|
||||
if (!sd_id128_equal(i->id, SD_ID128_NULL))
|
||||
if (!sd_id128_is_null(i->id))
|
||||
printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
|
||||
else
|
||||
putchar('\n');
|
||||
|
@ -61,9 +61,9 @@
|
||||
#include "fs-util.h"
|
||||
#include "gpt.h"
|
||||
#include "hostname-util.h"
|
||||
#include "id128-util.h"
|
||||
#include "log.h"
|
||||
#include "loopback-setup.h"
|
||||
#include "machine-id-setup.h"
|
||||
#include "machine-image.h"
|
||||
#include "macro.h"
|
||||
#include "missing.h"
|
||||
@ -76,10 +76,10 @@
|
||||
#include "nspawn-network.h"
|
||||
#include "nspawn-patch-uid.h"
|
||||
#include "nspawn-register.h"
|
||||
#include "nspawn-seccomp.h"
|
||||
#include "nspawn-settings.h"
|
||||
#include "nspawn-setuid.h"
|
||||
#include "nspawn-stub-pid1.h"
|
||||
#include "nspawn-seccomp.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
@ -594,9 +594,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
case ARG_UUID:
|
||||
r = sd_id128_from_string(optarg, &arg_uuid);
|
||||
if (r < 0) {
|
||||
log_error("Invalid UUID: %s", optarg);
|
||||
return r;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Invalid UUID: %s", optarg);
|
||||
|
||||
if (sd_id128_is_null(arg_uuid)) {
|
||||
log_error("Machine UUID may not be all zeroes.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
arg_settings_mask |= SETTING_MACHINE_ID;
|
||||
@ -1266,20 +1269,9 @@ static int setup_resolv_conf(const char *dest) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char* id128_format_as_uuid(sd_id128_t id, char s[37]) {
|
||||
assert(s);
|
||||
|
||||
snprintf(s, 37,
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
SD_ID128_FORMAT_VAL(id));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static int setup_boot_id(const char *dest) {
|
||||
sd_id128_t rnd = SD_ID128_NULL;
|
||||
const char *from, *to;
|
||||
sd_id128_t rnd = {};
|
||||
char as_uuid[37];
|
||||
int r;
|
||||
|
||||
if (arg_share_system)
|
||||
@ -1295,18 +1287,16 @@ static int setup_boot_id(const char *dest) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate random boot id: %m");
|
||||
|
||||
id128_format_as_uuid(rnd, as_uuid);
|
||||
|
||||
r = write_string_file(from, as_uuid, WRITE_STRING_FILE_CREATE);
|
||||
r = id128_write(from, ID128_UUID, rnd, false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write boot id: %m");
|
||||
|
||||
if (mount(from, to, NULL, MS_BIND, NULL) < 0)
|
||||
r = log_error_errno(errno, "Failed to bind mount boot id: %m");
|
||||
else if (mount(NULL, to, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL) < 0)
|
||||
log_warning_errno(errno, "Failed to make boot id read-only: %m");
|
||||
log_warning_errno(errno, "Failed to make boot id read-only, ignoring: %m");
|
||||
|
||||
unlink(from);
|
||||
(void) unlink(from);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -2232,33 +2222,37 @@ static int mount_device(const char *what, const char *where, const char *directo
|
||||
}
|
||||
|
||||
static int setup_machine_id(const char *directory) {
|
||||
const char *etc_machine_id;
|
||||
sd_id128_t id;
|
||||
int r;
|
||||
const char *etc_machine_id, *t;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
|
||||
/* If the UUID in the container is already set, then that's what counts, and we use. If it isn't set, and the
|
||||
* caller passed --uuid=, then we'll pass it in the $container_uuid env var to PID 1 of the container. The
|
||||
* assumption is that PID 1 will then write it to /etc/machine-id to make it persistent. If --uuid= is not
|
||||
* passed we generate a random UUID, and pass it via $container_uuid. In effect this means that /etc/machine-id
|
||||
* in the container and our idea of the container UUID will always be in sync (at least if PID 1 in the
|
||||
* container behaves nicely). */
|
||||
|
||||
etc_machine_id = prefix_roota(directory, "/etc/machine-id");
|
||||
|
||||
r = read_one_line_file(etc_machine_id, &s);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read machine ID from %s: %m", etc_machine_id);
|
||||
r = id128_read(etc_machine_id, ID128_PLAIN, &id);
|
||||
if (r < 0) {
|
||||
if (!IN_SET(r, -ENOENT, -ENOMEDIUM)) /* If the file is missing or empty, we don't mind */
|
||||
return log_error_errno(r, "Failed to read machine ID from container image: %m");
|
||||
|
||||
t = strstrip(s);
|
||||
|
||||
if (!isempty(t)) {
|
||||
r = sd_id128_from_string(t, &arg_uuid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse machine ID from %s: %m", etc_machine_id);
|
||||
} else {
|
||||
if (sd_id128_is_null(arg_uuid)) {
|
||||
r = sd_id128_randomize(&arg_uuid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate random machine ID: %m");
|
||||
return log_error_errno(r, "Failed to acquire randomized machine UUID: %m");
|
||||
}
|
||||
} else {
|
||||
if (sd_id128_is_null(id)) {
|
||||
log_error("Machine ID in container image is zero, refusing.");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
r = machine_id_setup(directory, arg_uuid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to setup machine ID: %m");
|
||||
arg_uuid = id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2663,9 +2657,9 @@ static int inner_child(
|
||||
(asprintf((char**)(envp + n_env++), "LOGNAME=%s", arg_user ? arg_user : "root") < 0))
|
||||
return log_oom();
|
||||
|
||||
assert(!sd_id128_equal(arg_uuid, SD_ID128_NULL));
|
||||
assert(!sd_id128_is_null(arg_uuid));
|
||||
|
||||
if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_format_as_uuid(arg_uuid, as_uuid)) < 0)
|
||||
if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_to_uuid_string(arg_uuid, as_uuid)) < 0)
|
||||
return log_oom();
|
||||
|
||||
if (fdset_size(fds) > 0) {
|
||||
|
@ -3764,7 +3764,7 @@ static void print_status_info(
|
||||
|
||||
if (i->running) {
|
||||
_cleanup_free_ char *comm = NULL;
|
||||
get_process_comm(i->main_pid, &comm);
|
||||
(void) get_process_comm(i->main_pid, &comm);
|
||||
if (comm)
|
||||
printf(" (%s)", comm);
|
||||
} else if (i->exit_code > 0) {
|
||||
@ -3783,17 +3783,19 @@ static void print_status_info(
|
||||
printf("signal=%s", signal_to_string(i->exit_status));
|
||||
printf(")");
|
||||
}
|
||||
|
||||
if (i->control_pid > 0)
|
||||
printf(";");
|
||||
}
|
||||
|
||||
if (i->control_pid > 0) {
|
||||
_cleanup_free_ char *c = NULL;
|
||||
|
||||
printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
|
||||
if (i->main_pid > 0)
|
||||
fputs("; Control PID: ", stdout);
|
||||
else
|
||||
fputs("Cntrl PID: ", stdout); /* if first in column, abbreviated so it fits alignment */
|
||||
|
||||
get_process_comm(i->control_pid, &c);
|
||||
printf(PID_FMT, i->control_pid);
|
||||
|
||||
(void) get_process_comm(i->control_pid, &c);
|
||||
if (c)
|
||||
printf(" (%s)", c);
|
||||
}
|
||||
@ -3810,7 +3812,7 @@ static void print_status_info(
|
||||
printf(" Tasks: %" PRIu64, i->tasks_current);
|
||||
|
||||
if (i->tasks_max != (uint64_t) -1)
|
||||
printf(" (limit: %" PRIi64 ")\n", i->tasks_max);
|
||||
printf(" (limit: %" PRIu64 ")\n", i->tasks_max);
|
||||
else
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
#include "id128-util.h"
|
||||
|
||||
#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10)
|
||||
#define STR_WALDI "0102030405060708090a0b0c0d0e0f10"
|
||||
@ -33,7 +34,7 @@
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
sd_id128_t id, id2;
|
||||
char t[33];
|
||||
char t[33], q[37];
|
||||
_cleanup_free_ char *b = NULL;
|
||||
|
||||
assert_se(sd_id128_randomize(&id) == 0);
|
||||
@ -57,6 +58,17 @@ int main(int argc, char *argv[]) {
|
||||
printf("waldi2: %s\n", b);
|
||||
assert_se(streq(t, b));
|
||||
|
||||
printf("waldi3: %s\n", id128_to_uuid_string(ID128_WALDI, q));
|
||||
assert_se(streq(q, UUID_WALDI));
|
||||
|
||||
b = mfree(b);
|
||||
assert_se(asprintf(&b, ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 36);
|
||||
printf("waldi4: %s\n", b);
|
||||
assert_se(streq(q, b));
|
||||
|
||||
assert_se(sd_id128_from_string(STR_WALDI, &id) >= 0);
|
||||
assert_se(sd_id128_equal(id, ID128_WALDI));
|
||||
|
||||
assert_se(sd_id128_from_string(UUID_WALDI, &id) >= 0);
|
||||
assert_se(sd_id128_equal(id, ID128_WALDI));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user