1
0
mirror of https://github.com/systemd/systemd synced 2026-04-25 00:14:54 +02:00

Compare commits

..

No commits in common. "a2587faa723e4f5400df034965ba2b7377472de1" and "673d1f4ab9a6b685db6b52f3784711a662458763" have entirely different histories.

10 changed files with 67 additions and 200 deletions

View File

@ -1063,18 +1063,10 @@ static uint64_t cgroup_weight_io_to_blkio(uint64_t io_weight) {
CGROUP_BLKIO_WEIGHT_MIN, CGROUP_BLKIO_WEIGHT_MAX);
}
static int set_bfq_weight(Unit *u, const char *controller, dev_t dev, uint64_t io_weight) {
static const char * const prop_names[] = {
"IOWeight",
"BlockIOWeight",
"IODeviceWeight",
"BlockIODeviceWeight",
};
static bool warned = false;
char buf[DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+STRLEN("\n")];
static void set_bfq_weight(Unit *u, const char *controller, uint64_t io_weight) {
char buf[DECIMAL_STR_MAX(uint64_t)+STRLEN("\n")];
const char *p;
uint64_t bfq_weight;
int r;
/* FIXME: drop this function when distro kernels properly support BFQ through "io.weight"
* See also: https://github.com/systemd/systemd/pull/13335 and
@ -1083,50 +1075,25 @@ static int set_bfq_weight(Unit *u, const char *controller, dev_t dev, uint64_t i
/* Adjust to kernel range is 1..1000, the default is 100. */
bfq_weight = BFQ_WEIGHT(io_weight);
if (major(dev) > 0)
xsprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), bfq_weight);
else
xsprintf(buf, "%" PRIu64 "\n", bfq_weight);
xsprintf(buf, "%" PRIu64 "\n", bfq_weight);
r = cg_set_attribute(controller, u->cgroup_path, p, buf);
/* FIXME: drop this when kernels prior
* 795fe54c2a82 ("bfq: Add per-device weight") v5.4
* are not interesting anymore. Old kernels will fail with EINVAL, while new kernels won't return
* EINVAL on properly formatted input by us. Treat EINVAL accordingly. */
if (r == -EINVAL && major(dev) > 0) {
if (!warned) {
log_unit_warning(u, "Kernel version does not accept per-device setting in %s.", p);
warned = true;
}
r = -EOPNOTSUPP; /* mask as unconfigured device */
} else if (r >= 0 && io_weight != bfq_weight)
log_unit_debug(u, "%s=%" PRIu64 " scaled to %s=%" PRIu64,
prop_names[2*(major(dev) > 0) + streq(controller, "blkio")],
if (set_attribute_and_warn(u, controller, p, buf) >= 0 && io_weight != bfq_weight)
log_unit_debug(u, "%sIOWeight=%" PRIu64 " scaled to %s=%" PRIu64,
streq(controller, "blkio") ? "Block" : "",
io_weight, p, bfq_weight);
return r;
}
static void cgroup_apply_io_device_weight(Unit *u, const char *dev_path, uint64_t io_weight) {
char buf[DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1];
dev_t dev;
int r, r1, r2;
int r;
if (lookup_block_device(dev_path, &dev) < 0)
r = lookup_block_device(dev_path, &dev);
if (r < 0)
return;
r1 = set_bfq_weight(u, "io", dev, io_weight);
xsprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), io_weight);
r2 = cg_set_attribute("io", u->cgroup_path, "io.weight", buf);
/* Look at the configured device, when both fail, prefer io.weight errno. */
r = r2 == -EOPNOTSUPP ? r1 : r2;
if (r < 0)
log_unit_full_errno(u, LOG_LEVEL_CGROUP_WRITE(r),
r, "Failed to set 'io[.bfq].weight' attribute on '%s' to '%.*s': %m",
empty_to_root(u->cgroup_path), (int) strcspn(buf, NEWLINE), buf);
(void) set_attribute_and_warn(u, "io", "io.weight", buf);
}
static void cgroup_apply_blkio_device_weight(Unit *u, const char *dev_path, uint64_t blkio_weight) {
@ -1331,7 +1298,7 @@ static void set_io_weight(Unit *u, uint64_t weight) {
assert(u);
(void) set_bfq_weight(u, "io", makedev(0, 0), weight);
set_bfq_weight(u, "io", weight);
xsprintf(buf, "default %" PRIu64 "\n", weight);
(void) set_attribute_and_warn(u, "io", "io.weight", buf);
@ -1342,7 +1309,7 @@ static void set_blkio_weight(Unit *u, uint64_t weight) {
assert(u);
(void) set_bfq_weight(u, "blkio", makedev(0, 0), weight);
set_bfq_weight(u, "blkio", weight);
xsprintf(buf, "%" PRIu64 "\n", weight);
(void) set_attribute_and_warn(u, "blkio", "blkio.weight", buf);

View File

@ -1216,7 +1216,7 @@ static int mount_image(const MountEntry *m, const char *root_directory) {
}
r = verity_dissect_and_mount(
/* src_fd= */ -1, mount_entry_source(m), mount_entry_path(m), m->image_options,
mount_entry_source(m), mount_entry_path(m), m->image_options,
host_os_release_id, host_os_release_version_id, host_os_release_sysext_level, NULL);
if (r == -ENOENT && m->ignore)
return 0;

View File

@ -1181,7 +1181,6 @@ static int find_matching_component(
static int tm_within_bounds(struct tm *tm, bool utc) {
struct tm t;
int cmp;
assert(tm);
/*
@ -1196,25 +1195,13 @@ static int tm_within_bounds(struct tm *tm, bool utc) {
if (mktime_or_timegm(&t, utc) < 0)
return negative_errno();
/*
* Did any normalization take place? If so, it was out of bounds before.
* Normalization could skip next elapse, e.g. result of normalizing 3-33
* is 4-2. This skips 4-1. So reset the sub time unit if upper unit was
* out of bounds. Normalization has occurred implies find_matching_component() > 0,
* other sub time units are already reset in find_next().
*/
if ((cmp = CMP(t.tm_year, tm->tm_year)) != 0)
t.tm_mon = 0;
else if ((cmp = CMP(t.tm_mon, tm->tm_mon)) != 0)
t.tm_mday = 1;
else if ((cmp = CMP(t.tm_mday, tm->tm_mday)) != 0)
t.tm_hour = 0;
else if ((cmp = CMP(t.tm_hour, tm->tm_hour)) != 0)
t.tm_min = 0;
else if ((cmp = CMP(t.tm_min, tm->tm_min)) != 0)
t.tm_sec = 0;
else
cmp = CMP(t.tm_sec, tm->tm_sec);
/* Did any normalization take place? If so, it was out of bounds before */
int cmp = CMP(t.tm_year, tm->tm_year) ?:
CMP(t.tm_mon, tm->tm_mon) ?:
CMP(t.tm_mday, tm->tm_mday) ?:
CMP(t.tm_hour, tm->tm_hour) ?:
CMP(t.tm_min, tm->tm_min) ?:
CMP(t.tm_sec, tm->tm_sec);
if (cmp < 0)
return -EDEADLK; /* Refuse to go backward */

View File

@ -92,21 +92,21 @@ int probe_filesystem(const char *node, char **ret_fstype) {
errno = 0;
r = blkid_do_safeprobe(b);
if (r == 1)
if (r == 1) {
log_debug("No type detected on partition %s", node);
goto not_found;
}
if (r == -2)
return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
"Results ambiguous for partition %s", node);
if (r != 0)
return log_debug_errno(errno_or_else(EIO), "Failed to probe partition %s: %m", node);
return errno_or_else(EIO);
(void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
if (fstype) {
char *t;
log_debug("Probed fstype '%s' on partition %s.", fstype, node);
t = strdup(fstype);
if (!t)
return -ENOMEM;
@ -116,7 +116,6 @@ int probe_filesystem(const char *node, char **ret_fstype) {
}
not_found:
log_debug("No type detected on partition %s", node);
*ret_fstype = NULL;
return 0;
#else
@ -3449,7 +3448,6 @@ static const char *const partition_designator_table[] = {
};
int verity_dissect_and_mount(
int src_fd,
const char *src,
const char *dest,
const MountOptions *options,
@ -3468,17 +3466,14 @@ int verity_dissect_and_mount(
assert(src);
assert(dest);
/* We might get an FD for the image, but we use the original path to look for the dm-verity files */
r = verity_settings_load(&verity, src, NULL, NULL);
if (r < 0)
return log_debug_errno(r, "Failed to load root hash: %m");
dissect_image_flags = verity.data_path ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0;
/* Note that we don't use loop_device_make here, as the FD is most likely O_PATH which would not be
* accepted by LOOP_CONFIGURE, so just let loop_device_make_by_path reopen it as a regular FD. */
r = loop_device_make_by_path(
src_fd >= 0 ? FORMAT_PROC_FD_PATH(src_fd) : src,
src,
-1,
verity.data_path ? 0 : LO_FLAGS_PARTSCAN,
&loop_device);

View File

@ -285,4 +285,4 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image);
int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, const MountOptions *options, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_sysext_scope);
int verity_dissect_and_mount(const char *src, const char *dest, const MountOptions *options, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_sysext_scope);

View File

@ -62,7 +62,9 @@ static int get_current_uevent_seqnum(uint64_t *ret) {
if (r < 0)
return log_debug_errno(r, "Failed to read current uevent sequence number: %m");
r = safe_atou64(strstrip(p), ret);
truncate_nl(p);
r = safe_atou64(p, ret);
if (r < 0)
return log_debug_errno(r, "Failed to parse current uevent sequence number: %s", p);
@ -71,7 +73,7 @@ static int get_current_uevent_seqnum(uint64_t *ret) {
static int device_has_block_children(sd_device *d) {
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
const char *main_ss, *main_dt;
const char *main_sn, *main_ss;
sd_device *q;
int r;
@ -80,6 +82,10 @@ static int device_has_block_children(sd_device *d) {
/* Checks if the specified device currently has block device children (i.e. partition block
* devices). */
r = sd_device_get_sysname(d, &main_sn);
if (r < 0)
return r;
r = sd_device_get_subsystem(d, &main_ss);
if (r < 0)
return r;
@ -87,13 +93,6 @@ static int device_has_block_children(sd_device *d) {
if (!streq(main_ss, "block"))
return -EINVAL;
r = sd_device_get_devtype(d, &main_dt);
if (r < 0)
return r;
if (!streq(main_dt, "disk")) /* Refuse invocation on partition block device, insist on "whole" device */
return -EINVAL;
r = sd_device_enumerator_new(&e);
if (r < 0)
return r;
@ -107,34 +106,26 @@ static int device_has_block_children(sd_device *d) {
return r;
FOREACH_DEVICE(e, q) {
const char *ss, *dt;
const char *ss, *sn;
r = sd_device_get_subsystem(q, &ss);
if (r < 0) {
log_device_debug_errno(q, r, "Failed to get subsystem of child, ignoring: %m");
if (r < 0)
continue;
}
if (!streq(ss, "block")) {
log_device_debug(q, "Skipping child that is not a block device (subsystem=%s).", ss);
if (!streq(ss, "block"))
continue;
}
r = sd_device_get_devtype(q, &dt);
if (r < 0) {
log_device_debug_errno(q, r, "Failed to get devtype of child, ignoring: %m");
r = sd_device_get_sysname(q, &sn);
if (r < 0)
continue;
}
if (!streq(dt, "partition")) {
log_device_debug(q, "Skipping non-partition child (devtype=%s).", dt);
if (streq(sn, main_sn))
continue;
}
return true; /* we have block device children */
return 1; /* we have block device children */
}
return false;
return 0;
}
static int loop_configure(
@ -514,17 +505,6 @@ static int loop_device_make_internal(
for (unsigned n_attempts = 0;;) {
_cleanup_close_ int loop = -1;
/* Let's take a lock on the control device first. On a busy system, where many programs
* attempt to allocate a loopback device at the same time, we might otherwise keep looping
* around relatively heavy operations: asking for a free loopback device, then opening it,
* validating it, attaching something to it. Let's serialize this whole operation, to make
* unnecessary busywork less likely. Note that this is just something we do to optimize our
* own code (and whoever else decides to use LOCK_EX locks for this), taking this lock is not
* necessary, it just means it's less likely we have to iterate through this loop again and
* again if our own code races against our own code. */
if (flock(control, LOCK_EX) < 0)
return -errno;
nr = ioctl(control, LOOP_CTL_GET_FREE);
if (nr < 0)
return -errno;
@ -536,7 +516,7 @@ static int loop_device_make_internal(
if (loop < 0) {
/* Somebody might've gotten the same number from the kernel, used the device,
* and called LOOP_CTL_REMOVE on it. Let's retry with a new number. */
if (!ERRNO_IS_DEVICE_ABSENT(errno))
if (!IN_SET(errno, ENOENT, ENXIO))
return -errno;
} else {
r = loop_configure(loop, nr, &config, &try_loop_configure, &seqnum, &timestamp);
@ -553,17 +533,9 @@ static int loop_device_make_internal(
return r;
}
/* OK, this didn't work, let's try again a bit later, but first release the lock on the
* control device */
if (flock(control, LOCK_UN) < 0)
return -errno;
if (++n_attempts >= 64) /* Give up eventually */
return -EBUSY;
/* Now close the loop device explicitly. This will release any lock acquired by
* attach_empty_file() or similar, while we sleep below. */
loop = safe_close(loop);
loopdev = mfree(loopdev);
/* Wait some random time, to make collision less likely. Let's pick a random time in the
@ -616,12 +588,6 @@ static int loop_device_make_internal(
.timestamp_not_before = timestamp,
};
log_debug("Successfully acquired %s, devno=%u:%u, nr=%i, diskseq=%" PRIu64,
d->node,
major(d->devno), minor(d->devno),
d->nr,
d->diskseq);
*ret = d;
return d->fd;
}

View File

@ -789,7 +789,6 @@ static int mount_in_namespace(
bool mount_slave_created = false, mount_slave_mounted = false,
mount_tmp_created = false, mount_tmp_mounted = false,
mount_outside_created = false, mount_outside_mounted = false;
_cleanup_free_ char *chased_src_path = NULL;
struct stat st, self_mntns_st;
pid_t child;
int r;
@ -827,10 +826,9 @@ static int mount_in_namespace(
if (r < 0)
return log_debug_errno(r == -ENOENT ? SYNTHETIC_ERRNO(EOPNOTSUPP) : r, "Target does not allow propagation of mount points");
r = chase_symlinks(src, NULL, 0, &chased_src_path, &chased_src_fd);
r = chase_symlinks(src, NULL, CHASE_TRAIL_SLASH, NULL, &chased_src_fd);
if (r < 0)
return log_debug_errno(r, "Failed to resolve source path of %s: %m", src);
log_debug("Chased source path of %s to %s", src, chased_src_path);
if (fstat(chased_src_fd, &st) < 0)
return log_debug_errno(errno, "Failed to stat() resolved source path %s: %m", src);
@ -875,7 +873,7 @@ static int mount_in_namespace(
mount_tmp_created = true;
if (is_image)
r = verity_dissect_and_mount(chased_src_fd, chased_src_path, mount_tmp, options, NULL, NULL, NULL, NULL);
r = verity_dissect_and_mount(FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, options, NULL, NULL, NULL, NULL);
else
r = mount_follow_verbose(LOG_DEBUG, FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, NULL, MS_BIND, NULL);
if (r < 0)

View File

@ -199,8 +199,6 @@ TEST(calendar_spec_next) {
test_next("2016-02~01 UTC", "", 12345, 1456704000000000);
test_next("Mon 2017-05~01..07 UTC", "", 12345, 1496016000000000);
test_next("Mon 2017-05~07/1 UTC", "", 12345, 1496016000000000);
test_next("*-*-01/5 04:00:00 UTC", "", 1646010000000000, 1646107200000000);
test_next("*-01/7-01 04:00:00 UTC", "", 1664607600000000, 1672545600000000);
test_next("2017-08-06 9,11,13,15,17:00 UTC", "", 1502029800000000, 1502031600000000);
test_next("2017-08-06 9..17/2:00 UTC", "", 1502029800000000, 1502031600000000);
test_next("2016-12-* 3..21/6:00 UTC", "", 1482613200000001, 1482634800000000);

View File

@ -10,12 +10,10 @@
#include "fileio.h"
#include "fs-util.h"
#include "gpt.h"
#include "main-func.h"
#include "missing_loop.h"
#include "mkfs-util.h"
#include "mount-util.h"
#include "namespace-util.h"
#include "parse-util.h"
#include "string-util.h"
#include "strv.h"
#include "tests.h"
@ -23,18 +21,16 @@
#include "user-util.h"
#include "virt.h"
static unsigned arg_n_threads = 5;
static unsigned arg_n_iterations = 3;
static usec_t arg_timeout = 0;
#define N_THREADS 5
#define N_ITERATIONS 3
#if HAVE_BLKID
static usec_t end = 0;
static void* thread_func(void *ptr) {
int fd = PTR_TO_FD(ptr);
int r;
for (unsigned i = 0; i < arg_n_iterations; i++) {
for (unsigned i = 0; i < N_ITERATIONS; i++) {
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
_cleanup_(umount_and_rmdir_and_freep) char *mounted = NULL;
_cleanup_(dissected_image_unrefp) DissectedImage *dissected = NULL;
@ -101,7 +97,6 @@ static void* thread_func(void *ptr) {
return NULL;
}
#endif
static bool have_root_gpt_type(void) {
#ifdef GPT_ROOT_NATIVE
@ -111,42 +106,20 @@ static bool have_root_gpt_type(void) {
#endif
}
static int run(int argc, char *argv[]) {
int main(int argc, char *argv[]) {
_cleanup_free_ char *p = NULL, *cmd = NULL;
_cleanup_(pclosep) FILE *sfdisk = NULL;
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
_cleanup_close_ int fd = -1;
_cleanup_(dissected_image_unrefp) DissectedImage *dissected = NULL;
_cleanup_(umount_and_rmdir_and_freep) char *mounted = NULL;
pthread_t threads[N_THREADS];
sd_id128_t id;
int r;
test_setup_logging(LOG_DEBUG);
log_show_tid(true);
log_show_time(true);
log_show_color(true);
if (argc >= 2) {
r = safe_atou(argv[1], &arg_n_threads);
if (r < 0)
return log_error_errno(r, "Failed to parse first argument (number of threads): %s", argv[1]);
if (arg_n_threads <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Number of threads must be at least 1, refusing.");
}
if (argc >= 3) {
r = safe_atou(argv[2], &arg_n_iterations);
if (r < 0)
return log_error_errno(r, "Failed to parse second argument (number of iterations): %s", argv[2]);
if (arg_n_iterations <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Number of iterations must be at least 1, refusing.");
}
if (argc >= 4) {
r = parse_sec(argv[3], &arg_timeout);
if (r < 0)
return log_error_errno(r, "Failed to parse third argument (timeout): %s", argv[3]);
}
if (argc >= 5)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too many arguments (expected 3 at max).");
if (!have_root_gpt_type()) {
log_tests_skipped("No root partition GPT defined for this architecture, exiting.");
@ -214,13 +187,6 @@ static int run(int argc, char *argv[]) {
sfdisk = NULL;
assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, LO_FLAGS_PARTSCAN, &loop) >= 0);
#if HAVE_BLKID
_cleanup_(dissected_image_unrefp) DissectedImage *dissected = NULL;
_cleanup_(umount_and_rmdir_and_freep) char *mounted = NULL;
pthread_t threads[arg_n_threads];
sd_id128_t id;
assert_se(dissect_image(loop->fd, NULL, NULL, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
assert_se(dissected->partitions[PARTITION_ESP].found);
@ -257,37 +223,27 @@ static int run(int argc, char *argv[]) {
log_notice("Threads are being started now");
/* zero timeout means pick default: let's make sure we run for 10s on slow systems at max */
if (arg_timeout == 0)
arg_timeout = slow_tests_enabled() ? 5 * USEC_PER_SEC : 1 * USEC_PER_SEC;
/* Let's make sure we run for 10s on slow systems at max */
end = usec_add(now(CLOCK_MONOTONIC),
slow_tests_enabled() ? 5 * USEC_PER_SEC :
1 * USEC_PER_SEC);
end = usec_add(now(CLOCK_MONOTONIC), arg_timeout);
if (arg_n_threads > 1)
for (unsigned i = 0; i < arg_n_threads; i++)
assert_se(pthread_create(threads + i, NULL, thread_func, FD_TO_PTR(fd)) == 0);
for (unsigned i = 0; i < N_THREADS; i++)
assert_se(pthread_create(threads + i, NULL, thread_func, FD_TO_PTR(fd)) == 0);
log_notice("All threads started now.");
if (arg_n_threads == 1)
assert_se(thread_func(FD_TO_PTR(fd)) == NULL);
else
for (unsigned i = 0; i < arg_n_threads; i++) {
log_notice("Joining thread #%u.", i);
for (unsigned i = 0; i < N_THREADS; i++) {
log_notice("Joining thread #%u.", i);
void *k;
assert_se(pthread_join(threads[i], &k) == 0);
assert_se(k == NULL);
void *k;
assert_se(pthread_join(threads[i], &k) == 0);
assert_se(k == NULL);
log_notice("Joined thread #%u.", i);
}
log_notice("Joined thread #%u.", i);
}
log_notice("Threads are all terminated now.");
#else
log_notice("Cutting test short, since we do not have libblkid.");
#endif
return 0;
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);

View File

@ -285,7 +285,7 @@ Type=notify
RemainAfterExit=yes
MountAPIVFS=yes
PrivateTmp=yes
ExecStart=/bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do sleep 0.1; done; mount | grep -F "/dev/mapper/${roothash}-verity" | grep -q -F "nosuid"'
ExecStart=/bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do sleep 0.1; done; mount | grep -F "/tmp/img" | grep -q -F "nosuid"'
EOF
systemctl start testservice-50d.service