mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-30 04:21:17 +00:00
network: Introduce network hooks
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@redhat.com>
This commit is contained in:
parent
e0a31274ec
commit
f1ab06e43d
@ -13,9 +13,15 @@
|
|||||||
actions occur:</p>
|
actions occur:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>The libvirt daemon starts, stops, or reloads its
|
<li>The libvirt daemon starts, stops, or reloads its
|
||||||
configuration<br/><br/></li>
|
configuration
|
||||||
<li>A QEMU guest is started or stopped<br/><br/></li>
|
(<span class="since">since 0.8.0</span>)<br/><br/></li>
|
||||||
<li>An LXC guest is started or stopped<br/><br/></li>
|
<li>A QEMU guest is started or stopped
|
||||||
|
(<span class="since">since 0.8.0</span>)<br/><br/></li>
|
||||||
|
<li>An LXC guest is started or stopped
|
||||||
|
(<span class="since">since 0.8.0</span>)<br/><br/></li>
|
||||||
|
<li>A network is started or stopped or an interface is
|
||||||
|
plugged/unplugged to/from the network
|
||||||
|
(<span class="since">since 1.2.2</span>)<br/><br/></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2><a name="location">Script location</a></h2>
|
<h2><a name="location">Script location</a></h2>
|
||||||
@ -44,6 +50,9 @@
|
|||||||
Executed when a QEMU guest is started, stopped, or migrated<br/><br/></li>
|
Executed when a QEMU guest is started, stopped, or migrated<br/><br/></li>
|
||||||
<li><code>/etc/libvirt/hooks/lxc</code><br /><br/>
|
<li><code>/etc/libvirt/hooks/lxc</code><br /><br/>
|
||||||
Executed when an LXC guest is started or stopped</li>
|
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 or an
|
||||||
|
interface is plugged/unplugged to/from the network</li>
|
||||||
</ul>
|
</ul>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@ -66,6 +75,39 @@
|
|||||||
XML description for the domain on their stdin. This includes items
|
XML description for the domain on their stdin. This includes items
|
||||||
such the UUID of the domain and its storage information, and is
|
such the UUID of the domain and its storage information, and is
|
||||||
intended to provide all the libvirt information the script needs.</p>
|
intended to provide all the libvirt information the script needs.</p>
|
||||||
|
<p>For all cases, stdin of the network hook script is provided with the
|
||||||
|
full XML description of the network status in the following form:</p>
|
||||||
|
|
||||||
|
<pre><hookData>
|
||||||
|
<network>
|
||||||
|
<name>$network_name</name>
|
||||||
|
<uuid>afca425a-2c3a-420c-b2fb-dd7b4950d722</uuid>
|
||||||
|
...
|
||||||
|
</network>
|
||||||
|
</hookData></pre>
|
||||||
|
|
||||||
|
<p>In the case of an interface
|
||||||
|
being plugged/unplugged to/from the network, the network XML will be
|
||||||
|
followed with the full XML description of the domain containing the
|
||||||
|
interface that is being plugged/unplugged:</p>
|
||||||
|
|
||||||
|
<pre><hookData>
|
||||||
|
<network>
|
||||||
|
<name>$network_name</name>
|
||||||
|
<uuid>afca425a-2c3a-420c-b2fb-dd7b4950d722</uuid>
|
||||||
|
...
|
||||||
|
</network>
|
||||||
|
<domain type='$domain_type' id='$domain_id'>
|
||||||
|
<name>$domain_name</name>
|
||||||
|
<uuid>afca425a-2c3a-420c-b2fb-dd7b4950d722</uuid>
|
||||||
|
...
|
||||||
|
</domain>
|
||||||
|
</hookData></pre>
|
||||||
|
|
||||||
|
<p>Please note that this approach is different from other cases such as
|
||||||
|
<code>daemon</code>, <code>qemu</code> or <code>lxc</code> hook scripts,
|
||||||
|
because two XMLs may be passed here, while in the other cases only a single
|
||||||
|
XML is passed.</p>
|
||||||
|
|
||||||
<p>The command line arguments take this approach:</p>
|
<p>The command line arguments take this approach:</p>
|
||||||
<ol>
|
<ol>
|
||||||
@ -181,25 +223,49 @@
|
|||||||
<pre>/etc/libvirt/hooks/lxc guest_name reconnect begin -</pre>
|
<pre>/etc/libvirt/hooks/lxc guest_name reconnect begin -</pre>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h5><a name="network">/etc/libvirt/hooks/network</a></h5>
|
||||||
|
<ul>
|
||||||
|
<li><span class="since">Since 1.2.2</span>, before a network is started,
|
||||||
|
this script is called as:<br/>
|
||||||
|
<pre>/etc/libvirt/hooks/network network_name start begin -</pre></li>
|
||||||
|
<li>After the network is started, up ∧ running, the script is
|
||||||
|
called as:<br/>
|
||||||
|
<pre>/etc/libvirt/hooks/network network_name started begin -</pre></li>
|
||||||
|
<li>When a network is shut down, this script is called as:<br/>
|
||||||
|
<pre>/etc/libvirt/hooks/network network_name stopped end -</pre></li>
|
||||||
|
<li>Later, when network is started and there's an interface from a
|
||||||
|
domain to be plugged into the network, the hook script is called as:<br/>
|
||||||
|
<pre>/etc/libvirt/hooks/network network_name plugged begin -</pre>
|
||||||
|
Please note, that in this case, the script is passed both network and
|
||||||
|
domain XMLs on its stdin.</li>
|
||||||
|
<li>When the domain from previous case is shutting down, the interface
|
||||||
|
is unplugged. This leads to another script invocation:<br/>
|
||||||
|
<pre>/etc/libvirt/hooks/network network_name unplugged begin -</pre>
|
||||||
|
And again, as in previous case, both network and domain XMLs are passed
|
||||||
|
onto script's stdin.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
<h2><a name="execution">Script execution</a></h2>
|
<h2><a name="execution">Script execution</a></h2>
|
||||||
<ul>
|
<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
|
executes <b>prior</b> to the object (guest or network) being created.
|
||||||
guest start operation to be aborted if the script returns indicating
|
This allows the object start operation to be aborted if the script
|
||||||
failure.<br/><br/></li>
|
returns indicating failure.<br/><br/></li>
|
||||||
<li>The "shutdown" operation for the guest hook scripts, qemu and lxc,
|
<li>The "shutdown" operation for the guest and network hook scripts,
|
||||||
executes <b>after</b> the guest has stopped. If the hook script
|
executes <b>after</b> the object (guest or network) has stopped. If
|
||||||
indicates failure in its return, the shut down of the guest cannot
|
the hook script indicates failure in its return, the shut down of the
|
||||||
be aborted because it has already been performed.<br/><br/></li>
|
object cannot be aborted because it has already been performed.
|
||||||
|
<br/><br/></li>
|
||||||
<li>Hook scripts execute in a synchronous fashion. Libvirt waits
|
<li>Hook scripts execute in a synchronous fashion. Libvirt waits
|
||||||
for them to return before continuing the given operation.<br/><br/>
|
for them to return before continuing the given operation.<br/><br/>
|
||||||
This is most noticeable with the guest start operation, as a lengthy
|
This is most noticeable with the guest or network start operation,
|
||||||
operation in the hook script can mean an extended wait for the guest
|
as a lengthy operation in the hook script can mean an extended wait
|
||||||
to be available to end users.<br/><br/></li>
|
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
|
<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
|
(e.g. chmod o+rx <i>qemu</i>), and must be present when the libvirt
|
||||||
daemon is started.<br/><br/></li>
|
daemon is started.<br/><br/></li>
|
||||||
<li>If a hook script is added to a host after the libvirt daemon is
|
<li>If a hook script is added to a host after the libvirt daemon is
|
||||||
already running, it won't be used until the libvirt daemon
|
already running, it won't be used until the libvirt daemon
|
||||||
|
@ -3937,7 +3937,7 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
|
|||||||
* network's pool of devices, or resolve bridge device name
|
* network's pool of devices, or resolve bridge device name
|
||||||
* to the one defined in the network definition.
|
* to the one defined in the network definition.
|
||||||
*/
|
*/
|
||||||
if (networkAllocateActualDevice(net) < 0)
|
if (networkAllocateActualDevice(vm->def, net) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
actualType = virDomainNetGetActualType(net);
|
actualType = virDomainNetGetActualType(net);
|
||||||
@ -4485,7 +4485,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
networkReleaseActualDevice(detach);
|
networkReleaseActualDevice(vm->def, detach);
|
||||||
virDomainNetRemove(vm->def, detachidx);
|
virDomainNetRemove(vm->def, detachidx);
|
||||||
virDomainNetDefFree(detach);
|
virDomainNetDefFree(detach);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
|
|||||||
iface->ifname));
|
iface->ifname));
|
||||||
ignore_value(virNetDevVethDelete(iface->ifname));
|
ignore_value(virNetDevVethDelete(iface->ifname));
|
||||||
}
|
}
|
||||||
networkReleaseActualDevice(iface);
|
networkReleaseActualDevice(vm->def, iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
virDomainConfVMNWFilterTeardown(vm);
|
virDomainConfVMNWFilterTeardown(vm);
|
||||||
@ -374,7 +374,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
|
|||||||
* network's pool of devices, or resolve bridge device name
|
* network's pool of devices, or resolve bridge device name
|
||||||
* to the one defined in the network definition.
|
* to the one defined in the network definition.
|
||||||
*/
|
*/
|
||||||
if (networkAllocateActualDevice(def->nets[i]) < 0)
|
if (networkAllocateActualDevice(def, def->nets[i]) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (VIR_EXPAND_N(*veths, *nveths, 1) < 0)
|
if (VIR_EXPAND_N(*veths, *nveths, 1) < 0)
|
||||||
@ -476,7 +476,7 @@ cleanup:
|
|||||||
ignore_value(virNetDevOpenvswitchRemovePort(
|
ignore_value(virNetDevOpenvswitchRemovePort(
|
||||||
virDomainNetGetActualBridgeName(iface),
|
virDomainNetGetActualBridgeName(iface),
|
||||||
iface->ifname));
|
iface->ifname));
|
||||||
networkReleaseActualDevice(iface);
|
networkReleaseActualDevice(def, iface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "viraccessapicheck.h"
|
#include "viraccessapicheck.h"
|
||||||
#include "network_event.h"
|
#include "network_event.h"
|
||||||
|
#include "virhook.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
||||||
|
|
||||||
@ -134,6 +135,51 @@ networkObjFromNetwork(virNetworkPtr net)
|
|||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
networkRunHook(virNetworkObjPtr network,
|
||||||
|
virDomainDefPtr dom,
|
||||||
|
int op,
|
||||||
|
int sub_op)
|
||||||
|
{
|
||||||
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
|
char *xml = NULL, *net_xml = NULL, *dom_xml = NULL;
|
||||||
|
int hookret;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (virHookPresent(VIR_HOOK_DRIVER_NETWORK)) {
|
||||||
|
virBufferAddLit(&buf, "<hookData>\n");
|
||||||
|
virBufferAdjustIndent(&buf, 2);
|
||||||
|
if (virNetworkDefFormatBuf(&buf, network->def, 0) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (dom && virDomainDefFormatInternal(dom, 0, &buf) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
virBufferAdjustIndent(&buf, -2);
|
||||||
|
virBufferAddLit(&buf, "</hookData>");
|
||||||
|
|
||||||
|
if (virBufferError(&buf) ||
|
||||||
|
!(xml = virBufferContentAndReset(&buf)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
hookret = virHookCall(VIR_HOOK_DRIVER_NETWORK, network->def->name,
|
||||||
|
op, sub_op, NULL, xml, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the script raised an error, pass it to the callee.
|
||||||
|
*/
|
||||||
|
if (hookret < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virBufferFreeAndReset(&buf);
|
||||||
|
VIR_FREE(xml);
|
||||||
|
VIR_FREE(net_xml);
|
||||||
|
VIR_FREE(dom_xml);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
networkDnsmasqLeaseFileNameDefault(const char *netname)
|
networkDnsmasqLeaseFileNameDefault(const char *netname)
|
||||||
{
|
{
|
||||||
@ -2008,6 +2054,13 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
|
|||||||
if (virNetworkObjSetDefTransient(network, true) < 0)
|
if (virNetworkObjSetDefTransient(network, true) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Run an early hook to set-up missing devices.
|
||||||
|
* If the script raised an error abort the launch. */
|
||||||
|
if (networkRunHook(network, NULL,
|
||||||
|
VIR_HOOK_NETWORK_OP_START,
|
||||||
|
VIR_HOOK_SUBOP_BEGIN) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
switch (network->def->forward.type) {
|
switch (network->def->forward.type) {
|
||||||
|
|
||||||
case VIR_NETWORK_FORWARD_NONE:
|
case VIR_NETWORK_FORWARD_NONE:
|
||||||
@ -2027,6 +2080,12 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* finally we can call the 'started' hook script if any */
|
||||||
|
if (networkRunHook(network, NULL,
|
||||||
|
VIR_HOOK_NETWORK_OP_STARTED,
|
||||||
|
VIR_HOOK_SUBOP_BEGIN) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
/* Persist the live configuration now that anything autogenerated
|
/* Persist the live configuration now that anything autogenerated
|
||||||
* is setup.
|
* is setup.
|
||||||
*/
|
*/
|
||||||
@ -2087,6 +2146,10 @@ static int networkShutdownNetwork(virNetworkDriverStatePtr driver,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now that we know it's stopped call the hook if present */
|
||||||
|
networkRunHook(network, NULL, VIR_HOOK_NETWORK_OP_STOPPED,
|
||||||
|
VIR_HOOK_SUBOP_END);
|
||||||
|
|
||||||
network->active = 0;
|
network->active = 0;
|
||||||
virNetworkObjUnsetDefTransient(network);
|
virNetworkObjUnsetDefTransient(network);
|
||||||
return ret;
|
return ret;
|
||||||
@ -3239,6 +3302,7 @@ finish:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* networkAllocateActualDevice:
|
/* networkAllocateActualDevice:
|
||||||
|
* @dom: domain definition that @iface belongs to
|
||||||
* @iface: the original NetDef from the domain
|
* @iface: the original NetDef from the domain
|
||||||
*
|
*
|
||||||
* Looks up the network reference by iface, allocates a physical
|
* Looks up the network reference by iface, allocates a physical
|
||||||
@ -3250,7 +3314,8 @@ finish:
|
|||||||
* Returns 0 on success, -1 on failure.
|
* Returns 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
networkAllocateActualDevice(virDomainNetDefPtr iface)
|
networkAllocateActualDevice(virDomainDefPtr dom,
|
||||||
|
virDomainNetDefPtr iface)
|
||||||
{
|
{
|
||||||
virNetworkDriverStatePtr driver = driverState;
|
virNetworkDriverStatePtr driver = driverState;
|
||||||
enum virDomainNetType actualType = iface->type;
|
enum virDomainNetType actualType = iface->type;
|
||||||
@ -3583,6 +3648,12 @@ validate:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* finally we can call the 'plugged' hook script if any */
|
||||||
|
if (networkRunHook(network, dom,
|
||||||
|
VIR_HOOK_NETWORK_OP_IFACE_PLUGGED,
|
||||||
|
VIR_HOOK_SUBOP_BEGIN) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (dev) {
|
if (dev) {
|
||||||
/* we are now assured of success, so mark the allocation */
|
/* we are now assured of success, so mark the allocation */
|
||||||
dev->connections++;
|
dev->connections++;
|
||||||
@ -3618,6 +3689,7 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* networkNotifyActualDevice:
|
/* networkNotifyActualDevice:
|
||||||
|
* @dom: domain definition that @iface belongs to
|
||||||
* @iface: the domain's NetDef with an "actual" device already filled in.
|
* @iface: the domain's NetDef with an "actual" device already filled in.
|
||||||
*
|
*
|
||||||
* Called to notify the network driver when libvirtd is restarted and
|
* Called to notify the network driver when libvirtd is restarted and
|
||||||
@ -3628,7 +3700,8 @@ error:
|
|||||||
* Returns 0 on success, -1 on failure.
|
* Returns 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
networkNotifyActualDevice(virDomainNetDefPtr iface)
|
networkNotifyActualDevice(virDomainDefPtr dom,
|
||||||
|
virDomainNetDefPtr iface)
|
||||||
{
|
{
|
||||||
virNetworkDriverStatePtr driver = driverState;
|
virNetworkDriverStatePtr driver = driverState;
|
||||||
enum virDomainNetType actualType = virDomainNetGetActualType(iface);
|
enum virDomainNetType actualType = virDomainNetGetActualType(iface);
|
||||||
@ -3781,6 +3854,11 @@ networkNotifyActualDevice(virDomainNetDefPtr iface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
|
/* finally we can call the 'plugged' hook script if any */
|
||||||
|
if (networkRunHook(network, dom, VIR_HOOK_NETWORK_OP_IFACE_PLUGGED,
|
||||||
|
VIR_HOOK_SUBOP_BEGIN) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
netdef->connections++;
|
netdef->connections++;
|
||||||
VIR_DEBUG("Using network %s, %d connections",
|
VIR_DEBUG("Using network %s, %d connections",
|
||||||
netdef->name, netdef->connections);
|
netdef->name, netdef->connections);
|
||||||
@ -3796,6 +3874,7 @@ error:
|
|||||||
|
|
||||||
|
|
||||||
/* networkReleaseActualDevice:
|
/* networkReleaseActualDevice:
|
||||||
|
* @dom: domain definition that @iface belongs to
|
||||||
* @iface: a domain's NetDef (interface definition)
|
* @iface: a domain's NetDef (interface definition)
|
||||||
*
|
*
|
||||||
* Given a domain <interface> element that previously had its <actual>
|
* Given a domain <interface> element that previously had its <actual>
|
||||||
@ -3806,7 +3885,8 @@ error:
|
|||||||
* Returns 0 on success, -1 on failure.
|
* Returns 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
networkReleaseActualDevice(virDomainNetDefPtr iface)
|
networkReleaseActualDevice(virDomainDefPtr dom,
|
||||||
|
virDomainNetDefPtr iface)
|
||||||
{
|
{
|
||||||
virNetworkDriverStatePtr driver = driverState;
|
virNetworkDriverStatePtr driver = driverState;
|
||||||
enum virDomainNetType actualType = virDomainNetGetActualType(iface);
|
enum virDomainNetType actualType = virDomainNetGetActualType(iface);
|
||||||
@ -3925,6 +4005,11 @@ networkReleaseActualDevice(virDomainNetDefPtr iface)
|
|||||||
success:
|
success:
|
||||||
if (iface->data.network.actual)
|
if (iface->data.network.actual)
|
||||||
netdef->connections--;
|
netdef->connections--;
|
||||||
|
|
||||||
|
/* finally we can call the 'unplugged' hook script if any */
|
||||||
|
networkRunHook(network, dom, VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED,
|
||||||
|
VIR_HOOK_SUBOP_BEGIN);
|
||||||
|
|
||||||
VIR_DEBUG("Releasing network %s, %d connections",
|
VIR_DEBUG("Releasing network %s, %d connections",
|
||||||
netdef->name, netdef->connections);
|
netdef->name, netdef->connections);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -34,12 +34,15 @@
|
|||||||
int networkRegister(void);
|
int networkRegister(void);
|
||||||
|
|
||||||
# if WITH_NETWORK
|
# if WITH_NETWORK
|
||||||
int networkAllocateActualDevice(virDomainNetDefPtr iface)
|
int networkAllocateActualDevice(virDomainDefPtr dom,
|
||||||
ATTRIBUTE_NONNULL(1);
|
virDomainNetDefPtr iface)
|
||||||
int networkNotifyActualDevice(virDomainNetDefPtr iface)
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
ATTRIBUTE_NONNULL(1);
|
int networkNotifyActualDevice(virDomainDefPtr dom,
|
||||||
int networkReleaseActualDevice(virDomainNetDefPtr iface)
|
virDomainNetDefPtr iface)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
int networkReleaseActualDevice(virDomainDefPtr dom,
|
||||||
|
virDomainNetDefPtr iface)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
int networkGetNetworkAddress(const char *netname, char **netaddr)
|
int networkGetNetworkAddress(const char *netname, char **netaddr)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
@ -51,9 +54,9 @@ int networkDnsmasqConfContents(virNetworkObjPtr network,
|
|||||||
dnsmasqCapsPtr caps);
|
dnsmasqCapsPtr caps);
|
||||||
# else
|
# else
|
||||||
/* Define no-op replacements that don't drag in any link dependencies. */
|
/* Define no-op replacements that don't drag in any link dependencies. */
|
||||||
# define networkAllocateActualDevice(iface) 0
|
# define networkAllocateActualDevice(dom, iface) 0
|
||||||
# define networkNotifyActualDevice(iface) (iface=iface, 0)
|
# define networkNotifyActualDevice(iface) (iface=iface, 0)
|
||||||
# define networkReleaseActualDevice(iface) (iface=iface, 0)
|
# define networkReleaseActualDevice(dom, iface) (dom=dom, iface=iface, 0)
|
||||||
# define networkGetNetworkAddress(netname, netaddr) (-2)
|
# define networkGetNetworkAddress(netname, netaddr) (-2)
|
||||||
# define networkDnsmasqConfContents(network, pidfile, configstr, \
|
# define networkDnsmasqConfContents(network, pidfile, configstr, \
|
||||||
dctx, caps) 0
|
dctx, caps) 0
|
||||||
|
@ -548,7 +548,7 @@ qemuNetworkPrepareDevices(virDomainDefPtr def)
|
|||||||
* network's pool of devices, or resolve bridge device name
|
* network's pool of devices, or resolve bridge device name
|
||||||
* to the one defined in the network definition.
|
* to the one defined in the network definition.
|
||||||
*/
|
*/
|
||||||
if (networkAllocateActualDevice(net) < 0)
|
if (networkAllocateActualDevice(def, net) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
actualType = virDomainNetGetActualType(net);
|
actualType = virDomainNetGetActualType(net);
|
||||||
|
@ -837,7 +837,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
|
|||||||
* network's pool of devices, or resolve bridge device name
|
* network's pool of devices, or resolve bridge device name
|
||||||
* to the one defined in the network definition.
|
* to the one defined in the network definition.
|
||||||
*/
|
*/
|
||||||
if (networkAllocateActualDevice(net) < 0)
|
if (networkAllocateActualDevice(vm->def, net) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
actualType = virDomainNetGetActualType(net);
|
actualType = virDomainNetGetActualType(net);
|
||||||
@ -1082,7 +1082,7 @@ cleanup:
|
|||||||
|
|
||||||
virDomainNetRemoveHostdev(vm->def, net);
|
virDomainNetRemoveHostdev(vm->def, net);
|
||||||
|
|
||||||
networkReleaseActualDevice(net);
|
networkReleaseActualDevice(vm->def, net);
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(nicstr);
|
VIR_FREE(nicstr);
|
||||||
@ -2017,7 +2017,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
|
|||||||
* free it if we fail for any reason
|
* free it if we fail for any reason
|
||||||
*/
|
*/
|
||||||
if (newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
|
if (newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
|
||||||
networkAllocateActualDevice(newdev) < 0) {
|
networkAllocateActualDevice(vm->def, newdev) < 0) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2204,7 +2204,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
/* this function doesn't work with HOSTDEV networks yet, thus
|
/* this function doesn't work with HOSTDEV networks yet, thus
|
||||||
* no need to change the pointer in the hostdev structure */
|
* no need to change the pointer in the hostdev structure */
|
||||||
networkReleaseActualDevice(olddev);
|
networkReleaseActualDevice(vm->def, olddev);
|
||||||
virDomainNetDefFree(olddev);
|
virDomainNetDefFree(olddev);
|
||||||
/* move newdev into the nets list, and NULL it out from the
|
/* move newdev into the nets list, and NULL it out from the
|
||||||
* virDomainDeviceDef that we were given so that the caller
|
* virDomainDeviceDef that we were given so that the caller
|
||||||
@ -2236,7 +2236,7 @@ cleanup:
|
|||||||
* replace the entire device object.
|
* replace the entire device object.
|
||||||
*/
|
*/
|
||||||
if (newdev)
|
if (newdev)
|
||||||
networkReleaseActualDevice(newdev);
|
networkReleaseActualDevice(vm->def, newdev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2649,7 +2649,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
|
|||||||
virDomainHostdevDefFree(hostdev);
|
virDomainHostdevDefFree(hostdev);
|
||||||
|
|
||||||
if (net) {
|
if (net) {
|
||||||
networkReleaseActualDevice(net);
|
networkReleaseActualDevice(vm->def, net);
|
||||||
virDomainNetDefFree(net);
|
virDomainNetDefFree(net);
|
||||||
}
|
}
|
||||||
virObjectUnref(cfg);
|
virObjectUnref(cfg);
|
||||||
@ -2717,7 +2717,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
|
|||||||
virDomainNetGetActualBridgeName(net),
|
virDomainNetGetActualBridgeName(net),
|
||||||
net->ifname));
|
net->ifname));
|
||||||
|
|
||||||
networkReleaseActualDevice(net);
|
networkReleaseActualDevice(vm->def, net);
|
||||||
virDomainNetDefFree(net);
|
virDomainNetDefFree(net);
|
||||||
virObjectUnref(cfg);
|
virObjectUnref(cfg);
|
||||||
}
|
}
|
||||||
|
@ -2773,7 +2773,7 @@ qemuProcessNotifyNets(virDomainDefPtr def)
|
|||||||
|
|
||||||
for (i = 0; i < def->nnets; i++) {
|
for (i = 0; i < def->nnets; i++) {
|
||||||
virDomainNetDefPtr net = def->nets[i];
|
virDomainNetDefPtr net = def->nets[i];
|
||||||
if (networkNotifyActualDevice(net) < 0)
|
if (networkNotifyActualDevice(def, net) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -4393,7 +4393,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
/* kick the device out of the hostdev list too */
|
/* kick the device out of the hostdev list too */
|
||||||
virDomainNetRemoveHostdev(def, net);
|
virDomainNetRemoveHostdev(def, net);
|
||||||
networkReleaseActualDevice(net);
|
networkReleaseActualDevice(vm->def, net);
|
||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
@ -48,12 +48,14 @@ VIR_ENUM_DECL(virHookDaemonOp)
|
|||||||
VIR_ENUM_DECL(virHookSubop)
|
VIR_ENUM_DECL(virHookSubop)
|
||||||
VIR_ENUM_DECL(virHookQemuOp)
|
VIR_ENUM_DECL(virHookQemuOp)
|
||||||
VIR_ENUM_DECL(virHookLxcOp)
|
VIR_ENUM_DECL(virHookLxcOp)
|
||||||
|
VIR_ENUM_DECL(virHookNetworkOp)
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virHookDriver,
|
VIR_ENUM_IMPL(virHookDriver,
|
||||||
VIR_HOOK_DRIVER_LAST,
|
VIR_HOOK_DRIVER_LAST,
|
||||||
"daemon",
|
"daemon",
|
||||||
"qemu",
|
"qemu",
|
||||||
"lxc")
|
"lxc",
|
||||||
|
"network")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virHookDaemonOp, VIR_HOOK_DAEMON_OP_LAST,
|
VIR_ENUM_IMPL(virHookDaemonOp, VIR_HOOK_DAEMON_OP_LAST,
|
||||||
"start",
|
"start",
|
||||||
@ -83,6 +85,13 @@ VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
|
|||||||
"started",
|
"started",
|
||||||
"reconnect")
|
"reconnect")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virHookNetworkOp, VIR_HOOK_NETWORK_OP_LAST,
|
||||||
|
"start",
|
||||||
|
"started",
|
||||||
|
"stopped",
|
||||||
|
"plugged",
|
||||||
|
"unplugged")
|
||||||
|
|
||||||
static int virHooksFound = -1;
|
static int virHooksFound = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,6 +255,8 @@ virHookCall(int driver,
|
|||||||
case VIR_HOOK_DRIVER_LXC:
|
case VIR_HOOK_DRIVER_LXC:
|
||||||
opstr = virHookLxcOpTypeToString(op);
|
opstr = virHookLxcOpTypeToString(op);
|
||||||
break;
|
break;
|
||||||
|
case VIR_HOOK_DRIVER_NETWORK:
|
||||||
|
opstr = virHookNetworkOpTypeToString(op);
|
||||||
}
|
}
|
||||||
if (opstr == NULL) {
|
if (opstr == NULL) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
@ -30,6 +30,7 @@ enum virHookDriverType {
|
|||||||
VIR_HOOK_DRIVER_DAEMON = 0, /* Daemon related events */
|
VIR_HOOK_DRIVER_DAEMON = 0, /* Daemon related events */
|
||||||
VIR_HOOK_DRIVER_QEMU, /* QEmu domains related events */
|
VIR_HOOK_DRIVER_QEMU, /* QEmu domains related events */
|
||||||
VIR_HOOK_DRIVER_LXC, /* LXC domains related events */
|
VIR_HOOK_DRIVER_LXC, /* LXC domains related events */
|
||||||
|
VIR_HOOK_DRIVER_NETWORK, /* network related events */
|
||||||
|
|
||||||
VIR_HOOK_DRIVER_LAST,
|
VIR_HOOK_DRIVER_LAST,
|
||||||
};
|
};
|
||||||
@ -74,6 +75,16 @@ enum virHookLxcOpType {
|
|||||||
VIR_HOOK_LXC_OP_LAST,
|
VIR_HOOK_LXC_OP_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum virHookNetworkOpType {
|
||||||
|
VIR_HOOK_NETWORK_OP_START, /* network is about to start */
|
||||||
|
VIR_HOOK_NETWORK_OP_STARTED, /* network has start */
|
||||||
|
VIR_HOOK_NETWORK_OP_STOPPED, /* network has stopped */
|
||||||
|
VIR_HOOK_NETWORK_OP_IFACE_PLUGGED, /* an interface has been plugged into the network */
|
||||||
|
VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED, /* an interface was unplugged from the network */
|
||||||
|
|
||||||
|
VIR_HOOK_NETWORK_OP_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
int virHookInitialize(void);
|
int virHookInitialize(void);
|
||||||
|
|
||||||
int virHookPresent(int driver);
|
int virHookPresent(int driver);
|
||||||
|
Loading…
Reference in New Issue
Block a user