[libvirt] [libvirt-designer PATCHv2] Add support for floppies and CDROMs

Christophe Fergeau cfergeau at redhat.com
Wed Apr 3 11:35:58 UTC 2013


This mirrors disk_file/disk_device API so that it's possible to
add CDROMs and floppies to a GVirDesignerDomain.
This also adds the corresponding -C/-F options to virtxml
---

Here is a reworked version of my patch to add support for CDROMs which
does not override the 'format' parameter this time.

Christophe

 examples/virtxml.c                         | 108 +++++++++++++++++++++---
 libvirt-designer/libvirt-designer-domain.c | 127 +++++++++++++++++++++++++++++
 libvirt-designer/libvirt-designer-domain.h |  14 ++++
 libvirt-designer/libvirt-designer.sym      |   4 +
 4 files changed, 240 insertions(+), 13 deletions(-)

diff --git a/examples/virtxml.c b/examples/virtxml.c
index 49a7b4e..d4c5967 100644
--- a/examples/virtxml.c
+++ b/examples/virtxml.c
@@ -33,7 +33,9 @@
 #include <unistd.h>
 #include <glib/gprintf.h>
 
+GList *cdrom_str_list = NULL;
 GList *disk_str_list = NULL;
+GList *floppy_str_list = NULL;
 GList *iface_str_list = NULL;
 OsinfoDb *db = NULL;
 
@@ -173,16 +175,17 @@ cleanup:
     return TRUE;
 }
 
+
 static void
