1
0
mirror of https://github.com/systemd/systemd synced 2026-03-18 19:14:46 +01:00

Compare commits

..

No commits in common. "756755d0fc5a0ef380416a54346b6438c3fb7ba5" and "cc815b7fea0ade5331e8dd22ef6b5183edb77608" have entirely different histories.

3 changed files with 61 additions and 100 deletions

36
TODO
View File

@ -49,6 +49,11 @@ Features:
* nspawn: make --bind= work sanely with --private-users when uid mapping mounts * nspawn: make --bind= work sanely with --private-users when uid mapping mounts
are used. are used.
* cryptsetup: tweak tpm2-device=auto logic, abort quickly if firmware tells us
there isn't any TPM2 device anyway. that way, we'll wait for the TPM2 device
to show up only if registered in LUKS header + the firmware suggests there is
a device worth waiting for.
* systemd-sysext: optionally, run it in initrd already, before transitioning * systemd-sysext: optionally, run it in initrd already, before transitioning
into host, to open up possibility for services shipped like that. into host, to open up possibility for services shipped like that.
@ -97,6 +102,20 @@ Features:
* move multiseat vid/pid matches from logind udev rule to hwdb * move multiseat vid/pid matches from logind udev rule to hwdb
* nspawn: default to 1:1 userns
* Provide a reasonably bespoke solution for mounting host $HOME directories
into containers:
• add new option --mount-user=$USER for mounting $HOME of the user into the
container at the same place
• check /etc/passwd for UID or user name clashes. If UID clash pick a different
UID in container, and map via userns. If user name clash, refuse. If
matching user already exists use that.
• otherwise: write user record of specified user into /run/host/passwd or so
• in nss-systemd pick up user record from there and make available to system
With all that in place if nspawn host and container payload are up-to-date
enough we have a very simple way to make host users available in containers.
* whenever we receive fds via SCM_RIGHTS make sure none got dropped due to the * whenever we receive fds via SCM_RIGHTS make sure none got dropped due to the
reception limit the kernel silently enforces. reception limit the kernel silently enforces.
@ -223,6 +242,8 @@ Features:
* homed: keep an fd to the homedir open at all times, to keep the fs pinned * homed: keep an fd to the homedir open at all times, to keep the fs pinned
(autofs and such) while user is logged in. (autofs and such) while user is logged in.
* nss-systemd: also synthesize shadow records for users/groups
* make use of new glibc 2.32 APIs sigabbrev_np() and strerrorname_np(). * make use of new glibc 2.32 APIs sigabbrev_np() and strerrorname_np().
* when main nspawn supervisor process gets suspended due to SIGSTOP/SIGTTOU or * when main nspawn supervisor process gets suspended due to SIGSTOP/SIGTTOU or
@ -435,6 +456,9 @@ Features:
shouldn't operate in a volatile mode unless we got told so from a trusted shouldn't operate in a volatile mode unless we got told so from a trusted
source. source.
* figure out automatic partition discovery when combining writable root dir
with immutable /usr
* coredump: maybe when coredumping read a new xattr from /proc/$PID/exe that * coredump: maybe when coredumping read a new xattr from /proc/$PID/exe that
may be used to mark a whole binary as non-coredumpable. Would fix: may be used to mark a whole binary as non-coredumpable. Would fix:
https://bugs.freedesktop.org/show_bug.cgi?id=69447 https://bugs.freedesktop.org/show_bug.cgi?id=69447
@ -555,6 +579,10 @@ Features:
a seccomp option we don't have to set NNP. For that, change uid first whil a seccomp option we don't have to set NNP. For that, change uid first whil
keeping CAP_SYS_ADMIN, then apply seccomp, the drop cap. keeping CAP_SYS_ADMIN, then apply seccomp, the drop cap.
* add a concept for automatically loading per-unit secrets off disk and
inserting them into the kernel keyring. Maybe SecretsDirectory= similar to
ConfigurationDirectory=.
* when no locale is configured, default to UEFI's PlatformLang variable * when no locale is configured, default to UEFI's PlatformLang variable
* bootctl,sd-boot: actually honour the "architecture" key * bootctl,sd-boot: actually honour the "architecture" key
@ -607,6 +635,13 @@ Features:
output of "systemctl list-units" slightly by showing the tree structure of output of "systemctl list-units" slightly by showing the tree structure of
the slices, and the units attached to them. the slices, and the units attached to them.
* the a-posteriori stopping of units bound to units that disappeared logic
should be reworked: there should be a queue of units, and we should only
enqueue stop jobs from a defer event that processes queue instead of
right-away when we find a unit that is bound to one that doesn't exist
anymore. (similar to how the stop-unneeded queue has been reworked the same
way)
* nspawn: make nspawn suitable for shell pipelines: instead of triggering a * nspawn: make nspawn suitable for shell pipelines: instead of triggering a
hangup when input is finished, send ^D, which synthesizes an EOF. Then wait hangup when input is finished, send ^D, which synthesizes an EOF. Then wait
for hangup or ^D before passing on the EOF. for hangup or ^D before passing on the EOF.
@ -1368,6 +1403,7 @@ Features:
https://bugzilla.redhat.com/show_bug.cgi?id=723942 https://bugzilla.redhat.com/show_bug.cgi?id=723942
- allow writing multiple conditions in unit files on one line - allow writing multiple conditions in unit files on one line
- introduce Type=pid-file - introduce Type=pid-file
- introduce mix of BindTo and Requisite
- add a concept of RemainAfterExit= to scope units - add a concept of RemainAfterExit= to scope units
- Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely - Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely
- add verification of [Install] section to systemd-analyze verify - add verification of [Install] section to systemd-analyze verify

