[libvirt] Why does libvirt not unlink qemu-ga or any other socket in function qemuProcessStop()
by Wangyufei (A)
Hello,
I have defined a vm with two UNIX domain sockets. One is for qemu-ga and the other is for my service. These two devices will act as UNIX domain socket server. They are automatically generated by qemu. But when the vm was dead, these two sockets were not deleted. I find that libvirt will unlink vm's monitor socket(/var/lib/libvirt/qemu) in function qemuProcessStop(). Why does libvirt not unlink qemu-ga or any other socket in function qemuProcessStop()?
xml file is given below.
----------------------------------------------------------------------------
<domain type='kvm' >
<name>kvm-1</name>
<memory>4194304</memory>
<currentMemory>4194304</currentMemory>
<vcpu>4</vcpu>
<cpu>
<topology sockets='1' cores='4' threads='1'/>
</cpu>
<os>
<type arch='x86_64'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='raw' cache='none' io='native'/>
<source file='/home/linux.img'/>
<target dev='sda' bus='virtio'/>
</disk>
<channel type='unix'>
<source mode='bind' path='/var/run/libvirt/qemu/kvm-1'/>
<target type='virtio' name='org.qemu.guest_agent.1'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<channel type='unix'>
<source mode='bind' path='/var/run/libvirt/qemu/kvm-1.agent'/>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='2'/>
</channel>
<interface type='bridge'>
<source bridge='br0'/>
<mac address='00:22:3e:56:55:a7'/>
<model type='virtio'/>
</interface>
<input type='tablet' bus='usb'/>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' autoport='yes' listen='0.0.0.0'>
<listen type='address' address='0.0.0.0'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
<memballon model='none'/>
</devices>
</domain>
------------------------------------------------------------------------
Thank you!
11 years, 4 months
[libvirt] [PATCH] cgroup: Free line even if no characters were read
by Ján Tomko
Even if getline doesn't read any characters it allocates a buffer.
==404== 120 bytes in 1 blocks are definitely lost in loss record 1,344 of 1,671
==404== at 0x4C2C71B: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==404== by 0x906F862: getdelim (iogetdelim.c:68)
==404== by 0x52A48FB: virCgroupPartitionNeedsEscaping (vircgroup.c:1136)
==404== by 0x52A0FB4: virCgroupPartitionEscape (vircgroup.c:1171)
==404== by 0x52A0EA4: virCgroupNewDomainPartition (vircgroup.c:1450)
Introduced by f366273.
---
Can STRPREFIX(path, line) be possibly true if tmp is NULL?
path[NULL - line] would be accessed in that case.
src/util/vircgroup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5a98393..2419d80 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1136,38 +1136,38 @@ static int virCgroupPartitionNeedsEscaping(const char *path)
while (getline(&line, &len, fp) > 0) {
if (STRPREFIX(line, "#subsys_name")) {
VIR_FREE(line);
continue;
}
char *tmp = strchr(line, ' ');
if (tmp)
*tmp = '\0';
len = tmp - line;
if (STRPREFIX(path, line) &&
path[len] == '.') {
ret = 1;
- VIR_FREE(line);
goto cleanup;
}
VIR_FREE(line);
}
if (ferror(fp)) {
ret = -EIO;
goto cleanup;
}
cleanup:
+ VIR_FREE(line);
VIR_FORCE_FCLOSE(fp);
return ret;
}
static int virCgroupPartitionEscape(char **path)
{
size_t len = strlen(*path) + 1;
int rc;
char escape = '_';
if ((rc = virCgroupPartitionNeedsEscaping(*path)) <= 0)
return rc;
--
1.8.1.5
11 years, 4 months
[libvirt] [PATCH] qemuDomainGetSchedulerType: Prefer qemuDomObjFromDomain
by Michal Privoznik
In all qemu APIs we tend to prefer qemuDomObjFromDomain over
virDomainObjListFindByUUID. But somehow the
qemuDomainGetSchedulerType left unattended.
---
src/qemu/qemu_driver.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4c90794..e2a94bc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7436,18 +7436,14 @@ cleanup:
static char *qemuDomainGetSchedulerType(virDomainPtr dom,
int *nparams)
{
- virQEMUDriverPtr driver = dom->conn->privateData;
char *ret = NULL;
int rc;
virDomainObjPtr vm = NULL;
qemuDomainObjPrivatePtr priv;
- vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
- if (vm == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("No such domain %s"), dom->uuid);
+ if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
- }
+
priv = vm->privateData;
if (virDomainGetSchedulerTypeEnsureACL(dom->conn, vm->def) < 0)
--
1.8.1.5
11 years, 4 months
[libvirt] [PATCH] add console support in libxl
by Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest. and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.
Signed-off-by: Bamvor Jian Zhang <bjzhang(a)suse.com>
---
src/libxl/libxl_conf.c | 97 ++++++++++++++++++++++++++++++++++++++
src/libxl/libxl_conf.h | 3 ++
src/libxl/libxl_driver.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 219 insertions(+)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index e170357..08095bc 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -332,6 +332,99 @@ error:
}
static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+ const char *type = virDomainChrTypeToString(def->source.type);
+ int ret;
+
+ if (!type) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("unexpected chr device type"));
+ return -1;
+ }
+
+ switch (def->source.type) {
+ case VIR_DOMAIN_CHR_TYPE_NULL:
+ case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_VC:
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ if (virAsprintf(buf, "%s", type) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if (virAsprintf(buf, "%s:%s", type,
+ def->source.data.file.path) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ if (virAsprintf(buf, "%s", def->source.data.file.path) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ break;
+ case VIR_DOMAIN_CHR_TYPE_UDP: {
+ const char *connectHost = def->source.data.udp.connectHost;
+ const char *bindHost = def->source.data.udp.bindHost;
+ const char *bindService = def->source.data.udp.bindService;
+
+ if (connectHost == NULL)
+ connectHost = "";
+ if (bindHost == NULL)
+ bindHost = "";
+ if (bindService == NULL)
+ bindService = "0";
+
+ ret = virAsprintf(buf, "udp:%s:%s@%s:%s",
+ connectHost,
+ def->source.data.udp.connectService,
+ bindHost,
+ bindService);
+ if ( ret < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ break;
+ }
+ case VIR_DOMAIN_CHR_TYPE_TCP:
+ if (def->source.data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) {
+ ret = virAsprintf(buf, "telnet:%s:%s%s",
+ def->source.data.tcp.host,
+ def->source.data.tcp.service,
+ def->source.data.tcp.listen ? ",server,nowait" : "");
+ } else {
+ ret = virAsprintf(buf, "tcp:%s:%s%s",
+ def->source.data.tcp.host,
+ def->source.data.tcp.service,
+ def->source.data.tcp.listen ? ",server,nowait" : "");
+ }
+ if ( ret < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ ret = virAsprintf(buf, "unix:%s%s",
+ def->source.data.nix.path,
+ def->source.data.nix.listen ? ",server,nowait" : "");
+ if ( ret < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int
libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
{
libxl_domain_build_info *b_info = &d_config->b_info;
@@ -404,6 +497,10 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
if (VIR_STRDUP(b_info->u.hvm.boot, bootorder) < 0)
goto error;
+ if (def->nserials &&
+ (libxlMakeChrdevStr(def->serials[0], &b_info->u.hvm.serial) < 0))
+ goto error;
+
/*
* The following comment and calculation were taken directly from
* libxenlight's internal function libxl_get_required_shadow_memory():
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 2b4a281..861d689 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -34,6 +34,7 @@
# include "configmake.h"
# include "virportallocator.h"
# include "virobject.h"
+# include "virchrdev.h"
# define LIBXL_VNC_PORT_MIN 5900
@@ -94,6 +95,8 @@ struct _libxlDomainObjPrivate {
/* per domain libxl ctx */
libxl_ctx *ctx;
+ /* console */
+ virChrdevsPtr devs;
libxl_evgen_domain_death *deathW;
/* list of libxl timeout registrations */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 1bae3d6..b8c6832 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -420,6 +420,9 @@ libxlDomainObjPrivateAlloc(void)
libxl_osevent_register_hooks(priv->ctx, &libxl_event_callbacks, priv);
+ if (!(priv->devs = virChrdevAlloc()))
+ return NULL;
+
return priv;
}
@@ -432,6 +435,7 @@ libxlDomainObjPrivateDispose(void *obj)
libxl_evdisable_domain_death(priv->ctx, priv->deathW);
libxl_ctx_free(priv->ctx);
+ virChrdevFree(priv->devs);
}
static void
@@ -4518,6 +4522,120 @@ libxlDomainSetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr params,
return libxlDomainSetSchedulerParametersFlags(dom, params, nparams, 0);
}
+
+static int
+libxlDomainOpenConsole(virDomainPtr dom,
+ const char *dev_name,
+ virStreamPtr st,
+ unsigned int flags)
+{
+ libxlDriverPrivatePtr driver = dom->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ int i;
+ virDomainChrDefPtr chr = NULL;
+ libxlDomainObjPrivatePtr priv;
+ char *console = NULL;
+ int num = 0;
+ libxl_console_type type;
+
+ virCheckFlags(VIR_DOMAIN_CONSOLE_SAFE |
+ VIR_DOMAIN_CONSOLE_FORCE, -1);
+
+ libxlDriverLock(driver);
+ vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
+ libxlDriverUnlock(driver);
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (!virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ if (dev_name) {
+ for (i = 0 ; !chr && i < vm->def->nconsoles ; i++) {
+ if (vm->def->consoles[i]->info.alias &&
+ STREQ(dev_name, vm->def->consoles[i]->info.alias)) {
+ chr = vm->def->consoles[i];
+ num = i;
+ }
+ }
+ for (i = 0 ; !chr && i < vm->def->nserials ; i++) {
+ if (STREQ(dev_name, vm->def->serials[i]->info.alias)) {
+ chr = vm->def->serials[i];
+ num = i;
+ }
+ }
+ for (i = 0 ; !chr && i < vm->def->nparallels ; i++) {
+ if (STREQ(dev_name, vm->def->parallels[i]->info.alias)) {
+ chr = vm->def->parallels[i];
+ num = i;
+ }
+ }
+ } else {
+ if (vm->def->nconsoles)
+ chr = vm->def->consoles[0];
+ else if (vm->def->nserials)
+ chr = vm->def->serials[0];
+ }
+
+ if (!chr) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot find character device %s"),
+ NULLSTR(dev_name));
+ goto cleanup;
+ }
+
+ if (chr->source.type != VIR_DOMAIN_CHR_TYPE_PTY) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("character device %s is not using a PTY"),
+ NULLSTR(dev_name));
+ goto cleanup;
+ }
+
+ if (dev_name) {
+ if (STREQ(vm->def->os.type, "hvm"))
+ type = LIBXL_CONSOLE_TYPE_SERIAL;
+ else
+ type = LIBXL_CONSOLE_TYPE_PV;
+ ret = libxl_console_get_tty(priv->ctx, vm->def->id, num, type, &console);
+ } else {
+ ret = libxl_primary_console_get_tty(priv->ctx, vm->def->id, &console);
+ }
+ if ( ret )
+ goto cleanup;
+
+ if (VIR_STRDUP(chr->source.data.file.path, console) < 0)
+ goto cleanup;
+
+ /* handle mutually exclusive access to console devices */
+ ret = virChrdevOpen(priv->devs,
+ &chr->source,
+ st,
+ (flags & VIR_DOMAIN_CONSOLE_FORCE) != 0);
+
+ if (ret == 1) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("Active console session exists for this domain"));
+ ret = -1;
+ }
+
+cleanup:
+ VIR_FREE(console);
+ if (vm)
+ virObjectUnlock(vm);
+ return ret;
+}
+
static int
libxlDomainIsActive(virDomainPtr dom)
{
@@ -4739,6 +4857,7 @@ static virDriver libxlDriver = {
.domainManagedSave = libxlDomainManagedSave, /* 0.9.2 */
.domainHasManagedSaveImage = libxlDomainHasManagedSaveImage, /* 0.9.2 */
.domainManagedSaveRemove = libxlDomainManagedSaveRemove, /* 0.9.2 */
+ .domainOpenConsole = libxlDomainOpenConsole, /* 1.0.8 */
.domainIsActive = libxlDomainIsActive, /* 0.9.0 */
.domainIsPersistent = libxlDomainIsPersistent, /* 0.9.0 */
.domainIsUpdated = libxlDomainIsUpdated, /* 0.9.0 */
--
1.8.1.4
11 years, 4 months
[libvirt] [test-API][PATCH] Modify repos/network/network_list.py and add network_list case to conf
by hongming zhang
Modify the old network_list.py. The new network_list.py covers all
flags of listAllNetworks and the following api. and add network_list to
basic_network.conf.
virNetwork:
name()
bridgeName()
isActive()
isPersistent()
virConnect:
listAllNetworks()
---
cases/basic_network.conf | 37 +++++-
repos/network/network_list.py | 279 ++++++++++++++++++-----------------------
2 files changed, 151 insertions(+), 165 deletions(-)
diff --git a/cases/basic_network.conf b/cases/basic_network.conf
index 991ad99..805cfd0 100644
--- a/cases/basic_network.conf
+++ b/cases/basic_network.conf
@@ -14,6 +14,16 @@ network:define
netmode
nat
+#VIR_CONNECT_LIST_NETWORKS_INACTIVE = 1
+#VIR_CONNECT_LIST_NETWORKS_ACTIVE = 2
+#VIR_CONNECT_LIST_NETWORKS_PERSISTENT = 4
+#VIR_CONNECT_LIST_NETWORKS_TRANSIENT = 8
+#VIR_CONNECT_LIST_NETWORKS_AUTOSTART = 16
+#VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART = 32
+network:network_list
+ flags
+ 1
+
network:start
networkname
$defaultnetname
@@ -24,10 +34,18 @@ network:autostart
autostart
enable
+network:network_list
+ flags
+ 3
+
network:destroy
networkname
$defaultnetname
+network:network_list
+ flags
+ 4
+
network:undefine
networkname
$defaultnetname
@@ -48,6 +66,10 @@ network:create
netmode
nat
+network:network_list
+ flags
+ 8
+
network:destroy
networkname
$defaultnetname
@@ -78,6 +100,10 @@ network:autostart
autostart
enable
+network:network_list
+ flags
+ 16
+
network:destroy
networkname
$defaultnetname
@@ -102,11 +128,14 @@ network:create
netmode
route
+network:network_list
+ flags
+ 32
+
network:destroy
networkname
$defaultnetname
-
network:define
networkname
$defaultnetname
@@ -141,7 +170,6 @@ network:undefine
networkname
$defaultnetname
-
network:create
networkname
$defaultnetname
@@ -162,8 +190,3 @@ network:destroy
networkname
$defaultnetname
-
-
-
-
-
diff --git a/repos/network/network_list.py b/repos/network/network_list.py
index 7c34f69..647da82 100644
--- a/repos/network/network_list.py
+++ b/repos/network/network_list.py
@@ -1,184 +1,147 @@
#!/usr/bin/env python
# To test "virsh net-list" command
-import os
-import sys
-import re
-import commands
-
import libvirt
from libvirt import libvirtError
from src import sharedmod
from utils import utils
-required_params = ('netlistopt',)
+required_params = ('flags',)
optional_params = {}
-VIRSH_QUIET_NETLIST = "virsh --quiet net-list %s|awk '{print $1}'"
-VIRSH_NETLIST = "virsh net-list %s"
-GET_BRIDGE_IP = "/sbin/ifconfig %s | grep 'inet addr:' | cut -d: -f2 | awk '{print $1}'"
-CONFIG_DIR = "/etc/libvirt/qemu/networks/"
-
-def get_option_list(params):
- """return options we need to test
- """
- logger = params['logger']
- option_list=[]
-
- value = params['netlistopt']
-
- if value == 'all':
- option_list = [' ', '--all', '--inactive']
- elif value == '--all' or value == '--inactive':
- option_list.append(value)
+VIRSH_NETWORK_LIST = "virsh net-list %s|sed -n '3,$'p|awk '{print $1}'"
+GET_BRIDGE_IP = "/sbin/ifconfig %s | grep 'inet addr:' | cut -d: -f2 | awk \
+ '{print $1}'"
+FLAGDICT = {1:" --inactive", 2:"", 4:" --persistent",\
+ 8:" --transient", 16:" --autostart", 32:" --no-autostart" }
+CONFIG_DIR = "ls /etc/libvirt/qemu/networks/"
+
+def check_bridge_ip(bridgename):
+ """ Check if the bridge has ip """
+
+ (status, output) = utils.exec_cmd(GET_BRIDGE_IP % bridgename,\
+ shell=True)
+ if not status and utils.do_ping(output[0], 50):
+ logger.info("Bridge %s is active" % bridgename)
+ logger.info("%s has ip: %s" % (bridgename, output[0]))
+ return True
else:
- logger.error("value %s is not supported" % value)
- return 1, option_list
-
- return 0, option_list
-
-def get_output(logger, command, flag):
- """execute shell command
- """
- status, ret = commands.getstatusoutput(command)
- if not flag and status:
- logger.error("executing "+ "\"" + command + "\"" + " failed")
- logger.error(ret)
- return status, ret
-
-def check_all_option(conn, logger):
- """check the output of virsh net-list with --all option
- """
- all_network = []
- entries = os.listdir(CONFIG_DIR)
- logger.debug("%s in %s" % (entries, CONFIG_DIR))
- status, network_names = get_output(logger, VIRSH_QUIET_NETLIST % '--all', 0)
- if not status:
- all_network = network_names.split('\n')
- logger.info("all network is %s" % all_network)
+ logger.error("Bridge %s has no ip or fails to ping" % bridgename)
+ return False
+
+def check_persistent_netxml(networkname):
+ """ Check if the network is persistent via checking network xml dir """
+
+ (status, output) = utils.exec_cmd(CONFIG_DIR, shell=True)
+ network_list_dir = []
+ if status:
+ logger.error("Executing " + CONFIG_DIR + " failed")
+ logger.error(output)
+ return False
else:
- return 1
-
- if all_network == ['']:
- return 0
-
- for entry in entries:
- if not entry.endswith('.xml'):
- continue
+ for i in range(len(output)):
+ network_list_dir.append(output[i][:-4])
+ del network_list_dir[0]
+ logger.info("Get persistent network name list under dir: %s" \
+ % network_list_dir)
+ if networkname in network_list_dir:
+ return True
else:
- network = entry[:-4]
- if network not in all_network:
- logger.error("network %s not in the output of virsh net-list" % network)
- return 1
- return 0
-
-def check_inactive_option(conn, logger):
- """check the output of virsh net-list with --inactive option
- """
- inactive_network = []
- status, network_names = get_output(logger, VIRSH_QUIET_NETLIST % '--inactive', 0)
- if not status:
- inactive_network = network_names.split('\n')
- logger.info("inactive network: %s" % inactive_network)
- else:
+ logger.error("Failed to get the persistent %s" % networkname)
+ return False
+
+def get_network_list_virsh(flaglist):
+ """ Get the network name list through virsh command """
+
+ flagstr = ""
+ # Convert the flags that be passed to API to VIRSH flags
+ for flag_key in flaglist:
+ if FLAGDICT.has_key(int(flag_key)):
+ flagstr += FLAGDICT.get(int(flag_key))
+ logger.info("Execute virsh net-list" + flagstr)
+
+ network_list_virsh = []
+ (status, output) = utils.exec_cmd(VIRSH_NETWORK_LIST % flagstr,\
+ shell=True)
+ if status:
+ logger.error("Executing " + VIRSH_NETWORK_LIST + " failed")
return 1
-
- if inactive_network == ['']:
- return 0
-
- for network in inactive_network:
- try:
- netobj = conn.networkLookupByName(network)
- bridgename = netobj.bridgeName()
- status, ip = get_output(logger, GET_BRIDGE_IP % bridgename, 1)
-
- if not status:
- logger.info("network %s is inactive as we expected" % network)
- else:
- logger.error("network %s is not inactive, wrong" % network)
- return 1
- except libvirtError, e:
- logger.error("API error message: %s, error code is %s" \
- % (e.message, e.get_error_code()))
- return 1
-
- return 0
-
-def check_default_option(conn, logger):
- """check the output of virsh net-list
- """
- active_network = []
- status, network_names = get_output(logger, VIRSH_QUIET_NETLIST % '', 0)
- if not status:
- active_network = network_names.split('\n')
- logger.info("running network: %s" % active_network)
else:
- return 1
-
- if active_network == ['']:
- return 0
-
- for network in active_network:
- try:
- netobj = conn.networkLookupByName(network)
- bridgename = netobj.bridgeName()
- status, ip = get_output(logger, GET_BRIDGE_IP % bridgename, 0)
- if not status and utils.do_ping(ip, 0):
- logger.info("network %s is active as we expected" % network)
- logger.debug("%s has ip: %s" % (bridgename, ip))
- else:
- logger.error("network %s has no ip or fails to ping" % network)
- return 1
- except libvirtError, e:
- logger.error("API error message: %s, error code is %s" \
- % (e.message, e.get_error_code()))
- return 1
+ network_list_virsh = output[:-1]
+ logger.info("Get network name list via VIRSH: %s" \
+ % network_list_virsh)
+
+def convert_flags(flags):
+ """ Bitwise-OR of flags in conf and convert them to the readable flags """
+
+ flaglist = []
+ flagstr = ""
+ logger.info("The given flags are %s " % flags)
+ if not '|' in flags:
+ flagn = int(flags)
+ flaglist.append(flagn)
+ else:
+ # bitwise-OR of flags of net-list
+ flaglist = flags.split('|')
+ flagn = 0
+ for flag in flaglist:
+ flagn |= int(flag)
- return 0
+ # Convert the flags in conf file to readable flag
+ for flag_key in flaglist:
+ if FLAGDICT.has_key(int(flag_key)):
+ flagstr += FLAGDICT.get(int(flag_key))
+ logger.info("List network with flags:" + flagstr)
-def execute_virsh_netlist(option, logger):
- """execute virsh net-list command with appropriate option given
- """
- status, ret = get_output(logger, VIRSH_NETLIST % option, 0)
- if not status:
- logger.info(ret)
+ return (flaglist, flagn)
def network_list(params):
- """test net-list command to virsh with default, --all, --inactive
- """
- logger = params['logger']
- ret, option_list = get_option_list(params)
-
- if ret:
- return 1
+ """ List network with all filters """
+ global logger
+ logger = params['logger']
conn = sharedmod.libvirtobj['conn']
-
- for option in option_list:
- if option == ' ':
- logger.info("check the output of virsh net-list")
- if not check_default_option(conn, logger):
- logger.info("virsh net-list checking succeeded")
- execute_virsh_netlist(option, logger)
- else:
- logger.error("virsh net-list checking failed")
- return 1
- elif option == '--inactive':
- logger.info("check the output of virsh net-list --inactive")
- if not check_inactive_option(conn, logger):
- logger.info("virsh net-list --inactive checking succeeded")
- execute_virsh_netlist(option, logger)
+ flags = params['flags']
+ (flaglist, flagn) = convert_flags(flags)
+
+ try:
+ logger.info("Flag list %s " % flaglist)
+ logger.info("Bitwise OR value of flags is %s" % flagn)
+
+ network_list_api = conn.listAllNetworks(flagn)
+ network_list_virsh = get_network_list_virsh(flaglist)
+ network_namelist_api = []
+ for network in network_list_api:
+
+ networkname = network.name()
+ network_namelist_api.append(networkname)
+ bridgename = network.bridgeName()
+ logger.info("Network name: %s " % networkname)
+ logger.info("Network %s 's bridge name: %s " % (networkname ,\
+ bridgename))
+ # Check if the network is active
+ if network.isActive() and check_bridge_ip(bridgename):
+ logger.info("The %s network is active" % networkname)
else:
- logger.error("virsh net-list --inactive checking failed")
- return 1
- elif option == '--all':
- logger.info("check the output of virsh net-list --all")
- if not check_all_option(conn, logger):
- logger.info("virsh net-list --all checking succeeded")
- execute_virsh_netlist(option, logger)
+ logger.info("The %s network isn't active" % networkname)
+
+ # Check if the network is persistent
+ if network.isPersistent() and check_persistent_netxml(networkname):
+ logger.info("The %s network is persistent" % networkname)
else:
- logger.error("virsh net-list --all checking failed")
- return 1
+ logger.info("The %s network isn't persistent" % networkname)
+
+ logger.info("Network list through API: %s " % network_namelist_api)
+ if cmp(network_namelist_api,network_list_virsh):
+ logger.info("Successfully get network list through API")
+ else:
+ logger.error("Failed to get network list through API")
+ return 1
+
+ except libvirtError, e:
+ logger.error("API error message: %s" % e.message)
+ return 1
return 0
+
--
1.7.1
11 years, 4 months
Re: [libvirt] Hard link to root-owned file now fails (since Fedora 19)
by Richard W.M. Jones
On Tue, Jul 16, 2013 at 01:37:33PM -0400, Colin Walters wrote:
> But ok, so as you said in the followup, the real root issue here is
> libvirt calling chown [on the kernel and initrd]. It's not clear
> to me why it does so.
It's a good question, and trying to formulate an answer made me
question some fundamental assumptions. I'm CC-ing libvir-list to see
if anyone has some ideas.
----------------------------------------
Some background: We've got three users involved here.
nova libvirtd qemu
-- invokes --> -- invokes -->
some $UID root qemu.qemu
The reason for this dance of three users is security. It provides
extra separation in case a rogue filesystem that we're examining
exploits the guest kernel and qemu (which is reckoned to be rather
easy). We don't want that rogue qemu process to be able to escalate
this to an attack on either the host or the process (nova) running
libguestfs.
SELinux is used too for extra extra security, but you may be amazed
that it's not unknown for people to turn SELinux off.
----------------------------------------
Now does libvirtd need to chown kernel & initrd?
Ideally (and something that's slowly being worked towards) libvirtd
would open all resources on qemu's behalf, and pass opened file
descriptors down to qemu. In the case of kernel and initrd libvirtd
could do this already by passing /dev/fd/<N> paths to qemu. This, I
think, would avoid any need to chown those.
For the appliance disk, /dev/fd/<N> also works, but only because we're
not hot-plugging this disk. (When you have to hot-plug a disk, you
are talking to qemu over the qemu monitor, so the only way to pass
fd's over is to use SCM_RIGHTS).
Could we just rely on Unix permissions? I think the answer is yes for
kernel & initrd (make them world readable), at least in this case. If
kernel & initrd had private data, you wouldn't want to do this. The
appliance disk is a little more tricky.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages. http://libguestfs.org
11 years, 4 months
[libvirt] [PATCH 00/12] Remove devices only after DEVICE_DELETED event
by Jiri Denemark
This series (partially) fixes a longstanding bug in device unplug from a
live domain. We considered the QEMU command used for that to be
synchronous and removed the unplugged device from domain definition
immediately after the command returned success. This is OK for USB
devices but other devices actually need guest cooperation to be
unplugged and thus they are actually unplugged asynchronously and QEMU
tells us about that using DEVICE_DELETED event. This series is not
complete, it does not check if any device finished unplug while libvirtd
was not running. I'm working on that part but I wanted to get some
feedback on this series as soon as possible.
Path 3/12 explains how I decided to deal with backward compatibility of
the virDomainDetachDeviceFlags API. No libvirt client/app should see any
real difference in behavior after this series unless they want to.
Jiri Denemark (12):
Add VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED event
examples: Handle VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED event
Clarify virDomainDetachDeviceFlags documentation
qemu: Add qemuDomainReleaseDeviceAddress to remove any address
qemu: Separate disk device removal into a standalone function
qemu: Separate controller removal into a standalone function
qemu: Separate net device removal into a standalone function
qemu: Separate host device removal into a standalone function
Add virDomainDefFindDevice for looking up a device by its alias
qemu: Add support for DEVICE_DELETED event
qemu: Remove devices only after DEVICE_DELETED event
qemu: Emit VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED events
daemon/remote.c | 32 +
examples/domain-events/events-c/event-test.c | 23 +-
examples/domain-events/events-python/event-test.py | 4 +
include/libvirt/libvirt.h.in | 18 +
python/libvirt-override-virConnect.py | 9 +
python/libvirt-override.c | 52 +-
src/conf/domain_conf.c | 41 ++
src/conf/domain_conf.h | 4 +
src/conf/domain_event.c | 85 ++-
src/conf/domain_event.h | 5 +
src/libvirt.c | 12 +
src/libvirt_private.syms | 3 +
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 35 +-
src/qemu/qemu_command.h | 8 +-
src/qemu/qemu_domain.h | 2 +
src/qemu/qemu_driver.c | 31 +-
src/qemu/qemu_hotplug.c | 660 ++++++++++++---------
src/qemu/qemu_hotplug.h | 7 +-
src/qemu/qemu_monitor.c | 13 +
src/qemu/qemu_monitor.h | 5 +
src/qemu/qemu_monitor_json.c | 15 +
src/qemu/qemu_process.c | 41 ++
src/remote/remote_driver.c | 32 +
src/remote/remote_protocol.x | 13 +-
src/remote_protocol-structs | 5 +
27 files changed, 847 insertions(+), 311 deletions(-)
--
1.8.3.2
11 years, 4 months
[libvirt] [PATCH] Create directory for lease files if it's missing
by Guido Günther
If we don't autostart a network it's not being created.
Debian Bug http://bugs.debian.org/715200
---
src/nwfilter/nwfilter_dhcpsnoop.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c
index 0965f63..3e9f046 100644
--- a/src/nwfilter/nwfilter_dhcpsnoop.c
+++ b/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -74,8 +74,9 @@
#ifdef HAVE_LIBPCAP
-# define LEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.leases"
-# define TMPLEASEFILE LOCALSTATEDIR "/run/libvirt/network/nwfilter.ltmp"
+# define LEASEFILE_DIR LOCALSTATEDIR "/run/libvirt/network/"
+# define LEASEFILE LEASEFILE_DIR "nwfilter.leases"
+# define TMPLEASEFILE LEASEFILE_DIR "nwfilter.ltmp"
struct virNWFilterSnoopState {
/* lease file */
@@ -1881,6 +1882,11 @@ virNWFilterSnoopLeaseFileRefresh(void)
{
int tfd;
+ if (virFileMakePathWithMode(LEASEFILE_DIR, 0700) < 0) {
+ virReportError(errno, _("mkdir(\"%s\")"), LEASEFILE_DIR);
+ return;
+ }
+
if (unlink(TMPLEASEFILE) < 0 && errno != ENOENT)
virReportSystemError(errno, _("unlink(\"%s\")"), TMPLEASEFILE);
--
1.8.3.2
11 years, 4 months
[libvirt] [PATCH] build: avoid compiler warning on shadowed name
by Eric Blake
Introduced in commit 24b08219; compilation on RHEL 6.4 complained:
qemu/qemu_hotplug.c: In function 'qemuDomainAttachChrDevice':
qemu/qemu_hotplug.c:1257: error: declaration of 'remove' shadows a global declaration [-Wshadow]
/usr/include/stdio.h:177: error: shadowed declaration is here [-Wshadow]
* src/qemu/qemu_hotplug.c (qemuDomainAttachChrDevice): Avoid the
name 'remove'.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the build-breaker rule
src/qemu/qemu_hotplug.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index d0198d1..0b7fed6 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1254,7 +1254,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
virDomainDefPtr vmdef = vm->def;
char *devstr = NULL;
char *charAlias = NULL;
- bool remove = false;
+ bool need_remove = false;
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -1275,7 +1275,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
if (qemuDomainChrInsert(vmdef, chr) < 0)
goto cleanup;
- remove = true;
+ need_remove = true;
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0) {
@@ -1293,7 +1293,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
ret = 0;
cleanup:
- if (ret < 0 && remove)
+ if (ret < 0 && need_remove)
qemuDomainChrRemove(vmdef, chr);
VIR_FREE(charAlias);
VIR_FREE(devstr);
--
1.8.3.1
11 years, 4 months
[libvirt] [PATCH RESEND 0/7] LXC: enhance user namespace support for adding the disk and host devices for libvirt lxc
by Gao feng
Libvirt lxc has supported user namespace since commit
c34107dfd3a25232255e6d6f559b1306ef99bb3b,but for the
disk devices and hostdevs, libvirt lxc still creates
these device nodes in container. this will fail when
container enables user namespace, since user namespace
is disallowed to create device node.
In order to reslove this problem, we should create device
nodes on host side for container,and change the owner of
these nodes to the root user of container.
Gao feng (7):
LXC: Setup disks for container on host side
LXC: controller: change the owner of disk to the root of container
LXC: Move virLXCControllerChown to lxc_container.c
LXC: Change the owner of live attached disk device
LXC: Create host devices for container on host side
LXC: Change the owner of host devices to the root of container
LXC: Change the owner of live attached host devices
src/lxc/lxc_container.c | 382 +++-------------------------------------
src/lxc/lxc_container.h | 2 +
src/lxc/lxc_controller.c | 450 ++++++++++++++++++++++++++++++++++++++++++++---
src/lxc/lxc_driver.c | 13 ++
4 files changed, 460 insertions(+), 387 deletions(-)
--
1.8.3.1
11 years, 4 months