-add_disk(gpointer data,
-         gpointer user_data)
+add_disk_generic(GVirDesignerDomain *domain,
+                 const char *path,
+                 GVirConfigDomainDiskGuestDeviceType type)
 {
-    GVirDesignerDomain *domain = (GVirDesignerDomain *) user_data;
     GVirConfigDomainDisk *disk;
-    char *path = (char *) data;
     char *format = NULL;
     struct stat buf;
     GError *error = NULL;
+    gboolean is_device;
 
     format = strchr(path, ',');
     if (format) {
@@ -195,12 +198,30 @@ add_disk(gpointer data,
         exit(EXIT_FAILURE);
     }
 
-    if (!stat(path, &buf) &&
-        !S_ISREG(buf.st_mode)) {
-        disk = gvir_designer_domain_add_disk_device(domain, path, &error);
-    } else {
-        disk = gvir_designer_domain_add_disk_file(domain, path, format, &error);
+    is_device = (!stat(path, &buf) && !S_ISREG(buf.st_mode));
+    switch(type) {
+        case GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_CDROM:
+            if (is_device)
+                disk = gvir_designer_domain_add_cdrom_device(domain, path, &error);
+            else
+                disk = gvir_designer_domain_add_cdrom_file(domain, path, format, &error);
+            break;
+        case GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_DISK:
+            if (is_device)
+                disk = gvir_designer_domain_add_disk_device(domain, path, &error);
+            else
+                disk = gvir_designer_domain_add_disk_file(domain, path, format, &error);
+            break;
+        case GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_FLOPPY:
+            if (is_device)
+                disk = gvir_designer_domain_add_floppy_device(domain, path, &error);
+            else
+                disk = gvir_designer_domain_add_floppy_file(domain, path, format, &error);
+            break;
+        default:
+            g_return_if_reached();
     }
+
     if (disk)
         g_object_unref(G_OBJECT(disk));
 
@@ -210,6 +231,42 @@ add_disk(gpointer data,
     }
 }
 
+
+static void add_cdrom(gpointer data, gpointer user_data)
+{
+    add_disk_generic(GVIR_DESIGNER_DOMAIN(user_data),
+                     (const char *)data,
+                     GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_CDROM);
+}
+
+
+static void add_disk(gpointer data, gpointer user_data)
+{
+    add_disk_generic(GVIR_DESIGNER_DOMAIN(user_data),
+                     (const char *)data,
+                     GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_DISK);
+}
+
+
+static void add_floppy(gpointer data, gpointer user_data)
+{
+    add_disk_generic(GVIR_DESIGNER_DOMAIN(user_data),
+                     (const char *)data,
+                     GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_FLOPPY);
+}
+
+
+static gboolean
+add_cdrom_str(const gchar *option_name,
+              const gchar *value,
+              gpointer data,
+              GError **error)
+{
+    cdrom_str_list = g_list_append(cdrom_str_list, g_strdup(value));
+    return TRUE;
+}
+
+
 static gboolean
 add_disk_str(const gchar *option_name,
              const gchar *value,
@@ -220,6 +277,18 @@ add_disk_str(const gchar *option_name,
     return TRUE;
 }
 
+
+static gboolean
+add_floppy_str(const gchar *option_name,
+               const gchar *value,
+               gpointer data,
+               GError **error)
+{
+    floppy_str_list = g_list_append(floppy_str_list, g_strdup(value));
+    return TRUE;
+}
+
+
 static void
 add_iface(gpointer data,
           gpointer user_data)
@@ -357,7 +426,7 @@ cleanup:
 }
 
 static OsinfoOs *
-guess_os_from_disk(GList *disk_list)
+guess_os_from_cdrom(GList *disk_list)
 {
     OsinfoOs *ret = NULL;
     GList *list_it = NULL;
@@ -512,8 +581,12 @@ main(int argc, char *argv[])
             "set hypervisor under which domain will be running", "PLATFORM"},
         {"architecture", 'a', 0, G_OPTION_ARG_STRING, &arch_str,
             "set domain architecture", "ARCH"},
+        {"cdrom", 'C', 0, G_OPTION_ARG_CALLBACK, add_cdrom_str,
+            "add CDROM to domain with PATH being source and FORMAT its format", "PATH[,FORMAT]"},
         {"disk", 'd', 0, G_OPTION_ARG_CALLBACK, add_disk_str,
             "add disk to domain with PATH being source and FORMAT its format", "PATH[,FORMAT]"},
+        {"floppy", 'F', 0, G_OPTION_ARG_CALLBACK, add_floppy_str,
+            "add floppy to domain with PATH being source and FORMAT its format", "PATH[,FORMAT]"},
         {"interface", 'i', 0, G_OPTION_ARG_CALLBACK, add_iface_str,
             "add interface with NETWORK source. Possible ARGs: mac, link={up,down}", "NETWORK[,ARG=VAL]"},
         {"resources", 'r', 0, G_OPTION_ARG_STRING, &resources_str,
@@ -543,7 +616,7 @@ main(int argc, char *argv[])
         if (!os)
             os = find_os_by_short_id(os_str);
     } else {
-        os = guess_os_from_disk(disk_str_list);
+        os = guess_os_from_cdrom(cdrom_str_list);
     }
 
     if (!os) {
@@ -593,8 +666,12 @@ main(int argc, char *argv[])
                                              NULL);
     }
 
+    g_list_foreach(cdrom_str_list, add_cdrom, domain);
+
     g_list_foreach(disk_str_list, add_disk, domain);
 
+    g_list_foreach(floppy_str_list, add_floppy, domain);
+
     g_list_foreach(iface_str_list, add_iface, domain);
 
     config = gvir_designer_domain_get_config(domain);
@@ -683,6 +760,11 @@ is and ID which can be obtained via I<--list-platform>.
 
 Set domain's architecture
 
+=item -C PATH[,FORMAT] --cdrom=PATH[,FORMAT]
+
+Add I<PATH> as a CDROM to the domain. To specify its format (e.g. raw,
+qcow2, phy) use I<FORMAT>.
+
 =item -d PATH[,FORMAT] --disk=PATH[,FORMAT]
 
 Add I<PATH> as a disk to the domain. To specify its format (e.g. raw,
@@ -712,12 +794,12 @@ platform. Usually, the platform is guessed from the connection URI.
 Domain with Fedora 17 from locally stored ISO and one NIC with mac
 00:11:22:33:44:55 and link set down:
 
-  # virtxml -d Fedora-17-x86_64-Live-KDE.iso \
+  # virtxml -C Fedora-17-x86_64-Live-KDE.iso \
             -i default,mac=00:11:22:33:44:55,link=down
 
 To add multiple devices just use appropriate argument multiple times:
 
-  # virtxml -d /tmp/Fedora-17-x86_64-Live-KDE.iso,raw \
+  # virtxml -d /tmp/home.img,qcow2 \
             -d /var/lib/libvirt/images/f17.img,qcow2 \
             -i default,mac=00:11:22:33:44:55,link=down \
             -i blue_network \
diff --git a/libvirt-designer/libvirt-designer-domain.c b/libvirt-designer/libvirt-designer-domain.c
index 0d47d3c..2226d39 100644
--- a/libvirt-designer/libvirt-designer-domain.c
+++ b/libvirt-designer/libvirt-designer-domain.c
@@ -841,6 +841,7 @@ gvir_designer_domain_next_disk_target(GVirDesignerDomain *design,
 static GVirConfigDomainDisk *
 gvir_designer_domain_add_disk_full(GVirDesignerDomain *design,
                                    GVirConfigDomainDiskType type,
+                                   GVirConfigDomainDiskGuestDeviceType guest_type,
                                    const char *path,
                                    const char *format,
                                    gchar *target,
@@ -960,6 +961,7 @@ GVirConfigDomainDisk *gvir_designer_domain_add_disk_file(GVirDesignerDomain *des
 
     ret = gvir_designer_domain_add_disk_full(design,
                                              GVIR_CONFIG_DOMAIN_DISK_FILE,
+                                             GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_DISK,
                                              filepath,
                                              format,
                                              NULL,
@@ -989,6 +991,7 @@ GVirConfigDomainDisk *gvir_designer_domain_add_disk_device(GVirDesignerDomain *d
 
     ret = gvir_designer_domain_add_disk_full(design,
                                              GVIR_CONFIG_DOMAIN_DISK_BLOCK,
+                                             GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_DISK,
                                              devpath,
                                              "raw",
                                              NULL,
@@ -996,6 +999,130 @@ GVirConfigDomainDisk *gvir_designer_domain_add_disk_device(GVirDesignerDomain *d
     return ret;
 }
 
+/**
+ * gvir_designer_domain_add_cdrom_file:
+ * @design: (transfer none): the domain designer instance
+ * @filepath: (transfer none): the path to a file
+ * @format: (transfer none): file format
+ * @error: return location for a #GError, or NULL
+ *
+ * Add a new disk to the domain.
+ *
+ * Returns: (transfer full): the pointer to new cdrom.
+ * If something fails NULL is returned and @error is set.
+ */
+GVirConfigDomainDisk *gvir_designer_domain_add_cdrom_file(GVirDesignerDomain *design,
+                                                          const char *filepath,
+                                                          const char *format,
+                                                          GError **error)
+{
+    g_return_val_if_fail(GVIR_DESIGNER_IS_DOMAIN(design), NULL);
+
+    GVirConfigDomainDisk *ret = NULL;
+
+    ret = gvir_designer_domain_add_disk_full(design,
+                                             GVIR_CONFIG_DOMAIN_DISK_FILE,
+                                             GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_CDROM,
+                                             filepath,
+                                             format,
+                                             NULL,
+                                             error);
+    return ret;
+}
+
+
+/**
+ * gvir_designer_domain_add_cdrom_device:
+ * @design: (transfer none): the domain designer instance
+ * @devpath: (transfer none): path to the device
+ * @error: return location for a #GError, or NULL
+ *
+ * Add given device as a new cdrom to the domain designer instance.
+ *
+ * Returns: (transfer full): the pointer to the new cdrom.
+ * If something fails NULL is returned and @error is set.
+ */
+GVirConfigDomainDisk *gvir_designer_domain_add_cdrom_device(GVirDesignerDomain *design,
+                                                            const char *devpath,
+                                                            GError **error)
+{
+    g_return_val_if_fail(GVIR_DESIGNER_IS_DOMAIN(design), NULL);
+
+    GVirConfigDomainDisk *ret = NULL;
+
+    ret = gvir_designer_domain_add_disk_full(design,
+                                             GVIR_CONFIG_DOMAIN_DISK_BLOCK,
+                                             GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_CDROM,
+                                             devpath,
+                                             "raw",
+                                             NULL,
+                                             error);
+    return ret;
+}
+
+
+/**
+ * gvir_designer_domain_add_floppy_file:
+ * @design: (transfer none): the domain designer instance
+ * @filepath: (transfer none): the path to a file
+ * @format: (transfer none): file format
+ * @error: return location for a #GError, or NULL
+ *
+ * Add a new disk to the domain.
+ *
+ * Returns: (transfer full): the pointer to new floppy.
+ * If something fails NULL is returned and @error is set.
+ */
+GVirConfigDomainDisk *gvir_designer_domain_add_floppy_file(GVirDesignerDomain *design,
+                                                           const char *filepath,
+                                                           const char *format,
+                                                           GError **error)
+{
+    g_return_val_if_fail(GVIR_DESIGNER_IS_DOMAIN(design), NULL);
+
+    GVirConfigDomainDisk *ret = NULL;
+
+    ret = gvir_designer_domain_add_disk_full(design,
+                                             GVIR_CONFIG_DOMAIN_DISK_FILE,
+                                             GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_FLOPPY,
+                                             filepath,
+                                             format,
+                                             NULL,
+                                             error);
+    return ret;
+}
+
+
+/**
+ * gvir_designer_domain_add_floppy_device:
+ * @design: (transfer none): the domain designer instance
+ * @devpath: (transfer none): path to the device
+ * @error: return location for a #GError, or NULL
+ *
+ * Add given device as a new floppy to the domain designer instance.
+ *
+ * Returns: (transfer full): the pointer to the new floppy.
+ * If something fails NULL is returned and @error is set.
+ */
+GVirConfigDomainDisk *gvir_designer_domain_add_floppy_device(GVirDesignerDomain *design,
+                                                             const char *devpath,
+                                                             GError **error)
+{
+    g_return_val_if_fail(GVIR_DESIGNER_IS_DOMAIN(design), NULL);
+
+    GVirConfigDomainDisk *ret = NULL;
+
+    ret = gvir_designer_domain_add_disk_full(design,
+                                             GVIR_CONFIG_DOMAIN_DISK_BLOCK,
+                                             GVIR_CONFIG_DOMAIN_DISK_GUEST_DEVICE_FLOPPY,
+                                             devpath,
+                                             "raw",
+                                             NULL,
+                                             error);
+    return ret;
+}
+
+
 
 static const gchar *
 gvir_designer_domain_get_preferred_nic_model(GVirDesignerDomain *design,
diff --git a/libvirt-designer/libvirt-designer-domain.h b/libvirt-designer/libvirt-designer-domain.h
index 4d68ff6..99c280b 100644
--- a/libvirt-designer/libvirt-designer-domain.h
+++ b/libvirt-designer/libvirt-designer-domain.h
@@ -99,6 +99,13 @@ gboolean gvir_designer_domain_setup_container_full(GVirDesignerDomain *design,
                                                    const char *arch,
                                                    GError **error);
 
+GVirConfigDomainDisk *gvir_designer_domain_add_cdrom_file(GVirDesignerDomain *design,
+                                                         const char *filepath,
+                                                         const char *format,
+                                                         GError **error);
+GVirConfigDomainDisk *gvir_designer_domain_add_cdrom_device(GVirDesignerDomain *design,
+                                                           const char *devpath,
+                                                           GError **error);
 GVirConfigDomainDisk *gvir_designer_domain_add_disk_file(GVirDesignerDomain *design,
                                                          const char *filepath,
                                                          const char *format,
@@ -106,6 +113,13 @@ GVirConfigDomainDisk *gvir_designer_domain_add_disk_file(GVirDesignerDomain *des
 GVirConfigDomainDisk *gvir_designer_domain_add_disk_device(GVirDesignerDomain *design,
                                                            const char *devpath,
                                                            GError **error);
+GVirConfigDomainDisk *gvir_designer_domain_add_floppy_file(GVirDesignerDomain *design,
+                                                           const char *filepath,
+                                                           const char *format,
+                                                           GError **error);
+GVirConfigDomainDisk *gvir_designer_domain_add_floppy_device(GVirDesignerDomain *design,
+                                                             const char *devpath,
+                                                             GError **error);
 
 GVirConfigDomainInterface *gvir_designer_domain_add_interface_network(GVirDesignerDomain *design,
                                                                       const char *network,
diff --git a/libvirt-designer/libvirt-designer.sym b/libvirt-designer/libvirt-designer.sym
index 79db09f..7a24f2c 100644
--- a/libvirt-designer/libvirt-designer.sym
+++ b/libvirt-designer/libvirt-designer.sym
@@ -10,8 +10,12 @@ LIBVIRT_DESIGNER_0.0.1 {
 	gvir_designer_domain_get_platform;
 	gvir_designer_domain_get_capabilities;
 
+	gvir_designer_domain_add_cdrom_file;
+	gvir_designer_domain_add_cdrom_device;
 	gvir_designer_domain_add_disk_file;
 	gvir_designer_domain_add_disk_device;
+	gvir_designer_domain_add_floppy_file;
+	gvir_designer_domain_add_floppy_device;
 	gvir_designer_domain_add_interface_network;
 	gvir_designer_domain_setup_resources;
 	gvir_designer_domain_resources_get_type;
-- 
1.8.1.4




More information about the libvir-list mailing list