Compare commits

..

14 Commits

Author SHA1 Message Date
Anita Zhang cee33a7ab3
Merge pull request #14001 from keszybz/test-unit-name-more
Test unit name more
2019-11-12 10:59:55 -08:00
Zbigniew Jędrzejewski-Szmek d1be9a4380
Merge pull request #13984 from yuwata/udev-fix-13976
udev: fix issue #13976
2019-11-12 19:05:24 +01:00
Zbigniew Jędrzejewski-Szmek 637bc63a5c
Merge pull request #13989 from keszybz/meson-warning
Adjust compiler option management to avoid warnings from meson
2019-11-12 19:03:50 +01:00
Lennart Poettering 462255c65b meson: order list of dependencies of libshared alphabetically
Let's make merging patches against this more stable.
2019-11-12 15:30:18 +01:00
Lennart Poettering 91fc013fc4 update TODO 2019-11-12 15:18:37 +01:00
Franck Bui 8246905af0 logind: fix (again) the race that might happen when logind restores VT
This patch is a new attempt to fix the race originally described in issue #9754.

The initial fix (commit ad96887a12) consisted in
spawning a sub process that became the controlling process of the VT and hence
kicked the old controlling process off to make sure that the VT wouldn't have
entered in HUP state while logind restored the VT.