View File

@ -143,37 +143,18 @@ layout: default
## Using C Constructs ## Using C Constructs
- Allocate local variables where it makes sense: at the top of the block, or at - Preferably allocate local variables on the top of the block:
the point where they can be initialized. `r` is typically used for a local
state variable, but should almost always be declared at the top of the
function.
```c ```c
{ {
uint64_t a, b; int a, b;
int r;
a = frobnicate(); a = 5;
b = a + 5; b = a;
r = do_something();
if (r < 0)
} }
``` ```
- Do not mix function invocations with variable definitions in one line. - Do not mix function invocations with variable definitions in one line. Wrong:
```c
{
uint64_t x = 7;
int a;
a = foobar();
}
```
instead of:
```c ```c
{ {
@ -182,7 +163,18 @@ layout: default
} }
``` ```
- Use `goto` for cleaning up, and only use it for that. I.e. you may only jump Right:
```c
{
int a;
uint64_t x = 7;
a = foobar();
}
```
- Use `goto` for cleaning up, and only use it for that. i.e. you may only jump
to the end of a function, and little else. Never jump backwards! to the end of a function, and little else. Never jump backwards!
- To minimize strict aliasing violations, we prefer unions over casting. - To minimize strict aliasing violations, we prefer unions over casting.
@ -355,7 +347,8 @@ layout: default
`log_oom()` for then printing a short message, but not in "library" code. `log_oom()` for then printing a short message, but not in "library" code.
- Avoid fixed-size string buffers, unless you really know the maximum size and - Avoid fixed-size string buffers, unless you really know the maximum size and
that maximum size is small. It is often nicer to use dynamic memory, that maximum size is small. They are a source of errors, since they possibly
result in truncated strings. It is often nicer to use dynamic memory,
`alloca()` or VLAs. If you do allocate fixed-size strings on the stack, then `alloca()` or VLAs. If you do allocate fixed-size strings on the stack, then
it is probably only OK if you either use a maximum size such as `LINE_MAX`, it is probably only OK if you either use a maximum size such as `LINE_MAX`,
or count in detail the maximum size a string can have. (`DECIMAL_STR_MAX` and or count in detail the maximum size a string can have. (`DECIMAL_STR_MAX` and

View File

@ -6,14 +6,12 @@
#include <unistd.h> #include <unistd.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "errno-list.h"
#include "fd-util.h" #include "fd-util.h"
#include "macro.h" #include "macro.h"
#include "mountpoint-util.h" #include "mountpoint-util.h"
#include "namespace-util.h" #include "namespace-util.h"
#include "path-util.h" #include "path-util.h"
#include "stat-util.h" #include "stat-util.h"
#include "tests.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
static void test_files_same(void) { static void test_files_same(void) {
@ -21,8 +19,6 @@ static void test_files_same(void) {
char name[] = "/tmp/test-files_same.XXXXXX"; char name[] = "/tmp/test-files_same.XXXXXX";
char name_alias[] = "/tmp/test-files_same.alias"; char name_alias[] = "/tmp/test-files_same.alias";
log_info("/* %s */", __func__);
fd = mkostemp_safe(name); fd = mkostemp_safe(name);
assert_se(fd >= 0); assert_se(fd >= 0);
assert_se(symlink(name, name_alias) >= 0); assert_se(symlink(name, name_alias) >= 0);
@ -41,8 +37,6 @@ static void test_is_symlink(void) {
char name_link[] = "/tmp/test-is_symlink.link"; char name_link[] = "/tmp/test-is_symlink.link";
_cleanup_close_ int fd = -1; _cleanup_close_ int fd = -1;
log_info("/* %s */", __func__);
fd = mkostemp_safe(name); fd = mkostemp_safe(name);
assert_se(fd >= 0); assert_se(fd >= 0);
assert_se(symlink(name, name_link) >= 0); assert_se(symlink(name, name_link) >= 0);
@ -56,33 +50,17 @@ static void test_is_symlink(void) {
} }
static void test_path_is_fs_type(void) { static void test_path_is_fs_type(void) {
log_info("/* %s */", __func__);
/* run might not be a mount point in build chroots */ /* run might not be a mount point in build chroots */
if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) { if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) {
assert_se(path_is_fs_type("/run", TMPFS_MAGIC) > 0); assert_se(path_is_fs_type("/run", TMPFS_MAGIC) > 0);
assert_se(path_is_fs_type("/run", BTRFS_SUPER_MAGIC) == 0); assert_se(path_is_fs_type("/run", BTRFS_SUPER_MAGIC) == 0);
} }
if (path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0) {
assert_se(path_is_fs_type("/proc", PROC_SUPER_MAGIC) > 0); assert_se(path_is_fs_type("/proc", PROC_SUPER_MAGIC) > 0);
assert_se(path_is_fs_type("/proc", BTRFS_SUPER_MAGIC) == 0); assert_se(path_is_fs_type("/proc", BTRFS_SUPER_MAGIC) == 0);
}
assert_se(path_is_fs_type("/i-dont-exist", BTRFS_SUPER_MAGIC) == -ENOENT); assert_se(path_is_fs_type("/i-dont-exist", BTRFS_SUPER_MAGIC) == -ENOENT);
} }
static void test_path_is_temporary_fs(void) { static void test_path_is_temporary_fs(void) {
const char *s;
int r;
log_info("/* %s */", __func__);
FOREACH_STRING(s, "/", "/run", "/sys", "/sys/", "/proc", "/i-dont-exist", "/var", "/var/lib") {
r = path_is_temporary_fs(s);
log_info_errno(r, "path_is_temporary_fs(\"%s\"): %d, %s",
s, r, r < 0 ? errno_to_name(r) : yes_no(r));
}
/* run might not be a mount point in build chroots */ /* run might not be a mount point in build chroots */
if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0)
assert_se(path_is_temporary_fs("/run") > 0); assert_se(path_is_temporary_fs("/run") > 0);
@ -90,42 +68,13 @@ static void test_path_is_temporary_fs(void) {
assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT); assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT);
} }
static void test_path_is_read_only_fs(void) {
const char *s;
int r;
log_info("/* %s */", __func__);
FOREACH_STRING(s, "/", "/run", "/sys", "/sys/", "/proc", "/i-dont-exist", "/var", "/var/lib") {
r = path_is_read_only_fs(s);
log_info_errno(r, "path_is_read_only_fs(\"%s\"): %d, %s",
s, r, r < 0 ? errno_to_name(r) : yes_no(r));
}
if (path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0)
assert_se(IN_SET(path_is_read_only_fs("/sys"), 0, 1));
assert_se(path_is_read_only_fs("/proc") == 0);
assert_se(path_is_read_only_fs("/i-dont-exist") == -ENOENT);
}
static void test_fd_is_ns(void) { static void test_fd_is_ns(void) {
_cleanup_close_ int fd = -1; _cleanup_close_ int fd = -1;
log_info("/* %s */", __func__);
assert_se(fd_is_ns(STDIN_FILENO, CLONE_NEWNET) == 0); assert_se(fd_is_ns(STDIN_FILENO, CLONE_NEWNET) == 0);
assert_se(fd_is_ns(STDERR_FILENO, CLONE_NEWNET) == 0); assert_se(fd_is_ns(STDERR_FILENO, CLONE_NEWNET) == 0);
assert_se(fd_is_ns(STDOUT_FILENO, CLONE_NEWNET) == 0); assert_se(fd_is_ns(STDOUT_FILENO, CLONE_NEWNET) == 0);
fd = open("/proc/self/ns/mnt", O_CLOEXEC|O_RDONLY); assert_se((fd = open("/proc/self/ns/mnt", O_CLOEXEC|O_RDONLY)) >= 0);
if (fd < 0) {
assert_se(errno == ENOENT);
log_notice("Path %s not found, skipping test", "/proc/self/ns/mnt");
return;
}
assert_se(fd >= 0);
assert_se(IN_SET(fd_is_ns(fd, CLONE_NEWNET), 0, -EUCLEAN)); assert_se(IN_SET(fd_is_ns(fd, CLONE_NEWNET), 0, -EUCLEAN));
fd = safe_close(fd); fd = safe_close(fd);
@ -138,8 +87,6 @@ static void test_fd_is_ns(void) {
} }
static void test_device_major_minor_valid(void) { static void test_device_major_minor_valid(void) {
log_info("/* %s */", __func__);
/* on glibc dev_t is 64bit, even though in the kernel it is only 32bit */ /* on glibc dev_t is 64bit, even though in the kernel it is only 32bit */
assert_cc(sizeof(dev_t) == sizeof(uint64_t)); assert_cc(sizeof(dev_t) == sizeof(uint64_t));
@ -181,21 +128,11 @@ static void test_device_path_make_canonical_one(const char *path) {
mode_t mode; mode_t mode;
int r; int r;
log_debug("> %s", path); assert_se(stat(path, &st) >= 0);
if (stat(path, &st) < 0) {
assert(errno == ENOENT);
log_notice("Path %s not found, skipping test", path);
return;
}
r = device_path_make_canonical(st.st_mode, st.st_rdev, &resolved); r = device_path_make_canonical(st.st_mode, st.st_rdev, &resolved);
if (r == -ENOENT) { if (r == -ENOENT) /* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we
/* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we
* run in a container or so? */ * run in a container or so? */
log_notice("Device %s cannot be resolved, skipping test", path);
return; return;
}
assert_se(r >= 0); assert_se(r >= 0);
assert_se(path_equal(path, resolved)); assert_se(path_equal(path, resolved));
@ -208,7 +145,6 @@ static void test_device_path_make_canonical_one(const char *path) {
} }
static void test_device_path_make_canonical(void) { static void test_device_path_make_canonical(void) {
log_info("/* %s */", __func__);
test_device_path_make_canonical_one("/dev/null"); test_device_path_make_canonical_one("/dev/null");
test_device_path_make_canonical_one("/dev/zero"); test_device_path_make_canonical_one("/dev/zero");
@ -224,14 +160,10 @@ static void test_device_path_make_canonical(void) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
log_show_color(true);
test_setup_logging(LOG_INFO);
test_files_same(); test_files_same();
test_is_symlink(); test_is_symlink();
test_path_is_fs_type(); test_path_is_fs_type();
test_path_is_temporary_fs(); test_path_is_temporary_fs();
test_path_is_read_only_fs();
test_fd_is_ns(); test_fd_is_ns();
test_device_major_minor_valid(); test_device_major_minor_valid();
test_device_path_make_canonical(); test_device_path_make_canonical();