1 /*
2 * libvirt-gconfig-domain.c: libvirt domain configuration
3 *
4 * Copyright (C) 2008 Daniel P. Berrange
5 * Copyright (C) 2010-2011 Red Hat, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 * Author: Daniel P. Berrange <berrange@redhat.com>
22 */
23
24 #include <config.h>
25
26 #include "libvirt-gconfig/libvirt-gconfig.h"
27 #include "libvirt-gconfig/libvirt-gconfig-private.h"
28
29 #define GVIR_CONFIG_DOMAIN_GET_PRIVATE(obj) \
30 (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN, GVirConfigDomainPrivate))
31
32 struct _GVirConfigDomainPrivate
33 {
34 gboolean unused;
35 };
36
37 G_DEFINE_TYPE_WITH_PRIVATE(GVirConfigDomain, gvir_config_domain, GVIR_CONFIG_TYPE_OBJECT);
38
39 enum {
40 PROP_0,
41 PROP_NAME,
42 PROP_UUID,
43 PROP_TITLE,
44 PROP_DESCRIPTION,
45 PROP_MEMORY,
46 PROP_VCPU,
47 PROP_FEATURES,
48 PROP_CURRENT_MEMORY
49 };
50
gvir_config_domain_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)51 static void gvir_config_domain_get_property(GObject *object,
52 guint prop_id,
53 GValue *value,
54 GParamSpec *pspec)
55 {
56 GVirConfigDomain *domain = GVIR_CONFIG_DOMAIN(object);
57
58 switch (prop_id) {
59 case PROP_NAME:
60 g_value_set_string(value, gvir_config_domain_get_name(domain));
61 break;
62 case PROP_UUID:
63 g_value_set_string(value, gvir_config_domain_get_uuid(domain));
64 break;
65 case PROP_TITLE:
66 g_value_set_string(value, gvir_config_domain_get_title(domain));
67 break;
68 case PROP_DESCRIPTION:
69 g_value_set_string(value, gvir_config_domain_get_description(domain));
70 break;
71 case PROP_MEMORY:
72 g_value_set_uint64(value, gvir_config_domain_get_memory(domain));
73 break;
74 case PROP_CURRENT_MEMORY:
75 g_value_set_uint64(value, gvir_config_domain_get_current_memory(domain));
76 break;
77 case PROP_VCPU:
78 g_value_set_uint64(value, gvir_config_domain_get_vcpus(domain));
79 break;
80 case PROP_FEATURES:
81 g_value_take_boxed(value, gvir_config_domain_get_features(domain));
82 break;
83
84 default:
85 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
86 }
87 }
88
gvir_config_domain_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)89 static void gvir_config_domain_set_property(GObject *object,
90 guint prop_id,
91 const GValue *value,
92 GParamSpec *pspec)
93 {
94 GVirConfigDomain *domain = GVIR_CONFIG_DOMAIN(object);
95
96 switch (prop_id) {
97 case PROP_NAME:
98 gvir_config_domain_set_name(domain, g_value_get_string(value));
99 break;
100 case PROP_UUID:
101 gvir_config_domain_set_uuid(domain, g_value_get_string(value));
102 break;
103 case PROP_TITLE:
104 gvir_config_domain_set_title(domain, g_value_get_string(value));
105 break;
106 case PROP_DESCRIPTION:
107 gvir_config_domain_set_description(domain, g_value_get_string(value));
108 break;
109 case PROP_MEMORY:
110 gvir_config_domain_set_memory(domain, g_value_get_uint64(value));
111 break;
112 case PROP_CURRENT_MEMORY:
113 gvir_config_domain_set_current_memory(domain, g_value_get_uint64(value));
114 break;
115 case PROP_VCPU:
116 gvir_config_domain_set_vcpus(domain, g_value_get_uint64(value));
117 break;
118 case PROP_FEATURES:
119 gvir_config_domain_set_features(domain, g_value_get_boxed(value));
120 break;
121 default:
122 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
123 }
124 }
125
126
gvir_config_domain_class_init(GVirConfigDomainClass * klass)127 static void gvir_config_domain_class_init(GVirConfigDomainClass *klass)
128 {
129 GObjectClass *object_class = G_OBJECT_CLASS(klass);
130
131 object_class->get_property = gvir_config_domain_get_property;
132 object_class->set_property = gvir_config_domain_set_property;
133
134 g_object_class_install_property(object_class,
135 PROP_NAME,
136 g_param_spec_string("name",
137 "Name",
138 "Domain Name",
139 NULL,
140 G_PARAM_READWRITE |
141 G_PARAM_STATIC_STRINGS));
142 g_object_class_install_property(object_class,
143 PROP_UUID,
144 g_param_spec_string("uuid",
145 "UUID",
146 "Domain UUID",
147 NULL,
148 G_PARAM_READWRITE |
149 G_PARAM_STATIC_STRINGS));
150 g_object_class_install_property(object_class,
151 PROP_TITLE,
152 g_param_spec_string("title",
153 "Title",
154 "A short description - title - of the domain",
155 NULL,
156 G_PARAM_READWRITE |
157 G_PARAM_STATIC_STRINGS));
158 g_object_class_install_property(object_class,
159 PROP_DESCRIPTION,
160 g_param_spec_string("description",
161 "Description",
162 "Some human readable description (could be anything).",
163 NULL,
164 G_PARAM_READWRITE |
165 G_PARAM_STATIC_STRINGS));
166 g_object_class_install_property(object_class,
167 PROP_MEMORY,
168 g_param_spec_uint64("memory",
169 "Memory",
170 "Maximum Guest Memory (in kilobytes)",
171 0, G_MAXUINT64,
172 0,
173 G_PARAM_READWRITE |
174 G_PARAM_STATIC_STRINGS));
175 g_object_class_install_property(object_class,
176 PROP_CURRENT_MEMORY,
177 g_param_spec_uint64("current-memory",
178 "Current memory",
179 "Current Guest Memory (in kilobytes)",
180 0, G_MAXUINT64,
181 0,
182 G_PARAM_READWRITE |
183 G_PARAM_STATIC_STRINGS));
184 g_object_class_install_property(object_class,
185 PROP_VCPU,
186 g_param_spec_uint64("vcpu",
187 "Virtual CPUs",
188 "Maximum Number of Guest Virtual CPUs",
189 0, G_MAXUINT64,
190 1,
191 G_PARAM_READWRITE |
192 G_PARAM_STATIC_STRINGS));
193 g_object_class_install_property(object_class,
194 PROP_FEATURES,
195 g_param_spec_boxed("features",
196 "Features",
197 "Hypervisor Features",
198 G_TYPE_STRV,
199 G_PARAM_READWRITE |
200 G_PARAM_STATIC_STRINGS));
201 }
202
203
gvir_config_domain_init(GVirConfigDomain * domain)204 static void gvir_config_domain_init(GVirConfigDomain *domain)
205 {
206 domain->priv = GVIR_CONFIG_DOMAIN_GET_PRIVATE(domain);
207 }
208
209
gvir_config_domain_new_from_xml(const gchar * xml,GError ** error)210 GVirConfigDomain *gvir_config_domain_new_from_xml(const gchar *xml,
211 GError **error)
212 {
213 GVirConfigObject *object;
214
215 object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN,
216 "domain",
217 DATADIR "/libvirt/schemas/domain.rng",
218 xml, error);
219 return GVIR_CONFIG_DOMAIN(object);
220 }
221
gvir_config_domain_new(void)222 GVirConfigDomain *gvir_config_domain_new(void)
223 {
224 GVirConfigObject *object;
225
226 object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN,
227 "domain",
228 DATADIR "/libvirt/schemas/domain.rng");
229 return GVIR_CONFIG_DOMAIN(object);
230 }
231
gvir_config_domain_get_virt_type(GVirConfigDomain * domain)232 GVirConfigDomainVirtType gvir_config_domain_get_virt_type(GVirConfigDomain *domain)
233 {
234 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain),
235 GVIR_CONFIG_DOMAIN_VIRT_QEMU);
236
237 return gvir_config_object_get_attribute_genum
238 (GVIR_CONFIG_OBJECT(domain),
239 NULL,
240 "type",
241 GVIR_CONFIG_TYPE_DOMAIN_VIRT_TYPE,
242 GVIR_CONFIG_DOMAIN_VIRT_QEMU);
243 }
244
gvir_config_domain_set_virt_type(GVirConfigDomain * domain,GVirConfigDomainVirtType type)245 void gvir_config_domain_set_virt_type(GVirConfigDomain *domain, GVirConfigDomainVirtType type)
246 {
247 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
248 gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(domain),
249 "type",
250 GVIR_CONFIG_TYPE_DOMAIN_VIRT_TYPE,
251 type, NULL);
252 }
253
254
gvir_config_domain_get_name(GVirConfigDomain * domain)255 const char *gvir_config_domain_get_name(GVirConfigDomain *domain)
256 {
257 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
258
259 return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
260 "name");
261 }
262
gvir_config_domain_get_uuid(GVirConfigDomain * domain)263 const char *gvir_config_domain_get_uuid(GVirConfigDomain *domain)
264 {
265 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
266
267 return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
268 "uuid");
269 }
270
gvir_config_domain_get_title(GVirConfigDomain * domain)271 const char *gvir_config_domain_get_title(GVirConfigDomain *domain)
272 {
273 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
274
275 return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
276 "title");
277 }
278
279 /**
280 * gvir_config_domain_set_name:
281 * @domain: a #GVirConfigDomain
282 * @name: (allow-none):
283 */
gvir_config_domain_set_name(GVirConfigDomain * domain,const char * name)284 void gvir_config_domain_set_name(GVirConfigDomain *domain, const char *name)
285 {
286 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
287
288 gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
289 "name", name);
290 g_object_notify(G_OBJECT(domain), "name");
291 }
292
293 /**
294 * gvir_config_domain_set_uuid:
295 * @domain: a #GVirConfigDomain
296 * @uuid: (allow-none):
297 */
gvir_config_domain_set_uuid(GVirConfigDomain * domain,const char * uuid)298 void gvir_config_domain_set_uuid(GVirConfigDomain *domain, const char *uuid)
299 {
300 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
301
302 gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
303 "uuid", uuid);
304 g_object_notify(G_OBJECT(domain), "uuid");
305 }
306
307 /**
308 * gvir_config_domain_set_title:
309 * @domain: a #GVirConfigDomain
310 * @title: (allow-none): title of the domain
311 *
312 * Sets the title of the domain. This is an optional short textual description of the domain. Passing a NULL @title
313 * unsets the current domain title.
314 */
gvir_config_domain_set_title(GVirConfigDomain * domain,const char * title)315 void gvir_config_domain_set_title(GVirConfigDomain *domain, const char *title)
316 {
317 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
318
319 gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
320 "title", title);
321 g_object_notify(G_OBJECT(domain), "title");
322 }
323
gvir_config_domain_get_description(GVirConfigDomain * domain)324 const char *gvir_config_domain_get_description(GVirConfigDomain *domain)
325 {
326 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
327
328 return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
329 "description");
330 }
331
332 /**
333 * gvir_config_domain_set_description:
334 * @domain: a #GVirConfigDomain
335 * @description: (allow-none):
336 */
gvir_config_domain_set_description(GVirConfigDomain * domain,const char * description)337 void gvir_config_domain_set_description(GVirConfigDomain *domain,
338 const char *description)
339 {
340 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
341
342 gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
343 "description", description);
344 g_object_notify(G_OBJECT(domain), "description");
345 }
346
insert_base(GHashTable * unit_bases,const char * unit,guint64 unit_base)347 static void insert_base(GHashTable *unit_bases,
348 const char *unit,
349 guint64 unit_base)
350 {
351 guint64 *base;
352 base = g_slice_alloc(sizeof(*base));
353 *base = unit_base;
354 g_hash_table_insert(unit_bases, (gpointer)unit, base);
355 }
356
set_unit_bases(G_GNUC_UNUSED gpointer user_data)357 static gpointer set_unit_bases(G_GNUC_UNUSED gpointer user_data)
358 {
359 GHashTable *unit_bases;
360
361 unit_bases = g_hash_table_new(g_str_hash, g_str_equal);
362
363 insert_base(unit_bases, "b", 1);
364 insert_base(unit_bases, "bytes", 1);
365 insert_base(unit_bases, "KB", 1000);
366 insert_base(unit_bases, "k", 1024);
367 insert_base(unit_bases, "KiB", 1024);
368 insert_base(unit_bases, "MB", 1000*1000);
369 insert_base(unit_bases, "M", 1024*1024);
370 insert_base(unit_bases, "MiB", 1024*1024);
371 insert_base(unit_bases, "GB", 1000*1000*1000);
372 insert_base(unit_bases, "G", 1024*1024*1024);
373 insert_base(unit_bases, "GiB", 1024*1024*1024);
374 insert_base(unit_bases, "TB", (guint64)1000*1000*1000*1000);
375 insert_base(unit_bases, "T", (guint64)1024*1024*1024*1024);
376 insert_base(unit_bases, "TiB", (guint64)1024*1024*1024*1024);
377
378 return unit_bases;
379 }
380
get_unit_base(const char * unit,guint64 default_base)381 static guint64 get_unit_base(const char *unit, guint64 default_base)
382 {
383 static GOnce set_unit_bases_once = G_ONCE_INIT;
384 GHashTable *unit_bases;
385 guint64 *unit_base;
386
387 if (unit == NULL) {
388 return default_base;
389 }
390
391 unit_bases = g_once (&set_unit_bases_once, set_unit_bases, &unit_bases);
392 g_return_val_if_fail (unit_bases != NULL, default_base);
393
394 unit_base = g_hash_table_lookup(unit_bases, unit);
395 if (unit_base == NULL) {
396 /* unknown unit, fall back to the default unit */
397 g_return_val_if_reached(default_base);
398 }
399
400 return *unit_base;
401 }
402
403 /**
404 * gvir_config_domain_get_memory:
405 * @domain: a #GVirConfigDomain
406 *
407 * Returns: maximum amount of RAM in kilobytes (i.e. blocks of 1024 bytes).
408 */
gvir_config_domain_get_memory(GVirConfigDomain * domain)409 guint64 gvir_config_domain_get_memory(GVirConfigDomain *domain)
410 {
411 const char *unit;
412 guint64 unit_base;
413 guint64 memory;
414
415 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), 0);
416
417 unit = gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(domain), "memory", "unit");
418 unit_base = get_unit_base(unit, 1024);
419
420 memory = gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
421 "memory");
422
423 return memory * unit_base / 1024;
424 }
425
426 /**
427 * gvir_config_domain_get_current_memory:
428 * @domain: a #GVirConfigDomain
429 *
430 * Returns: current amount of RAM in kilobytes (i.e. blocks of 1024 bytes).
431 */
gvir_config_domain_get_current_memory(GVirConfigDomain * domain)432 guint64 gvir_config_domain_get_current_memory(GVirConfigDomain *domain)
433 {
434 const char *unit;
435 guint64 unit_base;
436 guint64 memory;
437
438 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), 0);
439
440 unit = gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(domain), "currentMemory", "unit");
441 unit_base = get_unit_base(unit, 1024);
442
443 memory = gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
444 "currentMemory");
445
446 return memory * unit_base / 1024;
447 }
448
449 /**
450 * gvir_config_domain_set_memory:
451 * @domain: a #GVirConfigDomain
452 * @memory: The maximum amount of RAM in kilobytes.
453 *
454 * Sets the maximum amount of RAM allocated to @domain in kilobytes (i.e.
455 * blocks of 1024 bytes).
456 */
gvir_config_domain_set_memory(GVirConfigDomain * domain,guint64 memory)457 void gvir_config_domain_set_memory(GVirConfigDomain *domain, guint64 memory)
458 {
459 GVirConfigObject *node;
460
461 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
462
463 node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain), "memory");
464 gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(node), NULL, memory);
465 gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(node),
466 "unit", "KiB",
467 NULL);
468 g_object_unref(G_OBJECT(node));
469 g_object_notify(G_OBJECT(domain), "memory");
470 }
471
472 /**
473 * gvir_config_domain_set_current_memory:
474 * @domain: a #GVirConfigDomain
475 * @memory: The current amount of RAM in kilobytes.
476 *
477 * Sets the current amount of RAM allocated to @domain in kilobytes (i.e.
478 * blocks of 1024 bytes). This can be set to less than the maximum domain
479 * memory to allow to balloon the guest memory on the fly. Be aware that
480 * libvirt will set it automatically if it's not explictly set, which means
481 * you may need to set this value in addition to 'memory' if you want to
482 * change the available domain memory after creation.
483 */
gvir_config_domain_set_current_memory(GVirConfigDomain * domain,guint64 memory)484 void gvir_config_domain_set_current_memory(GVirConfigDomain *domain,
485 guint64 memory)
486 {
487 GVirConfigObject *node;
488
489 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
490
491 node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain), "currentMemory");
492 gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(node), NULL, memory);
493 gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(node),
494 "unit", "KiB",
495 NULL);
496 g_object_unref(G_OBJECT(node));
497 g_object_notify(G_OBJECT(domain), "current-memory");
498 }
499
gvir_config_domain_get_vcpus(GVirConfigDomain * domain)500 guint64 gvir_config_domain_get_vcpus(GVirConfigDomain *domain)
501 {
502 return gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
503 "vcpu");
504 }
505
gvir_config_domain_set_vcpus(GVirConfigDomain * domain,guint64 vcpu_count)506 void gvir_config_domain_set_vcpus(GVirConfigDomain *domain, guint64 vcpu_count)
507 {
508 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
509
510 gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
511 "vcpu", vcpu_count);
512 g_object_notify(G_OBJECT(domain), "vcpu");
513 }
514
add_feature(xmlNodePtr node,gpointer opaque)515 static gboolean add_feature(xmlNodePtr node, gpointer opaque)
516 {
517 GPtrArray *features;
518 g_return_val_if_fail(opaque != NULL, FALSE);
519
520 features = (GPtrArray *)opaque;
521
522 g_ptr_array_add(features, g_strdup((char *)node->name));
523
524 return TRUE;
525 }
526
527 /**
528 * gvir_config_domain_get_features:
529 * @domain: a #GVirConfigDomain
530 *
531 * Returns: (transfer full): The returned list should be freed with
532 * g_strfreev() when no longer needed.
533
534 */
gvir_config_domain_get_features(GVirConfigDomain * domain)535 GStrv gvir_config_domain_get_features(GVirConfigDomain *domain)
536 {
537 GPtrArray *features;
538
539 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
540
541 features = g_ptr_array_new();
542 gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "features",
543 add_feature, features);
544 g_ptr_array_add(features, NULL);
545
546 return (GStrv)g_ptr_array_free(features, FALSE);
547 }
548
gvir_config_domain_set_features(GVirConfigDomain * domain,const GStrv features)549 void gvir_config_domain_set_features(GVirConfigDomain *domain,
550 const GStrv features)
551 {
552 GVirConfigObject *features_node;
553 GStrv it;
554
555 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
556
557 features_node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain),
558 "features");
559 g_return_if_fail(GVIR_CONFIG_IS_OBJECT(features_node));
560 for (it = features; *it != NULL; it++) {
561 GVirConfigObject *feature;
562 feature = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(features_node),
563 *it);
564 g_object_unref(G_OBJECT(feature));
565 }
566 g_object_unref(G_OBJECT(features_node));
567 g_object_notify(G_OBJECT(domain), "features");
568 }
569
570
571 /**
572 * gvir_config_domain_get_clock:
573 * @domain: a #GVirConfigDomain
574 *
575 * Gets the clock configuration of @domain
576 *
577 * Returns: (transfer full): A #GVirConfigDomainClock. The returned
578 * object should be unreffed with g_object_unref() when no longer needed.
579 */
gvir_config_domain_get_clock(GVirConfigDomain * domain)580 GVirConfigDomainClock *gvir_config_domain_get_clock(GVirConfigDomain *domain)
581 {
582 GVirConfigObject *object;
583
584 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
585
586 object = gvir_config_object_get_child_with_type(GVIR_CONFIG_OBJECT(domain),
587 "clock",
588 GVIR_CONFIG_TYPE_DOMAIN_CLOCK);
589
590 return GVIR_CONFIG_DOMAIN_CLOCK(object);
591 }
592
593
594 /**
595 * gvir_config_domain_set_clock:
596 * @domain: a #GVirConfigDomain
597 * @klock: (allow-none):
598 */
gvir_config_domain_set_clock(GVirConfigDomain * domain,GVirConfigDomainClock * klock)599 void gvir_config_domain_set_clock(GVirConfigDomain *domain,
600 GVirConfigDomainClock *klock)
601 {
602 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
603 g_return_if_fail(klock == NULL || GVIR_CONFIG_IS_DOMAIN_CLOCK(klock));
604
605 gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
606 "clock",
607 GVIR_CONFIG_OBJECT(klock));
608 }
609
610 /**
611 * gvir_config_domain_get_os:
612 * @domain: a #GVirConfigDomain
613 *
614 * Gets the operating system configuration of @domain
615 *
616 * Returns: (transfer full): A #GVirConfigDomainOs. The returned
617 * object should be unreffed with g_object_unref() when no longer needed.
618 */
gvir_config_domain_get_os(GVirConfigDomain * domain)619 GVirConfigDomainOs *gvir_config_domain_get_os(GVirConfigDomain *domain)
620 {
621 GVirConfigObject *object;
622
623 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
624
625 object = gvir_config_object_get_child_with_type(GVIR_CONFIG_OBJECT(domain),
626 "os",
627 GVIR_CONFIG_TYPE_DOMAIN_OS);
628
629 return GVIR_CONFIG_DOMAIN_OS(object);
630 }
631
632 /**
633 * gvir_config_domain_set_os:
634 * @domain: a #GVirConfigDomain
635 * @os: (allow-none): the os configuration to set
636 */
gvir_config_domain_set_os(GVirConfigDomain * domain,GVirConfigDomainOs * os)637 void gvir_config_domain_set_os(GVirConfigDomain *domain,
638 GVirConfigDomainOs *os)
639 {
640 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
641 g_return_if_fail(os == NULL || GVIR_CONFIG_IS_DOMAIN_OS(os));
642
643 gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
644 "os",
645 GVIR_CONFIG_OBJECT(os));
646 }
647
648 /**
649 * gvir_config_domain_set_seclabel:
650 * @domain: a #GVirConfigDomain
651 * @seclabel: (allow-none): the security label configuration to set
652 */
gvir_config_domain_set_seclabel(GVirConfigDomain * domain,GVirConfigDomainSeclabel * seclabel)653 void gvir_config_domain_set_seclabel(GVirConfigDomain *domain,
654 GVirConfigDomainSeclabel *seclabel)
655 {
656 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
657 g_return_if_fail(seclabel == NULL ||
658 GVIR_CONFIG_IS_DOMAIN_SECLABEL(seclabel));
659
660 gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
661 "seclabel",
662 GVIR_CONFIG_OBJECT(seclabel));
663 }
664
gvir_config_domain_set_lifecycle(GVirConfigDomain * domain,GVirConfigDomainLifecycleEvent event,GVirConfigDomainLifecycleAction action)665 void gvir_config_domain_set_lifecycle(GVirConfigDomain *domain,
666 GVirConfigDomainLifecycleEvent event,
667 GVirConfigDomainLifecycleAction action)
668 {
669 const char *event_str;
670 const char *action_str;
671
672 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
673 g_return_if_fail((event == GVIR_CONFIG_DOMAIN_LIFECYCLE_ON_CRASH) ||
674 ((action != GVIR_CONFIG_DOMAIN_LIFECYCLE_COREDUMP_DESTROY) &&
675 (action != GVIR_CONFIG_DOMAIN_LIFECYCLE_COREDUMP_RESTART)));
676
677 event_str = gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_LIFECYCLE_EVENT, event);
678 g_return_if_fail(event_str != NULL);
679 action_str = gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_LIFECYCLE_ACTION, action);
680 g_return_if_fail(action_str != NULL);
681
682 gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
683 event_str, action_str);
684 }
685
686 /**
687 * gvir_config_domain_set_devices:
688 * @domain: a #GVirConfigDomain
689 * @devices: (in) (element-type LibvirtGConfig.DomainDevice):
690 */
gvir_config_domain_set_devices(GVirConfigDomain * domain,GList * devices)691 void gvir_config_domain_set_devices(GVirConfigDomain *domain,
692 GList *devices)
693 {
694 GVirConfigObject *devices_node;
695 GList *it;
696
697 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
698
699 if (devices == NULL) {
700 gvir_config_object_delete_children(GVIR_CONFIG_OBJECT(domain),
701 "devices",
702 NULL);
703 return;
704 }
705 devices_node = gvir_config_object_new(GVIR_CONFIG_TYPE_OBJECT,
706 "devices", NULL);
707
708 for (it = devices; it != NULL; it = it->next) {
709 if (!GVIR_CONFIG_IS_DOMAIN_DEVICE(it->data)) {
710 g_warn_if_reached();
711 continue;
712 }
713 gvir_config_object_attach_add(devices_node,
714 GVIR_CONFIG_OBJECT(it->data));
715 }
716
717 gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
718 "devices",
719 devices_node);
720 g_object_unref(G_OBJECT(devices_node));
721 }
722
gvir_config_domain_add_device(GVirConfigDomain * domain,GVirConfigDomainDevice * device)723 void gvir_config_domain_add_device(GVirConfigDomain *domain,
724 GVirConfigDomainDevice *device)
725 {
726 GVirConfigObject *devices_node;
727
728 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
729 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DEVICE(device));
730
731 devices_node = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain),
732 "devices");
733
734 gvir_config_object_attach_add(devices_node, GVIR_CONFIG_OBJECT(device));
735 g_object_unref(G_OBJECT(devices_node));
736 }
737
738 struct GetDeviceData {
739 GVirConfigXmlDoc *doc;
740 GList *devices;
741 };
742
add_device(xmlNodePtr node,gpointer opaque)743 static gboolean add_device(xmlNodePtr node, gpointer opaque)
744 {
745 struct GetDeviceData* data = (struct GetDeviceData*)opaque;
746 GVirConfigDomainDevice *device;
747
748 device = gvir_config_domain_device_new_from_tree(data->doc, node);
749 if (device != NULL)
750 data->devices = g_list_append(data->devices, device);
751 else
752 g_debug("Failed to parse %s node", node->name);
753
754 return TRUE;
755 }
756
757 /**
758 * gvir_config_domain_get_devices:
759 * @domain: a #GVirConfigDomain
760 *
761 * Gets the list of devices attached to @domain. The returned list should
762 * be freed with g_list_free(), after its elements have been unreffed with
763 * g_object_unref().
764 *
765 * Returns: (element-type LibvirtGConfig.DomainDevice) (transfer full):
766 * a newly allocated #GList of #GVirConfigDomainDevice.
767 */
gvir_config_domain_get_devices(GVirConfigDomain * domain)768 GList *gvir_config_domain_get_devices(GVirConfigDomain *domain)
769 {
770 struct GetDeviceData data;
771
772 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
773
774 g_object_get(G_OBJECT(domain), "doc", &data.doc, NULL);
775 data.devices = NULL;
776 gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "devices",
777 add_device, &data);
778 if (data.doc != NULL) {
779 g_object_unref(G_OBJECT(data.doc));
780 }
781
782 return data.devices;
783 }
784
gvir_config_domain_set_custom_xml_helper(GVirConfigDomain * domain,const gchar * xml,const gchar * ns,const gchar * ns_uri,gboolean ns_children,GError ** error)785 static gboolean gvir_config_domain_set_custom_xml_helper(GVirConfigDomain *domain,
786 const gchar *xml,
787 const gchar *ns,
788 const gchar *ns_uri,
789 gboolean ns_children,
790 GError **error)
791 {
792 GVirConfigObject *metadata;
793 GVirConfigObject *custom_xml;
794
795 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE);
796 g_return_val_if_fail(xml != NULL, FALSE);
797 g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
798
799 metadata = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain),
800 "metadata");
801
802 custom_xml = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_OBJECT,
803 NULL, NULL, xml, error);
804 if (custom_xml == NULL) {
805 g_assert_not_reached();
806 g_object_unref(G_OBJECT(metadata));
807 return FALSE;
808 }
809
810 gvir_config_object_set_namespace(custom_xml, ns, ns_uri, ns_children);
811
812 gvir_config_object_delete_children(metadata, NULL, ns_uri);
813 gvir_config_object_attach_add(metadata, custom_xml);
814 g_object_unref(G_OBJECT(metadata));
815 g_object_unref(G_OBJECT(custom_xml));
816
817 return TRUE;
818 }
819
gvir_config_domain_set_custom_xml(GVirConfigDomain * domain,const gchar * xml,const gchar * ns,const gchar * ns_uri,GError ** error)820 gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
821 const gchar *xml,
822 const gchar *ns,
823 const gchar *ns_uri,
824 GError **error)
825 {
826 return gvir_config_domain_set_custom_xml_helper(domain,
827 xml,
828 ns,
829 ns_uri,
830 FALSE,
831 error);
832 }
833
gvir_config_domain_set_custom_xml_ns_children(GVirConfigDomain * domain,const gchar * xml,const gchar * ns,const gchar * ns_uri,GError ** error)834 gboolean gvir_config_domain_set_custom_xml_ns_children(GVirConfigDomain *domain,
835 const gchar *xml,
836 const gchar *ns,
837 const gchar *ns_uri,
838 GError **error)
839 {
840 return gvir_config_domain_set_custom_xml_helper(domain,
841 xml,
842 ns,
843 ns_uri,
844 TRUE,
845 error);
846 }
847
848 struct LookupNamespacedNodeData {
849 const char *ns_uri;
850 xmlNodePtr node;
851 };
852
lookup_namespaced_node(xmlNodePtr node,gpointer opaque)853 static gboolean lookup_namespaced_node(xmlNodePtr node, gpointer opaque)
854 {
855 struct LookupNamespacedNodeData* data = opaque;
856
857 if (node->ns == NULL)
858 return TRUE;
859
860 if (g_strcmp0((char *)node->ns->href, data->ns_uri) == 0) {
861 data->node = node;
862 return FALSE;
863 }
864
865 return TRUE;
866 }
867
gvir_config_domain_get_custom_xml(GVirConfigDomain * domain,const gchar * ns_uri)868 gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
869 const gchar *ns_uri)
870 {
871 struct LookupNamespacedNodeData data = { NULL, NULL };
872
873 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
874 g_return_val_if_fail(ns_uri != NULL, NULL);
875
876 data.ns_uri = ns_uri;
877 gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "metadata",
878 lookup_namespaced_node, &data);
879 return gvir_config_xml_node_to_string(data.node);
880 }
881
882 /**
883 * gvir_config_domain_get_cpu:
884 * @domain: a #GVirConfigDomain
885 *
886 * Gets the CPU configuration of @domain
887 *
888 * Returns: (transfer full): A #GVirConfigDomainCpu. The returned object
889 * should be unreffed with g_object_unref() when no longer needed.
890 */
gvir_config_domain_get_cpu(GVirConfigDomain * domain)891 GVirConfigDomainCpu *gvir_config_domain_get_cpu(GVirConfigDomain *domain)
892 {
893 GVirConfigObject *object;
894
895 g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
896
897 object = gvir_config_object_get_child_with_type(GVIR_CONFIG_OBJECT(domain),
898 "cpu",
899 GVIR_CONFIG_TYPE_DOMAIN_CPU);
900
901 return GVIR_CONFIG_DOMAIN_CPU(object);
902 }
903
904 /**
905 * gvir_config_domain_set_cpu:
906 * @domain: a #GVirConfigDomain
907 * @cpu: (allow-none):
908 */
gvir_config_domain_set_cpu(GVirConfigDomain * domain,GVirConfigDomainCpu * cpu)909 void gvir_config_domain_set_cpu(GVirConfigDomain *domain,
910 GVirConfigDomainCpu *cpu)
911 {
912 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
913 g_return_if_fail(cpu == NULL || GVIR_CONFIG_IS_DOMAIN_CPU(cpu));
914
915 gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
916 "cpu",
917 GVIR_CONFIG_OBJECT(cpu));
918 }
919
920 /**
921 * gvir_config_domain_set_power_management:
922 * @domain: a #GVirConfigDomain
923 * @pm: (allow-none): a #GVirPowerManagement instance
924 */
gvir_config_domain_set_power_management(GVirConfigDomain * domain,GVirConfigDomainPowerManagement * pm)925 void gvir_config_domain_set_power_management(GVirConfigDomain *domain,
926 GVirConfigDomainPowerManagement *pm)
927 {
928 g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
929 g_return_if_fail(pm != NULL || GVIR_CONFIG_IS_DOMAIN_POWER_MANAGEMENT(pm));
930
931 gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
932 "pm",
933 GVIR_CONFIG_OBJECT(pm));
934 }
935