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

Compare commits

..

14 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek
6080987130
Merge pull request #18851 from yuwata/dissect-try-to-find-partition-on-timeout
dissect: try to find partition more frequently
2021-06-10 19:09:18 +02:00
Zbigniew Jędrzejewski-Szmek
c3988f36d3
Merge pull request #19870 from keszybz/install-foo-again
Tweak the install logic again
2021-06-10 18:56:03 +02:00
Lennart Poettering
31251469c0
Merge pull request #19878 from poettering/large-key-file-cryptsetup
add back support for large key files to systemd-cryptsetup
2021-06-10 17:10:32 +02:00
Štěpán Němec
6ae11e1220 docs/CODING_STYLE: fix some typos 2021-06-10 15:29:28 +01:00
Lennart Poettering
871f35af85 cryptsetup: improve error message when key files to load are too large
Let's make this easier to grok for users.

Prompted-by: #19193
2021-06-10 10:55:02 +02:00
Lennart Poettering
f6dd48fae8 fileio: bump limit for read_full_file() and friends to 64M
Apparently people use such large key files. Specifically, people used 4M
key files, and we lowered the limit from 4M to 4M-1 back in 248.

This raises the limit to 64M for read_full_file() to avoid these
specific issues and give some non-trivial room beyond the 4M files seen
IRL.

Note that that a 64M allocation in glibc is always immediately done via
mmap(), and is thus a lot slower than shorter allocations. This means
read_virtual_file() becomes ridiculously slow if we'd use the large
limit, since we use it all the time for reading /proc and /sys metadata,
and read_virtual_file() typically allocates the full size with malloc()
in advance.  In fact it becomes so slow, that test-process-util kept
timing out on me all the time, once I blindly raised the limit.

This patch hence introduces two distinct limits for read_full_file() and
read_virtual_file(): the former is much larger than the latter and the
latter remains where it is. This is safe since the former uses an
exponentially growing realloc() loop while the latter uses the
aforementioend ahead-of-time full limit allocation.

Fixes: #19193
2021-06-10 10:51:00 +02:00
Zbigniew Jędrzejewski-Szmek
ad5fdd3912 shared/install: ignore enablement of template units w/o instance when presetting
When we have a unit which cannot be enabled:
 # foo@.service:
 ...
 [Install]
 WantedBy=foo.target  # there is no instance, so we don't know what to enable

we should throw an error when invoked directly with 'enable', but
not when doing 'preset' or 'preset-all'.

Fixes #19856.
2021-06-10 10:02:38 +02:00
Zbigniew Jędrzejewski-Szmek
9b69770a49 shared/install: pass UnitFileFlags down into the call chain
This just propagates the parameter down into leaf functions,
without any functional change.
2021-06-10 10:00:36 +02:00
Zbigniew Jędrzejewski-Szmek
8331b221ba core/dbus: rename internal variable for clarity 2021-06-10 07:32:38 +02:00
Zbigniew Jędrzejewski-Szmek
e1f2f7f194 shared/install: improve message about template mismatch
$ systemctl enable --root=/ serial-getty@.service
Failed to enable unit, unit getty.target is a non-template unit.
↓
Failed to enable serial-getty@.service, destination unit getty.target is a non-template unit.
2021-06-09 21:39:33 +02:00
Zbigniew Jędrzejewski-Szmek
4a203a5177 shared/install: remove custom error handling in unit_file_preset_all()
This had some purpose back in the day, but right now I cannot see what
difference this makes. It's hard to keep the list of all possible errors up to
date. So let's remove this, hopefully nothing breaks.
2021-06-09 21:39:33 +02:00
Zbigniew Jędrzejewski-Szmek
3aa96361ed shared/install: ignore failures for auxiliary files
If Also= fails, warn, but otherwise ignore the failure.

Fixes #19407.
2021-06-09 21:39:15 +02:00
Yu Watanabe
61730746f7 dissect: find partition more frequently
With the previous commit, the partition may be found after 45 sec. It is
too late. Let's find partition more frequently.
2021-06-09 02:54:44 +09:00
Yu Watanabe
05c3c620f7 dissect: try to find partition again on timeout
Not sure, but at the time the target partition device is created or
enumerated, some sysattrs or properties may not be ready.

