1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "bus-label.h"
23 #include "bus-common-errors.h"
25 #include "machine-image.h"
26 #include "image-dbus.h"
28 static int image_find_by_bus_path(const char *path, Image **ret) {
29 _cleanup_free_ char *e = NULL;
34 p = startswith(path, "/org/freedesktop/machine1/image/");
38 e = bus_label_unescape(p);
42 return image_find(e, ret);
45 static int image_find_by_bus_path_with_error(const char *path, Image **ret, sd_bus_error *error) {
50 r = image_find_by_bus_path(path, ret);
52 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "Image doesn't exist.");
57 static int property_get_name(
60 const char *interface,
62 sd_bus_message *reply,
64 sd_bus_error *error) {
66 _cleanup_(image_unrefp) Image *image = NULL;
72 r = image_find_by_bus_path_with_error(path, &image, error);
76 r = sd_bus_message_append(reply, "s", image->name);
83 static int property_get_path(
86 const char *interface,
88 sd_bus_message *reply,
90 sd_bus_error *error) {
92 _cleanup_(image_unrefp) Image *image = NULL;
98 r = image_find_by_bus_path_with_error(path, &image, error);
102 r = sd_bus_message_append(reply, "s", image->path);
109 static int property_get_type(
112 const char *interface,
113 const char *property,
114 sd_bus_message *reply,
116 sd_bus_error *error) {
119 _cleanup_(image_unrefp) Image *image = NULL;
125 r = image_find_by_bus_path_with_error(path, &image, error);
129 r = sd_bus_message_append(reply, "s", image_type_to_string(image->type));
136 static int property_get_read_only(
139 const char *interface,
140 const char *property,
141 sd_bus_message *reply,
143 sd_bus_error *error) {
146 _cleanup_(image_unrefp) Image *image = NULL;
152 r = image_find_by_bus_path_with_error(path, &image, error);
156 r = sd_bus_message_append(reply, "b", image->read_only);
163 static int property_get_crtime(
166 const char *interface,
167 const char *property,
168 sd_bus_message *reply,
170 sd_bus_error *error) {
173 _cleanup_(image_unrefp) Image *image = NULL;
179 r = image_find_by_bus_path_with_error(path, &image, error);
183 r = sd_bus_message_append(reply, "t", image->crtime);
190 static int property_get_mtime(
193 const char *interface,
194 const char *property,
195 sd_bus_message *reply,
197 sd_bus_error *error) {
199 _cleanup_(image_unrefp) Image *image = NULL;
205 r = image_find_by_bus_path_with_error(path, &image, error);
209 r = sd_bus_message_append(reply, "t", image->mtime);
216 static int property_get_size(
219 const char *interface,
220 const char *property,
221 sd_bus_message *reply,
223 sd_bus_error *error) {
225 _cleanup_(image_unrefp) Image *image = NULL;
231 r = image_find_by_bus_path_with_error(path, &image, error);
235 r = sd_bus_message_append(reply, "t", image->size);
243 static int property_get_limit(
246 const char *interface,
247 const char *property,
248 sd_bus_message *reply,
250 sd_bus_error *error) {
252 _cleanup_(image_unrefp) Image *image = NULL;
258 r = image_find_by_bus_path_with_error(path, &image, error);
262 r = sd_bus_message_append(reply, "t", image->limit);
269 static int property_get_size_exclusive(
272 const char *interface,
273 const char *property,
274 sd_bus_message *reply,
276 sd_bus_error *error) {
278 _cleanup_(image_unrefp) Image *image = NULL;
284 r = image_find_by_bus_path_with_error(path, &image, error);
288 r = sd_bus_message_append(reply, "t", image->size_exclusive);
295 static int property_get_limit_exclusive(
298 const char *interface,
299 const char *property,
300 sd_bus_message *reply,
302 sd_bus_error *error) {
304 _cleanup_(image_unrefp) Image *image = NULL;
310 r = image_find_by_bus_path_with_error(path, &image, error);
314 r = sd_bus_message_append(reply, "t", image->limit_exclusive);
321 static int method_remove(
323 sd_bus_message *message,
325 sd_bus_error *error) {
327 _cleanup_(image_unrefp) Image *image = NULL;
333 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
337 r = image_remove(image);
341 return sd_bus_reply_method_return(message, NULL);
344 static int method_rename(
346 sd_bus_message *message,
348 sd_bus_error *error) {
350 _cleanup_(image_unrefp) Image *image = NULL;
351 const char *new_name;
357 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
361 r = sd_bus_message_read(message, "s", &new_name);
365 if (!image_name_is_valid(new_name))
366 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
368 r = image_rename(image, new_name);
372 return sd_bus_reply_method_return(message, NULL);
375 static int method_clone(
377 sd_bus_message *message,
379 sd_bus_error *error) {
381 _cleanup_(image_unrefp) Image *image = NULL;
382 const char *new_name;
388 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
392 r = sd_bus_message_read(message, "sb", &new_name, &read_only);
396 if (!image_name_is_valid(new_name))
397 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
399 r = image_clone(image, new_name, read_only);
403 return sd_bus_reply_method_return(message, NULL);
406 static int method_mark_read_only(
408 sd_bus_message *message,
410 sd_bus_error *error) {
412 _cleanup_(image_unrefp) Image *image = NULL;
418 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
422 r = sd_bus_message_read(message, "b", &read_only);
426 r = image_read_only(image, read_only);
430 return sd_bus_reply_method_return(message, NULL);
433 const sd_bus_vtable image_vtable[] = {
434 SD_BUS_VTABLE_START(0),
435 SD_BUS_PROPERTY("Name", "s", property_get_name, 0, 0),
436 SD_BUS_PROPERTY("Path", "s", property_get_path, 0, 0),
437 SD_BUS_PROPERTY("Type", "s", property_get_type, 0, 0),
438 SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
439 SD_BUS_PROPERTY("CreationTimestamp", "t", property_get_crtime, 0, 0),
440 SD_BUS_PROPERTY("ModificationTimestamp", "t", property_get_mtime, 0, 0),
441 SD_BUS_PROPERTY("Size", "t", property_get_size, 0, 0),
442 SD_BUS_PROPERTY("Limit", "t", property_get_limit, 0, 0),
443 SD_BUS_PROPERTY("SizeExclusive", "t", property_get_size_exclusive, 0, 0),
444 SD_BUS_PROPERTY("LimitExclusive", "t", property_get_limit_exclusive, 0, 0),
445 SD_BUS_METHOD("Remove", NULL, NULL, method_remove, 0),
446 SD_BUS_METHOD("Rename", "s", NULL, method_rename, 0),
447 SD_BUS_METHOD("Clone", "sb", NULL, method_clone, 0),
448 SD_BUS_METHOD("MarkeReadOnly", "b", NULL, method_mark_read_only, 0),
452 int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
460 r = image_find_by_bus_path(path, NULL);
468 char *image_bus_path(const char *name) {
469 _cleanup_free_ char *e = NULL;
473 e = bus_label_escape(name);
477 return strappend("/org/freedesktop/machine1/image/", e);
480 int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
481 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
482 _cleanup_strv_free_ char **l = NULL;
491 images = hashmap_new(&string_hash_ops);
495 r = image_discover(images);
499 HASHMAP_FOREACH(image, images, i) {
502 p = image_bus_path(image->name);
506 r = strv_consume(&l, p);