But it introduced a regression (see issue #11269) and thus was reverted. But
unlike it was described in the revert commit message, commit
adb8688b3f alone doen't fix the initial race.

This patch fixes the race in a simpler way by trying to restore the VT a second
time after making sure to re-open it if the first attempt fails.

Indeed if the old controlling process dies before or during the first attempt,
logind will fail to restore the VT. At this point the VT is in HUP state but
we're sure that it won't enter in a HUP state a second time. Therefore we will
retry by re-opening the VT to clear the HUP state and by restoring the VT a
second time, which should be safe this time.

Fixes: #9754
Fixes: #13241
2019-11-12 14:53:24 +01:00
Zbigniew Jędrzejewski-Szmek 642f41a4ec test-unit-name: check that unexpanded specifiers not valid unit name make 2019-11-12 11:52:22 +01:00
Zbigniew Jędrzejewski-Szmek c86ebcf389 test-unit-name: add usual headers and add more verbose output
This makes it easier to see what unit_name_is_valid() returns at a glance.
The output is not whitespace clean, but I think it's good enough for a test.
2019-11-12 11:52:22 +01:00
Zbigniew Jędrzejewski-Szmek e9f4f5667d meson: apply our -Wno-* options also in c++ calls
We compile some c++ code for tests. We would simply use the default options for
those. When the previous commit raised the default warning level, we started
getting warnings from c++ code. Let's add the most important options to the c++
command, so that we get a compilation without any warnings again.

I don't think it makes sense to add *all* the options that we add for c to the
c++ flags, because testing them takes quite a while, and the c++ compilations
are for small amounts of code, mostly to check that the headers have compatible
syntax.
2019-11-12 09:23:31 +01:00
Zbigniew Jędrzejewski-Szmek 827ca90986 meson: use warning_level=2 by default
Let's bump up the warning level, and not add by -Wextra by hand. This is the
approach recommended by meson. The idea is that all projects should be as
similar as possible to make it easier for users to switch between projects.
2019-11-12 09:23:31 +01:00
Zbigniew Jędrzejewski-Szmek cbe8049474 meson: avoid bogus meson warning
With meson-0.52.0-1.module_f31+6771+f5d842eb.noarch I get:
src/test/meson.build:19: WARNING: Overriding previous value of environment variable 'PATH' with a new one

When we're using *prepend*, the whole point is to modify an existing variable,
so meson shouldn't warn. But let's set avoid the warning and shorten things by
setting the final value immediately.
2019-11-12 09:23:31 +01:00
Yu Watanabe b64b83d13e udev: ignore error caused by device disconnection
During an add or change event, the device may be disconnected.

Fixes #13976.
2019-11-12 14:58:53 +09:00
Yu Watanabe ffdc9c891f udev: fix error code in the log message 2019-11-12 14:58:53 +09:00
Yu Watanabe 4b613ec212 udev: ignore ENOENT when chmod_and_chown() device node 2019-11-12 14:58:53 +09:00
8 changed files with 160 additions and 83 deletions

6
TODO
View File

@ -30,6 +30,12 @@ Before v244:
Features: Features:
* localed: if UTC is selected but timezone file for it doesn't exist, delete
/etc/localtime instead of creating a symlink
* socket units: allow creating a udev monitor socket with ListenDevices= or so,
with matches, then actviate app thorugh that passing socket oveer
* 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

View File

@ -8,6 +8,7 @@ project('systemd', 'c',
'prefix=/usr', 'prefix=/usr',
'sysconfdir=/etc', 'sysconfdir=/etc',
'localstatedir=/var', 'localstatedir=/var',
'warning_level=2',
], ],
meson_version : '>= 0.46', meson_version : '>= 0.46',
) )
@ -302,7 +303,8 @@ install_tests = get_option('install-tests')
if add_languages('cpp', required : fuzzer_build) if add_languages('cpp', required : fuzzer_build)
# Used only for tests # Used only for tests
cxx_cmd = ' '.join(meson.get_compiler('cpp').cmd_array()) cxx = meson.get_compiler('cpp')
cxx_cmd = ' '.join(cxx.cmd_array())
else else
cxx_cmd = '' cxx_cmd = ''
endif endif
@ -322,8 +324,25 @@ elif want_fuzzbuzz
fuzzing_engine = meson.get_compiler('cpp').find_library(get_option('fuzzbuzz-engine'), dirs: get_option('fuzzbuzz-engine-dir')) fuzzing_engine = meson.get_compiler('cpp').find_library(get_option('fuzzbuzz-engine'), dirs: get_option('fuzzbuzz-engine-dir'))
endif endif
# Those generate many false positives, and we do not want to change the code to
# avoid them.
basic_disabled_warnings = [
'-Wno-unused-parameter',
'-Wno-missing-field-initializers',
'-Wno-unused-result',
'-Wno-format-signedness',
]
if get_option('b_ndebug') == 'true'
# With asserts disabled with get a bunch of warnings about variables which
# are used only in the asserts. This is not useful at all, so let's just silence
# those warnings.
basic_disabled_warnings += [
'-Wno-unused-variable',
'-Wno-unused-but-set-variable',
]
endif
possible_cc_flags = [ possible_cc_flags = [
'-Wextra',
'-Werror=undef', '-Werror=undef',
'-Wlogical-op', '-Wlogical-op',
'-Wmissing-include-dirs', '-Wmissing-include-dirs',
@ -353,10 +372,6 @@ possible_cc_flags = [
'-Wnested-externs', '-Wnested-externs',
# negative arguments are correctly detected starting with meson 0.46. # negative arguments are correctly detected starting with meson 0.46.
'-Wno-unused-parameter',
'-Wno-missing-field-initializers',
'-Wno-unused-result',
'-Wno-format-signedness',
'-Wno-error=#warnings', # clang '-Wno-error=#warnings', # clang
'-Wno-string-plus-int', # clang '-Wno-string-plus-int', # clang
@ -401,16 +416,7 @@ if get_option('buildtype') != 'debug'
possible_link_flags += '-Wl,--gc-sections' possible_link_flags += '-Wl,--gc-sections'
endif endif
if get_option('b_ndebug') == 'true' add_project_arguments(cc.get_supported_arguments(basic_disabled_warnings), language : 'c')
# With asserts disabled with get a bunch of warnings about variables which
# are used only in the asserts. This is not useful at all, so let's just silence
# those warnings.
possible_cc_flags += [
'-Wno-unused-variable',
'-Wno-unused-but-set-variable',
]
endif
add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'c') add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'c')
add_project_link_arguments(cc.get_supported_link_arguments(possible_link_flags), language : 'c') add_project_link_arguments(cc.get_supported_link_arguments(possible_link_flags), language : 'c')
@ -427,6 +433,10 @@ if cc.compiles('''
add_project_arguments('-Werror=shadow', language : 'c') add_project_arguments('-Werror=shadow', language : 'c')
endif endif
if cxx_cmd != ''
add_project_arguments(cxx.get_supported_arguments(basic_disabled_warnings), language : 'cpp')
endif
cpp = ' '.join(cc.cmd_array()) + ' -E' cpp = ' '.join(cc.cmd_array()) + ' -E'
has_wstringop_truncation = cc.has_argument('-Wstringop-truncation') has_wstringop_truncation = cc.has_argument('-Wstringop-truncation')

View File

@ -1239,23 +1239,27 @@ error:
} }
static void session_restore_vt(Session *s) { static void session_restore_vt(Session *s) {
int r, vt, old_fd; int r;
/* We need to get a fresh handle to the virtual terminal, r = vt_restore(s->vtfd);
* since the old file-descriptor is potentially in a hung-up if (r == -EIO) {
* state after the controlling process exited; we do a int vt, old_fd;
* little dance to avoid having the terminal be available
* for reuse before we've cleaned it up.
*/
old_fd = TAKE_FD(s->vtfd);
vt = session_open_vt(s); /* It might happen if the controlling process exited before or while we were
safe_close(old_fd); * restoring the VT as it would leave the old file-descriptor in a hung-up
* state. In this case let's retry with a fresh handle to the virtual terminal. */
if (vt < 0) /* We do a little dance to avoid having the terminal be available
return; * for reuse before we've cleaned it up. */
old_fd = TAKE_FD(s->vtfd);
vt = session_open_vt(s);
safe_close(old_fd);
if (vt >= 0)
r = vt_restore(vt);
}
r = vt_restore(vt);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to restore VT, ignoring: %m"); log_warning_errno(r, "Failed to restore VT, ignoring: %m");

View File

@ -265,20 +265,20 @@ shared_sources += shared_generated_gperf_headers
libshared_name = 'systemd-shared-@0@'.format(meson.project_version()) libshared_name = 'systemd-shared-@0@'.format(meson.project_version())
libshared_deps = [threads, libshared_deps = [threads,
librt,
libcap,
libacl, libacl,
libblkid,
libcap,
libcryptsetup, libcryptsetup,
libgcrypt, libgcrypt,
libidn,
libiptc, libiptc,
libkmod, libkmod,
liblz4,
libmount, libmount,
librt,
libseccomp, libseccomp,
libselinux, libselinux,
libidn, libxz]
libxz,
liblz4,
libblkid]
libshared_sym_path = '@0@/libshared.sym'.format(meson.current_source_dir()) libshared_sym_path = '@0@/libshared.sym'.format(meson.current_source_dir())

View File

@ -11,12 +11,11 @@ test_hashmap_ordered_c = custom_target(
test_include_dir = include_directories('.') test_include_dir = include_directories('.')
path = run_command('sh', ['-c', 'echo "$PATH"']).stdout() path = run_command('sh', ['-c', 'echo "$PATH"']).stdout().strip()
test_env = environment() test_env = environment()
test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map) test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map)
test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map) test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
test_env.set('PATH', path) test_env.set('PATH', '@0@:@1@'.format(meson.build_root(), path))
test_env.prepend('PATH', meson.build_root())
############################################################ ############################################################

View File

@ -24,43 +24,61 @@
#include "user-util.h" #include "user-util.h"
#include "util.h" #include "util.h"
static void test_unit_name_is_valid_one(const char *name, UnitNameFlags flags, bool expected) {
log_info("%s ( %s%s%s ): %s",
name,
(flags & UNIT_NAME_PLAIN) ? "plain" : "",
(flags & UNIT_NAME_INSTANCE) ? " instance" : "",
(flags & UNIT_NAME_TEMPLATE) ? " template" : "",
yes_no(expected));
assert_se(unit_name_is_valid(name, flags) == expected);
}
static void test_unit_name_is_valid(void) { static void test_unit_name_is_valid(void) {
assert_se( unit_name_is_valid("foo.service", UNIT_NAME_ANY)); log_info("/* %s */", __func__);
assert_se( unit_name_is_valid("foo.service", UNIT_NAME_PLAIN));
assert_se(!unit_name_is_valid("foo.service", UNIT_NAME_INSTANCE));
assert_se(!unit_name_is_valid("foo.service", UNIT_NAME_TEMPLATE));
assert_se(!unit_name_is_valid("foo.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE));
assert_se( unit_name_is_valid("foo@bar.service", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo.service", UNIT_NAME_ANY, true);
assert_se(!unit_name_is_valid("foo@bar.service", UNIT_NAME_PLAIN)); test_unit_name_is_valid_one("foo.service", UNIT_NAME_PLAIN, true);
assert_se( unit_name_is_valid("foo@bar.service", UNIT_NAME_INSTANCE)); test_unit_name_is_valid_one("foo.service", UNIT_NAME_INSTANCE, false);
assert_se(!unit_name_is_valid("foo@bar.service", UNIT_NAME_TEMPLATE)); test_unit_name_is_valid_one("foo.service", UNIT_NAME_TEMPLATE, false);
assert_se( unit_name_is_valid("foo@bar.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)); test_unit_name_is_valid_one("foo.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE, false);
assert_se( unit_name_is_valid("foo@bar@bar.service", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo@bar.service", UNIT_NAME_ANY, true);
assert_se(!unit_name_is_valid("foo@bar@bar.service", UNIT_NAME_PLAIN)); test_unit_name_is_valid_one("foo@bar.service", UNIT_NAME_PLAIN, false);
assert_se( unit_name_is_valid("foo@bar@bar.service", UNIT_NAME_INSTANCE)); test_unit_name_is_valid_one("foo@bar.service", UNIT_NAME_INSTANCE, true);
assert_se(!unit_name_is_valid("foo@bar@bar.service", UNIT_NAME_TEMPLATE)); test_unit_name_is_valid_one("foo@bar.service", UNIT_NAME_TEMPLATE, false);
assert_se( unit_name_is_valid("foo@bar@bar.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)); test_unit_name_is_valid_one("foo@bar.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE, true);
assert_se( unit_name_is_valid("foo@.service", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo@bar@bar.service", UNIT_NAME_ANY, true);
assert_se(!unit_name_is_valid("foo@.service", UNIT_NAME_PLAIN)); test_unit_name_is_valid_one("foo@bar@bar.service", UNIT_NAME_PLAIN, false);
assert_se(!unit_name_is_valid("foo@.service", UNIT_NAME_INSTANCE)); test_unit_name_is_valid_one("foo@bar@bar.service", UNIT_NAME_INSTANCE, true);
assert_se( unit_name_is_valid("foo@.service", UNIT_NAME_TEMPLATE)); test_unit_name_is_valid_one("foo@bar@bar.service", UNIT_NAME_TEMPLATE, false);
assert_se( unit_name_is_valid("foo@.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)); test_unit_name_is_valid_one("foo@bar@bar.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE, true);
assert_se( unit_name_is_valid(".test.service", UNIT_NAME_PLAIN));
assert_se( unit_name_is_valid(".test@.service", UNIT_NAME_TEMPLATE));
assert_se( unit_name_is_valid("_strange::::.service", UNIT_NAME_ANY));
assert_se(!unit_name_is_valid(".service", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo@.service", UNIT_NAME_ANY, true);
assert_se(!unit_name_is_valid("", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo@.service", UNIT_NAME_PLAIN, false);
assert_se(!unit_name_is_valid("foo.waldo", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo@.service", UNIT_NAME_INSTANCE, false);
assert_se(!unit_name_is_valid("@.service", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo@.service", UNIT_NAME_TEMPLATE, true);
assert_se(!unit_name_is_valid("@piep.service", UNIT_NAME_ANY)); test_unit_name_is_valid_one("foo@.service", UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE, true);
test_unit_name_is_valid_one(".test.service", UNIT_NAME_PLAIN, true);
test_unit_name_is_valid_one(".test@.service", UNIT_NAME_TEMPLATE, true);
test_unit_name_is_valid_one("_strange::::.service", UNIT_NAME_ANY, true);
assert_se( unit_name_is_valid("user@1000.slice", UNIT_NAME_ANY)); test_unit_name_is_valid_one(".service", UNIT_NAME_ANY, false);
assert_se( unit_name_is_valid("user@1000.slice", UNIT_NAME_INSTANCE)); test_unit_name_is_valid_one("", UNIT_NAME_ANY, false);
assert_se(!unit_name_is_valid("user@1000.slice", UNIT_NAME_TEMPLATE)); test_unit_name_is_valid_one("foo.waldo", UNIT_NAME_ANY, false);
test_unit_name_is_valid_one("@.service", UNIT_NAME_ANY, false);
test_unit_name_is_valid_one("@piep.service", UNIT_NAME_ANY, false);
test_unit_name_is_valid_one("user@1000.slice", UNIT_NAME_ANY, true);
test_unit_name_is_valid_one("user@1000.slice", UNIT_NAME_INSTANCE, true);
test_unit_name_is_valid_one("user@1000.slice", UNIT_NAME_TEMPLATE, false);
test_unit_name_is_valid_one("foo@%i.service", UNIT_NAME_ANY, false);
test_unit_name_is_valid_one("foo@%i.service", UNIT_NAME_INSTANCE, false);
test_unit_name_is_valid_one("foo@%%i.service", UNIT_NAME_INSTANCE, false);
test_unit_name_is_valid_one("foo@%%i%f.service", UNIT_NAME_INSTANCE, false);
test_unit_name_is_valid_one("foo@%F.service", UNIT_NAME_INSTANCE, false);
} }
static void test_unit_name_replace_instance_one(const char *pattern, const char *repl, const char *expected, int ret) { static void test_unit_name_replace_instance_one(const char *pattern, const char *repl, const char *expected, int ret) {
@ -71,7 +89,8 @@ static void test_unit_name_replace_instance_one(const char *pattern, const char
} }
static void test_unit_name_replace_instance(void) { static void test_unit_name_replace_instance(void) {
puts("-------------------------------------------------"); log_info("/* %s */", __func__);
test_unit_name_replace_instance_one("foo@.service", "waldo", "foo@waldo.service", 0); test_unit_name_replace_instance_one("foo@.service", "waldo", "foo@waldo.service", 0);
test_unit_name_replace_instance_one("foo@xyz.service", "waldo", "foo@waldo.service", 0); test_unit_name_replace_instance_one("foo@xyz.service", "waldo", "foo@waldo.service", 0);
test_unit_name_replace_instance_one("xyz", "waldo", NULL, -EINVAL); test_unit_name_replace_instance_one("xyz", "waldo", NULL, -EINVAL);
@ -98,7 +117,8 @@ static void test_unit_name_from_path_one(const char *path, const char *suffix, c
} }
static void test_unit_name_from_path(void) { static void test_unit_name_from_path(void) {
puts("-------------------------------------------------"); log_info("/* %s */", __func__);
test_unit_name_from_path_one("/waldo", ".mount", "waldo.mount", 0); test_unit_name_from_path_one("/waldo", ".mount", "waldo.mount", 0);
test_unit_name_from_path_one("/waldo/quuix", ".mount", "waldo-quuix.mount", 0); test_unit_name_from_path_one("/waldo/quuix", ".mount", "waldo-quuix.mount", 0);
test_unit_name_from_path_one("/waldo/quuix/", ".mount", "waldo-quuix.mount", 0); test_unit_name_from_path_one("/waldo/quuix/", ".mount", "waldo-quuix.mount", 0);
@ -126,7 +146,7 @@ static void test_unit_name_from_path_instance_one(const char *pattern, const cha
} }
static void test_unit_name_from_path_instance(void) { static void test_unit_name_from_path_instance(void) {
puts("-------------------------------------------------"); log_info("/* %s */", __func__);
test_unit_name_from_path_instance_one("waldo", "/waldo", ".mount", "waldo@waldo.mount", 0); test_unit_name_from_path_instance_one("waldo", "/waldo", ".mount", "waldo@waldo.mount", 0);
test_unit_name_from_path_instance_one("waldo", "/waldo////quuix////", ".mount", "waldo@waldo-quuix.mount", 0); test_unit_name_from_path_instance_one("waldo", "/waldo////quuix////", ".mount", "waldo@waldo-quuix.mount", 0);
@ -146,6 +166,8 @@ static void test_unit_name_to_path_one(const char *unit, const char *path, int r
} }
static void test_unit_name_to_path(void) { static void test_unit_name_to_path(void) {
log_info("/* %s */", __func__);
test_unit_name_to_path_one("home.mount", "/home", 0); test_unit_name_to_path_one("home.mount", "/home", 0);
test_unit_name_to_path_one("home-lennart.mount", "/home/lennart", 0); test_unit_name_to_path_one("home-lennart.mount", "/home/lennart", 0);
test_unit_name_to_path_one("home-lennart-.mount", NULL, -EINVAL); test_unit_name_to_path_one("home-lennart-.mount", NULL, -EINVAL);
@ -175,7 +197,8 @@ static void test_unit_name_mangle_one(bool allow_globs, const char *pattern, con
} }
static void test_unit_name_mangle(void) { static void test_unit_name_mangle(void) {
puts("-------------------------------------------------"); log_info("/* %s */", __func__);
test_unit_name_mangle_one(false, "foo.service", "foo.service", 0); test_unit_name_mangle_one(false, "foo.service", "foo.service", 0);
test_unit_name_mangle_one(false, "/home", "home.mount", 1); test_unit_name_mangle_one(false, "/home", "home.mount", 1);
test_unit_name_mangle_one(false, "/dev/sda", "dev-sda.device", 1); test_unit_name_mangle_one(false, "/dev/sda", "dev-sda.device", 1);
@ -198,6 +221,8 @@ static int test_unit_printf(void) {
Unit *u; Unit *u;
int r; int r;
log_info("/* %s */", __func__);
assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid); assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid); assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
assert_se(host = gethostname_malloc()); assert_se(host = gethostname_malloc());
@ -299,6 +324,8 @@ static int test_unit_printf(void) {
} }
static void test_unit_instance_is_valid(void) { static void test_unit_instance_is_valid(void) {
log_info("/* %s */", __func__);
assert_se(unit_instance_is_valid("fooBar")); assert_se(unit_instance_is_valid("fooBar"));
assert_se(unit_instance_is_valid("foo-bar")); assert_se(unit_instance_is_valid("foo-bar"));
assert_se(unit_instance_is_valid("foo.stUff")); assert_se(unit_instance_is_valid("foo.stUff"));
@ -312,6 +339,8 @@ static void test_unit_instance_is_valid(void) {
} }
static void test_unit_prefix_is_valid(void) { static void test_unit_prefix_is_valid(void) {
log_info("/* %s */", __func__);
assert_se(unit_prefix_is_valid("fooBar")); assert_se(unit_prefix_is_valid("fooBar"));
assert_se(unit_prefix_is_valid("foo-bar")); assert_se(unit_prefix_is_valid("foo-bar"));
assert_se(unit_prefix_is_valid("foo.stUff")); assert_se(unit_prefix_is_valid("foo.stUff"));
@ -328,6 +357,8 @@ static void test_unit_prefix_is_valid(void) {
static void test_unit_name_change_suffix(void) { static void test_unit_name_change_suffix(void) {
char *t; char *t;
log_info("/* %s */", __func__);
assert_se(unit_name_change_suffix("foo.mount", ".service", &t) == 0); assert_se(unit_name_change_suffix("foo.mount", ".service", &t) == 0);
assert_se(streq(t, "foo.service")); assert_se(streq(t, "foo.service"));
free(t); free(t);
@ -340,6 +371,8 @@ static void test_unit_name_change_suffix(void) {
static void test_unit_name_build(void) { static void test_unit_name_build(void) {
char *t; char *t;
log_info("/* %s */", __func__);
assert_se(unit_name_build("foo", "bar", ".service", &t) == 0); assert_se(unit_name_build("foo", "bar", ".service", &t) == 0);
assert_se(streq(t, "foo@bar.service")); assert_se(streq(t, "foo@bar.service"));
free(t); free(t);
@ -354,6 +387,8 @@ static void test_unit_name_build(void) {
} }
static void test_slice_name_is_valid(void) { static void test_slice_name_is_valid(void) {
log_info("/* %s */", __func__);
assert_se( slice_name_is_valid(SPECIAL_ROOT_SLICE)); assert_se( slice_name_is_valid(SPECIAL_ROOT_SLICE));
assert_se( slice_name_is_valid("foo.slice")); assert_se( slice_name_is_valid("foo.slice"));
assert_se( slice_name_is_valid("foo-bar.slice")); assert_se( slice_name_is_valid("foo-bar.slice"));
@ -386,6 +421,8 @@ static void test_build_subslice(void) {
char *a; char *a;
char *b; char *b;
log_info("/* %s */", __func__);
assert_se(slice_build_subslice(SPECIAL_ROOT_SLICE, "foo", &a) >= 0); assert_se(slice_build_subslice(SPECIAL_ROOT_SLICE, "foo", &a) >= 0);
assert_se(slice_build_subslice(a, "bar", &b) >= 0); assert_se(slice_build_subslice(a, "bar", &b) >= 0);
free(a); free(a);
@ -408,6 +445,8 @@ static void test_build_parent_slice_one(const char *name, const char *expect, in
} }
static void test_build_parent_slice(void) { static void test_build_parent_slice(void) {
log_info("/* %s */", __func__);
test_build_parent_slice_one(SPECIAL_ROOT_SLICE, NULL, 0); test_build_parent_slice_one(SPECIAL_ROOT_SLICE, NULL, 0);
test_build_parent_slice_one("foo.slice", SPECIAL_ROOT_SLICE, 1); test_build_parent_slice_one("foo.slice", SPECIAL_ROOT_SLICE, 1);
test_build_parent_slice_one("foo-bar.slice", "foo.slice", 1); test_build_parent_slice_one("foo-bar.slice", "foo.slice", 1);
@ -430,6 +469,8 @@ static void test_unit_name_to_instance(void) {
char *instance; char *instance;
int r; int r;
log_info("/* %s */", __func__);
r = unit_name_to_instance("foo@bar.service", &instance); r = unit_name_to_instance("foo@bar.service", &instance);
assert_se(r == UNIT_NAME_INSTANCE); assert_se(r == UNIT_NAME_INSTANCE);
assert_se(streq(instance, "bar")); assert_se(streq(instance, "bar"));
@ -461,6 +502,8 @@ static void test_unit_name_to_instance(void) {
static void test_unit_name_escape(void) { static void test_unit_name_escape(void) {
_cleanup_free_ char *r; _cleanup_free_ char *r;
log_info("/* %s */", __func__);
r = unit_name_escape("ab+-c.a/bc@foo.service"); r = unit_name_escape("ab+-c.a/bc@foo.service");
assert_se(r); assert_se(r);
assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service")); assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
@ -475,6 +518,8 @@ static void test_u_n_t_one(const char *name, const char *expected, int ret) {
} }
static void test_unit_name_template(void) { static void test_unit_name_template(void) {
log_info("/* %s */", __func__);
test_u_n_t_one("foo@bar.service", "foo@.service", 0); test_u_n_t_one("foo@bar.service", "foo@.service", 0);
test_u_n_t_one("foo.mount", NULL, -EINVAL); test_u_n_t_one("foo.mount", NULL, -EINVAL);
} }
@ -487,6 +532,7 @@ static void test_unit_name_path_unescape_one(const char *name, const char *path,
} }
static void test_unit_name_path_unescape(void) { static void test_unit_name_path_unescape(void) {
log_info("/* %s */", __func__);
test_unit_name_path_unescape_one("foo", "/foo", 0); test_unit_name_path_unescape_one("foo", "/foo", 0);
test_unit_name_path_unescape_one("foo-bar", "/foo/bar", 0); test_unit_name_path_unescape_one("foo-bar", "/foo/bar", 0);
@ -510,6 +556,8 @@ static void test_unit_name_to_prefix_one(const char *input, int ret, const char
} }
static void test_unit_name_to_prefix(void) { static void test_unit_name_to_prefix(void) {
log_info("/* %s */", __func__);
test_unit_name_to_prefix_one("foobar.service", 0, "foobar"); test_unit_name_to_prefix_one("foobar.service", 0, "foobar");
test_unit_name_to_prefix_one("", -EINVAL, NULL); test_unit_name_to_prefix_one("", -EINVAL, NULL);
test_unit_name_to_prefix_one("foobar", -EINVAL, NULL); test_unit_name_to_prefix_one("foobar", -EINVAL, NULL);
@ -530,6 +578,8 @@ static void test_unit_name_from_dbus_path_one(const char *input, int ret, const
} }
static void test_unit_name_from_dbus_path(void) { static void test_unit_name_from_dbus_path(void) {
log_info("/* %s */", __func__);
test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dbus_2esocket", 0, "dbus.socket"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dbus_2esocket", 0, "dbus.socket");
test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2emount", 0, "-.mount"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2emount", 0, "-.mount");
test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2eslice", 0, "-.slice"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2eslice", 0, "-.slice");

View File

@ -296,8 +296,11 @@ static int node_permissions_apply(sd_device *dev, bool apply_mac,
else else
mode |= S_IFCHR; mode |= S_IFCHR;
if (lstat(devnode, &stats) < 0) if (lstat(devnode, &stats) < 0) {
if (errno == ENOENT)
return 0; /* this is necessarily racey, so ignore missing the device */
return log_device_debug_errno(dev, errno, "cannot stat() node %s: %m", devnode); return log_device_debug_errno(dev, errno, "cannot stat() node %s: %m", devnode);
}
if ((mode != MODE_INVALID && (stats.st_mode & S_IFMT) != (mode & S_IFMT)) || stats.st_rdev != devnum) if ((mode != MODE_INVALID && (stats.st_mode & S_IFMT) != (mode & S_IFMT)) || stats.st_rdev != devnum)
return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST), return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST),
@ -322,11 +325,13 @@ static int node_permissions_apply(sd_device *dev, bool apply_mac,
r = chmod_and_chown(devnode, mode, uid, gid); r = chmod_and_chown(devnode, mode, uid, gid);
if (r < 0) if (r < 0)
log_device_warning_errno(dev, r, "Failed to set owner/mode of %s to uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o: %m", log_device_full(dev, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r,
devnode, "Failed to set owner/mode of %s to uid=" UID_FMT
uid_is_valid(uid) ? uid : stats.st_uid, ", gid=" GID_FMT ", mode=%#o: %m",
gid_is_valid(gid) ? gid : stats.st_gid, devnode,
mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777); uid_is_valid(uid) ? uid : stats.st_uid,
gid_is_valid(gid) ? gid : stats.st_gid,
mode != MODE_INVALID ? mode & 0777 : stats.st_mode & 0777);
} else } else
log_device_debug(dev, "Preserve permissions of %s, uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o", log_device_debug(dev, "Preserve permissions of %s, uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o",
devnode, devnode,
@ -343,7 +348,8 @@ static int node_permissions_apply(sd_device *dev, bool apply_mac,
q = mac_selinux_apply(devnode, label); q = mac_selinux_apply(devnode, label);
if (q < 0) if (q < 0)
log_device_error_errno(dev, q, "SECLABEL: failed to set SELinux label '%s': %m", label); log_device_full(dev, q == -ENOENT ? LOG_DEBUG : LOG_ERR, q,
"SECLABEL: failed to set SELinux label '%s': %m", label);
else else
log_device_debug(dev, "SECLABEL: set SELinux label '%s'", label); log_device_debug(dev, "SECLABEL: set SELinux label '%s'", label);
@ -352,7 +358,8 @@ static int node_permissions_apply(sd_device *dev, bool apply_mac,
q = mac_smack_apply(devnode, SMACK_ATTR_ACCESS, label); q = mac_smack_apply(devnode, SMACK_ATTR_ACCESS, label);
if (q < 0) if (q < 0)
log_device_error_errno(dev, q, "SECLABEL: failed to set SMACK label '%s': %m", label); log_device_full(dev, q == -ENOENT ? LOG_DEBUG : LOG_ERR, q,
"SECLABEL: failed to set SMACK label '%s': %m", label);
else else
log_device_debug(dev, "SECLABEL: set SMACK label '%s'", label); log_device_debug(dev, "SECLABEL: set SMACK label '%s'", label);

View File

@ -2333,9 +2333,10 @@ static int apply_static_dev_perms(const char *devnode, uid_t uid, gid_t gid, mod
gid = 0; gid = 0;
r = chmod_and_chown(device_node, mode, uid, gid); r = chmod_and_chown(device_node, mode, uid, gid);
if (r == -ENOENT)
return 0;
if (r < 0) if (r < 0)
return log_error_errno(errno, "Failed to chown '%s' %u %u: %m", return log_error_errno(r, "Failed to chown '%s' %u %u: %m", device_node, uid, gid);
device_node, uid, gid);
else else
log_debug("chown '%s' %u:%u with mode %#o", device_node, uid, gid, mode); log_debug("chown '%s' %u:%u with mode %#o", device_node, uid, gid, mode);