[libvirt] [PATCH v1 2/2] network: Introduce start and shutdown hooks

Michal Privoznik mprivozn at redhat.com
Fri Jan 31 16:43:55 UTC 2014


There might be some use cases, where user wants to prepare the host or
its environment prior to starting a network and do some cleanup after
the network has been shut down. Consider all the functionality that
libvirt doesn't currently have as an example what a hook script can
possibly do.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 docs/hooks.html.in          | 43 +++++++++++++++++++++++++++++--------------
 src/network/bridge_driver.c | 29 +++++++++++++++++++++++++++++
 src/util/virhook.c          | 10 +++++++++-
 src/util/virhook.h          |  8 ++++++++
 4 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/docs/hooks.html.in b/docs/hooks.html.in
index f0f692b..b950031 100644
--- a/docs/hooks.html.in
+++ b/docs/hooks.html.in
@@ -16,6 +16,7 @@
           configuration<br/><br/></li>
       <li>A QEMU guest is started or stopped<br/><br/></li>
       <li>An LXC guest is started or stopped<br/><br/></li>
+      <li>A network is started or stopped<br/><br/></li>
     </ul>
 
     <h2><a name="location">Script location</a></h2>
@@ -44,6 +45,8 @@
           Executed when a QEMU guest is started, stopped, or migrated<br/><br/></li>
       <li><code>/etc/libvirt/hooks/lxc</code><br /><br/>
           Executed when an LXC guest is started or stopped</li>
+      <li><code>/etc/libvirt/hooks/network</code><br /><br/>
+          Executed when a network is started or stopped</li>
     </ul>
     <br/>
 
@@ -62,10 +65,11 @@
     <h2><a name="arguments">Script arguments</a></h2>
     <p>The hook scripts are called with specific command line arguments,
        depending upon the script, and the operation being performed.</p>
-    <p>The guest hook scripts, qemu and lxc, are also given the <b>full</b>
-       XML description for the domain on their stdin. This includes items
-       such the UUID of the domain and its storage information, and is
-       intended to provide all the libvirt information the script needs.</p>
+    <p>The guest hook scripts, qemu and lxc, or network hook script are
+       also given the <b>full</b> XML description for the domain on their
+       stdin. This includes items such as the UUID of the domain or network,
+       domain storage information, etc. and is intended to provide all the
+       libvirt information the script needs.</p>
 
     <p>The command line arguments take this approach:</p>
     <ol>
@@ -181,23 +185,34 @@
         <pre>/etc/libvirt/hooks/lxc guest_name reconnect begin -</pre>
       </li>
     </ul>
+
+    <h5><a name="network">/etc/libvirt/hooks/network</a></h5>
+    <ul>
+      <li><span class="since">Since 1.2.2</span>, when a network is started,
+        this script is called as:<br/>
+          <pre>/etc/libvirt/hooks/network network_name start - start</pre></li>
+      <li>When a network is shut down, this script is called as:<br/>
+          <pre>/etc/libvirt/hooks/network network_name shutdown - shutdown</pre></li>
+    </ul>
+
     <br/>
 
     <h2><a name="execution">Script execution</a></h2>
     <ul>
-      <li>The "start" operation for the guest hook scripts, qemu and lxc,
+      <li>The "start" operation for the guest and network hook scripts,
           executes <b>prior</b> to the guest being created.  This allows the
-          guest start operation to be aborted if the script returns indicating
-          failure.<br/><br/></li>
-      <li>The "shutdown" operation for the guest hook scripts, qemu and lxc,
-          executes <b>after</b> the guest has stopped.  If the hook script
-          indicates failure in its return, the shut down of the guest cannot
-          be aborted because it has already been performed.<br/><br/></li>
+          guest or network start operation to be aborted if the script returns
+          indicating failure.<br/><br/></li>
+      <li>The "shutdown" operation for the guest and network hook scripts,
+         executes <b>after</b> the guest or network has stopped.  If the hook
+          script indicates failure in its return, the shut down of the guest
+          or network cannot be aborted because it has already been performed.
+          <br/><br/></li>
       <li>Hook scripts execute in a synchronous fashion.  Libvirt waits
           for them to return before continuing the given operation.<br/><br/>
-          This is most noticeable with the guest start operation, as a lengthy
-          operation in the hook script can mean an extended wait for the guest
-          to be available to end users.<br/><br/></li>
+          This is most noticeable with the guest or network start operation,
+          as a lengthy operation in the hook script can mean an extended wait
+          for the guest or network to be available to end users.<br/><br/></li>
       <li>For a hook script to be utilised, it must have its execute bit set
           (ie. chmod o+rx <i>qemu</i>), and must be present when the libvirt
           daemon is started.<br/><br/></li>
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 53c2274..2bca5bc 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -71,6 +71,7 @@
 #include "virstring.h"
 #include "viraccessapicheck.h"
 #include "network_event.h"
