[libvirt] [PATCH 0/2] Fix 'make check' on RHEL-5.10
by Michal Privoznik
There are two tests failing for me on RHEL-5.10 and current git HEAD.
Fix them.
Michal Privoznik (2):
tests: Use lv_abs_top_builddir instead of bare abs_top_builddir
vircgroupmock: Mock access() to some more files
tests/Makefile.am | 2 +-
tests/vircgroupmock.c | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
--
1.8.1.5
11 years, 1 month
[libvirt] libvirt VF indexing issue
by Niilona
libvirt points to wrong VF -channel, when trying to change MAC -address.
libvirt v1 1.0.2
linux driver : ixgbe 3.17.3
Symptom description
----------------------------------
1.) How the VF channels are seen in the Host ( correct in increasing
address order )
command : ls -la /sys/bus/pci/devices/0000\:04\:00.0/
..................
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn0 -> ../0000:04:10.0/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn1 -> ../0000:04:10.2/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn10 -> ../0000:04:12.4/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn11 -> ../0000:04:12.6/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn12 -> ../0000:04:13.0/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn13 -> ../0000:04:13.2/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn2 -> ../0000:04:10.4/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn3 -> ../0000:04:10.6/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn4 -> ../0000:04:11.0/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn5 -> ../0000:04:11.2/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn6 -> ../0000:04:11.4/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn7 -> ../0000:04:11.6/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn8 -> ../0000:04:12.0/
lrwxrwxrwx 1 root root 0 Oct 17 12:25 virtfn9 -> ../0000:04:12.2/
-----------------------
2.) How the libvirt sees them
virsh nodedev-dumpxml pci_0000_04_00_0
<device>
<name>pci_0000_04_00_0</name>
<parent>pci_0000_00_03_0</parent>
<driver>
<name>ixgbe</name>
</driver>
<capability type='pci'>
<domain>0</domain>
<bus>4</bus>
<slot>0</slot>
<function>0</function>
<product id='0x10fb'>82599EB 10-Gigabit SFI/SFP+ Network
Connection</product>
<vendor id='0x8086'>Intel Corporation</vendor>
<capability type='virt_functions'>
<address domain='0x0000' bus='0x04' slot='0x12' function='0x4'/>
<address domain='0x0000' bus='0x04' slot='0x12' function='0x6'/>
<address domain='0x0000' bus='0x04' slot='0x13' function='0x0'/>
<address domain='0x0000' bus='0x04' slot='0x13' function='0x2'/>
<address domain='0x0000' bus='0x04' slot='0x10' function='0x0'/>
<address domain='0x0000' bus='0x04' slot='0x10' function='0x2'/>
<address domain='0x0000' bus='0x04' slot='0x10' function='0x4'/>
<address domain='0x0000' bus='0x04' slot='0x10' function='0x6'/>
<address domain='0x0000' bus='0x04' slot='0x11' function='0x0'/>
<address domain='0x0000' bus='0x04' slot='0x11' function='0x2'/>
<address domain='0x0000' bus='0x04' slot='0x11' function='0x4'/>
<address domain='0x0000' bus='0x04' slot='0x11' function='0x6'/>
<address domain='0x0000' bus='0x04' slot='0x12' function='0x0'/>
<address domain='0x0000' bus='0x04' slot='0x12' function='0x2'/>
</capability>
</capability>
</device>
3.) Libvirt sets MAC -address in slot/position 5 instead of 1
ip link show eth10
87: eth10: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 2100 qdisc mq
state UP mode DEFAULT qlen 1000
link/ether 00:1b:21:b9:a5:60 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 92:e2:6b:53:a7:c2, spoof checking off <------ this is the
slot, MAC tried to set
vf 1 MAC 0a:04:38:2c:79:35, spoof checking off
vf 2 MAC b2:46:b6:91:44:2e, spoof checking off
vf 3 MAC de:b6:28:da:20:44, spoof checking off
vf 4 MAC 02:00:00:80:00:01, spoof checking off <--------- MAC sets
in wrong slot
vf 5 MAC 02:00:00:80:00:02, spoof checking off
vf 6 MAC 02:00:00:80:00:20, spoof checking off
vf 7 MAC 02:00:00:80:00:30, spoof checking off
vf 8 MAC 52:54:00:de:f8:08, spoof checking off
vf 9 MAC 5e:b0:d0:34:d6:cc, spoof checking off
vf 10 MAC d2:88:5c:2d:db:b5, spoof checking off
vf 11 MAC 6a:06:8a:9c:31:8b, spoof checking off
vf 12 MAC 4a:38:be:8f:b3:bf, spoof checking off
vf 13 MAC b6:c1:d4:12:d3:3d, spoof checking off
5.) Question : Why this happens in ixgbe -driver and when we try to
use more than 10 VF's/physical port. ?
11 years, 1 month
[libvirt] [PATCH] libvirt_setuid_rpc_client_la: Link APPARMOR libs
by Michal Privoznik
The libvirt_setuid_rpc_client_la depends on vircommand.c, in which we
are conditionally calling aa_change_profile() - an AppArmor helper
function. However, in linking the libvirt-setuid-rpc-client.la we have
forgot to link AppArmor libraries leaving us with following error:
make[3]: Entering directory `/home/zippy/work/libvirt/libvirt.git/tools'
CCLD virsh
CCLD virt-host-validate
CCLD virt-login-shell
../src/.libs/libvirt-setuid-rpc-client.a(libvirt_setuid_rpc_client_la-vircommand.o): In function `virExec':
/home/zippy/work/libvirt/libvirt.git/src/util/vircommand.c:653: undefined reference to `aa_change_profile'
collect2: error: ld returned 1 exit status
make[3]: *** [virt-login-shell] Error 1
make[3]: *** Waiting for unfinished jobs....
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/Makefile.am | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 9dab4df..688c34c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2027,15 +2027,19 @@ libvirt_setuid_rpc_client_la_SOURCES = \
libvirt_setuid_rpc_client_la_LDFLAGS = \
$(AM_LDFLAGS) \
$(LIBXML_LIBS) \
- $(SELINUX_LIBS) \
- $(NULL)
+ $(SELINUX_LIBS)
libvirt_setuid_rpc_client_la_CFLAGS = \
-DLIBVIRT_SETUID_RPC_CLIENT \
-I$(top_srcdir)/src/conf \
-I$(top_srcdir)/src/rpc \
$(AM_CFLAGS) \
- $(SELINUX_CFLAGS) \
- $(NULL)
+ $(SELINUX_CFLAGS)
+
+if WITH_SECDRIVER_APPARMOR
+libvirt_setuid_rpc_client_la_LDFLAGS += $(APPARMOR_LIBS)
+libvirt_setuid_rpc_client_la_CFLAGS += $(APPARMOR_CFLAGS)
+endif WITH_SECDRIVER_APPARMOR
+
endif WITH_LXC
lockdriverdir = $(libdir)/libvirt/lock-driver
--
1.8.1.5
11 years, 1 month
[libvirt] Exploring linbvirt.
by cooldharma06
hi,
i am started to exploring libvirt. i am using the version libvirt-1.1.3 and
i want to know (or) find the path how the libvirt is creating VM with xen
(libxl) in the source. Any guide or reference is available for this. How i
can find the path of calling sequence for other operations(api). Guide me
to get some idea on debugging the libvirt.
Regards,
cooldharma06
11 years, 1 month
[libvirt] [libvirt-test-API][PATCH] npiv: Add basic NPIV test case
by jmiao
The original NPIV test function create_virtual_hba doesn't check the
validation of fabric_wwn, this patch modify create_virtual_hba to check
fabric_wwn whether is invalid (0xffffffff).
One the other hand, add a function destroy_virtual_hba to clean the vHBA which
is created by create_virtual_hba.
Add a global variable wwnn to global.cfg for create_virtual_hba. And add the
test case conf file basic_npiv.conf.
Signed-off-by: jmiao <jmiao(a)redhat.com>
---
cases/basic_npiv.conf | 3 +++
global.cfg | 10 ++++++++-
repos/npiv/create_virtual_hba.py | 24 +++++++++++---------
repos/npiv/destroy_virtual_hba.py | 46 +++++++++++++++++++++++++++++++++++++++
4 files changed, 72 insertions(+), 11 deletions(-)
create mode 100644 cases/basic_npiv.conf
create mode 100644 repos/npiv/destroy_virtual_hba.py
diff --git a/cases/basic_npiv.conf b/cases/basic_npiv.conf
new file mode 100644
index 0000000..b9cbd04
--- /dev/null
+++ b/cases/basic_npiv.conf
@@ -0,0 +1,3 @@
+npiv:create_virtual_hba
+
+npiv:destroy_virtual_hba
diff --git a/global.cfg b/global.cfg
index db8f71e..a35b985 100644
--- a/global.cfg
+++ b/global.cfg
@@ -210,7 +210,15 @@ testnic = eth1
# a PCI device to use for attach/detach/reset tests
# for example testpci = 00:19.0
-testpci =
+testpci = 00:19.0
+
+################################################################
+#
+# NPIV wwpn
+#
+
+# a word wide port name to use for create_virtual_hba tests
+wwnn =
################################################################
#
diff --git a/repos/npiv/create_virtual_hba.py b/repos/npiv/create_virtual_hba.py
index 0a02a9b..b637127 100644
--- a/repos/npiv/create_virtual_hba.py
+++ b/repos/npiv/create_virtual_hba.py
@@ -21,7 +21,7 @@ def check_nodedev_create(wwpn, device_name):
vport name in all FC list, to see if it exists.
"""
- pname_list = commands.getoutput("ls -1 -d /sys/class/*_host/host*/* \
+ pname_list = commands.getoutput("ls -1 -d /sys/class/*_host/host*/*
| grep port_name")
for pname in pname_list.split("\n"):
portid = open(pname).read()[2:].strip('\n')
@@ -38,11 +38,11 @@ def check_nodedev_parent(nodedev_obj, device_parent, device_name):
current_parent = nodedev_obj.parent()
if device_parent == current_parent:
- logger.info("The parent of node device '%s' is %s" \
+ logger.info("The parent of node device '%s' is %s"
% (device_name, current_parent))
return True
else:
- logger.info("Refer to bug 593995. The parent of node device \
+ logger.info("Refer to bug 593995. The parent of node device
'%s' is '%s'" % (device_name, current_parent))
return False
@@ -63,35 +63,39 @@ def create_virtual_hba(params):
fc_xml = nodedev.XMLDesc(0)
fc_cap = re.search('vport_ops', fc_xml)
if fc_cap:
+ doc = xml.dom.minidom.parseString(fc_xml)
+ logger.info("NPIV support on '%s'" % fc_name)
+ fabric_wwn = doc.getElementsByTagName('fabric_wwn')[0].childNodes[0].nodeValue.encode('ascii', 'ignore')
+ if fabric_wwn == 'ffffffff':
+ logger.info("fabric_wwn of '%s' is ffffffff" % fc_name)
+ continue
device_parent = fc_name
xmlstr = xmlstr.replace('PARENT', device_parent)
- doc = xml.dom.minidom.parseString(fc_xml)
wwnn_node = doc.getElementsByTagName('wwnn')[0]
xmlstr = xmlstr.replace('WWNN', wwnn_node.childNodes[0].nodeValue.encode('ascii', 'ignore'))
- logger.info("NPIV support on '%s'" % fc_name)
break
else:
logger.info("No NPIV capabilities on '%s'" % fc_name)
logger.debug("node device xml:\n%s" % xmlstr)
- return 0
try:
logger.info("creating a virtual HBA ...")
nodedev_obj = conn.nodeDeviceCreateXML(xmlstr, 0)
dev_name = nodedev_obj.name()
- if check_nodedev_create(wwpn, dev_name) and \
+ if check_nodedev_create(wwpn, dev_name) and
check_nodedev_parent(nodedev_obj, device_parent, dev_name):
- logger.info("the virtual HBA '%s' was created successfully" \
+ logger.info("the virtual HBA '%s' was created successfully"
% dev_name)
+ sharedmod.data['vhba'] = dev_name
return 0
else:
- logger.error("fail to create the virtual HBA '%s'" \
+ logger.error("fail to create the virtual HBA '%s'"
% dev_name)
return 1
except libvirtError, e:
- logger.error("API error message: %s, error code is %s" \
+ logger.error("API error message: %s, error code is %s"
% (e.message, e.get_error_code()))
logger.error("Error: fail to create %s virtual hba" % dev_name)
return 1
diff --git a/repos/npiv/destroy_virtual_hba.py b/repos/npiv/destroy_virtual_hba.py
new file mode 100644
index 0000000..7864ed4
--- /dev/null
+++ b/repos/npiv/destroy_virtual_hba.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# To test vHBA destroying.
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+
+required_params = ()
+optional_params = {}
+
+def destroy_virtual_hba(params):
+ """Destroy the vHBA created before."""
+ global logger
+ logger = params['logger']
+
+ conn = sharedmod.libvirtobj['conn']
+
+ if not sharedmod.data.has_key('vhba'):
+ logger.error("Failed to find the created vhba.")
+ return 1
+
+ dev_name = sharedmod.data['vhba']
+
+ logger.info("destroying the virtual HBA %s" % dev_name)
+
+
+ try:
+ nodedev_obj = conn.nodeDeviceLookupByName(dev_name)
+
+ nodedev_obj.destroy()
+
+ scsi_list = conn.listDevices('scsi_host', 0)
+
+ for fc_name in scsi_list:
+ if fc_name == dev_name:
+ logger.error("Fail to destroy the virtual HBA %s" % dev_name)
+ return 1
+
+ except libvirtError, e:
+ logger.error("API error message: %s, error code is %s"
+ % (e.message, e.get_error_code()))
+ logger.error("Error: fail to destroy %s virtual hba" % dev_name)
+ return 1
+
+ return 0
--
1.8.2.1
11 years, 1 month
Re: [libvirt] [Qemu-devel] [REMINDER] Key Signing Party at KVM Forum
by Eric Blake
Forwarding this information on:
On 10/22/2013 10:56 AM, Anthony Liguori wrote:
> Hi,
>
> We'll be hosting a key signing party at KVM Forum on Wednesday during
> the Hackathon.
>
> More information is at:
>
> http://wiki.qemu.org/KeySigningParty2013
>
> Here is the set of people who have sent me their fingerprints so far:
>
> http://wiki.qemu.org/download/keysigning.txt
>
> If you plan on participating, please make sure you key is in this list
> and if it is not, send me the output of gpg --fingerprint for the key
> you wish to use. I may have missed your mail so even if you sent me
> something, please check again.
>
> Make sure you bring proper ID too. Passports are the best form of ID.
>
> Please note that the key server on the wiki is currently down so
> please ignore that part of the howto.
>
> Regards,
>
> Anthony Liguori
>
>
>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
11 years, 1 month
[libvirt] [PATCH]docs: fix some typos about 'informations'
by Chen Hanxiao
From: Chen Hanxiao <chenhanxiao(a)cn.fujitsu.com>
s/informations/information
Signed-off-by: Chen Hanxiao <chenhanxiao(a)cn.fujitsu.com>
---
docs/bugs.html.in | 6 +++---
docs/logging.html.in | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/bugs.html.in b/docs/bugs.html.in
index 71e43e4..2295ae9 100644
--- a/docs/bugs.html.in
+++ b/docs/bugs.html.in
@@ -132,7 +132,7 @@
crash, the simplest is to run the program under gdb, reproduce the
steps leading to the crash and then issue a gdb "bt -a" command to
get the stack trace, attach it to the bug. Note that for the
- data to be really useful libvirt debug informations must be present
+ data to be really useful libvirt debug information must be present
for example by installing libvirt debuginfo package on Fedora or
Red Hat Enterprise Linux (with debuginfo-install libvirt) prior
to running gdb.</p>
@@ -147,11 +147,11 @@
<pre> # ps -o etime,pid `pgrep libvirt`
... note the process id from the output
# gdb /usr/sbin/libvirtd
-.... some informations about gdb and loading debug data
+.... some information about gdb and loading debug data
(gdb) attach $the_damon_process_id
....
(gdb) thread apply all bt
-.... informations to attach to the bug
+.... information to attach to the bug
(gdb)
</pre>
diff --git a/docs/logging.html.in b/docs/logging.html.in
index 86e178c..1cd15a1 100644
--- a/docs/logging.html.in
+++ b/docs/logging.html.in
@@ -68,7 +68,7 @@
<ul>
<li>1 or "debug": asking the library to log every message emitted,
though the filters can be used to avoid filling up the output</li>
- <li>2 or "info": log all non-debugging informations</li>
+ <li>2 or "info": log all non-debugging information</li>
<li>3 or "warn": log warnings and errors, that's the default value</li>
<li>4 or "error": log only error messages</li>
</ul></li>
@@ -89,7 +89,7 @@
<ul>
<li>4: only errors</li>
<li>3: warnings and errors</li>
- <li>2: informations, warnings and errors</li>
+ <li>2: information, warnings and errors</li>
<li>1: debug and everything</li>
</ul></li>
<li>log_filters: defines logging filters</li>
--
1.8.2.1
11 years, 1 month
Re: [libvirt] Support QEMU Live Upgrade in Libvirt
by Eric Blake
On 10/21/2013 08:16 AM, Zhou Zheng Sheng wrote:
> Hi all,
>
> Recently QEMU developers are working on a feature to allow upgrading a
> live QEMU instance to a new version without restarting the VM. This is
> implemented as live migration between the old and new QEMU process on
> the same host [1]. Here is the the use case:
>
> 1) Guests are running QEMU release 1.6.1.
> 2) Admin installs QEMU release 1.6.2 via RPM or deb.
> 3) Admin starts a new VM using the updated QEMU binary, and asks the old
> QEMU process to migrate the VM to the newly started VM.
This is NOT migration, but qemu upgrading. Libvirt has a very strong
notion that migration is between two distinct hosts, and libvirt WILL
DEADLOCK if you attempt to migrate to the same host (because of
assumptions that libvirt makes about the control sequence of managing
the migration).
While live upgrade may use migration under the hood in qemu, we would
need to add a new API to libvirt to expose the functionality as a qemu
in-place upgrade, rather than trying to add it as a flag to the existing
libvirt migration, because it would be something we want done by a
single libvirtd rather than reusing the code paths of existing migration
which requires handshakes between two libvirtd.
> The problem is that it requires twice host memory as the original VM
> does during the upgrading. Thus comes the ongoing development of using
> the system call vmsplice() to move memory pages between two QEMU
> instances, so that the kernel can just perform page re-mapping from
> source QEMU process to destination QEMU process in a zero-copy manner.
> This is expected to reduce memory consumption and speedup the whole
> procedure. This mechanism is based on Unix domain socket, pipes and FD
> inter-process passing magic [2].
Yes, I would love to have libvirt expose this functionality; it's just
that I think we need a new libvirt API for it.
>
> Solution #2 Adding New API virDomainHypervisorLiveUpgrade()
>
> Another idea is to have a new API and new flow dedicated to this
> feature. In my opinion, I think it's good to have a API to do hypervisor
> live upgrade in general, and we implement it in QEMU driver using a
> special local migration procedure. We can also provide a default
> implementation for all the hypervisors using this local migration trick
> if possible. However the work to do is much more than solution #1. The
> basic functions such as ACL, XML parsing, front-end device creation,
> QEMU process handling and so on can be re-used, but it seems most of the
> code in qemu_migration.c can not be re-used without massive refactoring.
> The UUID problem discussed the solution #1 is also still need to be solved.
This is the only viable solution. Are you interested in starting
patches along this direction?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
11 years, 1 month
Re: [libvirt] why no progress shown after introduce NBD migration cookie
by Zhanghaoyu (A)
>>>> hi Michal,
>>>>
>>>> I used libvirt-1.0.3, ran below command to perform live migration, why no progress shown up?
>>>> virsh migrate --live --verbose --copy-storage-all <domain>
>>>> qemu+tcp://<dest ip>/system
>>>>
>>>> If replacing libvirt-1.0.3 with libvirt-1.0.2, the migration
>>>> progress shown up, if performing migration without "--copy-storage-all", the migration progress shown up, too.
>>>>
>>>> Thanks,
>>>> Zhang Haoyu
>>>>
>>>
>>> Because since 1.0.3 we are using NBD to migrate storage. Truth is,
>>> qemu is reporting progress of storage migration, however, there is no generic formula to combine storage migration and internal state migration into one number. With NBD the process is something like this:
>>
>> How to use NBD to migrate storage?
>> Does NBD server in destination start automatically as soon as migration initiated, or some other configurations needed?
>> What's the advantages of using NBD to migrate storage over traditional method that migrating the storage in iteration way, just like the way in which migrating the memory?
>> Sorry for my poor knowledge in NBD, by which I used to implement shared storage for live migration without storage.
>
>NBD is used whenever both src and dst of migration is new enough to use it. That is, libvirt >= 1.0.3 and qemu >= 1.0.3. The NBD is turned on by libvirt whenever the conditions are met. User has no control over this.
>The advantage is: only specified disks can be transferred (currently not supported in libvirt), the previous implementation was buggy (according to some qemu developers), the storage is migrated via separate channel (a new connection) so it can be possible (in the future) to split migration of RAM + internal state and storage.
Could you make a detailed statement for the buggy previous implementation, please ?
Thanks,
Zhang Haoyu
>
>So frankly speaking, there's no real advantage for users now - besides not using buggy implementation.
>
>Michal
>
>BTW: It's better to ask these kind of info on the libvir-list next time, others might contribute with much more info as well (e.g. some qemu developers tend to watch the libvir-list too).
11 years, 1 month
[libvirt] [libvirt-test-API][PATCH] nodedevice: Add nodedevice test case
by jmiao
This patch adds node device test case to cover API: listAllDevice, listCaps,
numOfCaps, parent, name.
It lists all node devices by checking each uevent file of node in sysfs. If the
keywords are found in uevent, it will add this node to node device, and record
relationship with its parent node device.
Signed-off-by: jmiao <jmiao(a)redhat.com>
---
cases/basic_nodedevice.conf | 10 ++
repos/nodedevice/capabilities.py | 63 ++++++++
repos/nodedevice/list_nodedevices.py | 276 +++++++++++++++++++++++++++++++++++
repos/nodedevice/parent_name.py | 63 ++++++++
4 files changed, 412 insertions(+)
create mode 100644 repos/nodedevice/capabilities.py
create mode 100644 repos/nodedevice/list_nodedevices.py
create mode 100644 repos/nodedevice/parent_name.py
diff --git a/cases/basic_nodedevice.conf b/cases/basic_nodedevice.conf
index 85a68f7..1a19bde 100644
--- a/cases/basic_nodedevice.conf
+++ b/cases/basic_nodedevice.conf
@@ -1,3 +1,13 @@
+nodedevice:list_nodedevices
+
+nodedevice:parent_name
+ pciaddress
+ $testpci
+
+nodedevice:capabilities
+ pciaddress
+ $testpci
+
nodedevice:detach
pciaddress
$testpci
diff --git a/repos/nodedevice/capabilities.py b/repos/nodedevice/capabilities.py
new file mode 100644
index 0000000..9b94376
--- /dev/null
+++ b/repos/nodedevice/capabilities.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+
+required_params = ('pciaddress',)
+optional_params = {}
+
+def capabilities(params):
+ """check the capabilities of a given node device"""
+ global logger
+ logger = params['logger']
+
+ pciaddress = params['pciaddress']
+
+ nodedevice = None
+
+ node_capabilities = []
+
+ if not sharedmod.data.has_key('all_nodes'):
+ logger.error("Failed to get nodes.")
+ return 1
+
+
+ (bus, slot_func) = pciaddress.split(":")
+ (slot, func) = slot_func.split(".")
+ device_name = "pci_0000_%s_%s_%s" % (bus, slot, func)
+ logger.debug("the name of the pci device is: %s" % device_name)
+
+ nodes = sharedmod.data['all_nodes']
+
+ for entry in nodes:
+ if cmp(entry.name, device_name):
+ nodedevice = entry
+ else:
+ if nodedevice is None:
+ logger.error("parent_name cannot find %s" % device_name)
+ return 1
+
+ conn = sharedmod.libvirtobj['conn']
+
+ try:
+ node_obj = conn.nodeDeviceLookupByName(device_name)
+ node_capabilities = node_obj.listCaps()
+
+ logger.info("%s capabilities: %s" %(device_name, node_capabilities))
+
+ if len(node_capabilities) != node_obj.numOfCaps():
+ logger.error("The number of node capabilities error")
+ return 1
+
+ if not cmp(node_capabilities[0], nodedevice.capability):
+ logger.error("%s capabilities error: %s, should be %s."
+ % (device_name, node_capabilities[0], nodedevice.capability))
+ 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
diff --git a/repos/nodedevice/list_nodedevices.py b/repos/nodedevice/list_nodedevices.py
new file mode 100644
index 0000000..eb1f242
--- /dev/null
+++ b/repos/nodedevice/list_nodedevices.py
@@ -0,0 +1,276 @@
+#!/usr/bin/env python
+# list all node devices from host
+
+import commands
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+
+required_params = ()
+optional_params = {}
+
+g_pci = []
+g_usb_device = []
+g_usb = []
+g_scsi_host = []
+g_scsi_target = []
+g_scsi = []
+g_net = []
+g_storage = []
+g_nodes = []
+
+options = { 'pci' : ['PCI_ID', g_pci, 'pci_'],
+ 'usb_device' : ['DEVTYPE=usb_device', g_usb_device, 'usb_'],
+ 'usb' : ['DEVTYPE=usb_interface', g_usb, 'usb_'],
+ 'scsi_host' : ['DEVTYPE=scsi_host', g_scsi_host, 'scsi_'],
+ 'scsi_target' : ['DEVTYPE=scsi_target', g_scsi_target, 'scsi_'],
+ 'scsi' : ['DEVTYPE=scsi_device', g_scsi, 'scsi_'],
+ }
+
+class NodeDevice(object):
+ """A NodeDevice class to record related information."""
+ def __init__(self, name, path):
+ """init"""
+ self.name = name
+ self.path = path
+ self.parent = None
+ self.capability = None
+
+ def create_child(self, name, path, cap):
+ """create_child function"""
+ child = NodeDevice(name, path)
+ child.parent = self
+ child.capability = cap
+ return child
+
+def format_name(name):
+ """format name to libvirt style: pci_0000_00_00_0"""
+ name = name.replace('.', '_')
+ name = name.replace(':', '_')
+ name = name.replace('-', '_')
+ return name
+
+def extract_name(path):
+ """
+ extract name from a path. The argument must be a path which ending with
+ '/', and it will be parsed by this function.
+ """
+ pos2 = path.rfind('/')
+ path = path[0:pos2]
+ pos1 = path.rfind('/')
+ path = path[pos1+1:pos2]
+ return format_name(path)
+
+def list_net(root):
+ """list all net nodedevices"""
+ global g_net, g_pci
+ cmd = "ip link | awk {'print $2'}"
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status != 0:
+ return 1
+
+ tmp = ret.split('\n')
+
+ # bubble sort to reduce the replicated mac
+ for i in reversed(range(0, len(tmp)/2)):
+ for j in reversed(range(i, len(tmp)/2)):
+ if i != j and tmp[i*2+1] == tmp[j*2+1]:
+ del tmp[i*2+1]
+ del tmp[i*2]
+
+ for i in range(0, len(tmp)/2):
+ cmd = "ethtool -i %s | grep driver" % tmp[i*2][0:len(tmp[i*2])-1]
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status != 0:
+ g_net.append(root.create_child("net_" + format_name(tmp[i*2] +
+ tmp[i*2+1]), root.path, "net"))
+ continue
+
+ cmd = "echo %s | awk {'print $2'}" % ret
+ (status, ret) = commands.getstatusoutput(cmd)
+ driver = ret
+
+ cmd = "echo %s | egrep -v 'tun|bridge'" % driver
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status == 0:
+ for entry in g_pci:
+ cmd = "cat %s/uevent | grep %s" % (entry.path, driver)
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status == 0:
+ g_net.append(entry.create_child("net_" + format_name(
+ tmp[i*2] + tmp[i*2+1]), entry.path, "net"))
+ else:
+ g_net.append(root.create_child("net_" + format_name(tmp[i*2] +
+ tmp[i*2+1]), root.path, "net"))
+
+
+ return 0
+
+def list_scsi_host(node):
+ """list all scsi host nodedevices"""
+ cmd = "find %s -name host*" % node.path
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status != 0:
+ return 1
+ if len(ret) == 0:
+ return 1
+
+ dir = ret.split('\n')
+
+ for entry in dir:
+ entry_path = entry + '/'
+ cmd = "cat %s/uevent | egrep -i '%s'" % (entry_path,
+ options['scsi_host'][0])
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status == 0:
+ options['scsi_host'][1].append(node.create_child(
+ options['scsi_host'][2] + extract_name(entry_path),
+ entry_path, 'scsi_host'))
+
+
+def list_storage(root):
+ """list all storage nodedevices"""
+ global g_nodes, g_storage
+ cmd = "find %s -name block | sed -e 's/block//'" % root.path
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status != 0:
+ return 1
+
+ if len(ret) == 0:
+ return 1
+
+ blk = ret.split('\n')
+
+ for blk_entry in blk:
+ for node_entry in g_nodes:
+ if cmp(blk_entry, node_entry.path) == 0:
+ cmd = "ls %s/block" % blk_entry
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status != 0:
+ continue
+
+ g_storage.append(node_entry.create_child("block_" + ret,
+ blk_entry+"block/", "storage"))
+ return 0
+
+
+def list_node(node_device, path, cap, checktop):
+ """list a nodedevices though path."""
+ dirs = []
+ if checktop == True:
+ cmd = "cat %suevent | egrep -i '%s'" % (path, options[cap][0])
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status != 0:
+ return 1
+ else:
+ options[cap][1].append(node_device.create_child(options[cap][2]
+ + extract_name(path), path, cap))
+
+ cmd = "ls %s" % path
+ (status, ret) = commands.getstatusoutput(cmd)
+ if status != 0:
+ return 1
+
+ cmd = "ls -l %s | grep '^d' | awk {'print $9'}" % path
+ (status, ret) = commands.getstatusoutput(cmd)
+
+ if len(ret) == 0:
+ return 1
+
+ dirs = ret.split('\n')
+
+ for entry in dirs:
+ list_node(node_device, path + entry + "/", cap, True)
+
+ return 0
+
+
+def list_nodedevices(params):
+ """list all nodedevices"""
+ global logger
+ global g_nodes, g_pci, g_usb_device, g_usb, g_net
+ global g_scsi_host, g_scsi_target, g_scsi, g_storage
+ ret = 0
+
+ logger = params['logger']
+
+ root = NodeDevice("computer", "/sys/devices/pci0000:00/")
+ g_nodes.append(root)
+
+ # find pci
+ list_node(root, root.path, 'pci', False)
+ g_nodes += g_pci
+
+ # find usb_device
+ for entry in g_pci:
+ list_node(entry, entry.path, 'usb_device', False)
+ g_nodes += g_usb_device
+
+ # find usb
+ for entry in g_usb_device:
+ list_node(entry, entry.path, 'usb', False)
+ g_nodes += g_usb
+
+ # find scsi_host
+ for entry in g_pci + g_usb:
+ list_scsi_host(entry)
+ g_nodes += g_scsi_host
+
+ # find scsi_target
+ for entry in g_scsi_host:
+ list_node(entry, entry.path, 'scsi_target', False)
+ g_nodes += g_scsi_target
+
+ # find scsi
+ for entry in g_scsi_target:
+ list_node(entry, entry.path, 'scsi', False)
+ g_nodes += g_scsi
+
+ # find net
+ list_net(root)
+ g_nodes += g_net
+
+ # find storage
+ list_storage(root)
+ g_nodes += g_storage
+
+ logger.debug("Traverse the node device list")
+
+ sharedmod.data['all_nodes'] = g_nodes
+
+ try:
+ conn = sharedmod.libvirtobj['conn']
+ retlist = conn.listAllDevices(0)
+
+ if len(retlist) > len(g_nodes):
+ for entry in g_nodes:
+ print entry.name
+ logger.error("list_all_node_devices miss some devices")
+ return 1
+ elif len(retlist) < len(g_nodes):
+ for entry in g_nodes:
+ print entry.name
+ logger.error("listAllDevices miss some devices")
+ return 1
+
+ for entry in retlist:
+ checked = 0
+ for node in g_nodes:
+ if entry.name().find(node.name) == 0:
+ logger.info("%s \033[32mchecked\033[0m" % entry.name())
+ checked = 1
+ ret = 0
+ else:
+ if checked == 0:
+ logger.error("%s \033[31mnot found\033[0m" % entry.name())
+ ret = 1
+
+
+ except libvirtError, e:
+ logger.error("API error message: %s, error code is %s"
+ % (e.message, e.get_error_code()))
+ return 1
+
+ return ret
diff --git a/repos/nodedevice/parent_name.py b/repos/nodedevice/parent_name.py
new file mode 100644
index 0000000..5ce27f5
--- /dev/null
+++ b/repos/nodedevice/parent_name.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+import os
+import sys
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+from utils import utils
+
+required_params = ('pciaddress',)
+optional_params = {}
+
+def parent_name(params):
+ """check nodedevice parant and name API"""
+ global logger
+ logger = params['logger']
+
+ pciaddress = params['pciaddress']
+
+ nodedevice = None
+
+ if not sharedmod.data.has_key('all_nodes'):
+ logger.error("Failed to get nodes.")
+ return 1
+
+
+ (bus, slot_func) = pciaddress.split(":")
+ (slot, func) = slot_func.split(".")
+ device_name = "pci_0000_%s_%s_%s" % (bus, slot, func)
+ logger.debug("the name of the pci device is: %s" % device_name)
+
+ nodes = sharedmod.data['all_nodes']
+
+ for entry in nodes:
+ if cmp(entry.name, device_name):
+ nodedevice = entry
+ else:
+ if nodedevice is None:
+ logger.error("parent_name cannot find %s" % device_name)
+ return 1
+
+ parent_nodedevice = nodedevice.parent
+
+ conn = sharedmod.libvirtobj['conn']
+
+ try:
+ node_obj = conn.nodeDeviceLookupByName(device_name)
+ parent_node_name = node_obj.parent()
+
+ logger.info("%s's parent name is %s" %(device_name, parent_node_name))
+
+ if not cmp(parent_node_name, parent_nodedevice.name):
+ logger.error("%s's parent device name error: %s, should be %s."
+ % (device_name, parent_node_name, parent_nodedevice.name))
+ 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
--
1.8.2.1
11 years, 1 month