diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-05-27 14:11:56 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-05-31 01:09:29 +0900 |
commit | edea370222eec3d185dd84a7d9e942ec5933af63 (patch) | |
tree | 09f81bd86172ad2aabdc6a5ab52c6b6ebfd4da05 /src/portable | |
parent | 6a49fcdb3c90e00d8da350464816dcb63336353f (diff) | |
download | systemd-edea370222eec3d185dd84a7d9e942ec5933af63.tar.gz |
portable: remove drop-in configs even if the main unit file does not exist
When we run `portablectl detach --enable --runtime`, then it triggers
`DisableUnitFilesWithFlags` DBus method and the main unit file is
removed, but its drop-ins are not. Hence, portable_detach() failed to
list existing portable units.
This makes the loop for listing portable units also accept drop-in
directories. So, all remaining drop-in directories are correctly
removed.
Before:
```
testsuite-29.sh[600]: + portablectl detach --now --runtime --enable /tmp/rootdir minimal-app0
portablectl[1391]: (Matching unit files with prefixes 'minimal-app0'.)
portablectl[1391]: Queued /org/freedesktop/systemd1/job/1812 to call StopUnit on portable service minimal-app0-foo.service.
portablectl[1391]: Removed "/run/systemd/system.attached/minimal-app0-foo.service".
portablectl[1391]: Queued /org/freedesktop/systemd1/job/1813 to call StopUnit on portable service minimal-app0.service.
portablectl[1391]: Removed "/run/systemd/system.attached/minimal-app0.service".
portablectl[1391]: Got result done/Success for job minimal-app0-foo.service
portablectl[1391]: Got result done/Success for job minimal-app0.service
portablectl[1391]: DetachImage failed: No unit files associated with '/tmp/rootdir' found attached to the system. Image not attached?
```
After:
```
testsuite-29.sh[508]: + portablectl detach --now --runtime --enable /tmp/rootdir minimal-app0
portablectl[1076]: (Matching unit files with prefixes 'minimal-app0'.)
portablectl[1076]: Queued /org/freedesktop/systemd1/job/1946 to call StopUnit on portable service minimal-app0-foo.service.
portablectl[1076]: Removed "/run/systemd/system.attached/minimal-app0-foo.service".
portablectl[1076]: Queued /org/freedesktop/systemd1/job/1947 to call StopUnit on portable service minimal-app0.service.
portablectl[1076]: Removed "/run/systemd/system.attached/minimal-app0.service".
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0.service.d/10-profile.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0.service.d/20-portable.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0.service.d.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0-foo.service.d/10-profile.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0-foo.service.d/20-portable.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0-foo.service.d.
portablectl[1076]: Removed /run/portables/rootdir.
portablectl[1076]: Removed /run/systemd/system.attached.
```
Diffstat (limited to 'src/portable')
-rw-r--r-- | src/portable/portable.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/src/portable/portable.c b/src/portable/portable.c index 254d9f6abe..a8536c6692 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -1559,33 +1559,47 @@ int portable_detach( } FOREACH_DIRENT(de, d, return log_debug_errno(errno, "Failed to enumerate '%s' directory: %m", where)) { - _cleanup_free_ char *marker = NULL; + _cleanup_free_ char *marker = NULL, *unit_name = NULL; + const char *dot; + + /* When a portable service is enabled with "portablectl --runtime attach", and is disabled + * with "portablectl --enable detach", which calls DisableUnitFilesWithFlags DBus method, + * the main unit file is removed, but its drop-ins are not. Hence, here we need to list both + * main unit files and drop-in directories (without the main unit files). */ + + dot = endswith(de->d_name, ".d"); + if (dot) + unit_name = strndup(de->d_name, dot - de->d_name); + else + unit_name = strdup(de->d_name); + if (!unit_name) + return -ENOMEM; - if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY)) + if (!unit_name_is_valid(unit_name, UNIT_NAME_ANY)) continue; /* Filter out duplicates */ - if (set_contains(unit_files, de->d_name)) + if (set_contains(unit_files, unit_name)) continue; - if (!IN_SET(de->d_type, DT_LNK, DT_REG)) + if (dot ? !IN_SET(de->d_type, DT_LNK, DT_DIR) : !IN_SET(de->d_type, DT_LNK, DT_REG)) continue; - r = test_chroot_dropin(d, where, de->d_name, name_or_path, extension_image_paths, &marker); + r = test_chroot_dropin(d, where, unit_name, name_or_path, extension_image_paths, &marker); if (r < 0) return r; if (r == 0) continue; - r = unit_file_is_active(bus, de->d_name, error); + r = unit_file_is_active(bus, unit_name, error); if (r < 0) return r; if (!FLAGS_SET(flags, PORTABLE_REATTACH) && r > 0) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit file '%s' is active, can't detach.", de->d_name); + return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit file '%s' is active, can't detach.", unit_name); - r = set_put_strdup(&unit_files, de->d_name); + r = set_ensure_consume(&unit_files, &string_hash_ops_free, TAKE_PTR(unit_name)); if (r < 0) - return log_debug_errno(r, "Failed to add unit name '%s' to set: %m", de->d_name); + return log_oom_debug(); for (const char *p = marker;;) { _cleanup_free_ char *image = NULL; |