diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index ca69b36c22..4025b4a2cb 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -2006,8 +2006,8 @@ static int action_discover(void) { TABLE_SET_COLOR, startswith(img->name, ".") ? ANSI_GREY : NULL, TABLE_STRING, image_type_to_string(img->type), TABLE_STRING, image_class_to_string(img->class), - TABLE_BOOLEAN, img->read_only, - TABLE_SET_COLOR, !img->read_only ? ANSI_HIGHLIGHT_GREEN : ANSI_HIGHLIGHT_RED, + TABLE_BOOLEAN, image_is_read_only(img), + TABLE_SET_COLOR, image_is_read_only(img) ? ANSI_HIGHLIGHT_RED : ANSI_HIGHLIGHT_GREEN, TABLE_PATH, img->path, TABLE_TIMESTAMP, img->mtime != 0 ? img->mtime : img->crtime, TABLE_SIZE, img->usage, diff --git a/src/import/importd.c b/src/import/importd.c index 99b8af580d..91cd7ce648 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -1365,7 +1365,7 @@ static int method_list_images(sd_bus_message *msg, void *userdata, sd_bus_error i->name, image_type_to_string(i->type), i->path, - i->read_only, + image_is_read_only(i), i->crtime, i->mtime, i->usage, diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 9d4db0521f..7fe7cad77e 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -24,6 +24,20 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, image_type, ImageType); +static int property_get_read_only( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Image *image = ASSERT_PTR(userdata); + + return sd_bus_message_append(ASSERT_PTR(reply), "b", image_is_read_only(image)); +} + int bus_image_method_remove( sd_bus_message *message, void *userdata, @@ -448,7 +462,7 @@ const sd_bus_vtable image_vtable[] = { SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0), SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0), SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0), - SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0), + SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0), SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0), SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0), SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0), diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index ec34cbac36..1619d3fd6b 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -823,7 +823,7 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er r = sd_bus_message_append(reply, "(ssbttto)", image->name, image_type_to_string(image->type), - image->read_only, + image_is_read_only(image), image->crtime, image->mtime, image->usage, diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index a00dda1b73..13cf4713cf 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -638,7 +638,7 @@ static int list_image_one_and_maybe_read_metadata(Manager *m, sd_varlink *link, JSON_BUILD_PAIR_STRING_NON_EMPTY("path", image->path), SD_JSON_BUILD_PAIR_STRING("type", image_type_to_string(image->type)), SD_JSON_BUILD_PAIR_STRING("class", image_class_to_string(image->class)), - SD_JSON_BUILD_PAIR_BOOLEAN("readOnly", image->read_only), + SD_JSON_BUILD_PAIR_BOOLEAN("readOnly", image_is_read_only(image)), JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("creationTimestamp", image->crtime), JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("modificationTimestamp", image->mtime), JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("usage", image->usage, UINT64_MAX), diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index bc1ed4c9eb..fe622b26ce 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3077,7 +3077,7 @@ static int determine_names(void) { return log_oom(); if (!arg_ephemeral) - arg_read_only = arg_read_only || i->read_only; + arg_read_only = arg_read_only || image_is_read_only(i); } else { r = safe_getcwd(&arg_directory); if (r < 0) diff --git a/src/portable/portabled-bus.c b/src/portable/portabled-bus.c index d83e073023..7f3d496a6e 100644 --- a/src/portable/portabled-bus.c +++ b/src/portable/portabled-bus.c @@ -177,7 +177,7 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er r = sd_bus_message_append(reply, "(ssbtttso)", image->name, image_type_to_string(image->type), - image->read_only, + image_is_read_only(image), image->crtime, image->mtime, image->usage, diff --git a/src/portable/portabled-image-bus.c b/src/portable/portabled-image-bus.c index 68cf916924..17032c5dde 100644 --- a/src/portable/portabled-image-bus.c +++ b/src/portable/portabled-image-bus.c @@ -30,6 +30,20 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, image_type, ImageType); +static int property_get_read_only( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Image *image = ASSERT_PTR(userdata); + + return sd_bus_message_append(ASSERT_PTR(reply), "b", image_is_read_only(image)); +} + int bus_image_common_get_os_release( Manager *m, sd_bus_message *message, @@ -865,7 +879,7 @@ const sd_bus_vtable image_vtable[] = { SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0), SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0), SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0), - SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0), + SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0), SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0), SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0), SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0), diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 53938a1256..f903e3a6bd 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -1493,7 +1493,7 @@ int image_read_only(Image *i, bool b, RuntimeScope scope) { assert(i); - if (image_is_vendor(i) || image_is_host(i)) + if (image_is_vendor(i) || image_is_host(i) || image_is_hidden(i)) return -EROFS; /* Make sure we don't interfere with a running nspawn */ @@ -2005,7 +2005,7 @@ int image_to_json(const struct Image *img, sd_json_variant **ret) { SD_JSON_BUILD_PAIR_STRING("Class", image_class_to_string(img->class)), SD_JSON_BUILD_PAIR_STRING("Name", img->name), SD_JSON_BUILD_PAIR_CONDITION(!!img->path, "Path", SD_JSON_BUILD_STRING(img->path)), - SD_JSON_BUILD_PAIR_BOOLEAN("ReadOnly", img->read_only), + SD_JSON_BUILD_PAIR_BOOLEAN("ReadOnly", image_is_read_only(img)), SD_JSON_BUILD_PAIR_CONDITION(img->crtime != 0, "CreationTimestamp", SD_JSON_BUILD_UNSIGNED(img->crtime)), SD_JSON_BUILD_PAIR_CONDITION(img->mtime != 0, "ModificationTimestamp", SD_JSON_BUILD_UNSIGNED(img->mtime)), SD_JSON_BUILD_PAIR_CONDITION(img->usage != UINT64_MAX, "Usage", SD_JSON_BUILD_UNSIGNED(img->usage)), diff --git a/src/shared/discover-image.h b/src/shared/discover-image.h index a7370450a8..e4bc73390a 100644 --- a/src/shared/discover-image.h +++ b/src/shared/discover-image.h @@ -84,16 +84,28 @@ static inline char** image_extension_release(Image *image, ImageClass class) { return NULL; } -static inline bool image_is_hidden(const struct Image *i) { +static inline bool image_is_hidden(const Image *i) { assert(i); return i->name && i->name[0] == '.'; } -bool image_is_vendor(const struct Image *i); -bool image_is_host(const struct Image *i); +static inline int image_is_read_only(const Image *i) { + assert(i); -int image_to_json(const struct Image *i, sd_json_variant **ret); + /* We enforce the rule that hidden images are always read-only too. If people want to change hidden + * images they should make a copy first, and make that one mutable */ + + if (image_is_hidden(i)) + return true; + + return i->read_only; +} + +bool image_is_vendor(const Image *i); +bool image_is_host(const Image *i); + +int image_to_json(const Image *i, sd_json_variant **ret); int image_root_pick(RuntimeScope scope, ImageClass c, bool runtime, char **ret);