From c9a4b1688552a23867d3d9db18620501d57d33da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 16 Apr 2016 19:31:53 -0400 Subject: [PATCH] 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. Cherry-picked from: 9a0a413a195a21888cf926be5595d0efc1eef0fe Related: #1375097 --- src/core/dbus-manager.c | 12 +++++++----- src/libsystemd/sd-bus/bus-util.c | 10 ++++++++-- src/shared/install.c | 4 ++++ src/shared/install.h | 5 +++++ src/systemctl/systemctl.c | 20 ++++++++++++++------ 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 8d3758ac7e..c2067c099a 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1598,11 +1598,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/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index 9d70798cda..75d03708e2 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -1893,11 +1893,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 ab86cd1453..62da52d3b3 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -2402,6 +2402,9 @@ int unit_file_preset_all( continue; r = preset_prepare_one(scope, &plus, &minus, &paths, root_dir, mode, de->d_name); + if (r == -ESHUTDOWN) + r = unit_file_changes_add(changes, n_changes, + UNIT_FILE_IS_MASKED, de->d_name, NULL); if (r < 0) return r; } @@ -2535,6 +2538,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 87a40b67c1..f0e36661b5 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -60,10 +60,15 @@ typedef enum UnitFilePresetMode { typedef enum UnitFileChangeType { UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK, + UNIT_FILE_IS_MASKED, _UNIT_FILE_CHANGE_TYPE_MAX, _UNIT_FILE_CHANGE_TYPE_INVALID = -1 } UnitFileChangeType; +static inline bool unit_file_change_is_modification(UnitFileChangeType type) { + return IN_SET(type, UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK); +} + typedef struct UnitFileChange { UnitFileChangeType type; char *path; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index e4b404abc2..a688d69052 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1944,12 +1944,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) - log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source); - else - log_info("Removed symlink %s.", changes[i].path); - } + 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); + 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(sd_bus *bus, char **args) {