So, let's find partition on timeout. The device may be ready at that
time.
2021-06-09 02:54:29 +09:00
8 changed files with 171 additions and 67 deletions

View File

@ -404,7 +404,7 @@ layout: default
limits after which it will refuse operation. It's fine if it is hard-coded
(at least initially), but it needs to be there. This is particularly
important for objects that unprivileged users may allocate, but also matters
for everything else any user may allocated.
for everything else any user may allocate.
## Types
@ -439,7 +439,7 @@ layout: default
- Use the bool type for booleans, not integers. One exception: in public
headers (i.e those in `src/systemd/sd-*.h`) use integers after all, as `bool`
is C99 and in our public APIs we try to stick to C89 (with a few extension).
is C99 and in our public APIs we try to stick to C89 (with a few extensions).
## Deadlocks
@ -556,7 +556,7 @@ layout: default
process, please use `_exit()` instead of `exit()`, so that the exit handlers
are not run.
- We never use the POSIX version of `basename()` (which glibc defines it in
- We never use the POSIX version of `basename()` (which glibc defines in
`libgen.h`), only the GNU version (which glibc defines in `string.h`). The
only reason to include `libgen.h` is because `dirname()` is needed. Every
time you need that please immediately undefine `basename()`, and add a
@ -565,7 +565,7 @@ layout: default
- Never use `FILENAME_MAX`. Use `PATH_MAX` instead (for checking maximum size
of paths) and `NAME_MAX` (for checking maximum size of filenames).
`FILENAME_MAX` is not POSIX, and is a confusingly named alias for `PATH_MAX`
on Linux. Note the `NAME_MAX` does not include space for a trailing `NUL`,
on Linux. Note that `NAME_MAX` does not include space for a trailing `NUL`,
but `PATH_MAX` does. UNIX FTW!
## Committing to git

View File

@ -27,8 +27,17 @@
#include "string-util.h"
#include "tmpfile-util.h"
/* The maximum size of the file we'll read in one go. */
#define READ_FULL_BYTES_MAX (4U*1024U*1024U - 1)
/* The maximum size of the file we'll read in one go in read_full_file() (64M). */
#define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U)
/* The maximum size of virtual files we'll read in one go in read_virtual_file() (4M). Note that this limit
* is different (and much lower) than the READ_FULL_BYTES_MAX limit. This reflects the fact that we use
* different strategies for reading virtual and regular files: virtual files are generally size constrained:
* there we allocate the full buffer size in advance. Regular files OTOH can be much larger, and here we grow
* the allocations exponentially in a loop. In glibc large allocations are immediately backed by mmap()
* making them relatively slow (measurably so). Thus, when allocating the full buffer in advance the large
* limit is a problem. When allocating piecemeal it's not. Hence pick two distinct limits. */
#define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 1U)
int fopen_unlocked(const char *path, const char *options, FILE **ret) {
assert(ret);
@ -388,7 +397,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
if (fd < 0)
return -errno;
assert(max_size <= READ_FULL_BYTES_MAX || max_size == SIZE_MAX);
assert(max_size <= READ_VIRTUAL_BYTES_MAX || max_size == SIZE_MAX);
/* Limit the number of attempts to read the number of bytes returned by fstat(). */
n_retries = 3;
@ -403,7 +412,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
return -EBADF;
/* Be prepared for files from /proc which generally report a file size of 0. */
assert_cc(READ_FULL_BYTES_MAX < SSIZE_MAX);
assert_cc(READ_VIRTUAL_BYTES_MAX < SSIZE_MAX);
if (st.st_size > 0 && n_retries > 1) {
/* Let's use the file size if we have more than 1 attempt left. On the last attempt
* we'll ignore the file size */
@ -417,13 +426,13 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
} else {
size = MIN((size_t) st.st_size, max_size);
if (size > READ_FULL_BYTES_MAX)
if (size > READ_VIRTUAL_BYTES_MAX)
return -EFBIG;
}
n_retries--;
} else {
size = MIN(READ_FULL_BYTES_MAX, max_size);
size = MIN(READ_VIRTUAL_BYTES_MAX, max_size);
n_retries = 0;
}
@ -432,7 +441,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
return -ENOMEM;
/* Use a bigger allocation if we got it anyway, but not more than the limit. */
size = MIN3(MALLOC_SIZEOF_SAFE(buf) - 1, max_size, READ_FULL_BYTES_MAX);
size = MIN3(MALLOC_SIZEOF_SAFE(buf) - 1, max_size, READ_VIRTUAL_BYTES_MAX);
for (;;) {
ssize_t k;
@ -572,7 +581,7 @@ int read_full_stream_full(
}
memcpy_safe(t, buf, n);
explicit_bzero_safe(buf, n);
buf = mfree(buf);
free(buf);
} else {
t = realloc(buf, n_next + 1);
if (!t)

View File

@ -2272,7 +2272,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
UnitFileChange *changes = NULL;
size_t n_changes = 0;
Manager *m = userdata;
UnitFilePresetMode mm;
UnitFilePresetMode preset_mode;
int runtime, force, r;
UnitFileFlags flags;
const char *mode;
@ -2291,10 +2291,10 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
flags = unit_file_bools_to_flags(runtime, force);
if (isempty(mode))
mm = UNIT_FILE_PRESET_FULL;
preset_mode = UNIT_FILE_PRESET_FULL;
else {
mm = unit_file_preset_mode_from_string(mode);
if (mm < 0)
preset_mode = unit_file_preset_mode_from_string(mode);
if (preset_mode < 0)
return -EINVAL;
}
@ -2304,7 +2304,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = unit_file_preset(m->unit_file_scope, flags, NULL, l, mm, &changes, &n_changes);
r = unit_file_preset(m->unit_file_scope, flags, NULL, l, preset_mode, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
@ -2436,7 +2436,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
UnitFileChange *changes = NULL;
size_t n_changes = 0;
Manager *m = userdata;
UnitFilePresetMode mm;
UnitFilePresetMode preset_mode;
const char *mode;
UnitFileFlags flags;
int force, runtime, r;
@ -2455,10 +2455,10 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
flags = unit_file_bools_to_flags(runtime, force);
if (isempty(mode))
mm = UNIT_FILE_PRESET_FULL;
preset_mode = UNIT_FILE_PRESET_FULL;
else {
mm = unit_file_preset_mode_from_string(mode);
if (mm < 0)
preset_mode = unit_file_preset_mode_from_string(mode);
if (preset_mode < 0)
return -EINVAL;
}
@ -2468,7 +2468,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = unit_file_preset_all(m->unit_file_scope, flags, NULL, mm, &changes, &n_changes);
r = unit_file_preset_all(m->unit_file_scope, flags, NULL, preset_mode, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);

View File

@ -26,6 +26,8 @@ int find_key_file(
READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
bindname,
(char**) ret_key, ret_key_size);
if (r == -E2BIG)
return log_error_errno(r, "Key file '%s' too large.", key_file);
if (r < 0)
return log_error_errno(r, "Failed to load key file '%s': %m", key_file);
@ -46,6 +48,10 @@ int find_key_file(
(char**) ret_key, ret_key_size);
if (r >= 0)
return 1;
if (r == -E2BIG) {
log_warning_errno(r, "Key file '%s' too large, ignoring.", key_file);
continue;
}
if (r != -ENOENT)
return log_error_errno(r, "Failed to load key file '%s': %m", key_file);
}

View File

@ -1261,6 +1261,10 @@ static int attach_luks_or_plain_or_bitlk_by_key_file(
READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
bindname,
&kfdata, &kfsize);
if (r == -E2BIG) {
log_error_errno(r, "Failed to activate, key file '%s' too large.", key_file);
return -EAGAIN;
}
if (r == -ENOENT) {
log_error_errno(r, "Failed to activate, key file '%s' missing.", key_file);
return -EAGAIN; /* Log actual error, but return EAGAIN */

View File

@ -285,6 +285,8 @@ struct wait_data {
blkid_partition blkidp;
sd_device *found;
uint64_t uevent_seqnum_not_before;
usec_t timestamp_not_before;
DissectImageFlags flags;
};
static inline void wait_data_done(struct wait_data *d) {
@ -329,6 +331,49 @@ finish:
return sd_event_exit(sd_device_monitor_get_event(monitor), r);
}
static int timeout_handler(sd_event_source *s, uint64_t usec, void *userdata) {
struct wait_data *w = userdata;
int r;
assert(w);
/* Why partition not appeared within the timeout? We may lost some uevent, as some properties
* were not ready when we received uevent... Not sure, but anyway, let's try to find the
* partition again before give up. */
r = find_partition(w->parent_device, w->blkidp, w->timestamp_not_before, w->flags, &w->found);
if (r == -ENXIO)
return log_debug_errno(SYNTHETIC_ERRNO(ETIMEDOUT),
"Partition still not appeared after timeout reached.");
if (r < 0)
return log_debug_errno(r, "Failed to find partition: %m");
log_debug("Partition appeared after timeout reached.");
return sd_event_exit(sd_event_source_get_event(s), 0);
}
static int retry_handler(sd_event_source *s, uint64_t usec, void *userdata) {
struct wait_data *w = userdata;
int r;
assert(w);
r = find_partition(w->parent_device, w->blkidp, w->timestamp_not_before, w->flags, &w->found);
if (r != -ENXIO) {
if (r < 0)
return log_debug_errno(r, "Failed to find partition: %m");
log_debug("Partition found by a periodic search.");
return sd_event_exit(sd_event_source_get_event(s), 0);
}
r = sd_event_source_set_time_relative(s, 500 * USEC_PER_MSEC);
if (r < 0)
return r;
return sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
}
static int wait_for_partition_device(
sd_device *parent,
blkid_partition pp,
@ -338,7 +383,7 @@ static int wait_for_partition_device(
DissectImageFlags flags,
sd_device **ret) {
_cleanup_(sd_event_source_unrefp) sd_event_source *timeout_source = NULL;
_cleanup_(sd_event_source_unrefp) sd_event_source *timeout_source = NULL, *retry_source = NULL;
_cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
int r;
@ -379,6 +424,8 @@ static int wait_for_partition_device(
.parent_device = parent,
.blkidp = pp,
.uevent_seqnum_not_before = uevent_seqnum_not_before,
.timestamp_not_before = timestamp_not_before,
.flags = flags,
};
r = sd_device_monitor_start(monitor, device_monitor_handler, &w);
@ -394,11 +441,26 @@ static int wait_for_partition_device(
r = sd_event_add_time(
event, &timeout_source,
CLOCK_MONOTONIC, deadline, 0,
NULL, INT_TO_PTR(-ETIMEDOUT));
timeout_handler, &w);
if (r < 0)
return r;
r = sd_event_source_set_exit_on_failure(timeout_source, true);
if (r < 0)
return r;
}
r = sd_event_add_time_relative(
event, &retry_source,
CLOCK_MONOTONIC, 500 * USEC_PER_MSEC, 0,
retry_handler, &w);
if (r < 0)
return r;
r = sd_event_source_set_exit_on_failure(retry_source, true);
if (r < 0)
return r;
r = sd_event_loop(event);
if (r < 0)
return r;

View File

@ -269,7 +269,6 @@ int unit_file_changes_add(
_cleanup_free_ char *p = NULL, *s = NULL;
UnitFileChange *c;
assert(path);
assert(!changes == !n_changes);
if (type_or_errno >= 0)
@ -285,11 +284,13 @@ int unit_file_changes_add(
return -ENOMEM;
*changes = c;
p = strdup(path);
if (!p)
return -ENOMEM;
if (path) {
p = strdup(path);
if (!p)
return -ENOMEM;
path_simplify(p);
path_simplify(p);
}
if (source) {
s = strdup(source);
@ -355,6 +356,10 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
log_warning("Unit %s is added as a dependency to a non-existent unit %s.",
changes[i].source, changes[i].path);
break;
case UNIT_FILE_AUXILIARY_FAILED:
if (!quiet)
log_warning("Failed to enable auxiliary unit %s, ignoring.", changes[i].source);
break;
case -EEXIST:
if (changes[i].source)
log_error_errno(changes[i].type_or_errno,
@ -377,8 +382,8 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
logged = true;
break;
case -EIDRM:
log_error_errno(changes[i].type_or_errno, "Failed to %s unit, unit %s is a non-template unit.",
verb, changes[i].path);
log_error_errno(changes[i].type_or_errno, "Failed to %s %s, destination unit %s is a non-template unit.",
verb, changes[i].source, changes[i].path);
logged = true;
break;
case -EUCLEAN:
@ -1843,6 +1848,7 @@ static int install_info_symlink_alias(
static int install_info_symlink_wants(
UnitFileScope scope,
UnitFileFlags file_flags,
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
@ -1910,8 +1916,16 @@ static int install_info_symlink_wants(
return q;
if (!unit_name_is_valid(dst, valid_dst_type)) {
/* Generate a proper error here: EUCLEAN if the name is generally bad,
* EIDRM if the template status doesn't match. */
/* Generate a proper error here: EUCLEAN if the name is generally bad, EIDRM if the
* template status doesn't match. If we are doing presets don't bother reporting the
* error. This also covers cases like 'systemctl preset serial-getty@.service', which
* has no DefaultInstance, so there is nothing we can do. At the same time,
* 'systemctl enable serial-getty@.service' should fail, the user should specify an
* instance like in 'systemctl enable serial-getty@ttyS0.service'.
*/
if (file_flags & UNIT_FILE_IGNORE_AUXILIARY_FAILURE)
continue;
if (unit_name_is_valid(dst, UNIT_NAME_ANY)) {
unit_file_changes_add(changes, n_changes, -EIDRM, dst, n);
r = -EIDRM;
@ -1969,10 +1983,10 @@ static int install_info_symlink_link(
static int install_info_apply(
UnitFileScope scope,
UnitFileFlags file_flags,
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
bool force,
UnitFileChange **changes,
size_t *n_changes) {
@ -1985,13 +1999,15 @@ static int install_info_apply(
if (i->type != UNIT_FILE_TYPE_REGULAR)
return 0;
bool force = file_flags & UNIT_FILE_FORCE;
r = install_info_symlink_alias(i, paths, config_path, force, changes, n_changes);
q = install_info_symlink_wants(scope, i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
q = install_info_symlink_wants(scope, file_flags, i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
if (r == 0)
r = q;
q = install_info_symlink_wants(scope, i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
q = install_info_symlink_wants(scope, file_flags, i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
if (r == 0)
r = q;
@ -2005,10 +2021,10 @@ static int install_info_apply(
static int install_context_apply(
UnitFileScope scope,
UnitFileFlags file_flags,
InstallContext *c,
const LookupPaths *paths,
const char *config_path,
bool force,
SearchFlags flags,
UnitFileChange **changes,
size_t *n_changes) {
@ -2037,6 +2053,13 @@ static int install_context_apply(
q = install_info_traverse(scope, c, paths, i, flags, NULL);
if (q < 0) {
if (i->auxiliary) {
q = unit_file_changes_add(changes, n_changes, UNIT_FILE_AUXILIARY_FAILED, NULL, i->name);
if (q < 0)
return q;
continue;
}
unit_file_changes_add(changes, n_changes, q, i->name, NULL);
return q;
}
@ -2055,7 +2078,7 @@ static int install_context_apply(
if (i->type != UNIT_FILE_TYPE_REGULAR)
continue;
q = install_info_apply(scope, i, paths, config_path, force, changes, n_changes);
q = install_info_apply(scope, file_flags, i, paths, config_path, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
@ -2528,7 +2551,7 @@ int unit_file_revert(
int unit_file_add_dependency(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
char **files,
const char *target,
@ -2557,7 +2580,7 @@ int unit_file_add_dependency(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
config_path = (file_flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
@ -2593,12 +2616,13 @@ int unit_file_add_dependency(
return -ENOMEM;
}
return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
return install_context_apply(scope, file_flags, &c, &paths, config_path,
SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
}
int unit_file_enable(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
@ -2618,7 +2642,7 @@ int unit_file_enable(
if (r < 0)
return r;
config_path = config_path_from_flags(&paths, flags);
config_path = config_path_from_flags(&paths, file_flags);
if (!config_path)
return -ENXIO;
@ -2636,7 +2660,7 @@ int unit_file_enable(
is useful to determine whether the passed files had any
installation data at all. */
return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_LOAD, changes, n_changes);
return install_context_apply(scope, file_flags, &c, &paths, config_path, SEARCH_LOAD, changes, n_changes);
}
int unit_file_disable(
@ -3166,13 +3190,13 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
static int execute_preset(
UnitFileScope scope,
UnitFileFlags file_flags,
InstallContext *plus,
InstallContext *minus,
const LookupPaths *paths,
const char *config_path,
char **files,
UnitFilePresetMode mode,
bool force,
UnitFileChange **changes,
size_t *n_changes) {
@ -3198,7 +3222,9 @@ static int execute_preset(
int q;
/* Returns number of symlinks that where supposed to be installed. */
q = install_context_apply(scope, plus, paths, config_path, force, SEARCH_LOAD, changes, n_changes);
q = install_context_apply(scope,
file_flags | UNIT_FILE_IGNORE_AUXILIARY_FAILURE,
plus, paths, config_path, SEARCH_LOAD, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
@ -3266,7 +3292,7 @@ static int preset_prepare_one(
int unit_file_preset(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
char **files,
UnitFilePresetMode mode,
@ -3288,7 +3314,7 @@ int unit_file_preset(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
config_path = (file_flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
@ -3302,12 +3328,12 @@ int unit_file_preset(
return r;
}
return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
return execute_preset(scope, file_flags, &plus, &minus, &paths, config_path, files, mode, changes, n_changes);
}
int unit_file_preset_all(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
UnitFilePresetMode mode,
UnitFileChange **changes,
@ -3328,7 +3354,7 @@ int unit_file_preset_all(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
config_path = (file_flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
@ -3358,22 +3384,16 @@ int unit_file_preset_all(
if (!IN_SET(de->d_type, DT_LNK, DT_REG))
continue;
/* we don't pass changes[] in, because we want to handle errors on our own */
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, &presets, NULL, 0);
if (r == -ERFKILL)
r = unit_file_changes_add(changes, n_changes,
UNIT_FILE_IS_MASKED, de->d_name, NULL);
else if (r == -ENOLINK)
r = unit_file_changes_add(changes, n_changes,
UNIT_FILE_IS_DANGLING, de->d_name, NULL);
else if (r == -EADDRNOTAVAIL) /* Ignore generated/transient units when applying preset */
continue;
if (r < 0)
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, &presets, changes, n_changes);
if (r < 0 &&
!IN_SET(r, -EEXIST, -ERFKILL, -EADDRNOTAVAIL, -EIDRM, -EUCLEAN, -ELOOP, -ENOENT))
/* Ignore generated/transient/missing/invalid units when applying preset, propagate other errors.
* Coordinate with unit_file_dump_changes() above. */
return r;
}
}
return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
return execute_preset(scope, file_flags, &plus, &minus, &paths, config_path, NULL, mode, changes, n_changes);
}
static UnitFileList* unit_file_list_free_one(UnitFileList *f) {
@ -3493,6 +3513,7 @@ static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX]
[UNIT_FILE_IS_MASKED] = "masked",
[UNIT_FILE_IS_DANGLING] = "dangling",
[UNIT_FILE_DESTINATION_NOT_PRESENT] = "destination not present",
[UNIT_FILE_AUXILIARY_FAILED] = "auxiliary unit failed",
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, int);

View File

@ -33,15 +33,17 @@ enum {
UNIT_FILE_IS_MASKED,
UNIT_FILE_IS_DANGLING,
UNIT_FILE_DESTINATION_NOT_PRESENT,
UNIT_FILE_AUXILIARY_FAILED,
_UNIT_FILE_CHANGE_TYPE_MAX,
_UNIT_FILE_CHANGE_TYPE_INVALID = -EINVAL,
};
enum UnitFileFlags {
UNIT_FILE_RUNTIME = 1 << 0, /* Public API via DBUS, do not change */
UNIT_FILE_FORCE = 1 << 1, /* Public API via DBUS, do not change */
UNIT_FILE_PORTABLE = 1 << 2, /* Public API via DBUS, do not change */
UNIT_FILE_DRY_RUN = 1 << 3,
UNIT_FILE_RUNTIME = 1 << 0, /* Public API via DBUS, do not change */
UNIT_FILE_FORCE = 1 << 1, /* Public API via DBUS, do not change */
UNIT_FILE_PORTABLE = 1 << 2, /* Public API via DBUS, do not change */
UNIT_FILE_DRY_RUN = 1 << 3,
UNIT_FILE_IGNORE_AUXILIARY_FAILURE = 1 << 4,
_UNIT_FILE_FLAGS_MASK_PUBLIC = UNIT_FILE_RUNTIME|UNIT_FILE_PORTABLE|UNIT_FILE_FORCE,
};