mirror of
https://git.proxmox.com/git/systemd
synced 2026-01-04 19:46:01 +00:00
New upstream version 250.2
This commit is contained in:
parent
ea68745f2f
commit
36ceca0325
3
TODO
3
TODO
@ -4,9 +4,6 @@ Bugfixes:
|
||||
manager or system manager can be always set. It would be better to reject
|
||||
them when parsing config.
|
||||
|
||||
* userdbctl: "Password OK: yes" is shown even when there are no passwords
|
||||
or the password is locked.
|
||||
|
||||
* Jun 01 09:43:02 krowka systemd[1]: Unit user@1000.service has alias user@.service.
|
||||
Jun 01 09:43:02 krowka systemd[1]: Unit user@6.service has alias user@.service.
|
||||
Jun 01 09:43:02 krowka systemd[1]: Unit user-runtime-dir@6.service has alias user-runtime-dir@.service.
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
# Total Phase
|
||||
###########################################################
|
||||
# Aarvark I2C/SPI Host Adapter
|
||||
usb:v0403pe0d0*
|
||||
usb:v0403pE0D0*
|
||||
ID_SIGNAL_ANALYZER=1
|
||||
|
||||
# Beagle Protocol Analyzers
|
||||
@ -29,5 +29,16 @@ usb:v1679p3001*
|
||||
|
||||
# Power Delivery Analyzers
|
||||
usb:v1679p6003*
|
||||
usb:v0483pdf11*
|
||||
usb:v0483pDF11*
|
||||
ID_SIGNAL_ANALYZER=1
|
||||
|
||||
###########################################################
|
||||
# XGecu
|
||||
###########################################################
|
||||
# TL866A/CS
|
||||
usb:v04D8pE11C*
|
||||
ID_SIGNAL_ANALYZER=1
|
||||
|
||||
# TL866II+
|
||||
usb:vA466p0A53*
|
||||
ID_SIGNAL_ANALYZER=1
|
||||
|
||||
@ -212,21 +212,23 @@ def check_matches(groups):
|
||||
|
||||
# This is a partial check. The other cases could be also done, but those
|
||||
# two are most commonly wrong.
|
||||
grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4)),
|
||||
'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8)),
|
||||
grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*',
|
||||
'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*',
|
||||
}
|
||||
|
||||
for match in matches:
|
||||
prefix, rest = match.split(':', maxsplit=1)
|
||||
gr = grammars.get(prefix)
|
||||
if gr:
|
||||
# we check this first to provide an easy error message
|
||||
if rest[-1] not in '*:':
|
||||
error('pattern {} does not end with "*" or ":"', match)
|
||||
|
||||
try:
|
||||
gr.parseString(rest)
|
||||
except ParseBaseException as e:
|
||||
error('Pattern {!r} is invalid: {}', rest, e)
|
||||
continue
|
||||
if rest[-1] not in '*:':
|
||||
error('pattern {} does not end with "*" or ":"', match)
|
||||
|
||||
matches.sort()
|
||||
prev = None
|
||||
|
||||
@ -4554,10 +4554,10 @@ Bridge=bridge0</programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title></title>
|
||||
<title>Bridge port with VLAN forwarding</title>
|
||||
|
||||
<programlisting>
|
||||
# /etc/systemd/network/20-bridge-slave-interface-vlan.network
|
||||
# /etc/systemd/network/25-bridge-slave-interface-1.network
|
||||
[Match]
|
||||
Name=enp2s0
|
||||
|
||||
|
||||
@ -2123,7 +2123,7 @@ executable(
|
||||
install : true,
|
||||
install_dir : systemgeneratordir)
|
||||
|
||||
executable(
|
||||
exe = executable(
|
||||
'systemd-fstab-generator',
|
||||
'src/fstab-generator/fstab-generator.c',
|
||||
include_directories : includes,
|
||||
@ -2132,6 +2132,13 @@ executable(
|
||||
install : true,
|
||||
install_dir : systemgeneratordir)
|
||||
|
||||
if want_tests != 'false'
|
||||
test('test-fstab-generator',
|
||||
test_fstab_generator_sh,
|
||||
# https://github.com/mesonbuild/meson/issues/2681
|
||||
args : exe.full_path())
|
||||
endif
|
||||
|
||||
if conf.get('ENABLE_ENVIRONMENT_D') == 1
|
||||
executable(
|
||||
'30-systemd-environment-d-generator',
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <getopt.h>
|
||||
|
||||
#include "main-func.h"
|
||||
#include "util.h"
|
||||
#include "udev-util.h"
|
||||
|
||||
static bool arg_verbose = false;
|
||||
|
||||
|
||||
@ -395,8 +395,16 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not a backlight or LED device: '%s:%s'", ss, sysname);
|
||||
|
||||
r = sd_device_new_from_subsystem_sysname(&device, ss, sysname);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get backlight or LED device '%s:%s': %m", ss, sysname);
|
||||
if (r < 0) {
|
||||
bool ignore = r == -ENODEV;
|
||||
|
||||
/* Some drivers, e.g. for AMD GPU, removes acpi backlight device soon after it is added.
|
||||
* See issue #21997. */
|
||||
log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r,
|
||||
"Failed to get backlight or LED device '%s:%s'%s: %m",
|
||||
ss, sysname, ignore ? ", ignoring" : "");
|
||||
return ignore ? 0 : r;
|
||||
}
|
||||
|
||||
/* If max_brightness is 0, then there is no actual backlight device. This happens on desktops
|
||||
* with Asus mainboards that load the eeepc-wmi module. */
|
||||
|
||||
@ -114,6 +114,10 @@ int is_this_me(const char *username);
|
||||
|
||||
const char *get_home_root(void);
|
||||
|
||||
static inline bool hashed_password_is_locked_or_invalid(const char *password) {
|
||||
return password && password[0] != '$';
|
||||
}
|
||||
|
||||
/* A locked *and* invalid password for "struct spwd"'s .sp_pwdp and "struct passwd"'s .pw_passwd field */
|
||||
#define PASSWORD_LOCKED_AND_INVALID "!*"
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "build.h"
|
||||
#include "dirent-util.h"
|
||||
#include "env-file.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
@ -115,65 +114,6 @@ void in_initrd_force(bool value) {
|
||||
saved_in_initrd = value;
|
||||
}
|
||||
|
||||
int on_ac_power(void) {
|
||||
bool found_offline = false, found_online = false;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
int r;
|
||||
|
||||
d = opendir("/sys/class/power_supply");
|
||||
if (!d)
|
||||
return errno == ENOENT ? true : -errno;
|
||||
|
||||
FOREACH_DIRENT(de, d, return -errno) {
|
||||
_cleanup_close_ int device_fd = -1;
|
||||
_cleanup_free_ char *contents = NULL;
|
||||
unsigned v;
|
||||
|
||||
device_fd = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
|
||||
if (device_fd < 0) {
|
||||
if (IN_SET(errno, ENOENT, ENOTDIR))
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = read_virtual_file_at(device_fd, "type", SIZE_MAX, &contents, NULL);
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
delete_trailing_chars(contents, NEWLINE);
|
||||
|
||||
/* We assume every power source is AC, except for batteries. See
|
||||
* https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
|
||||
* for defined power source types. Also see:
|
||||
* https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power */
|
||||
if (streq(contents, "Battery"))
|
||||
continue;
|
||||
|
||||
contents = mfree(contents);
|
||||
|
||||
r = read_virtual_file_at(device_fd, "online", SIZE_MAX, &contents, NULL);
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
delete_trailing_chars(contents, NEWLINE);
|
||||
|
||||
r = safe_atou(contents, &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */
|
||||
found_online = true;
|
||||
else
|
||||
found_offline = true;
|
||||
}
|
||||
|
||||
return found_online || !found_offline;
|
||||
}
|
||||
|
||||
int container_get_leader(const char *machine, pid_t *pid) {
|
||||
_cleanup_free_ char *s = NULL, *class = NULL;
|
||||
const char *p;
|
||||
|
||||
@ -20,8 +20,6 @@ int prot_from_flags(int flags) _const_;
|
||||
bool in_initrd(void);
|
||||
void in_initrd_force(bool value);
|
||||
|
||||
int on_ac_power(void);
|
||||
|
||||
/* Note: log2(0) == log2(1) == 0 here and below. */
|
||||
|
||||
#define CONST_LOG2ULL(x) ((x) > 1 ? (unsigned) __builtin_clzll(x) ^ 63U : 0)
|
||||
|
||||
@ -1638,9 +1638,9 @@ static INTN config_entry_find(Config *config, const CHAR16 *needle) {
|
||||
if (!needle)
|
||||
return -1;
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++)
|
||||
for (INTN i = config->entry_count - 1; i >= 0; i--)
|
||||
if (MetaiMatch(config->entries[i]->id, (CHAR16*) needle))
|
||||
return (INTN) i;
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -45,10 +45,11 @@ static bool bpf_can_link_lsm_program(struct bpf_program *prog) {
|
||||
assert(prog);
|
||||
|
||||
link = sym_bpf_program__attach_lsm(prog);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
return 1;
|
||||
/* If bpf_program__attach_lsm fails the resulting value stores libbpf error code instead of memory
|
||||
* pointer. That is the case when the helper is called on architectures where BPF trampoline (hence
|
||||
* BPF_LSM_MAC attach type) is not supported. */
|
||||
return sym_libbpf_get_error(link) == 0;
|
||||
}
|
||||
|
||||
static int prepare_restrict_fs_bpf(struct restrict_fs_bpf **ret_obj) {
|
||||
@ -64,10 +65,10 @@ static int prepare_restrict_fs_bpf(struct restrict_fs_bpf **ret_obj) {
|
||||
|
||||
/* TODO Maybe choose a number based on runtime information? */
|
||||
r = sym_bpf_map__resize(obj->maps.cgroup_hash, CGROUP_HASH_SIZE_MAX);
|
||||
if (r != 0)
|
||||
return log_error_errno(r,
|
||||
"Failed to resize BPF map '%s': %m",
|
||||
sym_bpf_map__name(obj->maps.cgroup_hash));
|
||||
assert(r <= 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resize BPF map '%s': %m",
|
||||
sym_bpf_map__name(obj->maps.cgroup_hash));
|
||||
|
||||
/* Dummy map to satisfy the verifier */
|
||||
inner_map_fd = sym_bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint32_t), 128, 0);
|
||||
@ -75,11 +76,13 @@ static int prepare_restrict_fs_bpf(struct restrict_fs_bpf **ret_obj) {
|
||||
return log_error_errno(errno, "Failed to create BPF map: %m");
|
||||
|
||||
r = sym_bpf_map__set_inner_map_fd(obj->maps.cgroup_hash, inner_map_fd);
|
||||
assert(r <= 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set inner map fd: %m");
|
||||
|
||||
r = restrict_fs_bpf__load(obj);
|
||||
if (r)
|
||||
assert(r <= 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to load BPF object");
|
||||
|
||||
*ret_obj = TAKE_PTR(obj);
|
||||
@ -99,34 +102,27 @@ static int mac_bpf_use(void) {
|
||||
|
||||
r = read_one_line_file("/sys/kernel/security/lsm", &lsm_list);
|
||||
if (r < 0) {
|
||||
if (errno != ENOENT)
|
||||
log_debug_errno(r, "Failed to read /sys/kernel/security/lsm, ignoring: %m");
|
||||
|
||||
if (r != -ENOENT)
|
||||
log_notice_errno(r, "Failed to read /sys/kernel/security/lsm, assuming bpf is unavailable: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *p = lsm_list;
|
||||
|
||||
for (;;) {
|
||||
for (const char *p = lsm_list;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, ",", 0);
|
||||
if (r == 0)
|
||||
break;
|
||||
return 0;
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to parse /sys/kernel/security/lsm, ignoring: %m");
|
||||
log_notice_errno(r, "Failed to parse /sys/kernel/security/lsm, assuming bpf is unavailable: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(word, "bpf")) {
|
||||
cached_use = 1;
|
||||
break;
|
||||
}
|
||||
if (streq(word, "bpf"))
|
||||
return cached_use = 1;
|
||||
}
|
||||
|
||||
return cached_use;
|
||||
}
|
||||
|
||||
int lsm_bpf_supported(void) {
|
||||
@ -171,9 +167,9 @@ int lsm_bpf_supported(void) {
|
||||
if (r < 0)
|
||||
return supported = 0;
|
||||
|
||||
r = bpf_can_link_lsm_program(obj->progs.restrict_filesystems);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to link BPF program. Assuming BPF is not available: %m");
|
||||
if (!bpf_can_link_lsm_program(obj->progs.restrict_filesystems)) {
|
||||
log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Failed to link BPF program. Assuming BPF is not available");
|
||||
return supported = 0;
|
||||
}
|
||||
|
||||
@ -181,7 +177,7 @@ int lsm_bpf_supported(void) {
|
||||
}
|
||||
|
||||
int lsm_bpf_setup(Manager *m) {
|
||||
struct restrict_fs_bpf *obj = NULL;
|
||||
_cleanup_(restrict_fs_bpf_freep) struct restrict_fs_bpf *obj = NULL;
|
||||
_cleanup_(bpf_link_freep) struct bpf_link *link = NULL;
|
||||
int r;
|
||||
|
||||
@ -191,23 +187,21 @@ int lsm_bpf_setup(Manager *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m->restrict_fs = obj;
|
||||
|
||||
link = sym_bpf_program__attach_lsm(m->restrict_fs->progs.restrict_filesystems);
|
||||
link = sym_bpf_program__attach_lsm(obj->progs.restrict_filesystems);
|
||||
r = sym_libbpf_get_error(link);
|
||||
if (r != 0)
|
||||
return log_error_errno(r, "Failed to link '%s' LSM BPF program: %m",
|
||||
sym_bpf_program__name(m->restrict_fs->progs.restrict_filesystems));
|
||||
sym_bpf_program__name(obj->progs.restrict_filesystems));
|
||||
|
||||
log_info("LSM BPF program attached");
|
||||
|
||||
m->restrict_fs->links.restrict_filesystems = TAKE_PTR(link);
|
||||
obj->links.restrict_filesystems = TAKE_PTR(link);
|
||||
m->restrict_fs = TAKE_PTR(obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, bool allow_list) {
|
||||
int inner_map_fd = -1, outer_map_fd = -1;
|
||||
uint32_t dummy_value = 1, zero = 0;
|
||||
const char *fs;
|
||||
const statfs_f_type_t *magic;
|
||||
@ -216,7 +210,11 @@ int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, bool allo
|
||||
assert(filesystems);
|
||||
assert(u);
|
||||
|
||||
inner_map_fd = sym_bpf_create_map(
|
||||
if (!u->manager->restrict_fs)
|
||||
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Restrict filesystems BPF object is not set, BPF LSM setup has failed?");
|
||||
|
||||
int inner_map_fd = sym_bpf_create_map(
|
||||
BPF_MAP_TYPE_HASH,
|
||||
sizeof(uint32_t),
|
||||
sizeof(uint32_t),
|
||||
@ -225,7 +223,7 @@ int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, bool allo
|
||||
if (inner_map_fd < 0)
|
||||
return log_unit_error_errno(u, errno, "Failed to create inner LSM map: %m");
|
||||
|
||||
outer_map_fd = sym_bpf_map__fd(u->manager->restrict_fs->maps.cgroup_hash);
|
||||
int outer_map_fd = sym_bpf_map__fd(u->manager->restrict_fs->maps.cgroup_hash);
|
||||
if (outer_map_fd < 0)
|
||||
return log_unit_error_errno(u, errno, "Failed to get BPF map fd: %m");
|
||||
|
||||
@ -266,8 +264,6 @@ int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, bool allo
|
||||
}
|
||||
|
||||
int lsm_bpf_cleanup(const Unit *u) {
|
||||
int fd = -1;
|
||||
|
||||
assert(u);
|
||||
assert(u->manager);
|
||||
|
||||
@ -277,7 +273,7 @@ int lsm_bpf_cleanup(const Unit *u) {
|
||||
if (!u->manager->restrict_fs)
|
||||
return 0;
|
||||
|
||||
fd = sym_bpf_map__fd(u->manager->restrict_fs->maps.cgroup_hash);
|
||||
int fd = sym_bpf_map__fd(u->manager->restrict_fs->maps.cgroup_hash);
|
||||
if (fd < 0)
|
||||
return log_unit_error_errno(u, errno, "Failed to get BPF map fd: %m");
|
||||
|
||||
@ -350,10 +346,10 @@ int lsm_bpf_parse_filesystem(
|
||||
}
|
||||
|
||||
NULSTR_FOREACH(i, set->value) {
|
||||
/* Call ourselves again, for the group to parse. Note that we downgrade logging here (i.e. take
|
||||
* away the FILESYSTEM_PARSE_LOG flag) since any issues in the group table are our own problem,
|
||||
* not a problem in user configuration data and we shouldn't pretend otherwise by complaining
|
||||
* about them. */
|
||||
/* Call ourselves again, for the group to parse. Note that we downgrade logging here
|
||||
* (i.e. take away the FILESYSTEM_PARSE_LOG flag) since any issues in the group table
|
||||
* are our own problem, not a problem in user configuration data and we shouldn't
|
||||
* pretend otherwise by complaining about them. */
|
||||
r = lsm_bpf_parse_filesystem(i, filesystems, flags &~ FILESYSTEM_PARSE_LOG, unit, filename, line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -363,16 +359,10 @@ int lsm_bpf_parse_filesystem(
|
||||
* we want to allow it, then remove it from the list. */
|
||||
if (!(flags & FILESYSTEM_PARSE_INVERT) == !!(flags & FILESYSTEM_PARSE_ALLOW_LIST)) {
|
||||
r = set_put_strdup(filesystems, name);
|
||||
if (r < 0)
|
||||
switch (r) {
|
||||
case -ENOMEM:
|
||||
return flags & FILESYSTEM_PARSE_LOG ? log_oom() : -ENOMEM;
|
||||
case -EEXIST:
|
||||
/* Already in set, ignore */
|
||||
break;
|
||||
default:
|
||||
return r;
|
||||
}
|
||||
if (r == -ENOMEM)
|
||||
return flags & FILESYSTEM_PARSE_LOG ? log_oom() : -ENOMEM;
|
||||
if (r < 0 && r != -EEXIST) /* When already in set, ignore */
|
||||
return r;
|
||||
} else
|
||||
free(set_remove(*filesystems, name));
|
||||
}
|
||||
|
||||
@ -1731,14 +1731,6 @@ static int apply_lock_personality(const Unit* u, const ExecContext *c) {
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBBPF
|
||||
static bool skip_lsm_bpf_unsupported(const Unit* u, const char* msg) {
|
||||
if (lsm_bpf_supported())
|
||||
return false;
|
||||
|
||||
log_unit_debug(u, "LSM BPF not supported, skipping %s", msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int apply_restrict_filesystems(Unit *u, const ExecContext *c) {
|
||||
assert(u);
|
||||
assert(c);
|
||||
@ -1746,8 +1738,11 @@ static int apply_restrict_filesystems(Unit *u, const ExecContext *c) {
|
||||
if (!exec_context_restrict_filesystems_set(c))
|
||||
return 0;
|
||||
|
||||
if (skip_lsm_bpf_unsupported(u, "RestrictFileSystems="))
|
||||
if (!u->manager->restrict_fs) {
|
||||
/* LSM BPF is unsupported or lsm_bpf_setup failed */
|
||||
log_unit_debug(u, "LSM BPF not supported, skipping RestrictFileSystems=");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return lsm_bpf_unit_restrict_filesystems(u, c->restrict_filesystems, c->restrict_filesystems_allow_list);
|
||||
}
|
||||
@ -3968,13 +3963,11 @@ static int exec_child(
|
||||
}
|
||||
|
||||
#if HAVE_LIBBPF
|
||||
if (MANAGER_IS_SYSTEM(unit->manager) && lsm_bpf_supported()) {
|
||||
int bpf_map_fd = -1;
|
||||
|
||||
bpf_map_fd = lsm_bpf_map_restrict_fs_fd(unit);
|
||||
if (unit->manager->restrict_fs) {
|
||||
int bpf_map_fd = lsm_bpf_map_restrict_fs_fd(unit);
|
||||
if (bpf_map_fd < 0) {
|
||||
*exit_status = EXIT_FDS;
|
||||
return log_unit_error_errno(unit, r, "Failed to get restrict filesystems BPF map fd: %m");
|
||||
return log_unit_error_errno(unit, bpf_map_fd, "Failed to get restrict filesystems BPF map fd: %m");
|
||||
}
|
||||
|
||||
r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, bpf_map_fd, &bpf_map_fd);
|
||||
|
||||
@ -933,7 +933,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
||||
if (MANAGER_IS_SYSTEM(m) && lsm_bpf_supported()) {
|
||||
r = lsm_bpf_setup(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
log_warning_errno(r, "Failed to setup LSM BPF, ignoring: %m");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "fileio.h"
|
||||
#include "fstab-util.h"
|
||||
#include "generator.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "mkdir.h"
|
||||
@ -691,6 +692,57 @@ static int parse_fstab(bool initrd) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static int sysroot_is_nfsroot(void) {
|
||||
union in_addr_union u;
|
||||
const char *sep, *a;
|
||||
int r;
|
||||
|
||||
assert(arg_root_what);
|
||||
|
||||
/* From dracut.cmdline(7).
|
||||
*
|
||||
* root=[<server-ip>:]<root-dir>[:<nfs-options>]
|
||||
* root=nfs:[<server-ip>:]<root-dir>[:<nfs-options>],
|
||||
* root=nfs4:[<server-ip>:]<root-dir>[:<nfs-options>],
|
||||
* root={dhcp|dhcp6}
|
||||
*
|
||||
* mount nfs share from <server-ip>:/<root-dir>, if no server-ip is given, use dhcp next_server.
|
||||
* If server-ip is an IPv6 address it has to be put in brackets, e.g. [2001:DB8::1]. NFS options
|
||||
* can be appended with the prefix ":" or "," and are separated by ",". */
|
||||
|
||||
if (path_equal(arg_root_what, "/dev/nfs") ||
|
||||
STR_IN_SET(arg_root_what, "dhcp", "dhcp6") ||
|
||||
STARTSWITH_SET(arg_root_what, "nfs:", "nfs4:"))
|
||||
return true;
|
||||
|
||||
/* IPv6 address */
|
||||
if (arg_root_what[0] == '[') {
|
||||
sep = strchr(arg_root_what + 1, ']');
|
||||
if (!sep)
|
||||
return -EINVAL;
|
||||
|
||||
a = strndupa(arg_root_what + 1, sep - arg_root_what - 1);
|
||||
|
||||
r = in_addr_from_string(AF_INET6, a, &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* IPv4 address */
|
||||
sep = strchr(arg_root_what, ':');
|
||||
if (sep) {
|
||||
a = strndupa(arg_root_what, sep - arg_root_what);
|
||||
|
||||
if (in_addr_from_string(AF_INET, a, &u) >= 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* root directory without address */
|
||||
return path_is_absolute(arg_root_what) && !path_startswith(arg_root_what, "/dev");
|
||||
}
|
||||
|
||||
static int add_sysroot_mount(void) {
|
||||
_cleanup_free_ char *what = NULL;
|
||||
const char *opts, *fstype;
|
||||
@ -708,9 +760,27 @@ static int add_sysroot_mount(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (path_equal(arg_root_what, "/dev/nfs")) {
|
||||
r = sysroot_is_nfsroot();
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to determine if the root directory is on NFS, assuming not: %m");
|
||||
else if (r > 0) {
|
||||
/* This is handled by the kernel or the initrd */
|
||||
log_debug("Skipping root directory handling, as /dev/nfs was requested.");
|
||||
log_debug("Skipping root directory handling, as root on NFS was requested.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startswith(arg_root_what, "cifs://")) {
|
||||
log_debug("Skipping root directory handling, as root on CIFS was requested.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startswith(arg_root_what, "iscsi:")) {
|
||||
log_debug("Skipping root directory handling, as root on iSCSI was requested.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startswith(arg_root_what, "live:")) {
|
||||
log_debug("Skipping root directory handling, as root on live image was requested.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -853,7 +853,10 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, size_t n
|
||||
return;
|
||||
}
|
||||
|
||||
log_info_errno(r, "Failed to write entry (%zu items, %zu bytes), rotating before retrying: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
|
||||
if (r == -E2BIG)
|
||||
log_debug("Journal file %s is full, rotating to a new file", f->file->path);
|
||||
else
|
||||
log_info_errno(r, "Failed to write entry to %s (%zu items, %zu bytes), rotating before retrying: %m", f->file->path, n, IOVEC_TOTAL_SIZE(iovec, n));
|
||||
|
||||
server_rotate(s);
|
||||
server_vacuum(s, false);
|
||||
@ -865,7 +868,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, size_t n
|
||||
log_debug("Retrying write.");
|
||||
r = journal_file_append_entry(f->file, &ts, NULL, iovec, n, &s->seqnum, NULL, NULL);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to write entry (%zu items, %zu bytes) despite vacuuming, ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
|
||||
log_error_errno(r, "Failed to write entry to %s (%zu items, %zu bytes) despite vacuuming, ignoring: %m", f->file->path, n, IOVEC_TOTAL_SIZE(iovec, n));
|
||||
else
|
||||
server_schedule_sync(s, priority);
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ fi
|
||||
[ -z "$MACHINE_ID" ] && MACHINE_ID="Default"
|
||||
|
||||
[ -z "$BOOT_ROOT" ] && for suff in "$MACHINE_ID" "loader/entries"; do
|
||||
for pref in "/efi" "/boot/efi" "/boot"; do
|
||||
for pref in "/efi" "/boot" "/boot/efi" ; do
|
||||
if [ -d "$pref/$suff" ]; then
|
||||
BOOT_ROOT="$pref"
|
||||
break 2
|
||||
|
||||
@ -1654,7 +1654,6 @@ error:
|
||||
}
|
||||
|
||||
int manager_dispatch_delayed(Manager *manager, bool timeout) {
|
||||
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
Inhibitor *offending = NULL;
|
||||
int r;
|
||||
@ -1686,10 +1685,9 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
|
||||
|
||||
manager->action_unit = NULL;
|
||||
manager->action_what = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1; /* We did some work. */
|
||||
}
|
||||
|
||||
static int manager_inhibit_timeout_handler(
|
||||
@ -1698,13 +1696,11 @@ static int manager_inhibit_timeout_handler(
|
||||
void *userdata) {
|
||||
|
||||
Manager *manager = userdata;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
assert(manager->inhibit_timeout_source == s);
|
||||
|
||||
r = manager_dispatch_delayed(manager, true);
|
||||
return (r < 0) ? r : 0;
|
||||
return manager_dispatch_delayed(manager, true);
|
||||
}
|
||||
|
||||
static int delay_shutdown_or_sleep(
|
||||
|
||||
@ -8,6 +8,8 @@ set -o pipefail
|
||||
repart="${1:?}"
|
||||
test -x "$repart"
|
||||
|
||||
PATH=$PATH:/sbin:/usr/sbin
|
||||
|
||||
D="$(mktemp --tmpdir --directory "test-repart.XXXXXXXXXX")"
|
||||
|
||||
# shellcheck disable=SC2064
|
||||
@ -213,6 +215,6 @@ else
|
||||
fi
|
||||
|
||||
echo "### Testing json output ###"
|
||||
"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --json=help
|
||||
"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --json=pretty
|
||||
"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --json=short
|
||||
"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager --json=help
|
||||
"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager --json=pretty
|
||||
"$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --no-pager --json=short
|
||||
|
||||
@ -1402,6 +1402,8 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
|
||||
if (md_algorithm < 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
initialize_libgcrypt(false);
|
||||
|
||||
_cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
|
||||
|
||||
size_t hash_size = gcry_md_get_algo_dlen(md_algorithm);
|
||||
|
||||
@ -5,11 +5,13 @@
|
||||
#include "efi-loader.h"
|
||||
#include "macro.h"
|
||||
#include "time-util.h"
|
||||
#include "virt.h"
|
||||
|
||||
int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader) {
|
||||
usec_t x = 0, y = 0, a;
|
||||
int r;
|
||||
dual_timestamp _n;
|
||||
bool use_firmware = true;
|
||||
|
||||
assert(firmware);
|
||||
assert(loader);
|
||||
@ -24,6 +26,10 @@ int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_time
|
||||
r = efi_loader_get_boot_usec(&x, &y);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* If we are running in a VM, the init timestamp would
|
||||
* be equivalent to the host uptime. */
|
||||
use_firmware = detect_vm() <= 0;
|
||||
}
|
||||
|
||||
/* Let's convert this to timestamps where the firmware
|
||||
@ -33,12 +39,14 @@ int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_time
|
||||
* the monotonic timestamps here as negative of the actual
|
||||
* value. */
|
||||
|
||||
firmware->monotonic = y;
|
||||
if (use_firmware) {
|
||||
firmware->monotonic = y;
|
||||
a = n->monotonic + firmware->monotonic;
|
||||
firmware->realtime = n->realtime > a ? n->realtime - a : 0;
|
||||
} else
|
||||
firmware->monotonic = firmware->realtime = 0;
|
||||
|
||||
loader->monotonic = y - x;
|
||||
|
||||
a = n->monotonic + firmware->monotonic;
|
||||
firmware->realtime = n->realtime > a ? n->realtime - a : 0;
|
||||
|
||||
a = n->monotonic + loader->monotonic;
|
||||
loader->realtime = n->realtime > a ? n->realtime - a : 0;
|
||||
|
||||
|
||||
@ -50,9 +50,9 @@
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "tomoyo-util.h"
|
||||
#include "udev-util.h"
|
||||
#include "uid-alloc-range.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
|
||||
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
|
||||
|
||||
@ -52,7 +52,6 @@ static int patch_dirfd_mode(
|
||||
}
|
||||
|
||||
int unlinkat_harder(int dfd, const char *filename, int unlink_flags, RemoveFlags remove_flags) {
|
||||
|
||||
mode_t old_mode;
|
||||
int r;
|
||||
|
||||
@ -116,15 +115,16 @@ int fstatat_harder(int dfd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rm_rf_children_inner(
|
||||
static int rm_rf_inner_child(
|
||||
int fd,
|
||||
const char *fname,
|
||||
int is_dir,
|
||||
RemoveFlags flags,
|
||||
const struct stat *root_dev) {
|
||||
const struct stat *root_dev,
|
||||
bool allow_recursion) {
|
||||
|
||||
struct stat st;
|
||||
int r;
|
||||
int r, q = 0;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(fname);
|
||||
@ -141,10 +141,7 @@ static int rm_rf_children_inner(
|
||||
}
|
||||
|
||||
if (is_dir) {
|
||||
_cleanup_close_ int subdir_fd = -1;
|
||||
int q;
|
||||
|
||||
/* if root_dev is set, remove subdirectories only if device is same */
|
||||
/* If root_dev is set, remove subdirectories only if device is same */
|
||||
if (root_dev && st.st_dev != root_dev->st_dev)
|
||||
return 0;
|
||||
|
||||
@ -156,7 +153,6 @@ static int rm_rf_children_inner(
|
||||
return 0;
|
||||
|
||||
if ((flags & REMOVE_SUBVOLUME) && btrfs_might_be_subvol(&st)) {
|
||||
|
||||
/* This could be a subvolume, try to remove it */
|
||||
|
||||
r = btrfs_subvol_remove_fd(fd, fname, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
|
||||
@ -170,31 +166,40 @@ static int rm_rf_children_inner(
|
||||
return 1;
|
||||
}
|
||||
|
||||
subdir_fd = openat(fd, fname, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
|
||||
if (!allow_recursion)
|
||||
return -EISDIR;
|
||||
|
||||
int subdir_fd = openat(fd, fname, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
|
||||
if (subdir_fd < 0)
|
||||
return -errno;
|
||||
|
||||
/* We pass REMOVE_PHYSICAL here, to avoid doing the fstatfs() to check the file system type
|
||||
* again for each directory */
|
||||
q = rm_rf_children(TAKE_FD(subdir_fd), flags | REMOVE_PHYSICAL, root_dev);
|
||||
q = rm_rf_children(subdir_fd, flags | REMOVE_PHYSICAL, root_dev);
|
||||
|
||||
r = unlinkat_harder(fd, fname, AT_REMOVEDIR, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (q < 0)
|
||||
return q;
|
||||
} else if (flags & REMOVE_ONLY_DIRECTORIES)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
r = unlinkat_harder(fd, fname, is_dir ? AT_REMOVEDIR : 0, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (q < 0)
|
||||
return q;
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if (!(flags & REMOVE_ONLY_DIRECTORIES)) {
|
||||
r = unlinkat_harder(fd, fname, 0, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
typedef struct TodoEntry {
|
||||
DIR *dir; /* A directory that we were operating on. */
|
||||
char *dirname; /* The filename of that directory itself. */
|
||||
} TodoEntry;
|
||||
|
||||
return 1;
|
||||
static void free_todo_entries(TodoEntry **todos) {
|
||||
for (TodoEntry *x = *todos; x && x->dir; x++) {
|
||||
closedir(x->dir);
|
||||
free(x->dirname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
freep(todos);
|
||||
}
|
||||
|
||||
int rm_rf_children(
|
||||
@ -202,63 +207,114 @@ int rm_rf_children(
|
||||
RemoveFlags flags,
|
||||
const struct stat *root_dev) {
|
||||
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
_cleanup_(free_todo_entries) TodoEntry *todos = NULL;
|
||||
size_t n_todo = 0;
|
||||
_cleanup_free_ char *dirname = NULL; /* Set when we are recursing and want to delete ourselves */
|
||||
int ret = 0, r;
|
||||
|
||||
assert(fd >= 0);
|
||||
/* Return the first error we run into, but nevertheless try to go on.
|
||||
* The passed fd is closed in all cases, including on failure. */
|
||||
|
||||
/* This returns the first error we run into, but nevertheless tries to go on. This closes the passed
|
||||
* fd, in all cases, including on failure. */
|
||||
for (;;) { /* This loop corresponds to the directory nesting level. */
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
|
||||
d = fdopendir(fd);
|
||||
if (!d) {
|
||||
safe_close(fd);
|
||||
return -errno;
|
||||
}
|
||||
if (n_todo > 0) {
|
||||
/* We know that we are in recursion here, because n_todo is set.
|
||||
* We need to remove the inner directory we were operating on. */
|
||||
assert(dirname);
|
||||
r = unlinkat_harder(dirfd(todos[n_todo-1].dir), dirname, AT_REMOVEDIR, flags);
|
||||
if (r < 0 && r != -ENOENT && ret == 0)
|
||||
ret = r;
|
||||
dirname = mfree(dirname);
|
||||
|
||||
if (!(flags & REMOVE_PHYSICAL)) {
|
||||
struct statfs sfs;
|
||||
/* And now let's back out one level up */
|
||||
n_todo --;
|
||||
d = TAKE_PTR(todos[n_todo].dir);
|
||||
dirname = TAKE_PTR(todos[n_todo].dirname);
|
||||
|
||||
if (fstatfs(dirfd(d), &sfs) < 0)
|
||||
return -errno;
|
||||
assert(d);
|
||||
fd = dirfd(d); /* Retrieve the file descriptor from the DIR object */
|
||||
assert(fd >= 0);
|
||||
} else {
|
||||
next_fd:
|
||||
assert(fd >= 0);
|
||||
d = fdopendir(fd);
|
||||
if (!d) {
|
||||
safe_close(fd);
|
||||
return -errno;
|
||||
}
|
||||
fd = dirfd(d); /* We donated the fd to fdopendir(). Let's make sure we sure we have
|
||||
* the right descriptor even if it were to internally invalidate the
|
||||
* one we passed. */
|
||||
|
||||
if (is_physical_fs(&sfs)) {
|
||||
/* We refuse to clean physical file systems with this call, unless explicitly
|
||||
* requested. This is extra paranoia just to be sure we never ever remove non-state
|
||||
* data. */
|
||||
if (!(flags & REMOVE_PHYSICAL)) {
|
||||
struct statfs sfs;
|
||||
|
||||
_cleanup_free_ char *path = NULL;
|
||||
if (fstatfs(fd, &sfs) < 0)
|
||||
return -errno;
|
||||
|
||||
(void) fd_get_path(fd, &path);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"Attempted to remove disk file system under \"%s\", and we can't allow that.",
|
||||
strna(path));
|
||||
if (is_physical_fs(&sfs)) {
|
||||
/* We refuse to clean physical file systems with this call, unless
|
||||
* explicitly requested. This is extra paranoia just to be sure we
|
||||
* never ever remove non-state data. */
|
||||
|
||||
_cleanup_free_ char *path = NULL;
|
||||
|
||||
(void) fd_get_path(fd, &path);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"Attempted to remove disk file system under \"%s\", and we can't allow that.",
|
||||
strna(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FOREACH_DIRENT_ALL(de, d, return -errno) {
|
||||
int is_dir;
|
||||
|
||||
if (dot_or_dot_dot(de->d_name))
|
||||
continue;
|
||||
|
||||
is_dir = de->d_type == DT_UNKNOWN ? -1 : de->d_type == DT_DIR;
|
||||
|
||||
r = rm_rf_inner_child(fd, de->d_name, is_dir, flags, root_dev, false);
|
||||
if (r == -EISDIR) {
|
||||
/* Push the current working state onto the todo list */
|
||||
|
||||
if (!GREEDY_REALLOC0(todos, n_todo + 2))
|
||||
return log_oom();
|
||||
|
||||
_cleanup_free_ char *newdirname = strdup(de->d_name);
|
||||
if (!newdirname)
|
||||
return log_oom();
|
||||
|
||||
int newfd = openat(fd, de->d_name,
|
||||
O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
|
||||
if (newfd >= 0) {
|
||||
todos[n_todo++] = (TodoEntry) { TAKE_PTR(d), TAKE_PTR(dirname) };
|
||||
fd = newfd;
|
||||
dirname = TAKE_PTR(newdirname);
|
||||
|
||||
goto next_fd;
|
||||
|
||||
} else if (errno != -ENOENT && ret == 0)
|
||||
ret = -errno;
|
||||
|
||||
} else if (r < 0 && r != -ENOENT && ret == 0)
|
||||
ret = r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, REMOVE_SYNCFS) && syncfs(fd) < 0 && ret >= 0)
|
||||
ret = -errno;
|
||||
|
||||
if (n_todo == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
FOREACH_DIRENT_ALL(de, d, return -errno) {
|
||||
int is_dir;
|
||||
|
||||
if (dot_or_dot_dot(de->d_name))
|
||||
continue;
|
||||
|
||||
is_dir =
|
||||
de->d_type == DT_UNKNOWN ? -1 :
|
||||
de->d_type == DT_DIR;
|
||||
|
||||
r = rm_rf_children_inner(dirfd(d), de->d_name, is_dir, flags, root_dev);
|
||||
if (r < 0 && r != -ENOENT && ret == 0)
|
||||
ret = r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, REMOVE_SYNCFS) && syncfs(dirfd(d)) < 0 && ret >= 0)
|
||||
ret = -errno;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rm_rf(const char *path, RemoveFlags flags) {
|
||||
int fd, r;
|
||||
int fd, r, q = 0;
|
||||
|
||||
assert(path);
|
||||
|
||||
@ -290,49 +346,42 @@ int rm_rf(const char *path, RemoveFlags flags) {
|
||||
}
|
||||
|
||||
fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
|
||||
if (fd < 0) {
|
||||
if (fd >= 0) {
|
||||
/* We have a dir */
|
||||
r = rm_rf_children(fd, flags, NULL);
|
||||
|
||||
if (FLAGS_SET(flags, REMOVE_ROOT))
|
||||
q = RET_NERRNO(rmdir(path));
|
||||
} else {
|
||||
if (FLAGS_SET(flags, REMOVE_MISSING_OK) && errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
if (!IN_SET(errno, ENOTDIR, ELOOP))
|
||||
return -errno;
|
||||
|
||||
if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES))
|
||||
if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES) || !FLAGS_SET(flags, REMOVE_ROOT))
|
||||
return 0;
|
||||
|
||||
if (FLAGS_SET(flags, REMOVE_ROOT)) {
|
||||
|
||||
if (!FLAGS_SET(flags, REMOVE_PHYSICAL)) {
|
||||
struct statfs s;
|
||||
|
||||
if (statfs(path, &s) < 0)
|
||||
return -errno;
|
||||
if (is_physical_fs(&s))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"Attempted to remove files from a disk file system under \"%s\", refusing.",
|
||||
path);
|
||||
}
|
||||
|
||||
if (unlink(path) < 0) {
|
||||
if (FLAGS_SET(flags, REMOVE_MISSING_OK) && errno == ENOENT)
|
||||
return 0;
|
||||
if (!FLAGS_SET(flags, REMOVE_PHYSICAL)) {
|
||||
struct statfs s;
|
||||
|
||||
if (statfs(path, &s) < 0)
|
||||
return -errno;
|
||||
}
|
||||
if (is_physical_fs(&s))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"Attempted to remove files from a disk file system under \"%s\", refusing.",
|
||||
path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
r = 0;
|
||||
q = RET_NERRNO(unlink(path));
|
||||
}
|
||||
|
||||
r = rm_rf_children(fd, flags, NULL);
|
||||
|
||||
if (FLAGS_SET(flags, REMOVE_ROOT) &&
|
||||
rmdir(path) < 0 &&
|
||||
r >= 0 &&
|
||||
(!FLAGS_SET(flags, REMOVE_MISSING_OK) || errno != ENOENT))
|
||||
r = -errno;
|
||||
|
||||
return r;
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (q < 0 && (q != -ENOENT || !FLAGS_SET(flags, REMOVE_MISSING_OK)))
|
||||
return q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rm_rf_child(int fd, const char *name, RemoveFlags flags) {
|
||||
@ -351,5 +400,5 @@ int rm_rf_child(int fd, const char *name, RemoveFlags flags) {
|
||||
if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES|REMOVE_SUBVOLUME))
|
||||
return -EINVAL;
|
||||
|
||||
return rm_rf_children_inner(fd, name, -1, flags, NULL);
|
||||
return rm_rf_inner_child(fd, name, -1, flags, NULL, true);
|
||||
}
|
||||
|
||||
@ -286,6 +286,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
.name = "@default",
|
||||
.help = "System calls that are always permitted",
|
||||
.value =
|
||||
"arch_prctl\0" /* Used during platform-specific initialization by ld-linux.so. */
|
||||
"brk\0"
|
||||
"cacheflush\0"
|
||||
"clock_getres\0"
|
||||
@ -715,7 +716,6 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
|
||||
.name = "@process",
|
||||
.help = "Process control, execution, namespacing operations",
|
||||
.value =
|
||||
"arch_prctl\0"
|
||||
"capget\0" /* Able to query arbitrary processes */
|
||||
"clone\0"
|
||||
"clone3\0"
|
||||
|
||||
@ -579,3 +579,142 @@ int udev_queue_init(void) {
|
||||
|
||||
return TAKE_FD(fd);
|
||||
}
|
||||
|
||||
static int device_is_power_sink(sd_device *device) {
|
||||
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||
bool found_source = false, found_sink = false;
|
||||
sd_device *parent, *d;
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
|
||||
/* USB-C power supply device has two power roles: source or sink. See,
|
||||
* https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-typec */
|
||||
|
||||
r = sd_device_enumerator_new(&e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_enumerator_allow_uninitialized(e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_enumerator_add_match_subsystem(e, "typec", true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_get_parent(device, &parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_enumerator_add_match_parent(e, parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
FOREACH_DEVICE(e, d) {
|
||||
const char *val;
|
||||
|
||||
r = sd_device_get_sysattr_value(d, "power_role", &val);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
log_device_debug_errno(d, r, "Failed to read 'power_role' sysfs attribute, ignoring: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strstr(val, "[source]")) {
|
||||
found_source = true;
|
||||
log_device_debug(d, "The USB type-C port is in power source mode.");
|
||||
} else if (strstr(val, "[sink]")) {
|
||||
found_sink = true;
|
||||
log_device_debug(d, "The USB type-C port is in power sink mode.");
|
||||
}
|
||||
}
|
||||
|
||||
if (found_sink)
|
||||
log_device_debug(device, "The USB type-C device has at least one port in power sink mode.");
|
||||
else if (!found_source)
|
||||
log_device_debug(device, "The USB type-C device has no port in power source mode, assuming the device is in power sink mode.");
|
||||
else
|
||||
log_device_debug(device, "All USB type-C ports are in power source mode.");
|
||||
|
||||
return found_sink || !found_source;
|
||||
}
|
||||
|
||||
int on_ac_power(void) {
|
||||
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||
bool found_offline = false, found_online = false;
|
||||
sd_device *d;
|
||||
int r;
|
||||
|
||||
r = sd_device_enumerator_new(&e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_enumerator_allow_uninitialized(e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_enumerator_add_match_subsystem(e, "power_supply", true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
FOREACH_DEVICE(e, d) {
|
||||
const char *val;
|
||||
unsigned v;
|
||||
|
||||
r = sd_device_get_sysattr_value(d, "type", &val);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Failed to read 'type' sysfs attribute, ignoring: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We assume every power source is AC, except for batteries. See
|
||||
* https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
|
||||
* for defined power source types. Also see:
|
||||
* https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power */
|
||||
if (streq(val, "Battery")) {
|
||||
log_device_debug(d, "The power supply is battery, ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore USB-C power supply in source mode. See issue #21988. */
|
||||
if (streq(val, "USB")) {
|
||||
r = device_is_power_sink(d);
|
||||
if (r <= 0) {
|
||||
if (r < 0)
|
||||
log_device_debug_errno(d, r, "Failed to determine the current power role, ignoring: %m");
|
||||
else
|
||||
log_device_debug(d, "USB power supply is in source mode, ignoring.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_device_get_sysattr_value(d, "online", &val);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Failed to read 'online' sysfs attribute, ignoring: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
r = safe_atou(val, &v);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Failed to parse 'online' attribute, ignoring: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */
|
||||
found_online = true;
|
||||
else
|
||||
found_offline = true;
|
||||
|
||||
log_device_debug(d, "The power supply is currently %s.", v > 0 ? "online" : "offline");
|
||||
}
|
||||
|
||||
if (found_online)
|
||||
log_debug("Found at least one online non-battery power supply, system is running on AC power.");
|
||||
else if (!found_offline)
|
||||
log_debug("Found no offline non-battery power supply, assuming system is running on AC power.");
|
||||
else
|
||||
log_debug("All non-battery power supplies are offline, assuming system is running with battery.");
|
||||
|
||||
return found_online || !found_offline;
|
||||
}
|
||||
|
||||
@ -53,6 +53,8 @@ int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize,
|
||||
int udev_queue_is_empty(void);
|
||||
int udev_queue_init(void);
|
||||
|
||||
int on_ac_power(void);
|
||||
|
||||
#if HAVE_SYS_SDT_H
|
||||
|
||||
/* Each trace point can have different number of additional arguments. Note that when the macro is used only
|
||||
|
||||
@ -132,10 +132,28 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Password OK: %syes%s\n", ansi_highlight_green(), ansi_normal());
|
||||
break;
|
||||
if (strv_isempty(hr->hashed_password)) {
|
||||
if (hr->incomplete) /* Record might be incomplete, due to privs */
|
||||
break;
|
||||
printf(" Password OK: %sno%s (none set)\n", ansi_highlight(), ansi_normal());
|
||||
break;
|
||||
}
|
||||
if (strv_contains(hr->hashed_password, "")) {
|
||||
printf(" Password OK: %sno%s (empty set)\n", ansi_highlight_red(), ansi_normal());
|
||||
break;
|
||||
}
|
||||
bool has_valid_passwords = false;
|
||||
char **p;
|
||||
STRV_FOREACH(p, hr->hashed_password)
|
||||
if (!hashed_password_is_locked_or_invalid(*p)) {
|
||||
has_valid_passwords = true;
|
||||
break;
|
||||
}
|
||||
if (has_valid_passwords)
|
||||
printf(" Password OK: %syes%s\n", ansi_highlight_green(), ansi_normal());
|
||||
else
|
||||
printf(" Password OK: %sno%s (locked)\n", ansi_highlight(), ansi_normal());
|
||||
}
|
||||
|
||||
if (uid_is_valid(hr->uid))
|
||||
printf(" UID: " UID_FMT "\n", hr->uid);
|
||||
if (gid_is_valid(hr->gid)) {
|
||||
|
||||
@ -398,7 +398,7 @@ int logind_show_shutdown(void) {
|
||||
|
||||
log_info("%s scheduled for %s, use 'shutdown -c' to cancel.",
|
||||
action,
|
||||
FORMAT_TIMESTAMP_STYLE(arg_when, arg_timestamp_style));
|
||||
FORMAT_TIMESTAMP_STYLE(elapse, arg_timestamp_style));
|
||||
|
||||
return 0;
|
||||
#else
|
||||
|
||||
@ -551,7 +551,8 @@ tests += [
|
||||
[],
|
||||
core_includes, '', 'manual'],
|
||||
|
||||
[['src/test/test-watchdog.c']],
|
||||
[['src/test/test-watchdog.c'],
|
||||
[], [], [], '', 'unsafe'],
|
||||
|
||||
[['src/test/test-sched-prio.c'],
|
||||
[libcore,
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include "strv.h"
|
||||
#include "tests.h"
|
||||
#include "tomoyo-util.h"
|
||||
#include "udev-util.h"
|
||||
#include "uid-alloc-range.h"
|
||||
#include "user-util.h"
|
||||
#include "virt.h"
|
||||
|
||||
@ -12,6 +12,9 @@ if install_tests
|
||||
install_subdir('test-execute',
|
||||
exclude_files : '.gitattributes',
|
||||
install_dir : testdata_dir)
|
||||
install_subdir('test-fstab-generator',
|
||||
exclude_files : '.gitattributes',
|
||||
install_dir : testdata_dir)
|
||||
install_subdir('test-path',
|
||||
exclude_files : '.gitattributes',
|
||||
install_dir : testdata_dir)
|
||||
@ -83,6 +86,7 @@ if install_tests
|
||||
install_dir : testdata_dir)
|
||||
endif
|
||||
|
||||
test_fstab_generator_sh = find_program('test-fstab-generator.sh')
|
||||
test_network_generator_conversion_sh = find_program('test-network-generator-conversion.sh')
|
||||
test_systemd_tmpfiles_py = find_program('test-systemd-tmpfiles.py')
|
||||
hwdb_test_sh = find_program('hwdb-test.sh')
|
||||
@ -127,11 +131,13 @@ if install_tests
|
||||
install_mode : 'rwxr-xr-x',
|
||||
install_dir : testsdir)
|
||||
|
||||
if conf.get('ENABLE_NETWORKD') == 1
|
||||
install_data('test-network-generator-conversion.sh',
|
||||
install_mode : 'rwxr-xr-x',
|
||||
install_dir : testsdir)
|
||||
endif
|
||||
install_data('test-fstab-generator.sh',
|
||||
install_mode : 'rwxr-xr-x',
|
||||
install_dir : testsdir)
|
||||
|
||||
install_data('test-network-generator-conversion.sh',
|
||||
install_mode : 'rwxr-xr-x',
|
||||
install_dir : testsdir)
|
||||
endif
|
||||
|
||||
############################################################
|
||||
|
||||
40
test/test-fstab-generator.sh
Executable file
40
test/test-fstab-generator.sh
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -e
|
||||
|
||||
if [[ -n "$1" ]]; then
|
||||
generator=$1
|
||||
elif [[ -x /usr/lib/systemd/system-generators/systemd-fstab-generator ]]; then
|
||||
generator=/usr/lib/systemd/system-generators/systemd-fstab-generator
|
||||
elif [[ -x /lib/systemd/system-generators/systemd-fstab-generator ]]; then
|
||||
generator=/lib/systemd/system-generators/systemd-fstab-generator
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
src="$(dirname "$0")/testdata/test-fstab-generator"
|
||||
|
||||
for f in "$src"/test-*.input; do
|
||||
echo "*** Running $f"
|
||||
|
||||
(
|
||||
out=$(mktemp --tmpdir --directory "test-fstab-generator.XXXXXXXXXX")
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$out'" EXIT INT QUIT PIPE
|
||||
|
||||
# shellcheck disable=SC2046
|
||||
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
|
||||
|
||||
if [[ -f "$out"/systemd-fsck-root.service ]]; then
|
||||
# For split-usr system
|
||||
sed -i -e 's:ExecStart=/lib/systemd/systemd-fsck:ExecStart=/usr/lib/systemd/systemd-fsck:' "$out"/systemd-fsck-root.service
|
||||
fi
|
||||
|
||||
# We store empty files rather than symlinks, so that they don't get pruned when packaged up, so compare
|
||||
# the list of filenames rather than their content
|
||||
if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "${f%.input}.expected" -printf '%P\n' | sort); then
|
||||
echo "**** Unexpected output for $f"
|
||||
exit 1
|
||||
fi
|
||||
) || exit 1
|
||||
done
|
||||
1
test/test-fstab-generator/.gitattributes
vendored
Normal file
1
test/test-fstab-generator/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
* generated
|
||||
1
test/test-fstab-generator/test-01-dev-nfs.input
Normal file
1
test/test-fstab-generator/test-01-dev-nfs.input
Normal file
@ -0,0 +1 @@
|
||||
root=/dev/nfs nfsroot=192.168.0.1:/nfsroot/root1:rw
|
||||
1
test/test-fstab-generator/test-02-dhcp.input
Normal file
1
test/test-fstab-generator/test-02-dhcp.input
Normal file
@ -0,0 +1 @@
|
||||
root=dhcp
|
||||
1
test/test-fstab-generator/test-03-dhcp6.input
Normal file
1
test/test-fstab-generator/test-03-dhcp6.input
Normal file
@ -0,0 +1 @@
|
||||
root=dhcp6
|
||||
1
test/test-fstab-generator/test-04-nfs.input
Normal file
1
test/test-fstab-generator/test-04-nfs.input
Normal file
@ -0,0 +1 @@
|
||||
root=nfs:/nfsroot/root1:rw
|
||||
1
test/test-fstab-generator/test-05-nfs4.input
Normal file
1
test/test-fstab-generator/test-05-nfs4.input
Normal file
@ -0,0 +1 @@
|
||||
root=nfs4:/nfsroot/root1:rw
|
||||
1
test/test-fstab-generator/test-06-ipv4.input
Normal file
1
test/test-fstab-generator/test-06-ipv4.input
Normal file
@ -0,0 +1 @@
|
||||
root=192.168.0.1:/nfsroot/root1:rw
|
||||
1
test/test-fstab-generator/test-07-ipv6.input
Normal file
1
test/test-fstab-generator/test-07-ipv6.input
Normal file
@ -0,0 +1 @@
|
||||
root=[2001:db8::1]:/nfsroot/root1:rw
|
||||
1
test/test-fstab-generator/test-08-implicit-nfs.input
Normal file
1
test/test-fstab-generator/test-08-implicit-nfs.input
Normal file
@ -0,0 +1 @@
|
||||
root=/nfsroot/root1:rw
|
||||
1
test/test-fstab-generator/test-09-cifs.input
Normal file
1
test/test-fstab-generator/test-09-cifs.input
Normal file
@ -0,0 +1 @@
|
||||
root=cifs://username:password@192.168.0.1:/cifsroot
|
||||
1
test/test-fstab-generator/test-10-iscsi.input
Normal file
1
test/test-fstab-generator/test-10-iscsi.input
Normal file
@ -0,0 +1 @@
|
||||
root=iscsi:username:password@servername::::tgt
|
||||
1
test/test-fstab-generator/test-11-live.input
Normal file
1
test/test-fstab-generator/test-11-live.input
Normal file
@ -0,0 +1 @@
|
||||
root=live:http://example.com/liveboot.img
|
||||
@ -0,0 +1,5 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Requires=dev-sdx1.device
|
||||
After=dev-sdx1.device
|
||||
@ -0,0 +1,14 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-sdx1.target
|
||||
|
||||
[Mount]
|
||||
What=/dev/sdx1
|
||||
Where=/sysroot
|
||||
Options=ro
|
||||
@ -0,0 +1,16 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Description=File System Check on /dev/sdx1
|
||||
Documentation=man:systemd-fsck-root.service(8)
|
||||
DefaultDependencies=no
|
||||
BindsTo=dev-sdx1.device
|
||||
Conflicts=shutdown.target
|
||||
After=initrd-root-device.target local-fs-pre.target dev-sdx1.device
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
|
||||
TimeoutSec=0
|
||||
1
test/test-fstab-generator/test-12-dev-sdx.input
Normal file
1
test/test-fstab-generator/test-12-dev-sdx.input
Normal file
@ -0,0 +1 @@
|
||||
root=/dev/sdx1
|
||||
@ -0,0 +1,5 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Requires=dev-disk-by\x2dlabel-Root.device
|
||||
After=dev-disk-by\x2dlabel-Root.device
|
||||
@ -0,0 +1,14 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-disk-by\x2dlabel-Root.target
|
||||
|
||||
[Mount]
|
||||
What=/dev/disk/by-label/Root
|
||||
Where=/sysroot
|
||||
Options=ro
|
||||
@ -0,0 +1,16 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Description=File System Check on /dev/disk/by-label/Root
|
||||
Documentation=man:systemd-fsck-root.service(8)
|
||||
DefaultDependencies=no
|
||||
BindsTo=dev-disk-by\x2dlabel-Root.device
|
||||
Conflicts=shutdown.target
|
||||
After=initrd-root-device.target local-fs-pre.target dev-disk-by\x2dlabel-Root.device
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-label/Root
|
||||
TimeoutSec=0
|
||||
1
test/test-fstab-generator/test-13-label.input
Normal file
1
test/test-fstab-generator/test-13-label.input
Normal file
@ -0,0 +1 @@
|
||||
root=LABEL=Root
|
||||
@ -0,0 +1,5 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Requires=dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
After=dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
@ -0,0 +1,14 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.target
|
||||
|
||||
[Mount]
|
||||
What=/dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
Where=/sysroot
|
||||
Options=ro
|
||||
@ -0,0 +1,16 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Description=File System Check on /dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
Documentation=man:systemd-fsck-root.service(8)
|
||||
DefaultDependencies=no
|
||||
BindsTo=dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
Conflicts=shutdown.target
|
||||
After=initrd-root-device.target local-fs-pre.target dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
TimeoutSec=0
|
||||
1
test/test-fstab-generator/test-14-uuid.input
Normal file
1
test/test-fstab-generator/test-14-uuid.input
Normal file
@ -0,0 +1 @@
|
||||
root=UUID=3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
@ -0,0 +1,5 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Requires=dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
After=dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
@ -0,0 +1,14 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.target
|
||||
|
||||
[Mount]
|
||||
What=/dev/disk/by-partuuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
Where=/sysroot
|
||||
Options=ro
|
||||
@ -0,0 +1,16 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Description=File System Check on /dev/disk/by-partuuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
Documentation=man:systemd-fsck-root.service(8)
|
||||
DefaultDependencies=no
|
||||
BindsTo=dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
Conflicts=shutdown.target
|
||||
After=initrd-root-device.target local-fs-pre.target dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-partuuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
TimeoutSec=0
|
||||
1
test/test-fstab-generator/test-15-partuuid.input
Normal file
1
test/test-fstab-generator/test-15-partuuid.input
Normal file
@ -0,0 +1 @@
|
||||
root=PARTUUID=3f5ad593-4546-4a94-a374-bcfb68aa11f7
|
||||
@ -0,0 +1,12 @@
|
||||
# Automatically generated by systemd-fstab-generator
|
||||
|
||||
[Unit]
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
|
||||
[Mount]
|
||||
What=rootfs
|
||||
Where=/sysroot
|
||||
Type=tmpfs
|
||||
Options=rw
|
||||
1
test/test-fstab-generator/test-16-tmpfs.input
Normal file
1
test/test-fstab-generator/test-16-tmpfs.input
Normal file
@ -0,0 +1 @@
|
||||
root=tmpfs
|
||||
@ -26,7 +26,7 @@ teardown() {
|
||||
}
|
||||
|
||||
run_test() {
|
||||
since="$(date +%T)"
|
||||
since="$(date '+%F %T')"
|
||||
|
||||
SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action add /dev/null
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ Description=Home Area Manager
|
||||
Documentation=man:systemd-homed.service(8)
|
||||
Documentation=man:org.freedesktop.home1(5)
|
||||
|
||||
After=home.mount
|
||||
After=home.mount dbus.service
|
||||
|
||||
[Service]
|
||||
BusName=org.freedesktop.home1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user