1 /*
2  * libvirt-gconfig-domain-disk.c: libvirt domain disk configuration
3  *
4  * Copyright (C) 2011 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  *
20  * Author: Christophe Fergeau <cfergeau@gmail.com>
21  */
22 
23 #include <config.h>
24 
25 #include "libvirt-gconfig/libvirt-gconfig.h"
26 #include "libvirt-gconfig/libvirt-gconfig-private.h"
27 
28 #define GVIR_CONFIG_DOMAIN_DISK_GET_PRIVATE(obj)                         \
29         (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_DISK, GVirConfigDomainDiskPrivate))
30 
31 struct _GVirConfigDomainDiskPrivate
32 {
33     GVirConfigDomainDiskType type;
34 };
35 
36 G_DEFINE_TYPE_WITH_PRIVATE(GVirConfigDomainDisk, gvir_config_domain_disk, GVIR_CONFIG_TYPE_DOMAIN_DEVICE);
37 
38 
gvir_config_domain_disk_class_init(GVirConfigDomainDiskClass * klass G_GNUC_UNUSED)39 static void gvir_config_domain_disk_class_init(GVirConfigDomainDiskClass *klass G_GNUC_UNUSED)
40 {
41 }
42 
43 
gvir_config_domain_disk_init(GVirConfigDomainDisk * disk)44 static void gvir_config_domain_disk_init(GVirConfigDomainDisk *disk)
45 {
46     disk->priv = GVIR_CONFIG_DOMAIN_DISK_GET_PRIVATE(disk);
47 }
48 
49 
gvir_config_domain_disk_new(void)50 GVirConfigDomainDisk *gvir_config_domain_disk_new(void)
51 {
52     GVirConfigObject *object;
53 
54     object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN_DISK,
55                                     "disk", NULL);
56     return GVIR_CONFIG_DOMAIN_DISK(object);
57 }
58 
gvir_config_domain_disk_new_from_xml(const gchar * xml,GError ** error)59 GVirConfigDomainDisk *gvir_config_domain_disk_new_from_xml(const gchar *xml,
60                                                            GError **error)
61 {
62     GVirConfigObject *object;
63     object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_DISK,
64                                              "disk", NULL, xml, error);
65 
66     return GVIR_CONFIG_DOMAIN_DISK(object);
67 }
68 
69 GVirConfigDomainDevice *
gvir_config_domain_disk_new_from_tree(GVirConfigXmlDoc * doc,xmlNodePtr tree)70 gvir_config_domain_disk_new_from_tree(GVirConfigXmlDoc *doc,
71                                       xmlNodePtr tree)
72 {
73     GVirConfigObject *object;
74     GVirConfigDomainDisk *disk;
75     GVirConfigDomainDiskType type;
76     const char *type_str;
77 
78     type_str = gvir_config_xml_get_attribute_content(tree, "type");
79     if (type_str == NULL)
80         return NULL;
81 
82     type = gvir_config_genum_get_value(GVIR_CONFIG_TYPE_DOMAIN_DISK_TYPE,
83                                        type_str,
84                                        GVIR_CONFIG_DOMAIN_DISK_FILE);
85 
86     object = gvir_config_object_new_from_tree(GVIR_CONFIG_TYPE_DOMAIN_DISK,
87                                               doc, NULL, tree);
88     disk = GVIR_CONFIG_DOMAIN_DISK(object);
89     disk->priv->type = type;
90 
91     return GVIR_CONFIG_DOMAIN_DEVICE(object);
92 }
93 
gvir_config_domain_disk_set_type(GVirConfigDomainDisk * disk,GVirConfigDomainDiskType type)94 void gvir_config_domain_disk_set_type(GVirConfigDomainDisk *disk,
95                                       GVirConfigDomainDiskType type)
96 {
97     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
98 
99     gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(disk), "type",
100                                                GVIR_CONFIG_TYPE_DOMAIN_DISK_TYPE,
101                                                type, NULL);
102     disk->priv->type = type;
103 }
104 
gvir_config_domain_disk_set_guest_device_type(GVirConfigDomainDisk * disk,GVirConfigDomainDiskGuestDeviceType type)105 void gvir_config_domain_disk_set_guest_device_type(GVirConfigDomainDisk *disk,
106                                                    GVirConfigDomainDiskGuestDeviceType type)
107 {
108     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
109 
110     gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(disk), "device",
111                                                GVIR_CONFIG_TYPE_DOMAIN_DISK_GUEST_DEVICE_TYPE,
112                                                type, NULL);
113 }
114 
gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk * disk,GVirConfigDomainDiskSnapshotType type)115 void gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
116                                                GVirConfigDomainDiskSnapshotType type)
117 {
118     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
119 
120     gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(disk), "snapshot",
121                                                GVIR_CONFIG_TYPE_DOMAIN_DISK_SNAPSHOT_TYPE,
122                                                type, NULL);
123 }
124 
gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk * disk,GVirConfigDomainDiskStartupPolicy policy)125 void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk *disk,
126                                                 GVirConfigDomainDiskStartupPolicy policy)
127 {
128     const char *str;
129 
130     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
131     str = gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY, policy);
132     g_return_if_fail(str != NULL);
133     gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
134                                                 "source", "startupPolicy", str);
135 }
136 
gvir_config_domain_disk_set_source(GVirConfigDomainDisk * disk,const char * source)137 void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
138                                         const char *source)
139 {
140     const char *attribute_name;
141 
142     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
143 
144     switch (disk->priv->type) {
145         case GVIR_CONFIG_DOMAIN_DISK_FILE:
146             attribute_name = "file";
147             break;
148         case GVIR_CONFIG_DOMAIN_DISK_BLOCK:
149             attribute_name = "dev";
150             break;
151         case GVIR_CONFIG_DOMAIN_DISK_DIR:
152             attribute_name = "dir";
153             break;
154         case GVIR_CONFIG_DOMAIN_DISK_NETWORK:
155             attribute_name = "protocol";
156             break;
157         default:
158             g_return_if_reached();
159     }
160     gvir_config_object_replace_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
161                                                    "source",
162                                                    attribute_name, source);
163 }
164 
gvir_config_domain_disk_set_driver_name(GVirConfigDomainDisk * disk,const char * driver_name)165 void gvir_config_domain_disk_set_driver_name(GVirConfigDomainDisk *disk,
166                                              const char *driver_name)
167 {
168     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
169     gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
170                                                 "driver", "name", driver_name);
171 }
172 
173 /**
174  * gvir_config_domain_disk_set_driver_type:
175  *
176  * Deprecated: 0.1.7: Use gvir_config_domain_disk_set_driver_format()
177  * instead
178  */
gvir_config_domain_disk_set_driver_type(GVirConfigDomainDisk * disk,const char * driver_type)179 void gvir_config_domain_disk_set_driver_type(GVirConfigDomainDisk *disk,
180                                              const char *driver_type)
181 {
182     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
183     gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
184                                                 "driver", "type", driver_type);
185 }
186 
187 
gvir_config_domain_disk_set_driver_format(GVirConfigDomainDisk * disk,GVirConfigDomainDiskFormat format)188 void gvir_config_domain_disk_set_driver_format(GVirConfigDomainDisk *disk,
189                                                GVirConfigDomainDiskFormat format)
190 {
191     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
192     gvir_config_object_add_child_with_attribute_enum(GVIR_CONFIG_OBJECT(disk),
193                                                      "driver", "type",
194                                                      GVIR_CONFIG_TYPE_DOMAIN_DISK_FORMAT,
195                                                      format);
196 }
197 
198 
gvir_config_domain_disk_set_driver_cache(GVirConfigDomainDisk * disk,GVirConfigDomainDiskCacheType cache_type)199 void gvir_config_domain_disk_set_driver_cache(GVirConfigDomainDisk *disk,
200                                               GVirConfigDomainDiskCacheType cache_type)
201 {
202     const char *cache_str;
203 
204     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
205     cache_str = gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_DISK_CACHE_TYPE, cache_type);
206     g_return_if_fail(cache_str != NULL);
207     gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
208                                                 "driver", "cache", cache_str);
209 }
210 
gvir_config_domain_disk_set_target_bus(GVirConfigDomainDisk * disk,GVirConfigDomainDiskBus bus)211 void gvir_config_domain_disk_set_target_bus(GVirConfigDomainDisk *disk,
212                                             GVirConfigDomainDiskBus bus)
213 {
214     const char *bus_str;
215 
216     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
217     bus_str = gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_DISK_BUS, bus);
218     g_return_if_fail(bus_str != NULL);
219     gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
220                                                 "target", "bus", bus_str);
221 }
222 
gvir_config_domain_disk_set_target_dev(GVirConfigDomainDisk * disk,const char * dev)223 void gvir_config_domain_disk_set_target_dev(GVirConfigDomainDisk *disk,
224                                             const char *dev)
225 {
226     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
227     gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
228                                                 "target", "dev", dev);
229 }
230 
231 GVirConfigDomainDiskType
gvir_config_domain_disk_get_disk_type(GVirConfigDomainDisk * disk)232 gvir_config_domain_disk_get_disk_type(GVirConfigDomainDisk *disk)
233 {
234     return disk->priv->type;
235 }
236 
237 GVirConfigDomainDiskGuestDeviceType
gvir_config_domain_disk_get_guest_device_type(GVirConfigDomainDisk * disk)238 gvir_config_domain_disk_get_guest_device_type(GVirConfigDomainDisk *disk)
239 {
240     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
241                          GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_DISK);
242 
243     return gvir_config_object_get_attribute_genum(GVIR_CONFIG_OBJECT(disk),
244                                                   NULL,
245                                                   "device",
246                                                   GVIR_CONFIG_TYPE_DOMAIN_DISK_GUEST_DEVICE_TYPE,
247                                                   GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_DISK);
248 }
249 
250 GVirConfigDomainDiskSnapshotType
gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk * disk)251 gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk)
252 {
253     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
254                          GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_NO);
255 
256     return gvir_config_object_get_attribute_genum(GVIR_CONFIG_OBJECT(disk),
257                                                   NULL,
258                                                   "snapshot",
259                                                   GVIR_CONFIG_TYPE_DOMAIN_DISK_SNAPSHOT_TYPE,
260                                                   GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_NO);
261 }
262 
263 GVirConfigDomainDiskStartupPolicy
gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk * disk)264 gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk *disk)
265 {
266     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
267                          GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
268 
269     return gvir_config_object_get_attribute_genum
270                 (GVIR_CONFIG_OBJECT(disk),
271                  "source", "startupPolicy",
272                  GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY,
273                  GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
274 }
275 
276 const char *
gvir_config_domain_disk_get_source(GVirConfigDomainDisk * disk)277 gvir_config_domain_disk_get_source(GVirConfigDomainDisk *disk)
278 {
279     const char *attribute_name;
280 
281     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk), NULL);
282 
283     switch (disk->priv->type) {
284         case GVIR_CONFIG_DOMAIN_DISK_FILE:
285             attribute_name = "file";
286             break;
287         case GVIR_CONFIG_DOMAIN_DISK_BLOCK:
288             attribute_name = "dev";
289             break;
290         case GVIR_CONFIG_DOMAIN_DISK_DIR:
291             attribute_name = "dir";
292             break;
293         case GVIR_CONFIG_DOMAIN_DISK_NETWORK:
294             attribute_name = "protocol";
295             break;
296         default:
297             g_return_val_if_reached(NULL);
298     }
299     return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(disk),
300                                             "source", attribute_name);
301 }
302 
303 const char *
gvir_config_domain_disk_get_driver_name(GVirConfigDomainDisk * disk)304 gvir_config_domain_disk_get_driver_name(GVirConfigDomainDisk *disk)
305 {
306     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk), NULL);
307 
308     return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(disk),
309                                             "driver", "name");
310 }
311 
312 /**
313  * gvir_config_domain_disk_get_driver_type:
314  *
315  * Deprecated: 0.1.7: Use gvir_config_domain_disk_get_driver_format()
316  * instead
317  */
318 const char *
gvir_config_domain_disk_get_driver_type(GVirConfigDomainDisk * disk)319 gvir_config_domain_disk_get_driver_type(GVirConfigDomainDisk *disk)
320 {
321     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk), NULL);
322 
323     return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(disk),
324                                             "driver", "type");
325 }
326 
327 
328 GVirConfigDomainDiskFormat
gvir_config_domain_disk_get_driver_format(GVirConfigDomainDisk * disk)329 gvir_config_domain_disk_get_driver_format(GVirConfigDomainDisk *disk)
330 {
331     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
332                          GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW);
333 
334     return gvir_config_object_get_attribute_genum(GVIR_CONFIG_OBJECT(disk),
335                                                   "driver", "type",
336                                                   GVIR_CONFIG_TYPE_DOMAIN_DISK_FORMAT,
337                                                   GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW);
338 }
339 
340 
341 GVirConfigDomainDiskCacheType
gvir_config_domain_disk_get_driver_cache(GVirConfigDomainDisk * disk)342 gvir_config_domain_disk_get_driver_cache(GVirConfigDomainDisk *disk)
343 {
344     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
345                          GVIR_CONFIG_DOMAIN_DISK_CACHE_DEFAULT);
346 
347     return gvir_config_object_get_attribute_genum(GVIR_CONFIG_OBJECT(disk),
348                                                   "driver", "cache",
349                                                   GVIR_CONFIG_TYPE_DOMAIN_DISK_CACHE_TYPE,
350                                                   GVIR_CONFIG_DOMAIN_DISK_CACHE_DEFAULT);
351 }
352 
353 
354 GVirConfigDomainDiskBus
gvir_config_domain_disk_get_target_bus(GVirConfigDomainDisk * disk)355 gvir_config_domain_disk_get_target_bus(GVirConfigDomainDisk *disk)
356 {
357     /* FIXME: the default value depends on the "name" attribute, should we
358      * copy what libvirt is doing here?
359      */
360     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
361                          GVIR_CONFIG_DOMAIN_DISK_BUS_IDE);
362 
363     return gvir_config_object_get_attribute_genum(GVIR_CONFIG_OBJECT(disk),
364                                                   "target", "snapshot",
365                                                   GVIR_CONFIG_TYPE_DOMAIN_DISK_BUS,
366                                                   GVIR_CONFIG_DOMAIN_DISK_BUS_IDE);
367 }
368 
369 
370 const char *
gvir_config_domain_disk_get_target_dev(GVirConfigDomainDisk * disk)371 gvir_config_domain_disk_get_target_dev(GVirConfigDomainDisk *disk)
372 {
373     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk), NULL);
374 
375     return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(disk),
376                                             "target", "dev");
377 }
378 
379 
380 void
gvir_config_domain_disk_set_readonly(GVirConfigDomainDisk * disk,gboolean readonly)381 gvir_config_domain_disk_set_readonly(GVirConfigDomainDisk *disk,
382                                      gboolean readonly)
383 {
384     if (readonly) {
385         GVirConfigObject *node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(disk), "readonly");
386         g_object_unref(node);
387     } else
388         gvir_config_object_delete_child(GVIR_CONFIG_OBJECT(disk), "readonly", NULL);
389 }
390 
391 
392 /**
393  * gvir_config_domain_disk_set_driver:
394  * @disk: a #GVirConfigDomainDisk
395  * @driver: (allow-none): a #GVirConfigDomainDiskDriver
396  *
397  * Uses @driver as the driver configuration for @disk.
398  */
gvir_config_domain_disk_set_driver(GVirConfigDomainDisk * disk,GVirConfigDomainDiskDriver * driver)399 void gvir_config_domain_disk_set_driver(GVirConfigDomainDisk *disk,
400                                         GVirConfigDomainDiskDriver *driver)
401 {
402     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
403     g_return_if_fail(driver == NULL || GVIR_CONFIG_IS_DOMAIN_DISK_DRIVER(driver));
404 
405     gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(disk),
406                                       "driver",
407                                       GVIR_CONFIG_OBJECT(driver));
408 }
409 
410 
411 /**
412  * gvir_config_domain_disk_get_driver:
413  * @disk: a #GVirConfigDomainDisk
414  *
415  * Gets the driver configuration for @disk.
416  *
417  * Returns: (transfer full): A #GVirConfigDomainDiskDriver. The returned
418  * object should be unreffed with g_object_unref() when no longer needed.
419  */
gvir_config_domain_disk_get_driver(GVirConfigDomainDisk * disk)420 GVirConfigDomainDiskDriver *gvir_config_domain_disk_get_driver(GVirConfigDomainDisk *disk)
421 {
422     GVirConfigObject *object;
423 
424     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk), NULL);
425 
426     object = gvir_config_object_get_child_with_type(GVIR_CONFIG_OBJECT(disk),
427                                                     "driver",
428                                                     GVIR_CONFIG_TYPE_DOMAIN_DISK_DRIVER);
429 
430     return GVIR_CONFIG_DOMAIN_DISK_DRIVER(object);
431 }
432