Define hello API function and data types

This is the third post in the series “HOWTO: Add libvirt support for a qemu command”

When designing an API for libvirt, the first step is to think about how your API will be used and establish its calling conventions. Our new API interacts with a domain (by issuing a monitor command) so we will follow libvirt convention and name it virDomainHello. The hello qemu monitor command returns a string so let’s do the same in libvirt. The first parameter should be a pointer to the domain (qemu instance). The exclaim and language parameters could be passed individually (as an integer and string). I chose to pass them in a structure to show how structures are handled by libvirt.

Once the API is defined, we add an entry into the driver structure so that individual hypervisors (including qemu) can register an implementation of it. The driver structure is statically initialized by each hypervisor driver so this patch updates all drivers to set the new field to NULL.

Finally, virDomainHello breaks the Python bindings generator and causes compilation to fail. We can fix this by telling the generator to skip our function for the time being.

Let’s walk through the patch.

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 1cf9273..9fe724f 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2507,6 +2507,15 @@ int virDomainOpenConsole(virDomainPtr dom,
                          virStreamPtr st,
                          unsigned int flags);
 
+typedef struct _virHelloParams virHelloParams;
+struct _virHelloParams {
+    char *lang;
+    int exclaim;
+};
+typedef virHelloParams *virHelloParamsPtr;
+char *                   virDomainHello          (virDomainPtr dom,
+                                                  virHelloParamsPtr params);
+
 #ifdef __cplusplus
 }
 #endif

This first part of the patch defines the top-level data types. We create a new structure type virHelloParams to wrap the arguments. Libvirt coding style requires typedefs for the structure and structure pointers. Then we define the API function itself. It takes a domain pointer and a pointer to our new parameters structure as arguments and returns a string.

diff --git a/python/generator.py b/python/generator.py
index 4fa4f65..569f4a8 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -166,6 +166,7 @@ def enum(type, name, value):
 functions_failed = []
 functions_skipped = [
     "virConnectListDomains",
+    "virDomainHello",
 ]
 
 skipped_modules = {
@@ -180,6 +181,7 @@ skipped_types = {
      'virConnectDomainEventIOErrorCallback': "No function types in python",
      'virConnectDomainEventGraphicsCallback': "No function types in python",
      'virEventAddHandleFunc': "No function types in python",
+     'virHelloParamsPtr': "Not implemented yet",
 }
 
 #######################################################################

Here we tell the Python API generator to ignore our function and parameters structure. This is a compile fix. We’ll implement the Python bindings in a later patch.

diff --git a/src/driver.h b/src/driver.h
index 286130a..b2fc0e5 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -515,6 +515,8 @@ typedef int
                                virStreamPtr st,
                                unsigned int flags);
 
+typedef char *
+    (*virDrvDomainHello)(virDomainPtr dom, virHelloParamsPtr params);
 
 /**
  * _virDriver:
@@ -639,6 +641,7 @@ struct _virDriver {
     virDrvDomainSnapshotDelete domainSnapshotDelete;
     virDrvQemuDomainMonitorCommand qemuDomainMonitorCommand;
     virDrvDomainOpenConsole domainOpenConsole;
+    virDrvDomainHello domainHello;
 };
 
 typedef int

Add our new API to the driver structure.

diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index deda372..28cc0e4 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4675,6 +4675,7 @@ static virDriver esxDriver = {
     esxDomainSnapshotDelete,         /* domainSnapshotDelete */
     NULL,                            /* qemuDomainMonitorCommand */
     NULL,                            /* domainOpenConsole */
+    NULL,                            /* domainHello */
 };
 
 
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 3159e1b..1b3408f 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2904,6 +2904,7 @@ static virDriver lxcDriver = {
     NULL, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
     lxcDomainOpenConsole, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 static virStateDriver lxcStateDriver = {
diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c
index 3146589..6e1867f 100644
--- a/src/opennebula/one_driver.c
+++ b/src/opennebula/one_driver.c
@@ -832,6 +832,7 @@ static virDriver oneDriver = {
     NULL, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
     NULL, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 static virStateDriver oneStateDriver = {
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index fb30c37..0b9c270 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -1654,6 +1654,7 @@ static virDriver openvzDriver = {
     NULL, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
     NULL, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 int openvzRegister(void) {
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 51f9ff6..dcb848e 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -4055,6 +4055,7 @@ static virDriver phypDriver = {
     NULL,                       /* domainSnapshotDelete */
     NULL,                       /* qemuMonitorCommand */
     NULL, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 static virStorageDriver phypStorageDriver = {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index af897ad..40bb4c0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7191,6 +7191,7 @@ static virDriver qemuDriver = {
     qemuDomainSnapshotDelete, /* domainSnapshotDelete */
     qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
     qemuDomainOpenConsole, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index b05bbcb..87a68a6 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -11202,6 +11202,7 @@ static virDriver remote_driver = {
     remoteDomainSnapshotDelete, /* domainSnapshotDelete */
     remoteQemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
     remoteDomainOpenConsole, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 17f5ad9..57edda0 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -5447,6 +5447,7 @@ static virDriver testDriver = {
     NULL, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
     NULL, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 static virNetworkDriver testNetworkDriver = {
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 5514487..99d2f7a 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -2249,6 +2249,7 @@ static virDriver umlDriver = {
     NULL, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
     umlDomainOpenConsole, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 static int
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 8bd27dd..f532923 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -8647,6 +8647,7 @@ virDriver NAME(Driver) = {
     vboxDomainSnapshotDelete, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
     NULL, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 virNetworkDriver NAME(NetworkDriver) = {
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index b5e416b..3c14fbb 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -1007,6 +1007,7 @@ static virDriver vmwareDriver = {
     NULL,                       /* domainSnapshotDelete */
     NULL,                       /* qemuDomainMonitorCommand */
     NULL,                       /* domainOpenConsole */
+    NULL,                       /* domainHello */
 };
 
 int
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index bf422e6..ff2b172 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -2141,6 +2141,7 @@ static virDriver xenUnifiedDriver = {
     NULL, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
     xenUnifiedDomainOpenConsole, /* domainOpenConsole */
+    NULL, /* domainHello */
 };
 
 /**

It’s a bit tedious, but due to static initialization, we must add a placeholder to every driver.

Up next… Add hello to the public libvirt API

Advertisements

About aglitke

I am a software engineer working on Linux, open source software, and virtualization. I am proud to work at Red Hat on oVirt and Red Hat Virtualization with a focus on software defined storage. Other notable projects I have been involved in include: The Linux ppc64 architecture, Linux kernel crash dumps (kdump), Linux huge pages and libhugetlbfs, qemu, libvirt, and the Memory Overcommitment Manager.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s