LCOV - code coverage report
Current view: top level - machine - image-dbus.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 0 162 0.0 %
Date: 2015-07-29 18:47:03 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2014 Lennart Poettering
       7             : 
       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.
      12             : 
      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.
      17             : 
      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/>.
      20             : ***/
      21             : 
      22             : #include "bus-label.h"
      23             : #include "strv.h"
      24             : #include "bus-util.h"
      25             : #include "machine-image.h"
      26             : #include "image-dbus.h"
      27             : 
      28           0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, image_type, ImageType);
      29             : 
      30           0 : int bus_image_method_remove(
      31             :                 sd_bus_message *message,
      32             :                 void *userdata,
      33             :                 sd_bus_error *error) {
      34             : 
      35           0 :         Image *image = userdata;
      36           0 :         Manager *m = image->userdata;
      37             :         int r;
      38             : 
      39           0 :         assert(message);
      40           0 :         assert(image);
      41             : 
      42           0 :         r = bus_verify_polkit_async(
      43             :                         message,
      44             :                         CAP_SYS_ADMIN,
      45             :                         "org.freedesktop.machine1.manage-images",
      46             :                         false,
      47             :                         UID_INVALID,
      48             :                         &m->polkit_registry,
      49             :                         error);
      50           0 :         if (r < 0)
      51           0 :                 return r;
      52           0 :         if (r == 0)
      53           0 :                 return 1; /* Will call us back */
      54             : 
      55           0 :         r = image_remove(image);
      56           0 :         if (r < 0)
      57           0 :                 return r;
      58             : 
      59           0 :         return sd_bus_reply_method_return(message, NULL);
      60             : }
      61             : 
      62           0 : int bus_image_method_rename(
      63             :                 sd_bus_message *message,
      64             :                 void *userdata,
      65             :                 sd_bus_error *error) {
      66             : 
      67           0 :         Image *image = userdata;
      68           0 :         Manager *m = image->userdata;
      69             :         const char *new_name;
      70             :         int r;
      71             : 
      72           0 :         assert(message);
      73           0 :         assert(image);
      74             : 
      75           0 :         r = sd_bus_message_read(message, "s", &new_name);
      76           0 :         if (r < 0)
      77           0 :                 return r;
      78             : 
      79           0 :         if (!image_name_is_valid(new_name))
      80           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
      81             : 
      82           0 :         r = bus_verify_polkit_async(
      83             :                         message,
      84             :                         CAP_SYS_ADMIN,
      85             :                         "org.freedesktop.machine1.manage-images",
      86             :                         false,
      87             :                         UID_INVALID,
      88             :                         &m->polkit_registry,
      89             :                         error);
      90           0 :         if (r < 0)
      91           0 :                 return r;
      92           0 :         if (r == 0)
      93           0 :                 return 1; /* Will call us back */
      94             : 
      95           0 :         r = image_rename(image, new_name);
      96           0 :         if (r < 0)
      97           0 :                 return r;
      98             : 
      99           0 :         return sd_bus_reply_method_return(message, NULL);
     100             : }
     101             : 
     102           0 : int bus_image_method_clone(
     103             :                 sd_bus_message *message,
     104             :                 void *userdata,
     105             :                 sd_bus_error *error) {
     106             : 
     107           0 :         Image *image = userdata;
     108           0 :         Manager *m = image->userdata;
     109             :         const char *new_name;
     110             :         int r, read_only;
     111             : 
     112           0 :         assert(message);
     113           0 :         assert(image);
     114             : 
     115           0 :         r = sd_bus_message_read(message, "sb", &new_name, &read_only);
     116           0 :         if (r < 0)
     117           0 :                 return r;
     118             : 
     119           0 :         if (!image_name_is_valid(new_name))
     120           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
     121             : 
     122           0 :         r = bus_verify_polkit_async(
     123             :                         message,
     124             :                         CAP_SYS_ADMIN,
     125             :                         "org.freedesktop.machine1.manage-images",
     126             :                         false,
     127             :                         UID_INVALID,
     128             :                         &m->polkit_registry,
     129             :                         error);
     130           0 :         if (r < 0)
     131           0 :                 return r;
     132           0 :         if (r == 0)
     133           0 :                 return 1; /* Will call us back */
     134             : 
     135           0 :         r = image_clone(image, new_name, read_only);
     136           0 :         if (r < 0)
     137           0 :                 return r;
     138             : 
     139           0 :         return sd_bus_reply_method_return(message, NULL);
     140             : }
     141             : 
     142           0 : int bus_image_method_mark_read_only(
     143             :                 sd_bus_message *message,
     144             :                 void *userdata,
     145             :                 sd_bus_error *error) {
     146             : 
     147           0 :         Image *image = userdata;
     148           0 :         Manager *m = image->userdata;
     149             :         int r, read_only;
     150             : 
     151           0 :         assert(message);
     152             : 
     153           0 :         r = sd_bus_message_read(message, "b", &read_only);
     154           0 :         if (r < 0)
     155           0 :                 return r;
     156             : 
     157           0 :         r = bus_verify_polkit_async(
     158             :                         message,
     159             :                         CAP_SYS_ADMIN,
     160             :                         "org.freedesktop.machine1.manage-images",
     161             :                         false,
     162             :                         UID_INVALID,
     163             :                         &m->polkit_registry,
     164             :                         error);
     165           0 :         if (r < 0)
     166           0 :                 return r;
     167           0 :         if (r == 0)
     168           0 :                 return 1; /* Will call us back */
     169             : 
     170           0 :         r = image_read_only(image, read_only);
     171           0 :         if (r < 0)
     172           0 :                 return r;
     173             : 
     174           0 :         return sd_bus_reply_method_return(message, NULL);
     175             : }
     176             : 
     177           0 : int bus_image_method_set_limit(
     178             :                 sd_bus_message *message,
     179             :                 void *userdata,
     180             :                 sd_bus_error *error) {
     181             : 
     182           0 :         Image *image = userdata;
     183           0 :         Manager *m = image->userdata;
     184             :         uint64_t limit;
     185             :         int r;
     186             : 
     187           0 :         assert(message);
     188             : 
     189           0 :         r = sd_bus_message_read(message, "t", &limit);
     190           0 :         if (r < 0)
     191           0 :                 return r;
     192             : 
     193           0 :         r = bus_verify_polkit_async(
     194             :                         message,
     195             :                         CAP_SYS_ADMIN,
     196             :                         "org.freedesktop.machine1.manage-images",
     197             :                         false,
     198             :                         UID_INVALID,
     199             :                         &m->polkit_registry,
     200             :                         error);
     201           0 :         if (r < 0)
     202           0 :                 return r;
     203           0 :         if (r == 0)
     204           0 :                 return 1; /* Will call us back */
     205             : 
     206           0 :         r = image_set_limit(image, limit);
     207           0 :         if (r < 0)
     208           0 :                 return r;
     209             : 
     210           0 :         return sd_bus_reply_method_return(message, NULL);
     211             : }
     212             : 
     213             : const sd_bus_vtable image_vtable[] = {
     214             :         SD_BUS_VTABLE_START(0),
     215             :         SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
     216             :         SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
     217             :         SD_BUS_PROPERTY("Type", "s", property_get_type,  offsetof(Image, type), 0),
     218             :         SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
     219             :         SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
     220             :         SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
     221             :         SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
     222             :         SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0),
     223             :         SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0),
     224             :         SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0),
     225             :         SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
     226             :         SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
     227             :         SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
     228             :         SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
     229             :         SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
     230             :         SD_BUS_VTABLE_END
     231             : };
     232             : 
     233           0 : static int image_flush_cache(sd_event_source *s, void *userdata) {
     234           0 :         Manager *m = userdata;
     235             :         Image *i;
     236             : 
     237           0 :         assert(s);
     238           0 :         assert(m);
     239             : 
     240           0 :         while ((i = hashmap_steal_first(m->image_cache)))
     241           0 :                 image_unref(i);
     242             : 
     243           0 :         return 0;
     244             : }
     245             : 
     246           0 : int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
     247           0 :         _cleanup_free_ char *e = NULL;
     248           0 :         Manager *m = userdata;
     249           0 :         Image *image = NULL;
     250             :         const char *p;
     251             :         int r;
     252             : 
     253           0 :         assert(bus);
     254           0 :         assert(path);
     255           0 :         assert(interface);
     256           0 :         assert(found);
     257             : 
     258           0 :         p = startswith(path, "/org/freedesktop/machine1/image/");
     259           0 :         if (!p)
     260           0 :                 return 0;
     261             : 
     262           0 :         e = bus_label_unescape(p);
     263           0 :         if (!e)
     264           0 :                 return -ENOMEM;
     265             : 
     266           0 :         image = hashmap_get(m->image_cache, e);
     267           0 :         if (image) {
     268           0 :                 *found = image;
     269           0 :                 return 1;
     270             :         }
     271             : 
     272           0 :         r = hashmap_ensure_allocated(&m->image_cache, &string_hash_ops);
     273           0 :         if (r < 0)
     274           0 :                 return r;
     275             : 
     276           0 :         if (!m->image_cache_defer_event) {
     277           0 :                 r = sd_event_add_defer(m->event, &m->image_cache_defer_event, image_flush_cache, m);
     278           0 :                 if (r < 0)
     279           0 :                         return r;
     280             : 
     281           0 :                 r = sd_event_source_set_priority(m->image_cache_defer_event, SD_EVENT_PRIORITY_IDLE);
     282           0 :                 if (r < 0)
     283           0 :                         return r;
     284             :         }
     285             : 
     286           0 :         r = sd_event_source_set_enabled(m->image_cache_defer_event, SD_EVENT_ONESHOT);
     287           0 :         if (r < 0)
     288           0 :                 return r;
     289             : 
     290           0 :         r = image_find(e, &image);
     291           0 :         if (r <= 0)
     292           0 :                 return r;
     293             : 
     294           0 :         image->userdata = m;
     295             : 
     296           0 :         r = hashmap_put(m->image_cache, image->name, image);
     297           0 :         if (r < 0) {
     298           0 :                 image_unref(image);
     299           0 :                 return r;
     300             :         }
     301             : 
     302           0 :         *found = image;
     303           0 :         return 1;
     304             : }
     305             : 
     306           0 : char *image_bus_path(const char *name) {
     307           0 :         _cleanup_free_ char *e = NULL;
     308             : 
     309           0 :         assert(name);
     310             : 
     311           0 :         e = bus_label_escape(name);
     312           0 :         if (!e)
     313           0 :                 return NULL;
     314             : 
     315           0 :         return strappend("/org/freedesktop/machine1/image/", e);
     316             : }
     317             : 
     318           0 : int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
     319           0 :         _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
     320           0 :         _cleanup_strv_free_ char **l = NULL;
     321             :         Image *image;
     322             :         Iterator i;
     323             :         int r;
     324             : 
     325           0 :         assert(bus);
     326           0 :         assert(path);
     327           0 :         assert(nodes);
     328             : 
     329           0 :         images = hashmap_new(&string_hash_ops);
     330           0 :         if (!images)
     331           0 :                 return -ENOMEM;
     332             : 
     333           0 :         r = image_discover(images);
     334           0 :         if (r < 0)
     335           0 :                 return r;
     336             : 
     337           0 :         HASHMAP_FOREACH(image, images, i) {
     338             :                 char *p;
     339             : 
     340           0 :                 p = image_bus_path(image->name);
     341           0 :                 if (!p)
     342           0 :                         return -ENOMEM;
     343             : 
     344           0 :                 r = strv_consume(&l, p);
     345           0 :                 if (r < 0)
     346           0 :                         return r;
     347             :         }
     348             : 
     349           0 :         *nodes = l;
     350           0 :         l = NULL;
     351             : 
     352           0 :         return 1;
     353             : }

Generated by: LCOV version 1.11