#include "socket-util.h"
#include "string-table.h"
#include "strv.h"
+#include "tmpfile-util.h"
#include "user-util.h"
static const char profile_dirs[] = CONF_PATHS_NULSTR("systemd/portable/profile");
return mfree(i);
}
-Hashmap *portable_metadata_hashmap_unref(Hashmap *h) {
-
- for (;;) {
- PortableMetadata *i;
-
- i = hashmap_steal_first(h);
- if (!i)
- break;
-
- portable_metadata_unref(i);
- }
-
- return hashmap_free(h);
-}
-
static int compare_metadata(PortableMetadata *const *x, PortableMetadata *const *y) {
return strcmp((*x)->name, (*y)->name);
}
return 0;
}
+DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(portable_metadata_hash_ops, char, string_hash_func, string_compare_func,
+ PortableMetadata, portable_metadata_unref);
+
static int extract_now(
const char *where,
char **matches,
PortableMetadata **ret_os_release,
Hashmap **ret_unit_files) {
- _cleanup_(portable_metadata_hashmap_unrefp) Hashmap *unit_files = NULL;
+ _cleanup_hashmap_free_ Hashmap *unit_files = NULL;
_cleanup_(portable_metadata_unrefp) PortableMetadata *os_release = NULL;
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_close_ int os_release_fd = -1;
if (r < 0)
return log_debug_errno(r, "Failed to acquire lookup paths: %m");
- unit_files = hashmap_new(&string_hash_ops);
+ unit_files = hashmap_new(&portable_metadata_hash_ops);
if (!unit_files)
return -ENOMEM;
Hashmap **ret_unit_files,
sd_bus_error *error) {
- _cleanup_(portable_metadata_hashmap_unrefp) Hashmap *unit_files = NULL;
+ _cleanup_hashmap_free_ Hashmap *unit_files = NULL;
_cleanup_(portable_metadata_unrefp) PortableMetadata* os_release = NULL;
_cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
int r;
seq[1] = safe_close(seq[1]);
- unit_files = hashmap_new(&string_hash_ops);
+ unit_files = hashmap_new(&portable_metadata_hash_ops);
if (!unit_files)
return -ENOMEM;
r = copy_file_atomic(from, dropin, 0644, 0, COPY_REFLINK);
if (r < 0)
- return log_debug_errno(r, "Failed to copy %s %s %s: %m", from, special_glyph(ARROW), dropin);
+ return log_debug_errno(r, "Failed to copy %s %s %s: %m", from, special_glyph(SPECIAL_GLYPH_ARROW), dropin);
(void) portable_changes_add(changes, n_changes, PORTABLE_COPY, dropin, from);
} else {
if (symlink(from, dropin) < 0)
- return log_debug_errno(errno, "Failed to link %s %s %s: %m", from, special_glyph(ARROW), dropin);
+ return log_debug_errno(errno, "Failed to link %s %s %s: %m", from, special_glyph(SPECIAL_GLYPH_ARROW), dropin);
(void) portable_changes_add(changes, n_changes, PORTABLE_SYMLINK, dropin, from);
}
return 0;
}
-static const char *config_path(const LookupPaths *paths, PortableFlags flags) {
+static const char *attached_path(const LookupPaths *paths, PortableFlags flags) {
const char *where;
assert(paths);
if (flags & PORTABLE_RUNTIME)
- where = paths->runtime_config;
+ where = paths->runtime_attached;
else
- where = paths->persistent_config;
+ where = paths->persistent_attached;
assert(where);
return where;
assert(m);
assert(PORTABLE_METADATA_IS_UNIT(m));
- where = config_path(paths, flags);
- path = strjoina(where, "/", m->name);
+ where = attached_path(paths, flags);
+ (void) mkdir_parents(where, 0755);
+ if (mkdir(where, 0755) < 0) {
+ if (errno != EEXIST)
+ return -errno;
+ } else
+ (void) portable_changes_add(changes, n_changes, PORTABLE_MKDIR, where, NULL);
+
+ path = strjoina(where, "/", m->name);
dropin_dir = strjoin(path, ".d");
if (!dropin_dir)
return -ENOMEM;
- (void) mkdir_p(dropin_dir, 0755);
- (void) portable_changes_add(changes, n_changes, PORTABLE_MKDIR, dropin_dir, NULL);
+ if (mkdir(dropin_dir, 0755) < 0) {
+ if (errno != EEXIST)
+ return -errno;
+ } else
+ (void) portable_changes_add(changes, n_changes, PORTABLE_MKDIR, dropin_dir, NULL);
/* We install the drop-ins first, and the actual unit file last to achieve somewhat atomic behaviour if PID 1
* is reloaded while we are creating things here: as long as only the drop-ins exist the unit doesn't exist at
(void) mkdir_parents(sl, 0755);
if (symlink(image_path, sl) < 0)
- return log_debug_errno(errno, "Failed to link %s %s %s: %m", image_path, special_glyph(ARROW), sl);
+ return log_debug_errno(errno, "Failed to link %s %s %s: %m", image_path, special_glyph(SPECIAL_GLYPH_ARROW), sl);
(void) portable_changes_add(changes, n_changes, PORTABLE_SYMLINK, sl, image_path);
return 0;
size_t *n_changes,
sd_bus_error *error) {
- _cleanup_(portable_metadata_hashmap_unrefp) Hashmap *unit_files = NULL;
+ _cleanup_hashmap_free_ Hashmap *unit_files = NULL;
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(image_unrefp) Image *image = NULL;
PortableMetadata *item;
return log_debug_errno(errno, "Failed to open %s/%s: %m", where, p);
}
- f = fdopen(fd, "re");
+ f = fdopen(fd, "r");
if (!f)
return log_debug_errno(errno, "Failed to convert file handle: %m");
fd = -1;
if (r < 0)
return r;
- where = config_path(&paths, flags);
+ where = attached_path(&paths, flags);
d = opendir(where);
- if (!d)
+ if (!d) {
+ if (errno == ENOENT)
+ goto not_found;
+
return log_debug_errno(errno, "Failed to open '%s' directory: %m", where);
+ }
unit_files = set_new(&string_hash_ops);
if (!unit_files)
}
}
- if (set_isempty(unit_files)) {
- log_debug("No unit files associated with '%s' found. Image not attached?", name_or_path);
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "No unit files associated with '%s' found. Image not attached?", name_or_path);
- }
+ if (set_isempty(unit_files))
+ goto not_found;
SET_FOREACH(item, unit_files, iterator) {
_cleanup_free_ char *md = NULL;
portable_changes_add(changes, n_changes, PORTABLE_UNLINK, sl, NULL);
}
+ /* Try to remove the unit file directory, if we can */
+ if (rmdir(where) >= 0)
+ portable_changes_add(changes, n_changes, PORTABLE_UNLINK, where, NULL);
+
return ret;
+
+not_found:
+ log_debug("No unit files associated with '%s' found. Image not attached?", name_or_path);
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "No unit files associated with '%s' found. Image not attached?", name_or_path);
}
static int portable_get_state_internal(
if (r < 0)
return r;
- where = config_path(&paths, flags);
+ where = attached_path(&paths, flags);
d = opendir(where);
- if (!d)
+ if (!d) {
+ if (errno == ENOENT) {
+ /* If the 'attached' directory doesn't exist at all, then we know for sure this image isn't attached. */
+ *ret = PORTABLE_DETACHED;
+ return 0;
+ }
+
return log_debug_errno(errno, "Failed to open '%s' directory: %m", where);
+ }
unit_files = set_new(&string_hash_ops);
if (!unit_files)