+#include "virhook.h"
 
 #define VIR_FROM_THIS VIR_FROM_NETWORK
 
@@ -2011,6 +2012,23 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
     if (virNetworkObjSetDefTransient(network, true) < 0)
         goto cleanup;
 
+    /* Run an early hook to set-up missing devices */
+    if (virHookPresent(VIR_HOOK_DRIVER_NETWORK)) {
+        char *xml = virNetworkDefFormat(network->def, 0);
+        int hookret;
+
+        hookret = virHookCall(VIR_HOOK_DRIVER_NETWORK, network->def->name,
+                              VIR_HOOK_NETWORK_OP_START, VIR_HOOK_SUBOP_BEGIN,
+                              NULL, xml, NULL);
+        VIR_FREE(xml);
+
+        /*
+         * If the script raised an error abort the launch
+         */
+        if (hookret < 0)
+            goto cleanup;
+    }
+
     switch (network->def->forward.type) {
 
     case VIR_NETWORK_FORWARD_NONE:
@@ -2090,6 +2108,17 @@ static int networkShutdownNetwork(virNetworkDriverStatePtr driver,
         break;
     }
 
+    /* now that we know it's stopped call the hook if present */
+    if (virHookPresent(VIR_HOOK_DRIVER_NETWORK)) {
+        char *xml = virNetworkDefFormat(network->def, 0);
+
+        /* we can't stop the operation even if the script raised an error */
+        virHookCall(VIR_HOOK_DRIVER_NETWORK, network->def->name,
+                    VIR_HOOK_NETWORK_OP_STOPPED, VIR_HOOK_SUBOP_END,
+                    NULL, xml, NULL);
+        VIR_FREE(xml);
+    }
+
     network->active = 0;
     virNetworkObjUnsetDefTransient(network);
     return ret;
diff --git a/src/util/virhook.c b/src/util/virhook.c
index 159efdb..5206810 100644
--- a/src/util/virhook.c
+++ b/src/util/virhook.c
@@ -48,12 +48,14 @@ VIR_ENUM_DECL(virHookDaemonOp)
 VIR_ENUM_DECL(virHookSubop)
 VIR_ENUM_DECL(virHookQemuOp)
 VIR_ENUM_DECL(virHookLxcOp)
+VIR_ENUM_DECL(virHookNetworkOp)
 
 VIR_ENUM_IMPL(virHookDriver,
               VIR_HOOK_DRIVER_LAST,
               "daemon",
               "qemu",
-              "lxc")
+              "lxc",
+              "network")
 
 VIR_ENUM_IMPL(virHookDaemonOp, VIR_HOOK_DAEMON_OP_LAST,
               "start",
@@ -83,6 +85,10 @@ VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
               "started",
               "reconnect")
 
+VIR_ENUM_IMPL(virHookNetworkOp, VIR_HOOK_NETWORK_OP_LAST,
+              "start",
+              "stopped")
+
 static int virHooksFound = -1;
 
 /**
@@ -246,6 +252,8 @@ virHookCall(int driver,
         case VIR_HOOK_DRIVER_LXC:
             opstr = virHookLxcOpTypeToString(op);
             break;
+        case VIR_HOOK_DRIVER_NETWORK:
+            opstr = virHookNetworkOpTypeToString(op);
     }
     if (opstr == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
diff --git a/src/util/virhook.h b/src/util/virhook.h
index 96bf4cf..05ed3b5 100644
--- a/src/util/virhook.h
+++ b/src/util/virhook.h
@@ -30,6 +30,7 @@ enum virHookDriverType {
     VIR_HOOK_DRIVER_DAEMON = 0,        /* Daemon related events */
     VIR_HOOK_DRIVER_QEMU,              /* QEmu domains related events */
     VIR_HOOK_DRIVER_LXC,               /* LXC domains related events */
+    VIR_HOOK_DRIVER_NETWORK,           /* network related events */
 
     VIR_HOOK_DRIVER_LAST,
 };
@@ -74,6 +75,13 @@ enum virHookLxcOpType {
     VIR_HOOK_LXC_OP_LAST,
 };
 
+enum virHookNetworkOpType {
+    VIR_HOOK_NETWORK_OP_START,          /* network is about to start */
+    VIR_HOOK_NETWORK_OP_STOPPED,        /* network has stopped */
+
+    VIR_HOOK_NETWORK_OP_LAST,
+};
+
 int virHookInitialize(void);
 
 int virHookPresent(int driver);
-- 
1.8.5.2




More information about the libvir-list mailing list