From 76ec966f0e33685f8331603805c0349adceea836 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 16 Apr 2016 18:41:34 -0400 Subject: tree-wide: use ERFKILL instead of ESHUTDOWN for "unit masked" If the error code ever leaks (we print the strerror error instead of providing our own), the message for ESHUTDOWN is "Cannot send after transport endpoint shutdown", which can be misleading. In particular it suggest that some mishandling of the dbus connection occured. Let's change that to ERFKILL which has the advantage that a) it sounds implausible as actual error, b) has the connotation of disabling something manually. --- src/shared/install.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/shared') diff --git a/src/shared/install.c b/src/shared/install.c index 8d9f96553b..35d83dd16c 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -754,7 +754,7 @@ static int install_info_may_process(UnitFileInstallInfo *i, const LookupPaths *p * not subject to enable/disable operations. */ if (i->type == UNIT_FILE_TYPE_MASKED) - return -ESHUTDOWN; + return -ERFKILL; if (path_is_generator(paths, i->path)) return -EADDRNOTAVAIL; if (path_is_transient(paths, i->path)) -- cgit v1.2.3-54-g00ecf From 9a0a413a195a21888cf926be5595d0efc1eef0fe Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 16 Apr 2016 19:31:53 -0400 Subject: systemctl/core: ignore masked units in preset-all With any masked unit that would that would be enabled by presets, we'd get: test@rawhide $ sudo systemctl preset-all Failed to execute operation: Unit file is masked. test@rawhide $ sudo systemctl --root=/ preset-all Operation failed: Cannot send after transport endpoint shutdown Simply ignore those units: test@rawhide $ sudo systemctl preset-all Unit xxx.service is masked, ignoring. --- src/core/dbus-manager.c | 12 +++++++----- src/shared/bus-util.c | 10 ++++++++-- src/shared/install.c | 4 ++++ src/shared/install.h | 5 +++++ src/systemctl/systemctl.c | 16 ++++++++++++---- 5 files changed, 36 insertions(+), 11 deletions(-) (limited to 'src/shared') diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 0b12aae2ef..9a913a6c91 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1565,11 +1565,13 @@ static int reply_unit_file_changes_and_free( unsigned i; int r; - if (n_changes > 0) { - r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL); - if (r < 0) - log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m"); - } + for (i = 0; i < n_changes; i++) + if (unit_file_change_is_modification(changes[i].type)) { + r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL); + if (r < 0) + log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m"); + break; + } r = sd_bus_message_new_method_return(message, &reply); if (r < 0) diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 2b86b1fcd6..677970b7f0 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -2203,11 +2203,17 @@ int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, Un if (!quiet) { if (streq(type, "symlink")) log_info("Created symlink from %s to %s.", path, source); - else + else if (streq(type, "unlink")) log_info("Removed symlink %s.", path); + else if (streq(type, "masked")) + log_info("Unit %s is masked, ignoring.", path); + else + log_notice("Manager reported unknown change type \"%s\" for %s.", type, path); } - r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source); + r = unit_file_changes_add(changes, n_changes, + unit_file_change_type_from_string(type), + path, source); if (r < 0) return r; } diff --git a/src/shared/install.c b/src/shared/install.c index 35d83dd16c..74de8141f1 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -2539,6 +2539,9 @@ int unit_file_preset_all( continue; r = preset_prepare_one(scope, &plus, &minus, &paths, mode, de->d_name); + if (r == -ERFKILL) + r = unit_file_changes_add(changes, n_changes, + UNIT_FILE_IS_MASKED, de->d_name, NULL); if (r < 0) return r; } @@ -2652,6 +2655,7 @@ DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState); static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = { [UNIT_FILE_SYMLINK] = "symlink", [UNIT_FILE_UNLINK] = "unlink", + [UNIT_FILE_IS_MASKED] = "masked", }; DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType); diff --git a/src/shared/install.h b/src/shared/install.h index 6f8b45d4f6..6b760def9b 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -72,10 +72,15 @@ enum UnitFilePresetMode { enum UnitFileChangeType { UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK, + UNIT_FILE_IS_MASKED, _UNIT_FILE_CHANGE_TYPE_MAX, _UNIT_FILE_CHANGE_TYPE_INVALID = -1 }; +static inline bool unit_file_change_is_modification(UnitFileChangeType type) { + return IN_SET(type, UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK); +} + struct UnitFileChange { UnitFileChangeType type; char *path; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 4942dbb6ad..0c64cbab80 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1989,12 +1989,20 @@ static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_cha assert(changes || n_changes == 0); - for (i = 0; i < n_changes; i++) { - if (changes[i].type == UNIT_FILE_SYMLINK) + for (i = 0; i < n_changes; i++) + switch(changes[i].type) { + case UNIT_FILE_SYMLINK: log_info("Created symlink %s, pointing to %s.", changes[i].path, changes[i].source); - else + break; + case UNIT_FILE_UNLINK: log_info("Removed %s.", changes[i].path); - } + break; + case UNIT_FILE_IS_MASKED: + log_info("Unit %s is masked, ignoring.", changes[i].path); + break; + default: + assert_not_reached("bad change type"); + } } static int set_default(int argc, char *argv[], void *userdata) { -- cgit v1.2.3-54-g00ecf From 24737c291738313fd67924172988a8986f60e958 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 16 Apr 2016 23:08:23 -0400 Subject: install: allow paths like LookupPath.generator to be NULL Fixes #3047. --- src/basic/path-util.h | 4 ++++ src/shared/install.c | 28 ++++++++++++++-------------- src/test/test-path-util.c | 6 ++++++ 3 files changed, 24 insertions(+), 14 deletions(-) (limited to 'src/shared') diff --git a/src/basic/path-util.h b/src/basic/path-util.h index f43d477eb9..34d5cd1570 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -48,6 +48,10 @@ bool path_equal(const char *a, const char *b) _pure_; bool path_equal_or_files_same(const char *a, const char *b); char* path_join(const char *root, const char *path, const char *rest); +static inline bool path_equal_ptr(const char *a, const char *b) { + return !!a == !!b && (!a || path_equal(a, b)); +} + /* Note: the search terminates on the first NULL item. */ #define PATH_IN_SET(p, ...) \ ({ \ diff --git a/src/shared/install.c b/src/shared/install.c index 74de8141f1..10c724edbd 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -119,9 +119,9 @@ static int path_is_generator(const LookupPaths *p, const char *path) { if (!parent) return -ENOMEM; - return path_equal(p->generator, parent) || - path_equal(p->generator_early, parent) || - path_equal(p->generator_late, parent); + return path_equal_ptr(parent, p->generator) || + path_equal_ptr(parent, p->generator_early) || + path_equal_ptr(parent, p->generator_late); } static int path_is_transient(const LookupPaths *p, const char *path) { @@ -134,7 +134,7 @@ static int path_is_transient(const LookupPaths *p, const char *path) { if (!parent) return -ENOMEM; - return path_equal(p->transient, parent); + return path_equal_ptr(parent, p->transient); } static int path_is_control(const LookupPaths *p, const char *path) { @@ -147,8 +147,8 @@ static int path_is_control(const LookupPaths *p, const char *path) { if (!parent) return -ENOMEM; - return path_equal(parent, p->persistent_control) || - path_equal(parent, p->runtime_control); + return path_equal_ptr(parent, p->persistent_control) || + path_equal_ptr(parent, p->runtime_control); } static int path_is_config(const LookupPaths *p, const char *path) { @@ -164,8 +164,8 @@ static int path_is_config(const LookupPaths *p, const char *path) { if (!parent) return -ENOMEM; - return path_equal(parent, p->persistent_config) || - path_equal(parent, p->runtime_config); + return path_equal_ptr(parent, p->persistent_config) || + path_equal_ptr(parent, p->runtime_config); } static int path_is_runtime(const LookupPaths *p, const char *path) { @@ -186,12 +186,12 @@ static int path_is_runtime(const LookupPaths *p, const char *path) { if (!parent) return -ENOMEM; - return path_equal(parent, p->runtime_config) || - path_equal(parent, p->generator) || - path_equal(parent, p->generator_early) || - path_equal(parent, p->generator_late) || - path_equal(parent, p->transient) || - path_equal(parent, p->runtime_control); + return path_equal_ptr(parent, p->runtime_config) || + path_equal_ptr(parent, p->generator) || + path_equal_ptr(parent, p->generator_early) || + path_equal_ptr(parent, p->generator_late) || + path_equal_ptr(parent, p->transient) || + path_equal_ptr(parent, p->runtime_control); } static int path_is_vendor(const LookupPaths *p, const char *path) { diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index 7ce2695c5c..5d77e2959c 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -96,6 +96,12 @@ static void test_path(void) { assert_se(PATH_IN_SET("/bin", "/foo/bar", "/bin")); assert_se(PATH_IN_SET("/", "/", "/", "/foo/bar")); assert_se(!PATH_IN_SET("/", "/abc", "/def")); + + assert_se(path_equal_ptr(NULL, NULL)); + assert_se(path_equal_ptr("/a", "/a")); + assert_se(!path_equal_ptr("/a", "/b")); + assert_se(!path_equal_ptr("/a", NULL)); + assert_se(!path_equal_ptr(NULL, "/a")); } static void test_find_binary(const char *self) { -- cgit v1.2.3-54-g00ecf