From deepakcs at linux.vnet.ibm.com Thu Dec 1 14:07:20 2011 From: deepakcs at linux.vnet.ibm.com (Deepak Shetty) Date: Thu, 01 Dec 2011 19:37:20 +0530 Subject: [Libvirt-cim] [TEST] Unable to run cimtest on qemu kvm setup Message-ID: <4ED78A18.6090202@linux.vnet.ibm.com> dpkshetty at deepak-ThinkPad-T60p :~/work/cimtest/cimtest$ sudo CIM_NS=root/virt CIM_USER=root CIM_PASS=****** ./runtests libvirt-cim -i localhost -c -d -v KVM -g ComputerSys tem -t 04_defineStartVS.py Starting test suite: libvirt-cim Traceback (most recent call last): File "main.py", line 42, in from XenKvmLib.common_util import create_netpool_conf, destroy_netpool, \ File "./lib/XenKvmLib/common_util.py", line 31, in from XenKvmLib.test_xml import * File "./lib/XenKvmLib/test_xml.py", line 32, in from xml import xpath ImportError: cannot import name xpath I have all the pre-req installed as mentioned on the http://wiki.libvirt.org/page/Cimtest_setup wiki. there is no pyxml eq. on ubuntu ( I am on ubuntu host) but i do have these... dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep python | grep xml ii python-libxml2 2.7.8.dfsg-2 Python bindings for the GNOME XML library ii python-lxml 2.3-0.1 pythonic binding for the libxml2 and libxslt libraries dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep python2 ii libpython2.7 2.7.1-5ubuntu2 Shared Python runtime library (version 2.7) ii python2.6 2.6.6-6ubuntu7 An interactive high-level object-oriented language (version 2.6) ii python2.6-minimal 2.6.6-6ubuntu7 A minimal subset of the Python language (version 2.6) ii python2.7 2.7.1-5ubuntu2 An interactive high-level object-oriented language (version 2.7) ii python2.7-dev 2.7.1-5ubuntu2 Header files and a static library for Python (v2.7) ii python2.7-minimal 2.7.1-5ubuntu2 A minimal subset of the Python language (version 2.7) dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep wbem ii python-pywbem 0.7.0-4 Python WBEM Client and Provider Interface dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ Can someone help or tell me what am I missing ? My aim is to invole the create/define system flow via libvirt-cim. thanx, deepak -------------- next part -------------- An HTML attachment was scrubbed... URL: From deepakcs at linux.vnet.ibm.com Thu Dec 1 14:23:56 2011 From: deepakcs at linux.vnet.ibm.com (Deepak Shetty) Date: Thu, 01 Dec 2011 19:53:56 +0530 Subject: [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs support on QEMU/KVM environment Message-ID: <4ED78DFC.1070406@linux.vnet.ibm.com> Hi All, I need some help and inputs on the below. 1) I am looking at adding support for 9pfs ( 9p file system) in libvirt-cim. NOTE the support for the same already exists in libvirt & qemu. 2) Using 9pfs support, user can export a host file system to the guest ( domain). It uses the virtio framework, so its a passthru file system. NOTE: This support is exported as a 9p-virtio-device to the guest. Each host export path is exported as a pseudo 9p device to the guest. NOTE: This is currently supported only in qemu/kvm environment. 3) The xml tags related to 9pfs in libvirt are... an example below...
The node comes directly under the node. My approach for introducing 9pfs support in libvirt-cim is ... 1) Add a new CIM res type, eg; CIM_RES_TYPE_9PFS, is this ok ? 2) Add appropriate handlers for the above new resource type 3) Add new members in struct domain for representing this new device type. 4) Add appropriate xml parsing generation tags for the new resource type. 5) I probably need to add something like KVM_9PFSResourceAllocationSettingData -- I am not very clear on this yet. Need some help on how to do this ? Would appreciate inputs. thanx, deepak From snmishra at us.ibm.com Thu Dec 1 23:02:05 2011 From: snmishra at us.ibm.com (Sharad Mishra) Date: Thu, 1 Dec 2011 15:02:05 -0800 Subject: [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs support on QEMU/KVM environment In-Reply-To: <4ED78DFC.1070406@linux.vnet.ibm.com> References: <4ED78DFC.1070406@linux.vnet.ibm.com> Message-ID: > Deepak Shetty > Sent by: libvirt-cim-bounces at redhat.com > > 12/01/2011 06:23 AM > > Please respond to > List for discussion and development of libvirt CIM > > To > > libvirt-cim at redhat.com > > cc > > Subject > > [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs support on > QEMU/KVM environment > > Hi All, > I need some help and inputs on the below. > > 1) I am looking at adding support for 9pfs ( 9p file system) in > libvirt-cim. NOTE the support for the same already exists in libvirt & > qemu. > > 2) Using 9pfs support, user can export a host file system to the guest ( > domain). It uses the virtio framework, so its a passthru file system. > NOTE: This support is exported as a 9p-virtio-device to the guest. Each > host export path is exported as a pseudo 9p device to the guest. > NOTE: This is currently supported only in qemu/kvm environment. > > 3) The xml tags related to 9pfs in libvirt are... an example below... > > > > > > >
> Deepak, I am trying to understand your requirement and see what you need to do in libvirt-cim to enable 9pfs support. What in the above libvirt XML makes it specific to 9pfs? I am looking for special 'tags' or 'properties'. -Sharad Mishra > > The node comes directly under the node. > > My approach for introducing 9pfs support in libvirt-cim is ... > > 1) Add a new CIM res type, eg; CIM_RES_TYPE_9PFS, is this ok ? > > 2) Add appropriate handlers for the above new resource type > > 3) Add new members in struct domain for representing this new device type. > > 4) Add appropriate xml parsing generation tags for the new resource type. > > 5) I probably need to add something like > KVM_9PFSResourceAllocationSettingData -- I am not very clear on this yet. > Need some help on how to do this ? > > Would appreciate inputs. > > thanx, > deepak > > _______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim > From snmishra at us.ibm.com Thu Dec 1 23:11:31 2011 From: snmishra at us.ibm.com (Sharad Mishra) Date: Thu, 1 Dec 2011 16:11:31 -0700 Subject: [Libvirt-cim] [TEST] Unable to run cimtest on qemu kvm setup In-Reply-To: <4ED78A18.6090202@linux.vnet.ibm.com> References: <4ED78A18.6090202@linux.vnet.ibm.com> Message-ID: Most likely you are missing pywbem. I am attaching a tar file. After untaring, run "python setup.py build" and "python setup.py install" Also make sure you have PyXML installed. (See attached file: pywbem-0.7.0.tar.gz) Regards, Sharad Mishra Open Virtualization Linux Technology Center IBM libvirt-cim-bounces at redhat.com wrote on 12/01/2011 06:07:20 AM: > Deepak Shetty > Sent by: libvirt-cim-bounces at redhat.com > > 12/01/2011 06:07 AM > > Please respond to > List for discussion and development of libvirt CIM > > To > > libvirt-cim at redhat.com > > cc > > Subject > > [Libvirt-cim] [TEST] Unable to run cimtest on qemu kvm setup > > dpkshetty at deepak-ThinkPad-T60p > :~/work/cimtest/cimtest$ sudo > CIM_NS=root/virt CIM_USER=root CIM_PASS=****** ./runtests libvirt-cim > -i localhost -c -d -v KVM -g ComputerSys > tem -t 04_defineStartVS.py > Starting test suite: libvirt-cim > Traceback (most recent call last): > File "main.py", line 42, in > from XenKvmLib.common_util import create_netpool_conf, destroy_netpool, \ > File "./lib/XenKvmLib/common_util.py", line 31, in > from XenKvmLib.test_xml import * > File "./lib/XenKvmLib/test_xml.py", line 32, in > from xml import xpath > ImportError: cannot import name xpath > > > I have all the pre-req installed as mentioned on the > http://wiki.libvirt.org/page/Cimtest_setup wiki. > there is no pyxml eq. on ubuntu ( I am on ubuntu host) but i do have these... > > dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep > python | grep xml > ii python-libxml2 2.7.8.dfsg-2 > Python bindings for the GNOME XML library > ii python-lxml 2.3-0.1 > pythonic binding for the libxml2 and libxslt libraries > dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ > > dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep python2 > ii libpython2.7 2.7.1-5ubuntu2 > Shared Python runtime library (version 2.7) > ii python2.6 2.6.6-6ubuntu7 > An interactive high-level object-oriented language > (version 2.6) > ii python2.6-minimal 2.6.6-6ubuntu7 > A minimal subset of the Python language (version 2.6) > ii python2.7 2.7.1-5ubuntu2 > An interactive high-level object-oriented language > (version 2.7) > ii python2.7-dev 2.7.1-5ubuntu2 > Header files and a static library for Python (v2.7) > ii python2.7-minimal 2.7.1-5ubuntu2 > A minimal subset of the Python language (version 2.7) > dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ > > dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep wbem > ii python-pywbem 0.7.0-4 > Python WBEM Client and Provider Interface > dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ > > > Can someone help or tell me what am I missing ? > > My aim is to invole the create/define system flow via libvirt-cim. > > thanx, > deepak_______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim -------------- next part -------------- A non-text attachment was scrubbed... Name: pywbem-0.7.0.tar.gz Type: application/octet-stream Size: 131527 bytes Desc: not available URL: From deepakcs at linux.vnet.ibm.com Fri Dec 2 04:50:38 2011 From: deepakcs at linux.vnet.ibm.com (Deepak Shetty) Date: Fri, 02 Dec 2011 10:20:38 +0530 Subject: [Libvirt-cim] [TEST] Unable to run cimtest on qemu kvm setup In-Reply-To: References: <4ED78A18.6090202@linux.vnet.ibm.com> Message-ID: <4ED8591E.1080507@linux.vnet.ibm.com> On 12/02/2011 04:41 AM, Sharad Mishra wrote: > Most likely you are missing pywbem. I am attaching a tar file. After > untaring, run "python setup.py build" and "python setup.py install" > Also make sure you have PyXML installed. > > (See attached file: pywbem-0.7.0.tar.gz) > I already have pywbem installed, see the dpkg listing i posted below. I had spoken with Eduardo on this, and did some debug with him, it seems the pyXML package has been deprecated since 2009 ( found from launchpad.net) and ubuntu does not support and/or maintain it. Many of the google results tell me that one needs to use the core python xml bindings instead of pyXML which is not a maintained project hence discontinued. Eduardo was helping make changes to use libxml2 instead of pyXML . > Regards, > Sharad Mishra > Open Virtualization > Linux Technology Center > IBM > > libvirt-cim-bounces at redhat.com wrote on 12/01/2011 06:07:20 AM: > >> Deepak Shetty >> Sent by: libvirt-cim-bounces at redhat.com >> >> 12/01/2011 06:07 AM >> >> Please respond to >> List for discussion and development of libvirt CIM > >> To >> >> libvirt-cim at redhat.com >> >> cc >> >> Subject >> >> [Libvirt-cim] [TEST] Unable to run cimtest on qemu kvm setup >> >> dpkshetty at deepak-ThinkPad-T60p >> :~/work/cimtest/cimtest$ sudo >> CIM_NS=root/virt CIM_USER=root CIM_PASS=****** ./runtests libvirt-cim >> -i localhost -c -d -v KVM -g ComputerSys >> tem -t 04_defineStartVS.py >> Starting test suite: libvirt-cim >> Traceback (most recent call last): >> File "main.py", line 42, in >> from XenKvmLib.common_util import create_netpool_conf, > destroy_netpool, \ >> File "./lib/XenKvmLib/common_util.py", line 31, in >> from XenKvmLib.test_xml import * >> File "./lib/XenKvmLib/test_xml.py", line 32, in >> from xml import xpath >> ImportError: cannot import name xpath >> >> >> I have all the pre-req installed as mentioned on the >> http://wiki.libvirt.org/page/Cimtest_setup wiki. >> there is no pyxml eq. on ubuntu ( I am on ubuntu host) but i do have > these... >> dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep >> python | grep xml >> ii python-libxml2 2.7.8.dfsg-2 >> Python bindings for the GNOME XML library >> ii python-lxml 2.3-0.1 >> pythonic binding for the libxml2 and libxslt libraries >> dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ >> >> dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep > python2 >> ii libpython2.7 2.7.1-5ubuntu2 >> Shared Python runtime library (version 2.7) >> ii python2.6 2.6.6-6ubuntu7 >> An interactive high-level object-oriented language >> (version 2.6) >> ii python2.6-minimal 2.6.6-6ubuntu7 >> A minimal subset of the Python language (version 2.6) >> ii python2.7 2.7.1-5ubuntu2 >> An interactive high-level object-oriented language >> (version 2.7) >> ii python2.7-dev 2.7.1-5ubuntu2 >> Header files and a static library for Python (v2.7) >> ii python2.7-minimal 2.7.1-5ubuntu2 >> A minimal subset of the Python language (version 2.7) >> dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ >> >> dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ dpkg -l | grep > wbem >> ii python-pywbem 0.7.0-4 >> Python WBEM Client and Provider Interface >> dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest$ >> >> >> Can someone help or tell me what am I missing ? >> >> My aim is to invole the create/define system flow via libvirt-cim. >> >> thanx, >> deepak_______________________________________________ >> Libvirt-cim mailing list >> Libvirt-cim at redhat.com >> https://www.redhat.com/mailman/listinfo/libvirt-cim >> >> >> _______________________________________________ >> Libvirt-cim mailing list >> Libvirt-cim at redhat.com >> https://www.redhat.com/mailman/listinfo/libvirt-cim -------------- next part -------------- An HTML attachment was scrubbed... URL: From deepakcs at linux.vnet.ibm.com Fri Dec 2 07:53:14 2011 From: deepakcs at linux.vnet.ibm.com (Deepak Shetty) Date: Fri, 02 Dec 2011 13:23:14 +0530 Subject: [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs support on QEMU/KVM environment In-Reply-To: References: <4ED78DFC.1070406@linux.vnet.ibm.com> Message-ID: <4ED883EA.7070603@linux.vnet.ibm.com> On 12/02/2011 04:32 AM, Sharad Mishra wrote: >> Deepak Shetty >> Sent by: libvirt-cim-bounces at redhat.com >> >> 12/01/2011 06:23 AM >> >> Please respond to >> List for discussion and development of libvirt CIM > >> To >> >> libvirt-cim at redhat.com >> >> cc >> >> Subject >> >> [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs support on >> QEMU/KVM environment >> >> Hi All, >> I need some help and inputs on the below. >> >> 1) I am looking at adding support for 9pfs ( 9p file system) in >> libvirt-cim. NOTE the support for the same already exists in libvirt& >> qemu. >> >> 2) Using 9pfs support, user can export a host file system to the guest ( >> domain). It uses the virtio framework, so its a passthru file system. >> NOTE: This support is exported as a 9p-virtio-device to the guest. Each >> host export path is exported as a pseudo 9p device to the guest. >> NOTE: This is currently supported only in qemu/kvm environment. >> >> 3) The xml tags related to 9pfs in libvirt are... an example below... >> >> >> >> >> >> >>
function='0x0'/> >> > Deepak, I am trying to understand your requirement and see what you need to > do in libvirt-cim to enable 9pfs support. > What in the above libvirt XML makes it specific to 9pfs? I am looking for > special 'tags' or 'properties'. > > -Sharad Mishra type='mount' makes it specific to 9pfs. So its the type attribute of the filesystem tag. I confirmed the same by looking into libvirt code also. >> The node comes directly under the node. >> >> My approach for introducing 9pfs support in libvirt-cim is ... >> >> 1) Add a new CIM res type, eg; CIM_RES_TYPE_9PFS, is this ok ? >> >> 2) Add appropriate handlers for the above new resource type >> >> 3) Add new members in struct domain for representing this new device > type. >> 4) Add appropriate xml parsing generation tags for the new resource type. >> >> 5) I probably need to add something like >> KVM_9PFSResourceAllocationSettingData -- I am not very clear on this yet. >> Need some help on how to do this ? >> >> Would appreciate inputs. >> >> thanx, >> deepak >> >> _______________________________________________ >> Libvirt-cim mailing list >> Libvirt-cim at redhat.com >> https://www.redhat.com/mailman/listinfo/libvirt-cim >> > _______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim > > From deepakcs at linux.vnet.ibm.com Fri Dec 2 09:58:38 2011 From: deepakcs at linux.vnet.ibm.com (Deepak Shetty) Date: Fri, 02 Dec 2011 15:28:38 +0530 Subject: [Libvirt-cim] [TEST] cimtest make broken.... Message-ID: <4ED8A14E.8000002@linux.vnet.ibm.com> I was following the cimtest wiki @ http://wiki.libvirt.org/page/Cimtest_setup and it seems to be broken.. ~/work/cimtest/cimtest/suites/ libvirt-cim/images$ make mkdir -p xm-test (cd xm-test && wget http://xm-test.xensource.com/ramdisks/initrd-1.1-i386.img ) --2011-11-30 10:18:48-- http://xm-test.xensource.com/ramdisks/initrd-1.1-i386.img Resolving xm-test.xensource.com... failed: Name or service not known. wget: unable to resolve host address `xm-test.xensource.com ' make: *** [xm-test/initrd-1.1-i386.img] Error 4 I am connected to the internet, but that xm-test URL just does not ping. dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest/suites/libvirt-cim/images$ ping xm-test.xensource.com ping: unknown host xm-test.xensource.com dpkshetty at deepak-ThinkPad-T60p:~/work/cimtest/cimtest/suites/libvirt-cim/images$ ping www.yahoo.com PING any-fp3-real.wa1.b.yahoo.com (98.139.180.149) 56(84) bytes of data. 64 bytes from ir1.fp.vip.bf1.yahoo.com (98.139.180.149): icmp_req=1 ttl=52 time=430 ms 64 bytes from ir1.fp.vip.bf1.yahoo.com (98.139.180.149): icmp_req=2 ttl=52 time=318 ms 64 bytes from ir1.fp.vip.bf1.yahoo.com (98.139.180.149): icmp_req=3 ttl=52 time=323 ms -------------- next part -------------- An HTML attachment was scrubbed... URL: From eblima at linux.vnet.ibm.com Fri Dec 2 10:57:07 2011 From: eblima at linux.vnet.ibm.com (Eduardo Lima (Etrunko)) Date: Fri, 02 Dec 2011 08:57:07 -0200 Subject: [Libvirt-cim] [TEST] Unable to run cimtest on qemu kvm setup In-Reply-To: <4ED8591E.1080507@linux.vnet.ibm.com> References: <4ED78A18.6090202@linux.vnet.ibm.com> <4ED8591E.1080507@linux.vnet.ibm.com> Message-ID: <4ED8AF03.8000202@linux.vnet.ibm.com> On 12/02/2011 02:50 AM, Deepak Shetty wrote: > On 12/02/2011 04:41 AM, Sharad Mishra wrote: >> Most likely you are missing pywbem. I am attaching a tar file. After >> untaring, run "python setup.py build" and "python setup.py install" >> Also make sure you have PyXML installed. >> >> (See attached file: pywbem-0.7.0.tar.gz) >> > I already have pywbem installed, see the dpkg listing i posted below. > I had spoken with Eduardo on this, and did some debug with him, it seems > the pyXML package has been deprecated since 2009 ( found from launchpad.net) > and ubuntu does not support and/or maintain it. Many of the google > results tell me > that one needs to use the core python xml bindings instead of pyXML > which is > not a maintained project hence discontinued. Eduardo was helping make > changes to use libxml2 instead of pyXML . Yes, I am working on porting the PyXML bits to libxml2 (actually python-lxml). Patches coming soon. Best regards, -- Eduardo de Barros Lima Software Engineer, Open Virtualization Linux Technology Center - IBM/Brazil eblima at br.ibm.com From deepakcs at linux.vnet.ibm.com Fri Dec 2 13:13:13 2011 From: deepakcs at linux.vnet.ibm.com (Deepak Shetty) Date: Fri, 02 Dec 2011 18:43:13 +0530 Subject: [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs support on QEMU/KVM environment In-Reply-To: <4ED883EA.7070603@linux.vnet.ibm.com> References: <4ED78DFC.1070406@linux.vnet.ibm.com> <4ED883EA.7070603@linux.vnet.ibm.com> Message-ID: <4ED8CEE9.6020307@linux.vnet.ibm.com> On 12/02/2011 01:23 PM, Deepak Shetty wrote: > On 12/02/2011 04:32 AM, Sharad Mishra wrote: [...] >> >> >> >> >> >>
> function='0x0'/> >> >> What in the above libvirt XML makes it specific to 9pfs? I am >> looking for >> special 'tags' or 'properties'. >> >> -Sharad Mishra > type='mount' makes it specific to 9pfs. So its the type attribute of > the filesystem tag. > I confirmed the same by looking into libvirt code also. > [...] >>> The node comes directly under the node. >>> >>> My approach for introducing 9pfs support in libvirt-cim is ... >>> >>> 1) Add a new CIM res type, eg; CIM_RES_TYPE_9PFS, is this ok ? >>> >>> 2) Add appropriate handlers for the above new resource type >>> >>> 3) Add new members in struct domain for representing this new device >> type. >>> 4) Add appropriate xml parsing generation tags for the new resource >>> type. >>> >>> 5) I probably need to add something like >>> KVM_9PFSResourceAllocationSettingData -- I am not very clear on this >>> yet. >>> Need some help on how to do this ? >>> I found some more enlightment today looking at the code, so here are my newer thoughts... 1) It looks like the libvirt xml node ( that comes directly under ) is supported in a psuedo fashion, under CIM_RES_TYPE_DISK, is this correct ? It does res_type = ...DISK and dev_type = ..DISK_FS. 2) The cim code is structured in such a way that for each device type that comes under there is a virt-device and _device (eg: disk_device, net_device) structures and they are described by the respective RASDs. In following this tradition the there should have been virt_device and fs_device structures to correspond to the device type, eventually getting embedded under 'struct domain' but I don't see it, why is this so ? Why is treated differently in cim code ? 3) Assuming "yes" to #1 above, i need to extend the EmulatedType in KVM_DiskResourceAllocationSettingData to support "filesystem" as a value, set the disk_type = DISK_FS in disk_rasd_to_vdev and then it should probably work, as the disk_xml and disk_fs_xml code is already present to create the xml node. 4) I probably will re-use some of the members of KVM_DiskResourceAllocationSettingData from a 9pfs perspective, source and target will remain same as before, DriverCache, Address, may not be relevant for 9pfs. I might need to add few more stuff in DiskRASD as needed to support more sub-elements and attributes in for the in 9pfs case. Let me know if the above approach/understanding is correct. Appreciate your inputs. thanx, deepak From cvincent at linux.vnet.ibm.com Fri Dec 2 19:06:50 2011 From: cvincent at linux.vnet.ibm.com (Chip Vincent) Date: Fri, 02 Dec 2011 14:06:50 -0500 Subject: [Libvirt-cim] Release of libvirt-cim-0.5.15 Message-ID: <4ED921CA.2010808@linux.vnet.ibm.com> I'm happy announce the release of libvirt-cim-0.5.15. The new release is available at: ftp://libvirt.org/libvirt-cim/libvirt-cim-0.5.15.tar.gz libvirt-cim-0.5.15: * Fix include path (Eduardo Lima (Etrunko)) * xmlgen: Avoid double-free (Eduardo Lima (Etrunko)) * Fix possible use of uninitialized variables (Eduardo Lima (Etrunko)) * Fix misuse of signed variables (Eduardo Lima (Etrunko)) * Avoid NULL dereferences in various providers (Eduardo Lima (Etrunko)) * ACL: Plug leaks (Eduardo Lima (Etrunko)) * device_parsing: Avoid NULL dereferences (Eduardo Lima (Etrunko)) * pool_parsing: Avoid NULL dereferences (Eduardo Lima (Etrunko)) * acl_parsing: Avoid NULL dereference (Eduardo Lima (Etrunko)) * Avoid connection to libvirt if previous attempt fails (Eduardo Lima (Etrunko)) * Fix qos bug in primordial Network/0 pool (Gareth S. Bestor) * Rename .hgignore -> .gitignore (Chip Vincent) * Update autoconfiscate.sh to use git (Chip Vincent) * Add network qos (bandwidth) support for KVM guests (Gareth Bestor) * /dev/null should not be passed as source dev for cdrom device. (Sharad Mishra) * Add support for libvirt CPU cgroup for active KVM guests (Gareth S. Bestor) * FilterEntry: Set HdrProtocolID8021 property (Eduardo Lima (Etrunko)) * FilterEntry: Fix behavior of convert_ip_rule_to_instance (Eduardo Lima (Etrunko)) * FilterEntry: Support for mask in CIDR notation (Eduardo Lima (Etrunko)) * FilterEntry: Should be using srcipaddr instead of srcmacaddr (Eduardo Lima (Etrunko)) * acl_parsing: Share code for icmp and icmp rule types (Eduardo Lima (Etrunko)) * Pool names with space do not get parsed properly. (Sharad Mishra) * VirtualSystemManagementService: Avoid extra connection to libvirt (Eduardo Lima (Etrunko)) * (#2) Fix the problem that libvirt-cim can't find cdrom device that do not have disk (Wayne Xia) * device_parsing: Small code cleanup (Eduardo Lima (Etrunko)) * device_parsing: Use default values for vnc graphics device (Eduardo Lima (Etrunko)) * ACL: Add KVM_FilterEntry class (Eduardo Lima (Etrunko)) * Fix MOF download location - URL permanently changed (Chip Vincent) * Redirect stdout & stderr when run as out-of-process provider (Chip Vincent) * (#2) Return migration job status in CIM_ConcreteJob.ErrorCode (Sharad Mishra) * ACL: Add 'Action' property to KVM_{IPHeaders,Hdr8021}Filter (Eduardo Lima (Etrunko)) * (#2) Workaround to fix race condition around libvirt init. (Sharad Mishra) * VirtualSystemManagementService: Fix yet another possible leak (Eduardo Lima (Etrunko)) * VirtualSystemManagementService: Fixing potential null dereferences (Eduardo Lima (Etrunko)) * device_parsing: Fixing potential leaks (Eduardo Lima (Etrunko)) * Patches for Virt_SettingsDefineCapabilities: incorrect Default Value... (Gareth S. Bestor) * (#5) add sdl frame buffer support. (Wayne Xia) * (#5) made the graphic structure as union (Wayne Xia) * acl_parsing: Fixing potential leaks (Eduardo Lima (Etrunko)) * Check to see if stream is non-null before closing. (Sharad Mishra) * Retrun object paths for newly created filter associations. (Chip Vincent) * New entry "poolid" was not getting DUPed. (Sharad Mishra) * Fix connection leak introduced in patch 1119. (Sharad Mishra) -- Chip Vincent Open Virtualization IBM Linux Technology Center cvincent at linux.vnet.ibm.com From eblima at linux.vnet.ibm.com Mon Dec 5 16:24:05 2011 From: eblima at linux.vnet.ibm.com (Eduardo Lima (Etrunko)) Date: Mon, 5 Dec 2011 14:24:05 -0200 Subject: [Libvirt-cim] [PATCH] [TEST] Use python-lxml instead of PyXML Message-ID: <1323102245-19488-1-git-send-email-eblima@linux.vnet.ibm.com> From: Eduardo Lima (Etrunko) PyXML is a legacy python XML library which won't work with recent versions of python unless you patch the code. The following link describes the problem: http://stackoverflow.com/questions/4953600/pyxml-on-ubuntu In summary, when trying to install PyXML with easy_install, you get an error because it tries to use 'as' which is a reserved keyword introduced in python 2.5. This patch removes dependency of PyXML in favor of python-lxml, which provides bindings to the very complete and fast libxml2: http://lxml.de/intro.html Signed-off-by: Eduardo Lima (Etrunko) --- suites/libvirt-cim/cimtest/FilterList/helper.py | 8 +-- .../12_referenced_config.py | 14 +--- .../24_define_sys_features.py | 6 +- suites/libvirt-cim/lib/XenKvmLib/test_xml.py | 27 +++--- suites/libvirt-cim/lib/XenKvmLib/vxml.py | 95 ++++++++++---------- 5 files changed, 69 insertions(+), 81 deletions(-) diff --git a/suites/libvirt-cim/cimtest/FilterList/helper.py b/suites/libvirt-cim/cimtest/FilterList/helper.py index 138f941..9ae2f62 100644 --- a/suites/libvirt-cim/cimtest/FilterList/helper.py +++ b/suites/libvirt-cim/cimtest/FilterList/helper.py @@ -35,11 +35,7 @@ from XenKvmLib.vxml import get_class import VirtLib from VirtLib.utils import run_remote -try: - from xml.etree import cElementTree as ElementTree -except: - from xml.etree import ElementTree - +from lxml import etree class BaseTestObject(object): @@ -247,7 +243,7 @@ class FilterListTest(BaseTestObject): # Remove all unecessary spaces and new lines _xml = "".join([a.strip() for a in out.split("\n") if a]) - return ElementTree.fromstring(_xml) + return etree.fromstring(_xml) # libvirt_filter_dumpxml def libvirt_entries_in_filter_lists(self): diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py index 7af65fd..24b47e9 100644 --- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py +++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py @@ -102,20 +102,8 @@ def setup_second_guest(ip, virt, cxml2, ref): return PASS, "define" def get_dom_disk_src(xml, ip): - disk_list = [] - xml.dumpxml(ip) - myxml = xml.get_formatted_xml() - - lines = myxml.splitlines() - for l in lines: - if l.find("source file=") != -1: - disk = l.split('=')[1] - disk = disk.lstrip('\'') - disk = disk.rstrip('\'/>') - disk_list.append(disk) - - return disk_list + return xml.xdoc.xpath("/domain/devices/disk/source/@file") @do_main(sup_types) def main(): diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py index 9716cd1..42c59ec 100644 --- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py +++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py @@ -48,13 +48,13 @@ def main(): cxml.dumpxml(options.ip) - if cxml.xml_get_pae() == None: + if cxml.xml_get_pae() is None: raise Exception("Failed to set pae for dom: %s" % default_dom) - if cxml.xml_get_acpi() == None: + if cxml.xml_get_acpi() is None: raise Exception("Failed to set acpi for dom: %s" % default_dom) - if cxml.xml_get_apic() == None: + if cxml.xml_get_apic() is None: raise Exception("Failed to set apic for dom: %s" % default_dom) status = PASS diff --git a/suites/libvirt-cim/lib/XenKvmLib/test_xml.py b/suites/libvirt-cim/lib/XenKvmLib/test_xml.py index 033275b..b32ae4c 100755 --- a/suites/libvirt-cim/lib/XenKvmLib/test_xml.py +++ b/suites/libvirt-cim/lib/XenKvmLib/test_xml.py @@ -29,8 +29,7 @@ import os import sys import random from VirtLib import utils -from xml import xpath -from xml.dom import minidom, Node +from lxml import etree from CimTest.Globals import logger from XenKvmLib.test_doms import set_uuid, create_vnet from VirtLib.live import available_bridges @@ -212,22 +211,26 @@ def dumpxml(name, server, virt="Xen"): return o def get_value_xpath(xmlStr, xpathStr): - xmldoc = minidom.parseString(xmlStr) - nodes = xpath.Evaluate(xpathStr, xmldoc.documentElement) + xmldoc = etree.fromstring(xmlStr) + nodes = xmldoc.xpath(xpathStr) if len(nodes) != 1: raise LookupError('Zero or multiple xpath results found!') node = nodes[0] - if node.nodeType == Node.ATTRIBUTE_NODE: - return node.value - if node.nodeType == Node.TEXT_NODE: - return node.toxml() - if node.nodeType == Node.ELEMENT_NODE: + ret = '' + + if etree.iselement(node): + ret = node.text + for child in node: + ret = ret + child.text + elif isinstance(node, str): + ret = node + + if ret is None: ret = '' - for child in node.childNodes: - ret = ret + child.toxml() - return ret + + return ret def xml_get_dom_name(xmlStr): return get_value_xpath(xmlStr, diff --git a/suites/libvirt-cim/lib/XenKvmLib/vxml.py b/suites/libvirt-cim/lib/XenKvmLib/vxml.py index 15859c1..51a4166 100644 --- a/suites/libvirt-cim/lib/XenKvmLib/vxml.py +++ b/suites/libvirt-cim/lib/XenKvmLib/vxml.py @@ -34,15 +34,10 @@ import sys import random import platform import tempfile -from time import sleep import pywbem -from xml.dom import minidom, Node -from xml import xpath -try: - from xml.etree import cElementTree as ElementTree -except: - from xml.etree import ElementTree +from lxml import etree +from time import sleep from VirtLib import utils, live from XenKvmLib.xm_virt_util import get_bridge_from_network_xml, bootloader, \ @@ -64,35 +59,37 @@ class XMLClass: xdoc = None def __init__(self): - self.xdoc = minidom.Document() self.refresh() def __str__(self): return self.xml_string def refresh(self): - self.xml_string = self.xdoc.toxml() + if self.xdoc is not None: + self.xml_string = etree.tostring(self.xdoc) def get_node(self, ixpath): - node_list = xpath.Evaluate(ixpath, self.xdoc.documentElement) + if self.xdoc is None: + return None + + node_list = self.xdoc.xpath(ixpath) if len(node_list) != 1: raise LookupError('Zero or multiple nodes found for XPath' + ixpath) return node_list[0] + def add_sub_node(self, parent, node_name, text_cdata=None, **attrs): if isinstance(parent, basestring): pnode = self.get_node(parent) else: pnode = parent - node = self.xdoc.createElement(node_name) - - for key in attrs.keys(): - node.setAttribute(key, str(attrs[key])) - - if text_cdata is not None: - node.appendChild(self.xdoc.createTextNode(str(text_cdata))) + if pnode is None: + self.xdoc = etree.Element(node_name, **attrs) + node = self.xdoc + else: + node = etree.SubElement(pnode, node_name, **attrs) - pnode.appendChild(node) + node.text = str(text_cdata) self.refresh() return node @@ -103,13 +100,7 @@ class XMLClass: else: pnode = parent - for cnode in pnode.childNodes: - pnode.removeChild(cnode) - cnode.unlink() - - if text_cdata is not None: - pnode.appendChild(self.xdoc.createTextNode(str(text_cdata))) - + pnode.text = str(text_cdata) self.refresh() def set_attributes(self, node, **attrs): @@ -118,8 +109,8 @@ class XMLClass: else: pnode = node - for key in attrs.keys(): - pnode.setAttribute(key, str(attrs[key])) + for key, val in attrs.items(): + pnode.set(key, val) self.refresh() @@ -127,7 +118,7 @@ class XMLClass: '''Don't use this to define domain. Extra newline in the text node fails libvirt ''' - return self.xdoc.toprettyxml() + return etree.tostring(self.xdoc, pretty_print=True) def get_value_xpath(self, xpathStr): try: @@ -136,15 +127,19 @@ class XMLClass: logger.info('Zero or multiple node found') return None - if node.nodeType == Node.ATTRIBUTE_NODE: - return node.value - if node.nodeType == Node.TEXT_NODE: - return node.toxml() - if node.nodeType == Node.ELEMENT_NODE: + ret = '' + + if etree.iselement(node): + ret = node.text + for child in node: + ret = ret + child.text + elif isinstance(node, basestring): + ret = node + + if ret is None: ret = '' - for child in node.childNodes: - ret = ret + child.toxml() - return ret + + return ret class Virsh: @@ -220,7 +215,7 @@ class NetXML(Virsh, XMLClass): def _parse_net_dumpxml(_xml): try: - root = ElementTree.fromstring(_xml) + root = etree.fromstring(_xml) ip_element = root.find("ip") return ip_element.get("address") except: @@ -247,7 +242,7 @@ class NetXML(Virsh, XMLClass): return None else: self.xml_string = net_xml - self.xdoc = minidom.parseString(self.xml_string) + self.xdoc = etree.fromstring(self.xml_string) return network = self.add_sub_node(self.xdoc, 'network') @@ -337,7 +332,7 @@ class PoolXML(Virsh, XMLClass): return None else: self.xml_string = disk_xml - self.xdoc = minidom.parseString(self.xml_string) + self.xdoc = etree.fromstring(self.xml_string) return pool = self.add_sub_node(self.xdoc, 'pool', type='dir') @@ -547,8 +542,9 @@ class VirtXML(Virsh, XMLClass): cmd = 'virsh -c %s dumpxml %s 2>/dev/null' % (self.vuri, self.dname) s, o = utils.run_remote(ip, cmd) if s == 0: - self.xml_string = o - self.xdoc = minidom.parseString(self.xml_string) + o = "".join([i.strip() for i in o.split("\n") if i]) + self.xdoc = etree.fromstring(o) + self.refresh() def _set_emulator(self, emu): self.add_sub_node('/domain/devices', 'emulator', emu) @@ -562,7 +558,7 @@ class VirtXML(Virsh, XMLClass): # pick the 1st virtual bridge br = br_list[0] interface = self.get_node('/domain/devices/interface') - interface.setAttribute('type', 'bridge') + interface.set('type', 'bridge') self.add_sub_node(interface, 'source', bridge=br) return br @@ -570,20 +566,25 @@ class VirtXML(Virsh, XMLClass): def _set_vbridge(self, ip, virt_type, net_name): vbr = get_bridge_from_network_xml(net_name, ip, virt=virt_type) - interface = self.get_node('/domain/devices/interface') - interface.setAttribute('type', 'bridge') - self.add_sub_node(interface, 'source', bridge=vbr) + if vbr is not None: + interface = self.get_node('/domain/devices/interface') + interface.set('type', 'bridge') + self.add_sub_node(interface, 'source', bridge=vbr) return vbr def set_interface_details(self, devices, net_mac, net_type, net_name, virt_type): interface = self.add_sub_node(devices, 'interface', type=net_type) - self.add_sub_node(interface, 'mac', address=net_mac) + + if net_mac: + self.add_sub_node(interface, 'mac', address=net_mac) + if net_type == 'bridge': self._set_vbridge(CIM_IP, virt_type, net_name) elif net_type == 'network': - self.add_sub_node(interface, 'source', network=net_name) + if net_name: + self.add_sub_node(interface, 'source', network=net_name) elif net_type == 'ethernet': pass elif net_type == 'user': -- 1.7.4.4 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:18:58 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:18:58 +0800 Subject: [Libvirt-cim] [PATCH 00/15] vlan extension Message-ID: <1323249538-27410-1-git-send-email-xiawenc@linux.vnet.ibm.com> These patches would do following things: building up the network system CIM model, building up basic framework and functions below to implement the configuration, add the bridge and vlan802.1.q configuration capabilities in CIM model and library below. Now this patch implement the functionalities with commandline style, which means it depends on command ip, ifconfig, brctl and /proc/net/vlan/. In this way it is very sensitive to these command's output format. Maybe another implemetion could avoid that in the future. Since libvirt-cim is not a daemon program that would always be brought up when the emulator was up, so there lacks a mechnism to save the configuration and set them when system reboot, so these patch uses system directory /etc/sysconfig/network-script/ to store the settings. The things above means that a linux kernel later than 2.6 and RedHat distribution is needed. Other distriution may work but not tested. If the implemention goes to libvirt the restrict would be removed. Related profiles: the most important are DSP1050, DSP1097, DSP 2025(draft), Other are: DSP1041, DSP1014. Typical usage: assuming you have pNIC eth0. Use following xml files passed to wbemexec could create bridge testbr with eth0.10 attached, which means all VMs connecting to testbr would have access to IEEE802.1.q vlan 10. XML 1 Net_VirtualEthernetSwitchSystemManagementService Management Service KVM_HostSystem unknown instance of Net_VirtualEthernetSwitchSystemSettingData { VirtualSystemIdentifier ="VS_testbr1"; STP = 1; }; XML 2 Net_VirtualEthernetSwitchSystemManagementService Management Service KVM_HostSystem unknown Virt:VS_eth0 instance of Net_EthernetPortAllocationSettingData { InstanceID = "VS_eth0/EA_eth0.10"; ElementName = "EA_eth0.10"; VLANType = 1; Connection = {"VLAN10"}; ReorderHdr = 0; }; instance of Net_EthernetPortAllocationSettingData { InstanceID = "VS_eth0/EC_eth0.10"; HostResource = {"VS_testbr1"}; Parent = "EA_eth0.10"; }; Wayne Xia (15): vlan extension - makefile change vlan extension - CIM model - add class VESS vlan extension - CIM model - add class VESSSD vlan extension - CIM model - add class EthernetPort vlan extension - CIM model - add class EthernetPortAllocationSettingData vlan extension - CIM model - add association Net_SettingsDeineState vlan extension - CIM model - add association Net_SystemDevice vlan extension - CIM model - add association Net_VESSSDComponent vlan extension - CIM model - add association Net_ElementSettingData vlan extension - CIM model - add core class VESSMS vlan extension - CIM model - add help functions vlan extension - function lib - add the API vlan extension - function lib - add the core structure vlan extension - function lib - add the helper functions vlan extension - function lib - add the implemention of commandline Makefile.am | 16 +- libxkutil/Makefile.am | 11 +- libxkutil/host_network_API.c | 150 ++ libxkutil/host_network_API.h | 32 + libxkutil/host_network_basic.c | 639 +++++++ libxkutil/host_network_basic.h | 166 ++ libxkutil/host_network_error.h | 28 + libxkutil/host_network_helper.c | 659 +++++++ libxkutil/host_network_helper.h | 192 ++ libxkutil/host_network_implement_cmdline.c | 2002 ++++++++++++++++++++ libxkutil/host_network_implement_cmdline.h | 55 + libxkutil/network_model.c | 466 +++++ libxkutil/network_model.h | 105 + schema/ElementSettingData.mof | 16 +- schema/ElementSettingData.registration | 4 +- schema/EthernetPort.mof | 4 + schema/EthernetPort.registration | 3 + schema/EthernetPortAllocationSettingData.mof | 21 + .../EthernetPortAllocationSettingData.registration | 3 + schema/SettingsDefineState.mof | 9 +- schema/SettingsDefineState.registration | 3 +- schema/SystemDevice.mof | 18 +- schema/SystemDevice.registration | 3 +- schema/VESSSDComponent.mof | 8 + schema/VESSSDComponent.registration | 3 + schema/VirtualEthernetSwitchSystem.mof | 10 + schema/VirtualEthernetSwitchSystem.registration | 3 + ...irtualEthernetSwitchSystemManagementService.mof | 14 + ...ernetSwitchSystemManagementService.registration | 3 + schema/VirtualEthernetSwitchSystemSettingData.mof | 27 + ...ualEthernetSwitchSystemSettingData.registration | 3 + src/Makefile.am | 49 +- src/Virt_EASD.c | 733 +++++++ src/Virt_EASD.h | 61 + src/Virt_ElementSettingData.c | 229 +++- src/Virt_EthernetPort.c | 565 ++++++ src/Virt_EthernetPort.h | 58 + src/Virt_HostSystem.c | 2 +- src/Virt_HostSystem.h | 2 + src/Virt_SettingsDefineState.c | 256 +++ src/Virt_SystemDevice.c | 126 ++ src/Virt_VESSSD.c | 372 ++++ src/Virt_VESSSD.h | 39 + src/Virt_VESSSDComponent.c | 181 ++ src/Virt_VirtualEthernetSwitchSystem.c | 483 +++++ src/Virt_VirtualEthernetSwitchSystem.h | 52 + ..._VirtualEthernetSwitchSystemManagementService.c | 1342 +++++++++++++ ..._VirtualEthernetSwitchSystemManagementService.h | 31 + src/Virt_VirtualSystemManagementService.c | 17 +- src/Virt_VirtualSystemManagementService.h | 10 + 50 files changed, 9255 insertions(+), 29 deletions(-) create mode 100644 libxkutil/host_network_API.c create mode 100644 libxkutil/host_network_API.h create mode 100644 libxkutil/host_network_basic.c create mode 100644 libxkutil/host_network_basic.h create mode 100644 libxkutil/host_network_error.h create mode 100644 libxkutil/host_network_helper.c create mode 100644 libxkutil/host_network_helper.h create mode 100644 libxkutil/host_network_implement_cmdline.c create mode 100644 libxkutil/host_network_implement_cmdline.h create mode 100644 libxkutil/network_model.c create mode 100644 libxkutil/network_model.h create mode 100644 schema/EthernetPort.mof create mode 100644 schema/EthernetPort.registration create mode 100644 schema/EthernetPortAllocationSettingData.mof create mode 100644 schema/EthernetPortAllocationSettingData.registration create mode 100644 schema/VESSSDComponent.mof create mode 100644 schema/VESSSDComponent.registration create mode 100644 schema/VirtualEthernetSwitchSystem.mof create mode 100644 schema/VirtualEthernetSwitchSystem.registration create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.mof create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.registration create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.mof create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.registration create mode 100644 src/Virt_EASD.c create mode 100644 src/Virt_EASD.h create mode 100644 src/Virt_EthernetPort.c create mode 100644 src/Virt_EthernetPort.h create mode 100644 src/Virt_VESSSD.c create mode 100644 src/Virt_VESSSD.h create mode 100644 src/Virt_VESSSDComponent.c create mode 100644 src/Virt_VirtualEthernetSwitchSystem.c create mode 100644 src/Virt_VirtualEthernetSwitchSystem.h create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.c create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.h -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:21:03 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:21:03 +0800 Subject: [Libvirt-cim] [PATCH 01/15] vlan extension-makefile change Message-ID: <1323249663-27570-1-git-send-email-xiawenc@linux.vnet.ibm.com> this patch modifies the makefiles to add new files to be compiled Signed-off-by: Wayne Xia --- Makefile.am | 16 ++++++++++++++-- libxkutil/Makefile.am | 11 +++++++++-- src/Makefile.am | 49 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/Makefile.am b/Makefile.am index 5f004ec..32b84df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -63,7 +63,13 @@ MOFS = \ schema/EntriesInFilterList.mof \ schema/NestedFilterList.mof \ schema/AppliedFilterList.mof \ - schema/HostedFilterList.mof + schema/HostedFilterList.mof \ + schema/VirtualEthernetSwitchSystem.mof \ + schema/VirtualEthernetSwitchSystemManagementService.mof \ + schema/VirtualEthernetSwitchSystemSettingData.mof \ + schema/EthernetPort.mof \ + schema/EthernetPortAllocationSettingData.mof \ + schema/VESSSDComponent.mof INTEROP_MOFS = \ schema/ComputerSystem.mof \ @@ -150,7 +156,13 @@ REGS = \ schema/EntriesInFilterList.registration \ schema/NestedFilterList.registration \ schema/AppliedFilterList.registration \ - schema/HostedFilterList.registration + schema/HostedFilterList.registration \ + schema/VirtualEthernetSwitchSystem.registration \ + schema/VirtualEthernetSwitchSystemManagementService.registration \ + schema/VirtualEthernetSwitchSystemSettingData.registration \ + schema/EthernetPort.registration \ + schema/EthernetPortAllocationSettingData.registration \ + schema/VESSSDComponent.registration INTEROP_REGS = \ schema/RegisteredProfile.registration \ diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am index f6abce5..c5ac53c 100644 --- a/libxkutil/Makefile.am +++ b/libxkutil/Makefile.am @@ -5,12 +5,19 @@ AM_CFLAGS = $(CFLAGS_STRICT) \ -DLIBVIRTCIM_CONF=\"@sysconfdir@/@PACKAGE at .conf\" noinst_HEADERS = cs_util.h misc_util.h device_parsing.h xmlgen.h infostore.h \ - pool_parsing.h acl_parsing.h + pool_parsing.h acl_parsing.h \ + network_model.h \ + host_network_API.h host_network_basic.h host_network_helper.h \ + host_network_implement_cmdline.h host_network_error.h lib_LTLIBRARIES = libxkutil.la libxkutil_la_SOURCES = cs_util_instance.c misc_util.c device_parsing.c \ - xmlgen.c infostore.c pool_parsing.c acl_parsing.c + xmlgen.c infostore.c pool_parsing.c acl_parsing.c \ + network_model.c \ + host_network_API.c host_network_basic.c host_network_helper.c \ + host_network_implement_cmdline.c + libxkutil_la_LDFLAGS = -version-info @VERSION_INFO@ libxkutil_la_LIBADD = @LIBVIRT_LIBS@ \ @LIBUUID_LIBS@ diff --git a/src/Makefile.am b/src/Makefile.am index e4e8aa1..b067666 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,7 +25,12 @@ noinst_HEADERS = profiles.h svpc_types.h \ Virt_ConsoleRedirectionServiceCapabilities.h \ Virt_KVMRedirectionSAP.h \ Virt_FilterList.h \ - Virt_FilterEntry.h + Virt_FilterEntry.h \ + Virt_VirtualEthernetSwitchSystem.h \ + Virt_VirtualEthernetSwitchSystemManagementService.h \ + Virt_VESSSD.h \ + Virt_EthernetPort.h \ + Virt_EASD.h XKUADD = $(top_builddir)/libxkutil/libxkutil.la @@ -86,7 +91,13 @@ provider_LTLIBRARIES = libVirt_ComputerSystem.la \ libVirt_EntriesInFilterList.la \ libVirt_NestedFilterList.la \ libVirt_HostedFilterList.la \ - libVirt_AppliedFilterList.la + libVirt_AppliedFilterList.la \ + libVirt_VirtualEthernetSwitchSystem.la \ + libVirt_VirtualEthernetSwitchSystemManagementService.la \ + libVirt_VESSSD.la \ + libVirt_EthernetPort.la \ + libVirt_EASD.la \ + libVirt_VESSSDComponent.la libVirt_ComputerSystem_la_SOURCES = Virt_ComputerSystem.c libVirt_ComputerSystem_la_DEPENDENCIES = libVirt_VirtualSystemSnapshotService.la @@ -117,9 +128,9 @@ libVirt_VirtualSystemManagementCapabilities_la_DEPENDENCIES = libVirt_HostSystem libVirt_VirtualSystemManagementCapabilities_la_SOURCES = Virt_VirtualSystemManagementCapabilities.c libVirt_VirtualSystemManagementCapabilities_la_LIBADD = -lVirt_HostSystem -libVirt_SystemDevice_la_DEPENDENCIES = libVirt_ComputerSystem.la libVirt_Device.la +libVirt_SystemDevice_la_DEPENDENCIES = libVirt_ComputerSystem.la libVirt_Device.la libVirt_VirtualEthernetSwitchSystem.la libVirt_EthernetPort.la libVirt_SystemDevice_la_SOURCES = Virt_SystemDevice.c -libVirt_SystemDevice_la_LIBADD = -lVirt_ComputerSystem -lVirt_Device +libVirt_SystemDevice_la_LIBADD = -lVirt_ComputerSystem -lVirt_Device -lVirt_VirtualEthernetSwitchSystem -lVirt_EthernetPort libVirt_VSSD_la_SOURCES = Virt_VSSD.c libVirt_HostSystem_la_SOURCES = Virt_HostSystem.c @@ -188,9 +199,9 @@ libVirt_VSSDComponent_la_DEPENDENCIES = libVirt_VSSD.la libVirt_RASD.la libVirt_VSSDComponent_la_SOURCES = Virt_VSSDComponent.c libVirt_VSSDComponent_la_LIBADD = -lVirt_VSSD -lVirt_RASD -libVirt_SettingsDefineState_la_DEPENDENCIES = libVirt_Device.la libVirt_RASD.la libVirt_VSSD.la libVirt_ComputerSystem.la +libVirt_SettingsDefineState_la_DEPENDENCIES = libVirt_Device.la libVirt_RASD.la libVirt_VSSD.la libVirt_ComputerSystem.la libVirt_VirtualEthernetSwitchSystem.la libVirt_VESSSD.la libVirt_EASD.la libVirt_EthernetPort.la libVirt_SettingsDefineState_la_SOURCES = Virt_SettingsDefineState.c -libVirt_SettingsDefineState_la_LIBADD = -lVirt_Device -lVirt_RASD -lVirt_VSSD -lVirt_ComputerSystem +libVirt_SettingsDefineState_la_LIBADD = -lVirt_Device -lVirt_RASD -lVirt_VSSD -lVirt_ComputerSystem -lVirt_VirtualEthernetSwitchSystem -lVirt_VESSSD -lVirt_EASD -lVirt_EthernetPort libVirt_ResourceAllocationFromPool_la_DEPENDENCIES = libVirt_DevicePool.la libVirt_RASD.la libVirt_ResourceAllocationFromPool_la_SOURCES = Virt_ResourceAllocationFromPool.c @@ -204,9 +215,9 @@ libVirt_HostedService_la_DEPENDENCIES = libVirt_VirtualSystemManagementService.l libVirt_HostedService_la_SOURCES = Virt_HostedService.c libVirt_HostedService_la_LIBADD = -lVirt_VirtualSystemManagementService -lVirt_ResourcePoolConfigurationService -lVirt_VSMigrationService -lVirt_HostSystem -lVirt_ConsoleRedirectionService -libVirt_ElementSettingData_la_DEPENDENCIES = libVirt_VSSD.la libVirt_RASD.la +libVirt_ElementSettingData_la_DEPENDENCIES = libVirt_VSSD.la libVirt_RASD.la libVirt_EASD.la libVirt_VESSSD.la libVirt_EthernetPort.la libVirt_ElementSettingData_la_SOURCES = Virt_ElementSettingData.c -libVirt_ElementSettingData_la_LIBADD = -lVirt_VSSD -lVirt_RASD +libVirt_ElementSettingData_la_LIBADD = -lVirt_VSSD -lVirt_RASD -lVirt_EASD -lVirt_VESSSD -lVirt_EthernetPort libVirt_VSMigrationCapabilities_la_SOURCES = Virt_VSMigrationCapabilities.c @@ -275,3 +286,25 @@ libVirt_HostedFilterList_la_LIBADD = -lVirt_HostSystem -lVirt_FilterList libVirt_AppliedFilterList_la_DEPENDENCIES = libVirt_Device.la libVirt_FilterList.la libVirt_AppliedFilterList_la_SOURCES = Virt_AppliedFilterList.c libVirt_AppliedFilterList_la_LIBADD = -lVirt_Device -lVirt_FilterList + +libVirt_VirtualEthernetSwitchSystem_la_SOURCES = Virt_VirtualEthernetSwitchSystem.c + +libVirt_VESSSD_la_DEPENDENCIES = libVirt_VirtualEthernetSwitchSystem.la +libVirt_VESSSD_la_SOURCES = Virt_VESSSD.c +libVirt_VESSSD_la_LIBADD = -lVirt_VirtualEthernetSwitchSystem + +libVirt_EthernetPort_la_DEPENDENCIES = libVirt_EASD.la +libVirt_EthernetPort_la_SOURCES = Virt_EthernetPort.c +libVirt_EthernetPort_la_LIBADD = -lVirt_EASD + +libVirt_EASD_la_DEPENDENCIES = libVirt_VirtualEthernetSwitchSystem.la +libVirt_EASD_la_SOURCES = Virt_EASD.c +libVirt_EASD_la_LIBADD = -lVirt_VirtualEthernetSwitchSystem + +libVirt_VirtualEthernetSwitchSystemManagementService_la_DEPENDENCIES = libVirt_VirtualEthernetSwitchSystem.la libVirt_VESSSD.la libVirt_EASD.la libVirt_HostSystem.la libVirt_VirtualSystemManagementService.la +libVirt_VirtualEthernetSwitchSystemManagementService_la_SOURCES = Virt_VirtualEthernetSwitchSystemManagementService.c +libVirt_VirtualEthernetSwitchSystemManagementService_la_LIBADD = -lVirt_VirtualEthernetSwitchSystem -lVirt_VESSSD -lVirt_EASD -lVirt_HostSystem -lVirt_VirtualSystemManagementService + +libVirt_VESSSDComponent_la_DEPENDENCIES = libVirt_VESSSD.la libVirt_EASD.la +libVirt_VESSSDComponent_la_SOURCES = Virt_VESSSDComponent.c +libVirt_VESSSDComponent_la_LIBADD = -lVirt_VESSSD -lVirt_EASD -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:22:32 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:22:32 +0800 Subject: [Libvirt-cim] [PATCH 02/15] vlan extension - CIM model - add class VESS Message-ID: <1323249752-27626-1-git-send-email-xiawenc@linux.vnet.ibm.com> this patch added the Net_VirtualEthernetSwitchSystem class. Signed-off-by: Wayne Xia --- schema/VirtualEthernetSwitchSystem.mof | 10 + schema/VirtualEthernetSwitchSystem.registration | 3 + src/Virt_VirtualEthernetSwitchSystem.c | 483 +++++++++++++++++++++++ src/Virt_VirtualEthernetSwitchSystem.h | 52 +++ 4 files changed, 548 insertions(+), 0 deletions(-) create mode 100644 schema/VirtualEthernetSwitchSystem.mof create mode 100644 schema/VirtualEthernetSwitchSystem.registration create mode 100644 src/Virt_VirtualEthernetSwitchSystem.c create mode 100644 src/Virt_VirtualEthernetSwitchSystem.h diff --git a/schema/VirtualEthernetSwitchSystem.mof b/schema/VirtualEthernetSwitchSystem.mof new file mode 100644 index 0000000..5c016fd --- /dev/null +++ b/schema/VirtualEthernetSwitchSystem.mof @@ -0,0 +1,10 @@ +// Copyright IBM Corp. 2011 +[Description ( + "A class derived from CIM_ComputerSystem to represent " + "the Virtual Bridge on the host."), + Provider("cmpi::Virt_VirtualEthernetSwitchSystem") +] +class Net_VirtualEthernetSwitchSystem : CIM_ComputerSystem +{ + +}; diff --git a/schema/VirtualEthernetSwitchSystem.registration b/schema/VirtualEthernetSwitchSystem.registration new file mode 100644 index 0000000..4cd6bf4 --- /dev/null +++ b/schema/VirtualEthernetSwitchSystem.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2007 +# Classname Namespace ProviderName ProviderModule ProviderTypes +Net_VirtualEthernetSwitchSystem root/virt Virt_VirtualEthernetSwitchSystem Virt_VirtualEthernetSwitchSystem instance method diff --git a/src/Virt_VirtualEthernetSwitchSystem.c b/src/Virt_VirtualEthernetSwitchSystem.c new file mode 100644 index 0000000..1998205 --- /dev/null +++ b/src/Virt_VirtualEthernetSwitchSystem.c @@ -0,0 +1,483 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "cs_util.h" +#include +#include "misc_util.h" +#include "infostore.h" +#include "device_parsing.h" + +#include +#include +#include + +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_HostSystem.h" +#include "Virt_VirtualSystemSnapshotService.h" +#include "network_model.h" + +static const CMPIBroker *_BROKER; + +static int set_primary_for_switch(const CMPIBroker *broker, EthIface *piface, + CMPIInstance *instance) +{ + char *name; + uint16_t dedicated; + CMPIArray *array; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + if (piface->name == NULL) { + return 0; + } + + name = get_switch_name_from_iface(piface->name); + CMSetProperty(instance, "Name", + (CMPIValue *)name, CMPI_chars); + CMSetProperty(instance, "ElementName", + (CMPIValue *)name, CMPI_chars); + SAFE_FREE(name); + + array = CMNewArray(broker, 1, CMPI_uint16, &s); + if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array))) { + return 0; + } + dedicated = CIM_NUM_SWITCH_DEDICATED; + CMSetArrayElementAt(array, 0, &dedicated, CMPI_uint16); + CMSetProperty(instance, "Dedicated", + (CMPIValue *)&array, CMPI_uint16A); + + return 1; +} + +static int set_secondary_for_switch(const CMPIBroker *broker, EthIface *piface, + CMPIInstance *instance) +{ + int state; + if (piface->run_prop.state == ETH_STATE_DOWN) { + state = CIM_STATE_DISABLED; + } else if (piface->run_prop.state == ETH_STATE_UP) { + state = CIM_STATE_ENABLED; + } else { + state = CIM_STATE_UNKNOWN; + } + CMSetProperty(instance, "EnabledState", + (CMPIValue *)&state, CMPI_uint16); + CMSetProperty(instance, "RequestedState", + (CMPIValue *)&state, CMPI_uint16); + + return 1; +} + +/* Populate an instance with information from a switch */ +static CMPIStatus set_properties(const CMPIBroker *broker, + EthIface *piface, + const char *prefix, + CMPIInstance *instance) +{ + CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + char *errstr; + + if (!set_primary_for_switch(broker, piface, instance)) { + errstr = "failed to set primary properties for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + if (!set_secondary_for_switch(broker, piface, instance)) { + errstr = "failed to set secondary properties for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + cu_statusf(broker, &s, + CMPI_RC_OK, + ""); + + out: + return s; +} + +static CMPIStatus instance_from_switch(const CMPIBroker *broker, + const CMPIObjectPath *reference, + EthIface *piface, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + inst = get_typed_instance(broker, + NETWORK_CLASS_PREFIX, + "VirtualEthernetSwitchSystem", + NAMESPACE(reference)); + if (inst == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to init VirtualEthernetSwitchSystem instance"); + goto out; + } + + s = set_properties(broker, + piface, + NETWORK_CLASS_PREFIX, + inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + *_inst = inst; + + out: + return s; +} + +CMPIStatus enum_switches(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const CMPIResult *results, + bool names_only) +{ + struct inst_list list; + CMPIStatus s = {CMPI_RC_OK, NULL}; + EthIfacesList ifaces_list; + int ret, i; + char *errstr; + + inst_list_init(&list); + eth_ifaceslist_init(&ifaces_list); + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_switch, NULL); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + i = 0; + while (i < ifaces_list.count) { + CMPIInstance *inst = NULL; + + s = instance_from_switch(broker, + reference, + ifaces_list.pifaces[i], + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + inst_list_add(&list, inst); + i++; + } + + if (names_only) { + cu_return_instance_names(results, &list); + } else { + cu_return_instances(results, &list); + } + + out: + inst_list_free(&list); + eth_ifaceslist_uninit(&ifaces_list); + + return s; +} + +CMPIStatus get_switch_by_name(const CMPIBroker *broker, + const char *name, + const CMPIObjectPath *reference, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *eth_name = NULL; + char *errstr; + int ret; + EthIfacesList ifaces_list; + + eth_ifaceslist_init(&ifaces_list); + + eth_name = get_iface_name_from_switch(name); + if (eth_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to convert switch_name"); + CU_DEBUG("switch name %s failed to convert.", name); + goto out; + } + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_switch_for_name, eth_name); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + if (ifaces_list.count != 1) { + errstr = "expected switch not found."; + CU_DEBUG("%s\n", errstr); + eth_ifaceslist_print(&ifaces_list); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + s = instance_from_switch(broker, + reference, + ifaces_list.pifaces[0], + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + eth_ifaceslist_uninit(&ifaces_list); + SAFE_FREE(eth_name); + return s; +} + +CMPIStatus get_switch_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + const char *name = NULL; + + if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "No domain name specified"); + goto out; + } + + s = get_switch_by_name(broker, name, reference, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + s = cu_validate_ref(broker, reference, inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + + return s; +} + +static CMPIStatus __state_change(const CMPIBroker *broker, + const char *name, + uint16_t state, + const CMPIObjectPath *ref) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + EthIface iface; + int iface_state; + int ret; + char *errstr; + + eth_iface_init(&iface); + iface.name = get_iface_name_from_switch(name); + if (iface.name == NULL) { + errstr = "failed to get iface name."; + CU_DEBUG("for %s, %s.", name, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + if (state == CIM_STATE_ENABLED) { + iface_state = ETH_STATE_UP; + } else if (state == CIM_STATE_DISABLED) { + iface_state = ETH_STATE_DOWN; + } else { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_SUPPORTED, + "State not supported"); + goto out; + } + + ret = change_state_host_iface(&iface, iface_state); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + + out: + eth_iface_uninit(&iface); + return s; +} + +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference) +{ + return enum_switches(_BROKER, reference, results, true); +} + +static CMPIStatus EnumInstances(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + return enum_switches(_BROKER, reference, results, false); +} + +static CMPIStatus GetInstance(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + s = get_switch_by_ref(_BROKER, reference, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + CMReturnInstance(results, inst); + + out: + return s; +} + +DEFAULT_CI(); +DEFAULT_MI(); +DEFAULT_DI(); +DEFAULT_EQ(); +DEFAULT_INST_CLEANUP(); + +static CMPIStatus state_change(CMPIMethodMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIStatus s; + CMPIInstance *prev_inst = NULL; + uint16_t state; + int ret; + const char *name = NULL; + uint32_t rc = 1; + + ret = cu_get_u16_arg(argsin, "RequestedState", &state); + if (ret != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Invalid RequestedState"); + goto out; + } + + if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Name key not specified"); + goto out; + } + + s = get_switch_by_name(_BROKER, name, reference, &prev_inst); + if (s.rc != CMPI_RC_OK || prev_inst == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Unable to get instance for guest '%s'", + name); + goto out; + } + + s = __state_change(_BROKER, name, state, reference); + + if (s.rc == CMPI_RC_OK) { + rc = 0; + } + out: + CMReturnData(results, &rc, CMPI_uint32); + + return s; +} + +STD_InstanceMIStub(, + Virt_VirtualEthernetSwitchSystem, + _BROKER, + libvirt_cim_init()); + +static struct method_handler RequestStateChange = { + .name = "RequestStateChange", + .handler = state_change, + .args = {{"RequestedState", CMPI_uint16, false}, + {"TimeoutPeriod", CMPI_dateTime, true}, + ARG_END + } +}; + +static struct method_handler *my_handlers[] = { + &RequestStateChange, + NULL +}; + +STDIM_MethodMIStub(, + Virt_VirtualEthernetSwitchSystem, + _BROKER, + libvirt_cim_init(), + my_handlers); + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/src/Virt_VirtualEthernetSwitchSystem.h b/src/Virt_VirtualEthernetSwitchSystem.h new file mode 100644 index 0000000..de8587b --- /dev/null +++ b/src/Virt_VirtualEthernetSwitchSystem.h @@ -0,0 +1,52 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __VIRT_VIRTUALETHERNETSWITCHSYSTEM_H +#define __VIRT_VIRTUALETHERNETSWITCHSYSTEM_H + +#include "misc_util.h" + +CMPIStatus enum_switches(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const CMPIResult *results, + bool names_only); + +CMPIStatus get_switch_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + CMPIInstance **_inst); + + +CMPIStatus get_switch_by_name(const CMPIBroker *broker, + const char *name, + const CMPIObjectPath *reference, + CMPIInstance **_inst); + + +#endif + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:24:18 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:24:18 +0800 Subject: [Libvirt-cim] [PATCH 03/15] vlan extension - CIM model - add class VESSSD Message-ID: <1323249858-27682-1-git-send-email-xiawenc@linux.vnet.ibm.com> This patch added class the Net_VirtualEthernetSwitchSystemSettingData. Signed-off-by: Wayne Xia --- schema/VirtualEthernetSwitchSystemSettingData.mof | 27 ++ ...ualEthernetSwitchSystemSettingData.registration | 3 + src/Virt_VESSSD.c | 372 ++++++++++++++++++++ src/Virt_VESSSD.h | 39 ++ 4 files changed, 441 insertions(+), 0 deletions(-) create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.mof create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.registration create mode 100644 src/Virt_VESSSD.c create mode 100644 src/Virt_VESSSD.h diff --git a/schema/VirtualEthernetSwitchSystemSettingData.mof b/schema/VirtualEthernetSwitchSystemSettingData.mof new file mode 100644 index 0000000..81ef22a --- /dev/null +++ b/schema/VirtualEthernetSwitchSystemSettingData.mof @@ -0,0 +1,27 @@ +// Copyright IBM Corp. 2007 + + +/* fix me: the libvirt-cim lacks parent class + "VirtualEthernetSwitchSettingData" defined in DSP1050 */ +[Description ( + "A class derived from Virt_VirtualEthernetSystemSettingData to represent " + "the config of ."), + Provider("cmpi::Virt_VESSSD") +] +class Net_VirtualEthernetSwitchSystemSettingData : CIM_VirtualSystemSettingData +{ + + [Description ("Virtual Switch System type number")] + string VirtualSystemType; + + string AssociatedResourcePool; + + uint16 VLAN_Connection[]; + + uint16 MaxNumAddress; + + uint16 EVBMode; + + uint16 STP; + +}; diff --git a/schema/VirtualEthernetSwitchSystemSettingData.registration b/schema/VirtualEthernetSwitchSystemSettingData.registration new file mode 100644 index 0000000..14bfc30 --- /dev/null +++ b/schema/VirtualEthernetSwitchSystemSettingData.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2011 +# Classname Namespace ProviderName ProviderModule ProviderTypes +Net_VirtualEthernetSwitchSystemSettingData root/virt Virt_VESSSD Virt_VESSSD instance diff --git a/src/Virt_VESSSD.c b/src/Virt_VESSSD.c new file mode 100644 index 0000000..71627da --- /dev/null +++ b/src/Virt_VESSSD.c @@ -0,0 +1,372 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "cs_util.h" +#include "misc_util.h" +#include "device_parsing.h" + +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_VESSSD.h" +#include "network_model.h" + +static const CMPIBroker *_BROKER; + +static int set_primary_for_vesssd(const char *prefix, const CMPIBroker *broker, + EthIface *piface, CMPIInstance *instance) +{ + char *name, *vesssd_name; + int asret; + + if (piface->name == NULL) { + return 0; + } + + CMSetProperty(instance, "VirtualSystemType", + (CMPIValue *)"DMTF:VirtualEthernetSwitch", CMPI_chars); + + name = get_switch_name_from_iface(piface->name); + asret = asprintf(&vesssd_name, "%s:%s", prefix, name); + + CMSetProperty(instance, "InstanceID", + (CMPIValue *)vesssd_name, CMPI_chars); + CMSetProperty(instance, "ElementName", + (CMPIValue *)name, CMPI_chars); + CMSetProperty(instance, "VirtualSystemIdentifier", + (CMPIValue *)name, CMPI_chars); + CMSetProperty(instance, "VirtualSystemType", + (CMPIValue *)prefix, CMPI_chars); + + + + free(vesssd_name); + SAFE_FREE(name); + + return 1; +} + +static int set_secondary_for_vesssd(const CMPIBroker *broker, EthIface *piface, + CMPIInstance *instance) +{ + if (piface->eth_type == ETH_TYPE_BRIDGE) { + CMSetProperty(instance, "STP", + (CMPIValue *)&piface->pbr_prop->STP, CMPI_uint16); + } + + /* TODO add VLAN id discovery */ + return 1; +} + +/* Populate an instance with information from a switch */ +static CMPIStatus set_properties(const CMPIBroker *broker, + EthIface *piface, + const char *prefix, + CMPIInstance *instance) +{ + CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + char *errstr; + + if (!set_primary_for_vesssd(prefix, broker, piface, instance)) { + errstr = "failed to set primary properties for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + if (!set_secondary_for_vesssd(broker, piface, instance)) { + errstr = "failed to set secondary properties for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + cu_statusf(broker, &s, + CMPI_RC_OK, + ""); + + out: + return s; +} + +static CMPIStatus instance_from_vesssd(const CMPIBroker *broker, + const CMPIObjectPath *reference, + EthIface *piface, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + inst = get_typed_instance(broker, + NETWORK_CLASS_PREFIX, + "VirtualEthernetSwitchSystemSettingData", + NAMESPACE(reference)); + if (inst == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to init SwitchSystem instance"); + goto out; + } + + s = set_properties(broker, + piface, + VESSD_SYSTEM_PREFIX, + inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + return s; +} + +CMPIStatus enum_vesssd(const CMPIBroker *broker, + const CMPIObjectPath *reference, + struct inst_list *plist) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + EthIfacesList ifaces_list; + int ret, i; + char *errstr; + + eth_ifaceslist_init(&ifaces_list); + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_switch, NULL); + + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + i = 0; + while (i < ifaces_list.count) { + CMPIInstance *inst = NULL; + + s = instance_from_vesssd(broker, + reference, + ifaces_list.pifaces[i], + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(plist, inst); + i++; + } + + out: + eth_ifaceslist_uninit(&ifaces_list); + + return s; +} + +static CMPIStatus return_enum_vesssd(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const CMPIResult *results, + bool names_only) +{ + struct inst_list list; + CMPIStatus s = {CMPI_RC_OK, NULL}; + inst_list_init(&list); + + s = enum_vesssd(broker, reference, &list); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + if (names_only) { + cu_return_instance_names(results, &list); + } else { + cu_return_instances(results, &list); + } + out: + inst_list_free(&list); + return s; +} + +CMPIStatus get_vesssd_by_name(const CMPIBroker *broker, + const char *name, + const CMPIObjectPath *reference, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *eth_name = NULL; + char *errstr; + int ret; + EthIfacesList ifaces_list; + + eth_ifaceslist_init(&ifaces_list); + + eth_name = get_iface_name_from_switch(name); + if (eth_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to convert switch_name"); + CU_DEBUG("switch name %s failed to convert.", name); + goto out; + } + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_switch_for_name, eth_name); + + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + if (ifaces_list.count != 1) { + errstr = "expected switch not found."; + CU_DEBUG("%s\n", errstr); + eth_ifaceslist_print(&ifaces_list); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + s = instance_from_vesssd(broker, + reference, + ifaces_list.pifaces[0], + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + eth_ifaceslist_uninit(&ifaces_list); + SAFE_FREE(eth_name); + return s; +} + +CMPIStatus get_vesssd_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *name = NULL; + + if ((!parse_instanceid(reference, NULL, &name)) || (name == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "No such instance (InstanceID)"); + goto out; + } + + s = get_vesssd_by_name(broker, name, reference, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + s = cu_validate_ref(broker, reference, inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + free(name); + + return s; +} + +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference) +{ + return return_enum_vesssd(_BROKER, reference, results, true); +} + +static CMPIStatus EnumInstances(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + return return_enum_vesssd(_BROKER, reference, results, false); +} + +static CMPIStatus GetInstance(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + CMPIStatus s; + CMPIInstance *inst = NULL; + + s = get_vesssd_by_ref(_BROKER, reference, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + CMReturnInstance(results, inst); + + out: + return s; +} + +DEFAULT_CI(); +DEFAULT_MI(); +DEFAULT_DI(); +DEFAULT_EQ(); +DEFAULT_INST_CLEANUP(); + +STD_InstanceMIStub(, + Virt_VESSSD, + _BROKER, + libvirt_cim_init()); + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/src/Virt_VESSSD.h b/src/Virt_VESSSD.h new file mode 100644 index 0000000..5105057 --- /dev/null +++ b/src/Virt_VESSSD.h @@ -0,0 +1,39 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __VIRT_VESSSD_H +#define __VIRT_VESSSD_H + + +CMPIStatus enum_vesssd(const CMPIBroker *broker, + const CMPIObjectPath *reference, + struct inst_list *plist); + +CMPIStatus get_vesssd_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + CMPIInstance **_inst); + +CMPIStatus get_vesssd_by_name(const CMPIBroker *broker, + const char *name, + const CMPIObjectPath *reference, + CMPIInstance **_inst); + + +#endif -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:24:40 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:24:40 +0800 Subject: [Libvirt-cim] [PATCH 04/15] vlan extension - CIM model - add class EthernetPort Message-ID: <1323249880-27716-1-git-send-email-xiawenc@linux.vnet.ibm.com> adding the Net_EthernetPort class. Signed-off-by: Wayne Xia --- schema/EthernetPort.mof | 4 + schema/EthernetPort.registration | 3 + src/Virt_EthernetPort.c | 565 ++++++++++++++++++++++++++++++++++++++ src/Virt_EthernetPort.h | 58 ++++ 4 files changed, 630 insertions(+), 0 deletions(-) create mode 100644 schema/EthernetPort.mof create mode 100644 schema/EthernetPort.registration create mode 100644 src/Virt_EthernetPort.c create mode 100644 src/Virt_EthernetPort.h diff --git a/schema/EthernetPort.mof b/schema/EthernetPort.mof new file mode 100644 index 0000000..4a81c91 --- /dev/null +++ b/schema/EthernetPort.mof @@ -0,0 +1,4 @@ +// Copyright IBM Corp. 2011 +class Net_EthernetPort : CIM_EthernetPort +{ +}; diff --git a/schema/EthernetPort.registration b/schema/EthernetPort.registration new file mode 100644 index 0000000..67320d0 --- /dev/null +++ b/schema/EthernetPort.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2011 +# Classname Namespace ProviderName ProviderModule ProviderTypes +Net_EthernetPort root/virt Virt_EthernetPort Virt_EthernetPort instance diff --git a/src/Virt_EthernetPort.c b/src/Virt_EthernetPort.c new file mode 100644 index 0000000..751fb33 --- /dev/null +++ b/src/Virt_EthernetPort.c @@ -0,0 +1,565 @@ +/* + * Copyright IBM Corp. 2007 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "misc_util.h" +#include "cs_util.h" +#include "infostore.h" + +#include "Virt_EthernetPort.h" +#include "svpc_types.h" +#include "Virt_Device.h" +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_EASD.h" +#include "network_model.h" + +static const CMPIBroker *_BROKER; + +static int set_primary_for_ep(const CMPIBroker *broker, const char* prefix, + EthIface *piface, CMPIInstance *instance) +{ + char *eth_name, *ep_name; + const char *syscls_name = "Virt_VirtualEthernetSwitchSystem"; + int asret; + + if (piface->name == NULL) { + return 0; + } + + eth_name = get_ethport_name_from_iface(piface->name); + asret = asprintf(&ep_name, "%s/%s", prefix, eth_name); + + CMSetProperty(instance, "DeviceID", + (CMPIValue *)ep_name, CMPI_chars); + + CMSetProperty(instance, "InstanceID", + (CMPIValue *)ep_name, CMPI_chars); + + CMSetProperty(instance, "ElementName", + (CMPIValue *)eth_name, CMPI_chars); + SAFE_FREE(ep_name); + SAFE_FREE(eth_name); + + CMSetProperty(instance, "SystemCreationClassName", + (CMPIValue *)syscls_name, CMPI_chars); + + CMSetProperty(instance, "SystemName", + (CMPIValue *)prefix, CMPI_chars); + + return 1; +} + +static int set_secondary_for_ep(const CMPIBroker *broker, EthIface *piface, + CMPIInstance *instance) +{ + int state; + uint16_t cim_type; + CMPIArray *array; + CMPIStatus s; + CMPIString *str; + + if (piface->run_prop.state == ETH_STATE_DOWN) { + state = CIM_STATE_DISABLED; + } else if (piface->run_prop.state == ETH_STATE_UP) { + state = CIM_STATE_ENABLED; + } else { + state = CIM_STATE_UNKNOWN; + } + CMSetProperty(instance, "EnabledState", + (CMPIValue *)&state, CMPI_uint16); + CMSetProperty(instance, "RequestedState", + (CMPIValue *)&state, CMPI_uint16); + + cim_type = CIM_NUM_NET_ETHERNET; + CMSetProperty(instance, "LinkTechnology", + (CMPIValue *)&cim_type, CMPI_uint16); + + if (piface->mac != NULL) { + array = CMNewArray(broker, 1, CMPI_string, &s); + if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array))) { + CU_DEBUG("failed to create array."); + return 0; + } + str = CMNewString(broker, piface->mac, &s); + if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(str))) { + CU_DEBUG("failed to create array."); + return 0; + } + + CMSetArrayElementAt(array, 0, &str, CMPI_string); + + CMSetProperty(instance, "NetworkAddresses", + (CMPIValue *)&array, CMPI_stringA); + } + + return 1; +} + +static CMPIStatus set_properties(const CMPIBroker *broker, + EthIface *piface, + const char *prefix, + CMPIInstance *instance) +{ + CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + char *errstr; + + if (!set_primary_for_ep(broker, prefix, piface, instance)) { + errstr = "failed to set primary properties for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + if (!set_secondary_for_ep(broker, piface, instance)) { + errstr = "failed to set secondary properties for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + cu_statusf(broker, &s, + CMPI_RC_OK, + ""); + + out: + return s; +} + + +static CMPIStatus instance_from_ep_build(const CMPIBroker *broker, + EthIface *piface, + const char *prefix, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIInstance *inst = NULL; + CMPIStatus s = {CMPI_RC_OK, NULL}; + const char *keys[] = {"InstanceID", NULL}; + + inst = get_typed_instance(broker, + NETWORK_CLASS_PREFIX, + "EthernetPort", + NAMESPACE(reference)); + if (inst == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to init ep instance"); + goto out; + } + + s = CMSetPropertyFilter(inst, properties, keys); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Unable to set property filter: %d", s.rc); + } + + s = set_properties(broker, + piface, + prefix, + inst); + + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + return s; +} + + +static CMPIStatus instance_from_ep(const CMPIBroker *broker, + EthIface *piface, + const char *vsname, + const CMPIObjectPath *reference, + const char **properties, + struct inst_list *plist) +{ + + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *br1_name = NULL, *br2_name = NULL; + + get_possible_bridge_name_for_cim_model(piface, &br1_name, &br2_name); + if (br1_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to find any bridge for the port."); + CU_DEBUG("failed to find any bridge for the port %s.", + piface->name); + goto out; + } + + /* building up the instance */ + if ((vsname == NULL) || (0 == strcmp(vsname, br1_name))) { + inst = NULL; + s = instance_from_ep_build(broker, + piface, + br1_name, + reference, + properties, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + inst_list_add(plist, inst); + } + + /* following is to make it comform to CIM profile which require two + ethports connectted to pNIC and vswitch, but we have only one piface + on linux indicating it is connected to pNIC and bridge at sametime */ + if (br2_name == NULL) { + goto out; + } + + if ((vsname == NULL) || (0 == strcmp(vsname, br2_name))) { + inst = NULL; + s = instance_from_ep_build(broker, + piface, + br2_name, + reference, + properties, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + inst_list_add(plist, inst); + } + + + out: + SAFE_FREE(br1_name); + SAFE_FREE(br2_name); + return s; +} + +CMPIStatus get_ep_by_name(const CMPIBroker *broker, + const char *prefix, + const char *name, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *eth_name = NULL; + char *dest = NULL; + char *errstr; + int ret; + EthIfacesList ifaces_list; + struct inst_list list; + + eth_ifaceslist_init(&ifaces_list); + inst_list_init(&list); + + eth_name = get_iface_name_from_ethport(name); + if (eth_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to convert instance name"); + CU_DEBUG("ethport name %s failed to convert.", name); + goto out; + } + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_ethport_for_name, eth_name); + + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + if (ifaces_list.count != 1) { + errstr = "expected ethport not found."; + CU_DEBUG("%s\n", errstr); + eth_ifaceslist_print(&ifaces_list); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + inst = NULL; + s = instance_from_ep(broker, + ifaces_list.pifaces[0], + prefix, + reference, + properties, + &list); + + if (s.rc != CMPI_RC_OK) { + goto out; + } + + if (list.cur == 0) { + CU_DEBUG("%d instance found, expect is 1.", list.cur); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "no such instance."); + goto out; + } + + if (list.cur > 1) { + CU_DEBUG("%d instance found, expect is 1.", list.cur); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "instance found do not match expectation"); + goto out; + } + + *_inst = list.list[0]; + list.list[0] = NULL; + + out: + eth_ifaceslist_uninit(&ifaces_list); + inst_list_free(&list); + SAFE_FREE(eth_name); + SAFE_FREE(dest); + return s; +} + +CMPIStatus get_ep_by_id(const CMPIBroker *broker, + const char *id, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + char *prefix = NULL; + char *suffix = NULL; + if (id == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "ID is NULL'", id); + } + if (!parse_fq_devid(id, &prefix, &suffix) || (prefix == NULL) || + (suffix == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Invalid InstanceID `%s'", id); + goto out; + } + s = get_ep_by_name(broker, prefix, suffix, reference, + properties, _inst); + + out: + SAFE_FREE(prefix); + SAFE_FREE(suffix); + return s; +} + +CMPIStatus get_ep_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *name = NULL; + char *prefix = NULL; + const char *id; + + if (cu_get_str_path(reference, "DeviceID", &id) != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "No such instance (InstanceID)"); + goto out; + } + if ((!parse_fq_devid(id, &prefix, &name)) || + (name == NULL) || (prefix == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "Failed to translate (InstanceID)"); + goto out; + } + + s = get_ep_by_name(broker, prefix, name, reference, + properties, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + s = cu_validate_ref(broker, reference, inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + free(name); + free(prefix); + + return s; +} + + +CMPIStatus enum_eps(const CMPIBroker *broker, + const char *ref_vsname, + const CMPIObjectPath *reference, + const char **properties, + struct inst_list *plist) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + EthIfacesList ifaces_list; + int ret, i; + char *errstr; + + eth_ifaceslist_init(&ifaces_list); + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_ethport, NULL); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + CU_DEBUG("enum ep, found following devices.") + eth_ifaceslist_print(&ifaces_list); + + i = 0; + while (i < ifaces_list.count) { + s = instance_from_ep(broker, + ifaces_list.pifaces[i], + ref_vsname, + reference, + properties, + plist); + i++; + /* this should never fail */ + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("unexpected fail."); + break; + } + } + + + out: + eth_ifaceslist_uninit(&ifaces_list); + + return s; +} + +static CMPIStatus return_enum_eps(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const CMPIResult *results, + const char **properties, + const bool names_only) +{ + struct inst_list list; + CMPIStatus s = {CMPI_RC_OK, NULL}; + inst_list_init(&list); + s = enum_eps(broker, NULL, reference, properties, &list); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + if (names_only) { + cu_return_instance_names(results, &list); + } else { + cu_return_instances(results, &list); + } + + out: + inst_list_free(&list); + return s; +} + +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference) +{ + return return_enum_eps(_BROKER, reference, results, NULL, true); +} + +static CMPIStatus EnumInstances(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + + return return_enum_eps(_BROKER, reference, results, properties, false); +} + +static CMPIStatus GetInstance(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *ref, + const char **properties) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + s = get_ep_by_ref(_BROKER, ref, properties, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + CMReturnInstance(results, inst); + + out: + return s; +} + +DEFAULT_CI(); +DEFAULT_MI(); +DEFAULT_DI(); +DEFAULT_INST_CLEANUP(); +DEFAULT_EQ(); + +STD_InstanceMIStub(, + Virt_EthernetPort, + _BROKER, + libvirt_cim_init()); + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/src/Virt_EthernetPort.h b/src/Virt_EthernetPort.h new file mode 100644 index 0000000..f474af2 --- /dev/null +++ b/src/Virt_EthernetPort.h @@ -0,0 +1,58 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wencao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __VIRT_ETHERNETPORT_H +#define __VIRT_ETHERNETPORT_H + +CMPIStatus enum_eps(const CMPIBroker *broker, + const char *ref_vsname, + const CMPIObjectPath *reference, + const char **properties, + struct inst_list *plist); + +CMPIStatus get_ep_by_name(const CMPIBroker *broker, + const char *prefix, + const char *name, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst); + +CMPIStatus get_ep_by_id(const CMPIBroker *broker, + const char *id, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst); + +CMPIStatus get_ep_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst); + +#endif + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:38 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:38 +0800 Subject: [Libvirt-cim] [PATCH 05/15] vlan extension - CIM model - add class EASD Message-ID: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> add the class Net_EthernetPortAllocationSettingData. According To DSP1050, there are two kinds of EASD, EASD_EA and EASD_EC, which describe Ethernetprot settings and connection settings. Signed-off-by: Wayne Xia --- schema/EthernetPortAllocationSettingData.mof | 21 + .../EthernetPortAllocationSettingData.registration | 3 + src/Virt_EASD.c | 733 ++++++++++++++++++++ src/Virt_EASD.h | 61 ++ 4 files changed, 818 insertions(+), 0 deletions(-) create mode 100644 schema/EthernetPortAllocationSettingData.mof create mode 100644 schema/EthernetPortAllocationSettingData.registration create mode 100644 src/Virt_EASD.c create mode 100644 src/Virt_EASD.h diff --git a/schema/EthernetPortAllocationSettingData.mof b/schema/EthernetPortAllocationSettingData.mof new file mode 100644 index 0000000..8a1b38b --- /dev/null +++ b/schema/EthernetPortAllocationSettingData.mof @@ -0,0 +1,21 @@ +// Copyright IBM Corp. 2011 + +[Description ("Virtutal EthernetPort Setting Data"), + Provider("cmpi::Virt_EASD") +] + +class Net_EthernetPortAllocationSettingData : CIM_EthernetPortAllocationSettingData +{ + uint16 PortVID; + uint16 DesiredEndPointMode; + + [Description("VLAN type of the port, " + "Now only support IEEE 802.1.q."), + ValueMap { "0", "1", "2", "3" }, + Values { "Not VLAN", "IEEE 802.1.q", "IEEE 802.1.qbg", "IEEE 802.1.qbh" }] + uint16 VLANType; + + uint16 ReorderHdr; + string VLANQosIngress; + string VLANQosEgress; +}; diff --git a/schema/EthernetPortAllocationSettingData.registration b/schema/EthernetPortAllocationSettingData.registration new file mode 100644 index 0000000..bedd029 --- /dev/null +++ b/schema/EthernetPortAllocationSettingData.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2011 +# Classname Namespace ProviderName ProviderModule ProviderTypes +Net_EthernetPortAllocationSettingData root/virt Virt_EASD Virt_EASD instance diff --git a/src/Virt_EASD.c b/src/Virt_EASD.c new file mode 100644 index 0000000..cb786a5 --- /dev/null +++ b/src/Virt_EASD.c @@ -0,0 +1,733 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "misc_util.h" +#include "cs_util.h" +#include "infostore.h" + +#include "Virt_EASD.h" +#include "svpc_types.h" +#include "Virt_Device.h" +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "network_model.h" + +static const CMPIBroker *_BROKER; + +static int set_primary_for_easd(const CMPIBroker *broker, const char* prefix, + EthIface *piface, int type, CMPIInstance *instance) +{ + char *eth_name, *easd_name; + int asret; + uint16_t res_type = CIM_NUM_SWITCHPORT; + uint16_t vlan_mode; + + if (piface->name == NULL) { + return 0; + } + + eth_name = get_ethportsd_name_from_iface(piface->name, type); + asret = asprintf(&easd_name, "%s/%s", prefix, eth_name); + + CMSetProperty(instance, "InstanceID", + (CMPIValue *)easd_name, CMPI_chars); + CMSetProperty(instance, "ElementName", + (CMPIValue *)eth_name, CMPI_chars); + SAFE_FREE(easd_name); + SAFE_FREE(eth_name); + + CMSetProperty(instance, "ResourceType", + (CMPIValue *)&res_type, CMPI_uint16); + + if (piface->eth_type == ETH_TYPE_PHYSICAL) { + vlan_mode = CIM_NUM_VLAN_MODE_TRUNK; + CMSetProperty(instance, "DesiredEndPointMode", + (CMPIValue *)&vlan_mode, CMPI_uint16); + } + + + if (piface->mac != NULL) { + CMSetProperty(instance, "Address", + (CMPIValue *)piface->mac, CMPI_chars); + } + + return 1; +} + +static int set_secondary_for_easd(const CMPIBroker *broker, EthIface *piface, + CMPIInstance *instance) +{ + VLAN_Prop *pvlan; + VLAN_Prop_8021q *pvlan8021q; + uint16_t vid, hdr; + CMPIArray *conn_array; + CMPIString *cm_str; + char *str = NULL, *egress = NULL, *ingress = NULL; + CMPIStatus s; + int ret; + uint16_t vlantype = 0; + uint16_t visibility = CIM_NUM_CONSUMERVISIBILITY_VIRTUALIZED; + + if (piface->eth_type == ETH_TYPE_PHYSICAL) { + visibility = CIM_NUM_CONSUMERVISIBILITY_PASSEDTHROUGH; + } + CMSetProperty(instance, "ConsumerVisibility", + (CMPIValue *)&visibility, CMPI_uint16); + + if ((piface->eth_type != ETH_TYPE_VLAN) || + (piface->pvlan_prop == NULL)) { + goto out; + } + pvlan = piface->pvlan_prop; + + if (pvlan->vlan_type == VLAN_TYPE_802_1_Q) { + pvlan8021q = &(pvlan->props.prop_8021q); + vid = pvlan8021q->vlan_id; + CMSetProperty(instance, "PortVID", + (CMPIValue *)&vid, CMPI_uint16); + + str = vlanid_to_connection_name(vid); + conn_array = CMNewArray(broker, 1, CMPI_string, &s); + if ((s.rc != CMPI_RC_OK) || (str == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Error creating Connection " + "list and its string"); + CU_DEBUG("CMNewArray or string creation failed"); + goto out; + } + cm_str = CMNewString(broker, str, &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error creating CMPIString"); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Error creating CMPIString for " + "BootDevices item"); + + goto out; + } + CMSetArrayElementAt(conn_array, 0, (CMPIValue *)&cm_str, + CMPI_string); + CMSetProperty(instance, "Connection", + (CMPIValue *)&conn_array, CMPI_stringA); + hdr = pvlan8021q->reorder_hdr; + CMSetProperty(instance, "ReorderHdr", + (CMPIValue *)&hdr, CMPI_uint16); + + if ((pvlan8021q->ingress.count > 0) && + (pvlan8021q->ingress.count <= 8)) { + ret = vlan_8021q_qos_num_to_str(&ingress, + &(pvlan8021q->ingress)); + if (ret == 1) { + CMSetProperty(instance, "VLANQosIngress", + (CMPIValue *)ingress, CMPI_chars); + } else { + CU_DEBUG("failed to generate vlan qos " + "string."); + } + } + if ((pvlan8021q->egress.count > 0) && + (pvlan8021q->egress.count <= 8)) { + ret = vlan_8021q_qos_num_to_str(&egress, + &(pvlan8021q->egress)); + if (ret == 1) { + CMSetProperty(instance, "VLANQosEgress", + (CMPIValue *)egress, CMPI_chars); + } else { + CU_DEBUG("failed to generate vlan qos " + "string."); + } + } + vlantype = 1; + } + CMSetProperty(instance, "VLANType", + (CMPIValue *)&vlantype, CMPI_uint16); + +out: + SAFE_FREE(str); + SAFE_FREE(egress); + SAFE_FREE(ingress); + return 1; +} + +static CMPIStatus add_conn_properties(const CMPIBroker *broker, + EthIface *piface, + const char *prefix, + const char *dest, + CMPIInstance *instance) +{ + CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + char *eth_name, *easd_name; + int asret; + CMPIArray *array; + CMPIString *tmp; + + if (piface->name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "device name not set"); + goto out; + } + if (dest == NULL) { + CU_DEBUG("warn: connection dest is NULL."); + } + + eth_name = get_ethportsd_name_from_iface(piface->name, EASD_TYPE_EA); + asret = asprintf(&easd_name, "%s:%s", prefix, eth_name); + CMSetProperty(instance, "Parent", + (CMPIValue *)easd_name, CMPI_chars); + SAFE_FREE(easd_name); + SAFE_FREE(eth_name); + + array = CMNewArray(broker, 1, CMPI_string, &s); + tmp = CMNewString(broker, dest, NULL); + CMSetArrayElementAt(array, 0, &(tmp), CMPI_string); + CMSetProperty(instance, "HostResource", + (CMPIValue *)&array, CMPI_stringA); + + + out: + return s; +} + +static CMPIStatus set_properties(const CMPIBroker *broker, + EthIface *piface, + const char *prefix, + const char *dest, + int type, + CMPIInstance *instance) +{ + CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + char *errstr; + + if (!set_primary_for_easd(broker, prefix, piface, type, instance)) { + errstr = "failed to set primary properties for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + if (type == EASD_TYPE_EA) { + if (!set_secondary_for_easd(broker, piface, instance)) { + errstr = "failed to set secondary properties" + " for instance."; + CU_DEBUG("%s, iface name %s.", errstr, piface->name); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + } else { + s = add_conn_properties(broker, + piface, + prefix, + dest, + instance); + if (s.rc != CMPI_RC_OK) { + goto out; + } + } + + cu_statusf(broker, &s, + CMPI_RC_OK, + ""); + + out: + return s; +} + +static CMPIStatus instance_from_easd_build(const CMPIBroker *broker, + EthIface *piface, + const char *prefix, + const char *dest, + int type, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIInstance *inst = NULL; + CMPIStatus s = {CMPI_RC_OK, NULL}; + const char *keys[] = {"InstanceID", NULL}; + + inst = get_typed_instance(broker, + NETWORK_CLASS_PREFIX, + "EthernetPortAllocationSettingData", + NAMESPACE(reference)); + if (inst == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to init SwitchSystem instance"); + goto out; + } + + + s = CMSetPropertyFilter(inst, properties, keys); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Unable to set property filter: %d", s.rc); + } + + s = set_properties(broker, + piface, + prefix, + dest, + type, + inst); + + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + return s; +} + +/* vsname and req_type are filter conditions */ +static CMPIStatus instance_from_easd(const CMPIBroker *broker, + EthIface *piface, + const char *vsname, + int req_type, + const CMPIObjectPath *reference, + const char **properties, + struct inst_list *plist) +{ + + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *br1_name = NULL, *br2_name = NULL; + + CU_DEBUG("enter instance_for_easd with vsname %s, type %d.", + vsname, req_type); + get_possible_bridge_name_for_cim_model(piface, &br1_name, &br2_name); + if (br1_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to find any bridge for the port."); + CU_DEBUG("failed to find any bridge for the port %s.", + piface->name); + goto out; + } + + /* building the EA instance */ + if (!(req_type&EASD_TYPE_EA)) { + goto ea_build_end; + } + if ((vsname == NULL) || (0 == strcmp(vsname, br1_name))) { + inst = NULL; + s = instance_from_easd_build(broker, + piface, + br1_name, + NULL, + EASD_TYPE_EA, + reference, + properties, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + inst_list_add(plist, inst); + } + + /* following is to make it comform to CIM profile which require two + ethports connectted to pNIC and vswitch, but we have only one piface + on linux indicating it is connected to pNIC and bridge at sametime */ + if (br2_name == NULL) { + goto out; + } + + if ((vsname == NULL) || (0 == strcmp(vsname, br2_name))) { + inst = NULL; + s = instance_from_easd_build(broker, + piface, + br2_name, + NULL, + EASD_TYPE_EA, + reference, + properties, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + inst_list_add(plist, inst); + } + ea_build_end: + + /* building the EC instance */ + if (!(req_type&EASD_TYPE_EC)) { + goto ec_build_end; + } + if ((br1_name == NULL) || (br2_name == NULL)) { + goto ec_build_end; + } + /* connection exist, so a EC_easd should be added for each bridge */ + if ((vsname == NULL) || (0 == strcmp(vsname, br1_name))) { + inst = NULL; + s = instance_from_easd_build(broker, + piface, + br1_name, + br2_name, + EASD_TYPE_EC, + reference, + properties, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + inst_list_add(plist, inst); + } + if ((vsname == NULL) || (0 == strcmp(vsname, br2_name))) { + inst = NULL; + s = instance_from_easd_build(broker, + piface, + br2_name, + br1_name, + EASD_TYPE_EC, + reference, + properties, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + inst_list_add(plist, inst); + } + ec_build_end: + + out: + SAFE_FREE(br1_name); + SAFE_FREE(br2_name); + return s; +} + +CMPIStatus get_easd_by_name(const CMPIBroker *broker, + const char *prefix, + const char *name, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *eth_name = NULL; + char *dest = NULL; + char *errstr; + int ret; + int type; + EthIfacesList ifaces_list; + struct inst_list list; + + CU_DEBUG("####prefix %s", prefix); + eth_ifaceslist_init(&ifaces_list); + inst_list_init(&list); + + eth_name = get_iface_name_from_ethportsd(name, &type); + if (eth_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to convert instance name"); + CU_DEBUG("ethport name %s failed to convert.", name); + goto out; + } + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_ethport_for_name, eth_name); + + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + if (ifaces_list.count != 1) { + errstr = "expected ethport not found."; + CU_DEBUG("%d ethportd found.", ifaces_list.count); + eth_ifaceslist_print(&ifaces_list); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + inst = NULL; + s = instance_from_easd(broker, + ifaces_list.pifaces[0], + prefix, + type, + reference, + properties, + &list); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + if (list.cur == 0) { + CU_DEBUG("%d instance found, expect is 1.", list.cur); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "no such instance."); + goto out; + } + + if (list.cur > 1) { + CU_DEBUG("%d instance found, expect is 1.", list.cur); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "instance found do not match expectation"); + goto out; + } + + *_inst = list.list[0]; + list.list[0] = NULL; + + out: + eth_ifaceslist_uninit(&ifaces_list); + inst_list_free(&list); + SAFE_FREE(eth_name); + SAFE_FREE(dest); + return s; +} + +CMPIStatus get_easd_by_id(const CMPIBroker *broker, + const char *id, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + char *prefix = NULL; + char *suffix = NULL; + if (id == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "ID is NULL'", id); + } + if (!parse_fq_devid(id, &prefix, &suffix) || (prefix == NULL) || + (suffix == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Invalid InstanceID `%s'", id); + goto out; + } + s = get_easd_by_name(broker, prefix, suffix, reference, + properties, _inst); + + out: + SAFE_FREE(prefix); + SAFE_FREE(suffix); + return s; +} + +CMPIStatus get_easd_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *name = NULL; + char *prefix = NULL; + const char *id; + + if (cu_get_str_path(reference, "InstanceID", &id) != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "No such instance (InstanceID)"); + goto out; + } + if ((!parse_fq_devid(id, &prefix, &name)) || + (name == NULL) || (prefix == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "Failed to translate (InstanceID)"); + goto out; + } + + s = get_easd_by_name(broker, prefix, name, reference, + properties, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + s = cu_validate_ref(broker, reference, inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + *_inst = inst; + + out: + free(name); + free(prefix); + + return s; +} + + +CMPIStatus enum_easds(const CMPIBroker *broker, + const char *ref_vsname, + const CMPIObjectPath *reference, + const char **properties, + struct inst_list *plist) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + EthIfacesList ifaces_list; + int ret, i; + char *errstr; + + eth_ifaceslist_init(&ifaces_list); + + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_cim_ethport, NULL); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + CU_DEBUG("enum easd, found following devices.") + eth_ifaceslist_print(&ifaces_list); + + i = 0; + while (i < ifaces_list.count) { + s = instance_from_easd(broker, + ifaces_list.pifaces[i], + ref_vsname, + EASD_TYPE_EA|EASD_TYPE_EC, + reference, + properties, + plist); + i++; + /* this should never fail */ + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("unexpected fail."); + break; + } + } + + + out: + eth_ifaceslist_uninit(&ifaces_list); + + return s; +} + +static CMPIStatus return_enum_easds(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const CMPIResult *results, + const char **properties, + const bool names_only) +{ + struct inst_list list; + CMPIStatus s = {CMPI_RC_OK, NULL}; + inst_list_init(&list); + s = enum_easds(broker, NULL, reference, properties, &list); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + if (names_only) { + cu_return_instance_names(results, &list); + } else { + cu_return_instances(results, &list); + } + + out: + inst_list_free(&list); + return s; +} + +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference) +{ + return return_enum_easds(_BROKER, reference, results, + NULL, true); +} + +static CMPIStatus EnumInstances(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + + return return_enum_easds(_BROKER, reference, results, + properties, false); +} + +static CMPIStatus GetInstance(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *ref, + const char **properties) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + s = get_easd_by_ref(_BROKER, ref, properties, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + CMReturnInstance(results, inst); + + out: + return s; +} + +DEFAULT_CI(); +DEFAULT_MI(); +DEFAULT_DI(); +DEFAULT_INST_CLEANUP(); +DEFAULT_EQ(); + +STD_InstanceMIStub(, + Virt_EASD, + _BROKER, + libvirt_cim_init()); + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/src/Virt_EASD.h b/src/Virt_EASD.h new file mode 100644 index 0000000..215553b --- /dev/null +++ b/src/Virt_EASD.h @@ -0,0 +1,61 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __VIRT_EASD_H +#define __VIRT_EASD_H + +#include "device_parsing.h" + +CMPIStatus enum_easds(const CMPIBroker *broker, + const char *ref_vsname, + const CMPIObjectPath *reference, + const char **properties, + struct inst_list *plist); + +CMPIStatus get_easd_by_name(const CMPIBroker *broker, + const char *prefix, + const char *name, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst); + +CMPIStatus get_easd_by_id(const CMPIBroker *broker, + const char *id, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst); + +CMPIStatus get_easd_by_ref(const CMPIBroker *broker, + const CMPIObjectPath *reference, + const char **properties, + CMPIInstance **_inst); + + +#endif + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:39 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:39 +0800 Subject: [Libvirt-cim] [PATCH 06/15] vlan extension - CIM model - add association Net_SettingsDeineState In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-2-git-send-email-xiawenc@linux.vnet.ibm.com> add the association of Net_SettingSDefineState. Signed-off-by: Wayne Xia --- schema/SettingsDefineState.mof | 9 +- schema/SettingsDefineState.registration | 3 +- src/Virt_SettingsDefineState.c | 256 +++++++++++++++++++++++++++++++ 3 files changed, 266 insertions(+), 2 deletions(-) diff --git a/schema/SettingsDefineState.mof b/schema/SettingsDefineState.mof index 7664ae2..1ee6698 100644 --- a/schema/SettingsDefineState.mof +++ b/schema/SettingsDefineState.mof @@ -1,4 +1,4 @@ -// Copyright IBM Corp. 2007 +// Copyright IBM Corp. 2011 [Association, Provider("cmpi::Virt_SettingsDefineState") @@ -20,3 +20,10 @@ class KVM_SettingsDefineState : CIM_SettingsDefineState class LXC_SettingsDefineState : CIM_SettingsDefineState { }; + +[Association, + Provider("cmpi::Virt_SettingsDefineState") +] +class Net_SettingsDefineState : CIM_SettingsDefineState +{ +}; diff --git a/schema/SettingsDefineState.registration b/schema/SettingsDefineState.registration index 0563491..b5e03ba 100644 --- a/schema/SettingsDefineState.registration +++ b/schema/SettingsDefineState.registration @@ -1,5 +1,6 @@ -# Copyright IBM Corp. 2007 +# Copyright IBM Corp. 2011 # Classname Namespace ProviderName ProviderModule ProviderTypes Xen_SettingsDefineState root/virt Virt_SettingsDefineState Virt_SettingsDefineState association KVM_SettingsDefineState root/virt Virt_SettingsDefineState Virt_SettingsDefineState association LXC_SettingsDefineState root/virt Virt_SettingsDefineState Virt_SettingsDefineState association +Net_SettingsDefineState root/virt Virt_SettingsDefineState Virt_SettingsDefineState association diff --git a/src/Virt_SettingsDefineState.c b/src/Virt_SettingsDefineState.c index b4e4b80..ae7054f 100644 --- a/src/Virt_SettingsDefineState.c +++ b/src/Virt_SettingsDefineState.c @@ -4,6 +4,9 @@ * Authors: * Dan Smith * + * Modified by: + * Wenchao Xia + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -36,6 +39,11 @@ #include "Virt_ComputerSystem.h" #include "Virt_VSSD.h" #include "svpc_types.h" +#include "Virt_VESSSD.h" +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_EASD.h" +#include "Virt_EthernetPort.h" +#include "network_model.h" const static CMPIBroker *_BROKER; @@ -319,6 +327,172 @@ static CMPIStatus vssd_to_vs(const CMPIObjectPath *ref, return s; } +static CMPIStatus vess_to_vesssd(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst; + const char *name = NULL; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + /* the step of creating a vess instance is skipped to make it fast */ + if (cu_get_str_path(ref, "Name", &name) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing Name property"); + goto out; + } + + CU_DEBUG("vess to vesssd , name %s", name); + s = get_vesssd_by_name(_BROKER, name, ref, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + return s; +} + +static CMPIStatus vesssd_to_vess(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + const char *id = NULL; + char *pfx = NULL; + char *name = NULL; + int ret; + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* the step of creating a vesssd instance is skipped to make it fast */ + if (cu_get_str_path(ref, "InstanceID", &id) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing InstanceID"); + goto out; + } + + ret = sscanf(id, "%a[^:]:%as", &pfx, &name); + if (ret != 2) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Invalid InstanceID"); + goto out; + } + + CU_DEBUG("vesssd to vess , name %s", name); + s = get_switch_by_name(_BROKER, name, ref, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + free(name); + free(pfx); + + return s; +} + +/* according to DSP 1050.1.0.0_0 page 41, SDS only associate EP with EASD_EA */ +static CMPIStatus ep_to_easd(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *newid = NULL; + const char *name; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* the step of creating a ep instance is skipped to make it fast */ + if (cu_get_str_path(ref, "DeviceID", &name) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "No DeviceID specified"); + goto out; + } + + newid = ep_id_to_easdea_id(name); + if (newid == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_NOT_FOUND, + "Invalid DeviceID set."); + goto out; + } + + s = get_easd_by_id(_BROKER, + newid, + ref, + NULL, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + free(newid); + return s; +} + +static CMPIStatus easd_to_ep(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + const char *name = NULL; + char *newid = NULL; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* the step of creating a easd instance is skipped to make it fast */ + + if (cu_get_str_path(ref, "InstanceID", &name) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing InstanceID"); + goto out; + } + newid = easdea_id_to_ep_id(name); + + if (newid == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_NOT_FOUND, + "Invalid InstanceID set."); + goto out; + } + + s = get_ep_by_id(_BROKER, newid, ref, NULL, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + + out: + free(newid); + return s; +} + LIBVIRT_CIM_DEFAULT_MAKEREF() static char* logical_device[] = { @@ -386,6 +560,32 @@ static char* assoc_classname[] = { NULL }; + +static char *vess_name[] = { + "Net_VirtualEthernetSwitchSystem", + NULL +}; + +static char *vesssd_name[] = { + "Net_VirtualEthernetSwitchSystemSettingData", + NULL +}; + +static char *ep_name[] = { + "Net_EthernetPort", + NULL +}; + +static char *easd_name[] = { + "Net_EthernetPortAllocationSettingData", + NULL +}; + +static char *vess_assoc_name[] = { + "Net_SettingsDefineState", + NULL +}; + static struct std_assoc _dev_to_rasd = { .source_class = (char**)&logical_device, .source_prop = "ManagedElement", @@ -438,11 +638,67 @@ static struct std_assoc _vssd_to_vs = { .make_ref = make_ref }; +static struct std_assoc _vess_to_vesssd = { + .source_class = (char **)&vess_name, + .source_prop = "ManagedElement", + + .target_class = (char **)&vesssd_name, + .target_prop = "SettingData", + + .assoc_class = (char **)&vess_assoc_name, + + .handler = vess_to_vesssd, + .make_ref = make_ref +}; + +static struct std_assoc _vesssd_to_vess = { + .source_class = (char **)&vesssd_name, + .source_prop = "SettingData", + + .target_class = (char **)&vess_name, + .target_prop = "ManagedElement", + + .assoc_class = (char **)&vess_assoc_name, + + .handler = vesssd_to_vess, + .make_ref = make_ref +}; + +static struct std_assoc _ep_to_easd = { + .source_class = (char **)&ep_name, + .source_prop = "ManagedElement", + + .target_class = (char **)&easd_name, + .target_prop = "SettingData", + + .assoc_class = (char **)&vess_assoc_name, + + .handler = ep_to_easd, + .make_ref = make_ref +}; + +static struct std_assoc _easd_to_ep = { + .source_class = (char **)&easd_name, + .source_prop = "SettingData", + + .target_class = (char **)&ep_name, + .target_prop = "ManagedElement", + + .assoc_class = (char **)&vess_assoc_name, + + .handler = easd_to_ep, + .make_ref = make_ref +}; + static struct std_assoc *handlers[] = { &_dev_to_rasd, &_rasd_to_dev, &_vs_to_vssd, &_vssd_to_vs, + &_vess_to_vesssd, + &_vesssd_to_vess, + &_ep_to_easd, + &_easd_to_ep, NULL }; -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:40 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:40 +0800 Subject: [Libvirt-cim] [PATCH 07/15] vlan extension - CIM model - add association VESSD. In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-3-git-send-email-xiawenc@linux.vnet.ibm.com> add the class Net_VirtualEthernetSwitchSystemDevice. Signed-off-by: Wayne Xia --- schema/SystemDevice.mof | 18 +++++- schema/SystemDevice.registration | 3 +- src/Virt_SystemDevice.c | 126 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 2 deletions(-) diff --git a/schema/SystemDevice.mof b/schema/SystemDevice.mof index e13b265..13f45ae 100644 --- a/schema/SystemDevice.mof +++ b/schema/SystemDevice.mof @@ -1,4 +1,4 @@ -// Copyright IBM Corp. 2007 +// Copyright IBM Corp. 2011 [Association, Description ( @@ -47,3 +47,19 @@ class LXC_SystemDevice : CIM_SystemDevice CIM_LogicalDevice REF PartComponent; }; + +[Association, + Description ( + "A class to associate switch system." ), + Provider("cmpi::Virt_SwitchSystemDevice") +] +class Net_VirtualEthernetSwitchSystemDevice : CIM_SystemDevice +{ + + [Override ( "GroupComponent" )] + Net_VirtualEthernetSwitchSystem REF GroupComponent; + + [Override ( "PartComponent" )] + Net_EthernetPort REF PartComponent; + +}; diff --git a/schema/SystemDevice.registration b/schema/SystemDevice.registration index d6c331d..83dcbc6 100644 --- a/schema/SystemDevice.registration +++ b/schema/SystemDevice.registration @@ -1,5 +1,6 @@ -# Copyright IBM Corp. 2007 +# Copyright IBM Corp. 2011 # Classname Namespace ProviderName ProviderModule ProviderTypes Xen_SystemDevice root/virt Virt_SystemDevice Virt_SystemDevice association KVM_SystemDevice root/virt Virt_SystemDevice Virt_SystemDevice association LXC_SystemDevice root/virt Virt_SystemDevice Virt_SystemDevice association +Net_VirtualEthernetSwitchSystemDevice root/virt Virt_SystemDevice Virt_SystemDevice association diff --git a/src/Virt_SystemDevice.c b/src/Virt_SystemDevice.c index 31d6b61..0b166fa 100644 --- a/src/Virt_SystemDevice.c +++ b/src/Virt_SystemDevice.c @@ -6,6 +6,9 @@ * Jay Gagnon * Zhengang Li * + * Modified by: + * Wenchao Xia + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -37,6 +40,8 @@ #include "Virt_ComputerSystem.h" #include "Virt_Device.h" +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_EthernetPort.h" /* Associate an XXX_ComputerSystem to the proper XXX_LogicalDisk * and XXX_NetworkPort instances. @@ -44,6 +49,11 @@ * -- or -- * * Associate an XXX_LogicalDevice to the proper XXX_ComputerSystem + * + * -- or -- + * + * Virtual Ethernet Switch System with Ethernet Port + * */ const static CMPIBroker *_BROKER; @@ -120,6 +130,79 @@ static CMPIStatus dev_to_sys(const CMPIObjectPath *ref, return s; } +static CMPIStatus vess_to_ep(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + const char *host = NULL; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* the step of creating a vess instance is skipped to make it fast */ + if (cu_get_str_path(ref, "Name", &host) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing Name"); + goto out; + } + + s = enum_eps(_BROKER, + host, + ref, + info->properties, + list); + + + out: + return s; +} + +static CMPIStatus ep_to_vess(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + const char *devid = NULL; + char *host = NULL; + char *dev = NULL; + CMPIInstance *inst = NULL; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* the step of creating a ep instance is skipped to make it fast */ + + if (cu_get_str_path(ref, "DeviceID", &devid) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing DeviceID"); + goto out; + } + + if (!parse_fq_devid(devid, &host, &dev)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Invalid DeviceID"); + goto out; + } + + s = get_switch_by_name(_BROKER, host, ref, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + free(host); + free(dev); + return s; +} + LIBVIRT_CIM_DEFAULT_MAKEREF() static char* group_component[] = { @@ -158,6 +241,21 @@ static char* assoc_classname[] = { NULL }; +static char *vess_group_component[] = { + "Net_VirtualEthernetSwitchSystem", + NULL +}; + +static char *vess_part_component[] = { + "Net_EthernetPort", + NULL +}; + +static char *vess_assoc_classname[] = { + "Net_VirtualEthernetSwitchSystemDevice", + NULL +}; + static struct std_assoc forward = { .source_class = (char**)&group_component, .source_prop = "GroupComponent", @@ -184,9 +282,37 @@ static struct std_assoc backward = { .make_ref = make_ref }; +static struct std_assoc assoc_vess_to_ep = { + .source_class = (char **)&vess_group_component, + .source_prop = "GroupComponent", + + .target_class = (char **)&vess_part_component, + .target_prop = "PartComponent", + + .assoc_class = (char **)&vess_assoc_classname, + + .handler = vess_to_ep, + .make_ref = make_ref +}; + +static struct std_assoc assoc_ep_to_vess = { + .source_class = (char **)&vess_part_component, + .source_prop = "PartComponent", + + .target_class = (char **)&vess_group_component, + .target_prop = "GroupComponent", + + .assoc_class = (char **)&vess_assoc_classname, + + .handler = ep_to_vess, + .make_ref = make_ref +}; + static struct std_assoc *assoc_handlers[] = { &forward, &backward, + &assoc_vess_to_ep, + &assoc_ep_to_vess, NULL }; -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:42 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:42 +0800 Subject: [Libvirt-cim] [PATCH 09/15] vlan extension - CIM model - add association Net_ElementSettingData In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-5-git-send-email-xiawenc@linux.vnet.ibm.com> add two association class accroding to DSP1050, Net_ElementSettingData and Net_EthernetPortConnectionSettingData. Signed-off-by: Wayne Xia --- schema/ElementSettingData.mof | 16 ++- schema/ElementSettingData.registration | 4 +- src/Virt_ElementSettingData.c | 229 +++++++++++++++++++++++++++++++- 3 files changed, 246 insertions(+), 3 deletions(-) diff --git a/schema/ElementSettingData.mof b/schema/ElementSettingData.mof index 2bfc52a..9ba116f 100644 --- a/schema/ElementSettingData.mof +++ b/schema/ElementSettingData.mof @@ -1,4 +1,4 @@ -// Copyright IBM Corp. 2007 +// Copyright IBM Corp. 2011 [Association, Provider("cmpi::Virt_ElementSettingData") @@ -20,3 +20,17 @@ class KVM_ElementSettingData : CIM_ElementSettingData class LXC_ElementSettingData : CIM_ElementSettingData { }; + +[Association, + Provider("cmpi::Virt_ElementSettingData") +] +class Net_ElementSettingData : CIM_ElementSettingData +{ +}; + +[Association, + Provider("cmpi::Virt_ElementSettingData") +] +class Net_EthernetPortConnectionSettingData : CIM_ElementSettingData +{ +}; diff --git a/schema/ElementSettingData.registration b/schema/ElementSettingData.registration index edec78c..8cff13b 100644 --- a/schema/ElementSettingData.registration +++ b/schema/ElementSettingData.registration @@ -1,5 +1,7 @@ -# Copyright IBM Corp. 2007 +# Copyright IBM Corp. 2011 # Classname Namespace ProviderName ProviderModule ProviderTypes Xen_ElementSettingData root/virt Virt_ElementSettingData Virt_ElementSettingData association KVM_ElementSettingData root/virt Virt_ElementSettingData Virt_ElementSettingData association LXC_ElementSettingData root/virt Virt_ElementSettingData Virt_ElementSettingData association +Net_ElementSettingData root/virt Virt_ElementSettingData Virt_ElementSettingData association +Net_EthernetPortConnectionSettingData root/virt Virt_ElementSettingData Virt_ElementSettingData association diff --git a/src/Virt_ElementSettingData.c b/src/Virt_ElementSettingData.c index b5b7b02..269b3d2 100644 --- a/src/Virt_ElementSettingData.c +++ b/src/Virt_ElementSettingData.c @@ -1,9 +1,12 @@ /* - * Copyright IBM Corp. 2007 + * Copyright IBM Corp. 2011 * * Authors: * Kaitlin Rupert * + * Modified by: + * Wenchao Xia + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -32,6 +35,10 @@ #include "Virt_VSSD.h" #include "Virt_RASD.h" +#include "Virt_VESSSD.h" +#include "Virt_EASD.h" +#include "Virt_EthernetPort.h" +#include "network_model.h" const static CMPIBroker *_BROKER; @@ -81,6 +88,145 @@ static CMPIStatus rasd_to_rasd(const CMPIObjectPath *ref, return s; } +static CMPIStatus vesssd_to_vesssd(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* Special association case: + * VESSSD instance is pointing to itself + */ + s = get_vesssd_by_ref(_BROKER, ref, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + return s; +} + +static CMPIStatus easd_to_easd(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* Special association case: + * EASD instance is pointing to itself + */ + s = get_easd_by_ref(_BROKER, ref, info->properties, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + return s; +} + +/* according to DSP 1050.1.0.0_0 page 41, ESD only associate EP with EASD_EC */ +static CMPIStatus easd_to_ep(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + const char *name = NULL; + char *newid = NULL; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* the step of creating a easd instance is skipped to make it fast */ + + if (cu_get_str_path(ref, "InstanceID", &name) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing InstanceID"); + goto out; + } + newid = easdec_id_to_ep_id(name); + + if (newid == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_NOT_FOUND, + "Invalid InstanceID set."); + goto out; + } + + s = get_ep_by_id(_BROKER, newid, ref, NULL, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + + out: + free(newid); + return s; +} + +static CMPIStatus ep_to_easd(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char *newid = NULL; + const char *name; + + if (!match_hypervisor_prefix(ref, info)) { + return s; + } + + /* the step of creating a ep instance is skipped to make it fast */ + if (cu_get_str_path(ref, "DeviceID", &name) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "No DeviceID specified"); + goto out; + } + + newid = ep_id_to_easdec_id(name); + if (newid == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_NOT_FOUND, + "Invalid DeviceID set."); + goto out; + } + + s = get_easd_by_id(_BROKER, + newid, + ref, + NULL, + &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + free(newid); + return s; +} + static CMPIInstance *make_ref(const CMPIObjectPath *source_ref, const CMPIInstance *target_inst, struct std_assoc_info *info, @@ -151,6 +297,31 @@ static char* assoc_classname[] = { NULL }; +static char *vesssd[] = { + "Net_VirtualEthernetSwitchSystemSettingData", + NULL +}; + +static char *easd[] = { + "Net_EthernetPortAllocationSettingData", + NULL +}; + +static char *ep[] = { + "Net_EthernetPort", + NULL +}; + +static char *assoc_vess[] = { + "Net_ElementSettingData", + NULL +}; + +static char *assoc_conn[] = { + "Net_EthernetPortConnectionSettingData", + NULL +}; + static struct std_assoc _vssd_to_vssd = { .source_class = (char**)&virtual_system_setting_data, .source_prop = "ManagedElement", @@ -177,9 +348,65 @@ static struct std_assoc _rasd_to_rasd = { .make_ref = make_ref }; +static struct std_assoc _vesssd_to_vesssd = { + .source_class = (char **)&vesssd, + .source_prop = "ManagedElement", + + .target_class = (char **)&vesssd, + .target_prop = "SettingData", + + .assoc_class = (char **)&assoc_vess, + + .handler = vesssd_to_vesssd, + .make_ref = make_ref +}; + +static struct std_assoc _easd_to_easd = { + .source_class = (char **)&easd, + .source_prop = "ManagedElement", + + .target_class = (char **)&easd, + .target_prop = "SettingData", + + .assoc_class = (char **)&assoc_vess, + + .handler = easd_to_easd, + .make_ref = make_ref +}; + +static struct std_assoc _easd_to_ep = { + .source_class = (char **)&easd, + .source_prop = "ManagedElement", + + .target_class = (char **)&ep, + .target_prop = "SettingData", + + .assoc_class = (char **)&assoc_conn, + + .handler = easd_to_ep, + .make_ref = make_ref +}; + +static struct std_assoc _ep_to_easd = { + .source_class = (char **)&ep, + .source_prop = "ManagedElement", + + .target_class = (char **)&easd, + .target_prop = "SettingData", + + .assoc_class = (char **)&assoc_conn, + + .handler = ep_to_easd, + .make_ref = make_ref +}; + static struct std_assoc *handlers[] = { &_vssd_to_vssd, &_rasd_to_rasd, + &_vesssd_to_vesssd, + &_easd_to_easd, + &_easd_to_ep, + &_ep_to_easd, NULL }; -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:41 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:41 +0800 Subject: [Libvirt-cim] [PATCH 08/15] vlan extension - CIM model - add association Net_VESSSDComponent In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-4-git-send-email-xiawenc@linux.vnet.ibm.com> add the class Net_VirtualEthernetSwitchSystemSettingDataComponent. Signed-off-by: Wayne Xia --- schema/VESSSDComponent.mof | 8 ++ schema/VESSSDComponent.registration | 3 + src/Virt_VESSSDComponent.c | 181 +++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 0 deletions(-) create mode 100644 schema/VESSSDComponent.mof create mode 100644 schema/VESSSDComponent.registration create mode 100644 src/Virt_VESSSDComponent.c diff --git a/schema/VESSSDComponent.mof b/schema/VESSSDComponent.mof new file mode 100644 index 0000000..a96d837 --- /dev/null +++ b/schema/VESSSDComponent.mof @@ -0,0 +1,8 @@ +// Copyright IBM Corp. 2011 + +[Association, + Provider("cmpi::Virt_VESSSDComponent") +] +class Net_VirtualEthernetSwitchSystemSettingDataComponent : CIM_VirtualSystemSettingDataComponent +{ +}; diff --git a/schema/VESSSDComponent.registration b/schema/VESSSDComponent.registration new file mode 100644 index 0000000..0416881 --- /dev/null +++ b/schema/VESSSDComponent.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2011 +# Classname Namespace ProviderName ProviderModule ProviderTypes +Net_VirtualEthernetSwitchSystemSettingDataComponent root/virt Virt_VESSSDComponent Virt_VESSSDComponent association diff --git a/src/Virt_VESSSDComponent.c b/src/Virt_VESSSDComponent.c new file mode 100644 index 0000000..34f2cbc --- /dev/null +++ b/src/Virt_VESSSDComponent.c @@ -0,0 +1,181 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include "cmpidt.h" +#include "cmpift.h" +#include "cmpimacs.h" + +#include +#include +#include "misc_util.h" +#include "device_parsing.h" + +#include "Virt_VESSSD.h" +#include "Virt_EASD.h" +#include "svpc_types.h" +#include "misc_util.h" + +static const CMPIBroker *_BROKER; + +static CMPIStatus vesssd_to_easd(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + char *name = NULL; + + if (!match_hypervisor_prefix(ref, info)) { + CU_DEBUG("Requested a unexpectted assoc."); + goto out; + } + + /* the step of creating a vesssd instance is skipped to make it fast */ + if (!parse_instanceid(ref, NULL, &name)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to get system name"); + goto out; + } + + s = enum_easds(_BROKER, + name, + ref, + info->properties, + list); + + free(name); + + out: + return s; +} + +static CMPIStatus easd_to_vesssd(const CMPIObjectPath *ref, + struct std_assoc_info *info, + struct inst_list *list) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + const char *id = NULL; + char *host = NULL; + char *devid = NULL; + int ret; + + if (!match_hypervisor_prefix(ref, info)) { + CU_DEBUG("Requested a unexpectted assoc."); + goto out; + } + + /* the step of creating a easd instance is skipped to make it fast */ + if (cu_get_str_path(ref, "InstanceID", &id) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing InstanceID"); + goto out; + } + + ret = parse_fq_devid(id, &host, &devid); + if (!ret) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Invalid InstanceID"); + goto out; + } + + s = get_vesssd_by_name(_BROKER, host, ref, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + inst_list_add(list, inst); + + out: + free(host); + free(devid); + + return s; +} + +LIBVIRT_CIM_DEFAULT_MAKEREF() + +static char *group_component[] = { + "Net_VirtualEthernetSwitchSystemSettingData", + NULL +}; + +static char *part_component[] = { + "Net_EthernetPortAllocationSettingData", + NULL +}; + +static char *assoc_classname[] = { + "Net_VirtualEthernetSwitchSystemSettingDataComponent", + NULL +}; + +static struct std_assoc forward = { + .source_class = (char **)&group_component, + .source_prop = "GroupComponent", + + .target_class = (char **)&part_component, + .target_prop = "PartComponent", + + .assoc_class = (char **)&assoc_classname, + + .handler = vesssd_to_easd, + .make_ref = make_ref +}; + +static struct std_assoc backward = { + .source_class = (char **)&part_component, + .source_prop = "PartComponent", + + .target_class = (char **)&group_component, + .target_prop = "GroupComponent", + + .assoc_class = (char **)&assoc_classname, + + .handler = easd_to_vesssd, + .make_ref = make_ref +}; + +static struct std_assoc *handlers[] = { + &forward, + &backward, + NULL +}; + +STDA_AssocMIStub(, + Virt_VESSSDComponent, + _BROKER, + libvirt_cim_init(), + handlers); + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:43 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:43 +0800 Subject: [Libvirt-cim] [PATCH 10/15] vlan extension - CIM model - add core class VESSMS In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-6-git-send-email-xiawenc@linux.vnet.ibm.com> This patch add the core functions in CIM model, which provided the capabilities to configure the bridge and vlan child ports. It is based on DSP1050. Signed-off-by: Wayne Xia --- ...irtualEthernetSwitchSystemManagementService.mof | 14 + ...ernetSwitchSystemManagementService.registration | 3 + ..._VirtualEthernetSwitchSystemManagementService.c | 1342 ++++++++++++++++++++ ..._VirtualEthernetSwitchSystemManagementService.h | 31 + 4 files changed, 1390 insertions(+), 0 deletions(-) create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.mof create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.registration create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.c create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.h diff --git a/schema/VirtualEthernetSwitchSystemManagementService.mof b/schema/VirtualEthernetSwitchSystemManagementService.mof new file mode 100644 index 0000000..5317305 --- /dev/null +++ b/schema/VirtualEthernetSwitchSystemManagementService.mof @@ -0,0 +1,14 @@ +// Copyright IBM Corp. 2011 + +[Provider("cmpi::Virt_VirtualEthernetSwitchSystemManagementService")] +class Net_VirtualEthernetSwitchSystemManagementService : CIM_VirtualSystemManagementService +{ + [Description("HG changeset id of the providers")] + string Changeset; + + [Description("HG revision number of the providers")] + string Revision; + + [Description("Package Version")] + string Release; +}; diff --git a/schema/VirtualEthernetSwitchSystemManagementService.registration b/schema/VirtualEthernetSwitchSystemManagementService.registration new file mode 100644 index 0000000..ef2b4b1 --- /dev/null +++ b/schema/VirtualEthernetSwitchSystemManagementService.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2011 +# Classname Namespace ProviderName ProviderModule ProviderTypes +Net_VirtualEthernetSwitchSystemManagementService root/virt Virt_VirtualEthernetSwitchSystemManagementService Virt_VirtualEthernetSwitchSystemManagementService method instance diff --git a/src/Virt_VirtualEthernetSwitchSystemManagementService.c b/src/Virt_VirtualEthernetSwitchSystemManagementService.c new file mode 100644 index 0000000..c60068c --- /dev/null +++ b/src/Virt_VirtualEthernetSwitchSystemManagementService.c @@ -0,0 +1,1342 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cmpidt.h" +#include "cmpift.h" +#include "cmpimacs.h" + +#include "cs_util.h" +#include "misc_util.h" +#include "device_parsing.h" +#include "xmlgen.h" + +#include +#include +#include +#include + +#include "misc_util.h" +#include "infostore.h" + +#include "Virt_VirtualSystemManagementService.h" +#include "Virt_VirtualEthernetSwitchSystemManagementService.h" +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_HostSystem.h" +#include "Virt_EASD.h" +#include "network_model.h" +#include "svpc_types.h" + +#include "config.h" + + +static const CMPIBroker *_BROKER; + +typedef enum ResourceAction { + RESOURCE_ADD, + RESOURCE_DEL, + RESOURCE_MOD, +} ResourceAction; + +static CMPIArray *set_result_res_vessms(struct inst_list *list, + const char *ns) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIObjectPath *op = NULL; + CMPIArray *res = NULL; + int i = 0; + + if (list->cur == 0) { + CU_DEBUG("No resources were added or modified"); + return res; + } + + res = CMNewArray(_BROKER, list->cur, CMPI_ref, &s); + if ((s.rc != CMPI_RC_OK) || (res == NULL)) { + CU_DEBUG("Unable to create results array"); + goto out; + } + + for (i = 0; list->list[i] != NULL; i++) { + op = CMGetObjectPath(list->list[i], NULL); + if (op == NULL) { + CU_DEBUG("Unable to EASD reference"); + goto out; + } + CMSetNameSpace(op, ns); + + s = CMSetArrayElementAt(res, i, (CMPIValue *)&op, CMPI_ref); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Error setting results array element"); + goto out; + } + } + + out: + if (s.rc != CMPI_RC_OK) { + res = NULL; + } + + return res; +} + +static CMPIStatus check_piface_for_easd_ea(const CMPIBroker *broker, + EthIface *piface) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + VLAN_Prop_8021q *pvlan_8021q; + if ((piface->eth_type != ETH_TYPE_VLAN) || + (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "now only support opertaion for IEEE 802.1.q."); + CU_DEBUG("only support IEEE 802.1.q."); + eth_iface_print(piface); + goto out; + } + + pvlan_8021q = &(piface->pvlan_prop->props.prop_8021q); + if ((pvlan_8021q->vlan_id < 0) || (pvlan_8021q->vlan_id > 4095)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "invalid vlan id set."); + CU_DEBUG("invalid vlan id %d set.", pvlan_8021q->vlan_id); + goto out; + } + + out: + return s; +} + +static CMPIStatus check_piface_for_easd_ec(const CMPIBroker *broker, + EthIface *piface_src, + EthIface *piface_dest) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + if ((piface_dest->eth_type != ETH_TYPE_BRIDGE) || + (piface_dest->name == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "now only support connection between bridge and " + "port, but the dest is not a bridge or " + "dest name not got."); + CU_DEBUG("requested connectting device %s is not a bridge.", + piface_dest->name); + goto out; + } + + if (piface_src->name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "connection src port was not got."); + CU_DEBUG("connection src port was not got."); + goto out; + } + + out: + return s; +} + +/* piface need to be created before calling the funtion */ +static CMPIStatus instance_to_vesssd(const CMPIBroker *broker, + EthIface *piface, + CMPIInstance *inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIObjectPath *opathp = NULL; + const char *brname = NULL; + const char *cn; + char *pfx = NULL; + uint16_t stp; + int ret; + + opathp = CMGetObjectPath(inst, NULL); + if (opathp == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "failed to get object path."); + goto out; + } + + cn = CLASSNAME(opathp); + pfx = class_prefix_name(cn); + if (pfx == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "Unknown prefix for the class."); + goto out; + } + + ret = cu_get_str_prop(inst, "VirtualSystemIdentifier", &brname); + if (ret != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "property VirtualSystemIdentifier not set."); + CU_DEBUG("failed to get property VirtualSystemIdentifier."); + goto out; + } + piface->name = get_iface_name_from_switch(brname); + if (piface->name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to convert switch_name"); + CU_DEBUG("switch name %s failed to convert.", brname); + goto out; + } + + ret = cu_get_u16_prop(inst, "STP", &stp); + if (ret == CMPI_RC_OK) { + piface->pbr_prop->STP = stp; + } + + out: + free(pfx); + return s; +} + +static CMPIStatus instance_to_easd_ea(const CMPIBroker *broker, + EthIface *piface, + CMPIInstance *inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIStatus s_tmp; + int ret, temp; + uint16_t vlan_type = 0; + uint16_t hdr = 0; + char *charpvalues[8]; + int charpcount = 0; + VLAN_Prop_8021q *pvlan_8021q = NULL; + VLAN_Qos_8021q qos; + const char *ingress; + const char *egress; + + ret = cu_get_u16_prop(inst, "VLANType", &vlan_type); + if (ret == CMPI_RC_OK) { + if (vlan_type == 1) { + piface->eth_type = ETH_TYPE_VLAN; + piface->pvlan_prop->vlan_type = VLAN_TYPE_802_1_Q; + pvlan_8021q = &(piface->pvlan_prop->props.prop_8021q); + } else { + CU_DEBUG("unsupported VLANType " + "%d requested", vlan_type); + } + } else { + CU_DEBUG("VLANType is missing"); + } + + if ((pvlan_8021q == NULL) || + (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q)) { + goto end_of_8021q; + } + + pvlan_8021q->parent = SAFE_STRDUP(piface->dep_ifname); + + s_tmp = get_array_string_from_instance(broker, inst, "Connection", + charpvalues, &charpcount, 8); + if ((s_tmp.rc == CMPI_RC_OK) && (charpcount == 1)) { + temp = vlanid_from_connection_name(charpvalues[0]); + if ((temp >= 0) && (temp < 4096)) { + pvlan_8021q->vlan_id = temp; + } + } else { + CU_DEBUG("Connnection property have %d settings.", charpcount); + } + + /* optional settings */ + ret = cu_get_u16_prop(inst, "ReorderHdr", &hdr); + if (ret == CMPI_RC_OK) { + pvlan_8021q->reorder_hdr = hdr; + } + + ret = cu_get_str_prop(inst, "VLANQosIngress", &ingress); + if (ret == CMPI_RC_OK) { + CU_DEBUG("vlan qos ingress was got."); + if (1 == vlan_8021q_qos_str_to_num(&qos, ingress)) { + pvlan_8021q->ingress = qos; + } else { + CU_DEBUG("invalid ingress string.") + } + } + + ret = cu_get_str_prop(inst, "VLANQosEgress", &egress); + if (ret == CMPI_RC_OK) { + CU_DEBUG("vlan qos egress was got."); + if (1 == vlan_8021q_qos_str_to_num(&qos, egress)) { + pvlan_8021q->egress = qos; + } else { + CU_DEBUG("invalid ingress string.") + } + } + + end_of_8021q: + return s; +} + +static CMPIStatus instance_to_easd_ec(const CMPIBroker *broker, + EthIface *piface_src, + EthIface *piface_dest, + CMPIInstance *inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}, s_tmp; + int ret, i; + char *charpvalues[8]; + int charpcount = 0; + char *prefix = NULL, *portname = NULL; + const char *tmp; + + s_tmp = get_array_string_from_instance(broker, inst, "HostResource", + charpvalues, &charpcount, 8); + if ((s_tmp.rc == CMPI_RC_OK) && (charpcount == 1)) { + piface_dest->name = get_iface_name_from_switch(charpvalues[0]); + if (piface_dest->name != NULL) { + piface_dest->eth_type = ETH_TYPE_BRIDGE; + } + } else { + CU_DEBUG("HostResource have %d settings.", charpcount); + } + i = 0; + while (i < charpcount) { + SAFE_FREE(charpvalues[i]); + i++; + } + + ret = cu_get_str_prop(inst, "Parent", &tmp); + if (ret == CMPI_RC_OK) { + if (1 == parse_fq_devid(tmp, &prefix, &portname)) { + SAFE_FREE(piface_src->name); + piface_src->name = get_iface_name_from_ethportsd(portname, + NULL); + } + } + + SAFE_FREE(prefix); + SAFE_FREE(portname); + return s; +} + +/* pifaces need to be created before calling the funtion */ +static CMPIStatus instance_to_easd(const CMPIBroker *broker, + const char *preset_parent, + EthIface *piface_src, + EthIface *piface_dest, + CMPIInstance *inst, + int *type) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + char *prefix = NULL; + char *name = NULL; + char *port_name = NULL; + char *switch_name = NULL; + const char *tmp; + int request_type = 0; + int ret; + + CU_DEBUG("enter inst to easd, preset_parent is %s.", preset_parent); + /* If a preset_parent is set by the user, then the code use it as + parent device. This parameter was used when user call the method + with parameter AffectedSystem was set. */ + if (preset_parent == NULL) { + s = get_instanceid(inst, &prefix, &name); + if ((s.rc != CMPI_RC_OK) || + (prefix == NULL) || (name == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "failed to translate InstanceId"); + CU_DEBUG("failed to translate InstanceId, " + "prefix %s, name %s.", prefix, name); + goto out; + } + } else { + /*fix me, use value from Parent if ElementName was not set */ + ret = cu_get_str_prop(inst, "ElementName", &tmp); + if (ret == CMPI_RC_OK) { + name = SAFE_STRDUP(tmp); + prefix = SAFE_STRDUP(preset_parent); + } else { + s = get_instanceid(inst, &prefix, &name); + if ((s.rc != CMPI_RC_OK) || (name == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "failed to get port name, " + "InstanceID or ElementName " + "need to be set correctly."); + CU_DEBUG("failed to geto port name, " + "prefix %s, name %s.", prefix, name); + goto out; + } + } + } + + if (name == NULL) { + s = get_instanceid(inst, &prefix, &name); + if ((s.rc != CMPI_RC_OK) || + (prefix == NULL) || (name == NULL)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "failed to translate InstanceId"); + CU_DEBUG("failed to translate InstanceId, " + "prefix %s, name %s.", prefix, name); + goto out; + } + } + + switch_name = get_iface_name_from_switch(prefix); + if (switch_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to convert instance prefix name"); + CU_DEBUG("switch name %s failed to convert.", prefix); + goto out; + } + port_name = get_iface_name_from_ethportsd(name, &request_type); + if (port_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to convert instance suffix name"); + CU_DEBUG("ethport name %s failed to convert.", name); + goto out; + } + + if (request_type == EASD_TYPE_EA) { + piface_src->name = port_name; + piface_src->dep_ifname = switch_name; + port_name = NULL; + switch_name = NULL; + s = instance_to_easd_ea(broker, piface_src, inst); + } else { + piface_src->name = port_name; + port_name = NULL; + s = instance_to_easd_ec(broker, piface_src, piface_dest, inst); + } + + out: + *type = request_type; + SAFE_FREE(prefix); + SAFE_FREE(name); + SAFE_FREE(port_name); + SAFE_FREE(switch_name); + return s; +} + +static CMPIStatus find_merge_existing_easd(const CMPIBroker *broker, + EthIface *piface) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + EthIface iface_ref; + EthIfacesList ifaces_list; + int ret; + + eth_ifaceslist_init(&ifaces_list); + eth_iface_init(&iface_ref); + if (piface->name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "switch name not set."); + goto out; + } + iface_ref.name = SAFE_STRDUP(piface->name); + iface_ref.eth_type = piface->eth_type; + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_by_ref, &iface_ref); + if ((ret != 1) || (ifaces_list.count != 1)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to get original easd settings," + " maybe it do not exist."); + goto out; + } + eth_iface_merge(piface, ifaces_list.pifaces[0], 1); + out: + eth_ifaceslist_uninit(&ifaces_list); + eth_iface_uninit(&iface_ref); + return s; +} + +static CMPIStatus _update_easd_for(const CMPIBroker *broker, + const CMPIContext *context, + const CMPIObjectPath *ref, + const char *preset_parent, + CMPIInstance *rasd, + ResourceAction action) +{ + CMPIStatus s; + int type; + EthIface iface_src, iface_dest; + int ret; + char *errstr; + + eth_iface_init(&iface_src); + eth_iface_init(&iface_dest); + eth_iface_add_br_prop(&iface_src); + eth_iface_add_vlan_prop(&iface_src, VLAN_TYPE_802_1_Q); + eth_iface_add_br_prop(&iface_dest); + eth_iface_add_vlan_prop(&iface_dest, VLAN_TYPE_802_1_Q); + + + CU_DEBUG("Enter _update_easd_for"); + s = instance_to_easd(broker, preset_parent, + &iface_src, &iface_dest, rasd, &type); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + if (type == EASD_TYPE_EA) { + s = check_piface_for_easd_ea(broker, &iface_src); + if (s.rc != CMPI_RC_OK) { + goto out; + } + CU_DEBUG("easd-EA operation with request type %d," + "iface settings is :", action); + eth_iface_print(&iface_src); + if (action == RESOURCE_ADD) { + ret = add_host_iface(&iface_src, 1); + } else if (action == RESOURCE_MOD) { + s = find_merge_existing_easd(broker, &iface_src); + if (s.rc != CMPI_RC_OK) { + goto out; + } + ret = mod_host_iface(&iface_src, 1); + } else if (action == RESOURCE_DEL) { + ret = del_host_iface(&iface_src, 1); + } else { + errstr = "requested an unsupported operation."; + CU_DEBUG("%s", errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + } else { + s = check_piface_for_easd_ec(broker, &iface_src, &iface_dest); + if (s.rc != CMPI_RC_OK) { + goto out; + } + CU_DEBUG("easd-EC operation with request type %d," + "iface settings are :", action); + eth_iface_print(&iface_src); + eth_iface_print(&iface_dest); + if (action == RESOURCE_ADD) { + ret = connect_two_ifaces(&iface_src, &iface_dest, 1); + } else if (action == RESOURCE_DEL) { + ret = disconnect_two_ifaces(&iface_src, &iface_dest, 1); + } else { + errstr = "requested an unsupported operation."; + CU_DEBUG("%s", errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + } + + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + out: + eth_iface_uninit(&iface_src); + eth_iface_uninit(&iface_dest); + return s; +} + +static CMPIStatus _update_easd_settings(const CMPIContext *context, + const CMPIObjectPath *ref, + const char *bridge, + CMPIArray *resources, + const CMPIResult *results, + ResourceAction action, + struct inst_list *list) +{ + int i; + CMPIStatus s = {CMPI_RC_OK, NULL}; + int count = 0; + uint32_t rc = CIM_SVPC_RETURN_FAILED; + + CU_DEBUG("Enter _update_easd_settings"); + if (resources == NULL) { + CU_DEBUG("No easd settings."); + goto out; + } + + count = CMGetArrayCount(resources, &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("failed to get array size."); + goto out; + } + + i = 0; + CU_DEBUG("Trying update %d easds.", count); + while (i < count) { + CMPIData item; + CMPIInstance *inst; + item = CMGetArrayElementAt(resources, i, NULL); + inst = item.value.inst; + + s = _update_easd_for(_BROKER, + context, + ref, + bridge, + inst, + action); + if (s.rc != CMPI_RC_OK) { + break; + } + inst_list_add(list, inst); + i++; + } + + out: + if (s.rc == CMPI_RC_OK) { + rc = CIM_SVPC_RETURN_COMPLETED; + } + if ((results != NULL) && (resources != NULL)) { + CMReturnData(results, &rc, CMPI_uint32); + } + + return s; +} + +static CMPIStatus easd_refs_to_insts(const CMPIBroker *broker, + const CMPIContext *ctx, + const CMPIObjectPath *reference, + CMPIArray *arr, + CMPIArray **ret_arr) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIArray *tmp_arr; + int i; + int c; + + c = CMGetArrayCount(arr, &s); + if (s.rc != CMPI_RC_OK) { + return s; + } + + tmp_arr = CMNewArray(broker, + c, + CMPI_instance, + &s); + + for (i = 0; i < c; i++) { + CMPIData d; + CMPIObjectPath *ref; + CMPIInstance *inst = NULL; + const char *id; + + d = CMGetArrayElementAt(arr, i, &s); + ref = d.value.ref; + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Unable to get ResourceSettings[%i]", i); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to get ResourceSettings"); + goto out; + } + + if (cu_get_str_path(ref, "InstanceID", &id) != CMPI_RC_OK) { + CU_DEBUG("Unable to get InstanceID of `%s'", + REF2STR(ref)); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Unable to get InstanceID"); + goto out; + } + + s = get_easd_by_id(broker, id, reference, NULL, &inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + CMSetArrayElementAt(tmp_arr, i, + &inst, + CMPI_instance); + + } + + *ret_arr = tmp_arr; + + out: + return s; +} + +static CMPIInstance *create_switch_system(const CMPIContext *context, + CMPIInstance *vsssd, + CMPIArray *resources, + const CMPIObjectPath *ref, + const CMPIObjectPath *refconf, + CMPIStatus *s) +{ + CMPIInstance *inst = NULL; + EthIface iface_br; + int ret; + char *errstr; + char *br_name = NULL; + struct inst_list list; + + inst_list_init(&list); + eth_iface_init(&iface_br); + eth_iface_add_br_prop(&iface_br); + + CU_DEBUG("Enter create_switch_system"); + if (refconf != NULL) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "creating switch system with" + " reference is not supported now."); + goto out; + } + + *s = instance_to_vesssd(_BROKER, &iface_br, vsssd); + if (s->rc != CMPI_RC_OK) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "failed to translate settings."); + goto out; + } + iface_br.eth_type = ETH_TYPE_BRIDGE; + CU_DEBUG("Creating Switch System as follow:"); + eth_iface_print(&iface_br); + + ret = add_host_iface(&iface_br, 1); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + br_name = get_switch_name_from_iface(iface_br.name); + *s = _update_easd_settings(context, + ref, + br_name, + resources, + NULL, + RESOURCE_ADD, + &list); + + + *s = get_switch_by_name(_BROKER, + br_name, + ref, + &inst); + + out: + inst_list_free(&list); + eth_iface_uninit(&iface_br); + free(br_name); + + return inst; +} + +static CMPIStatus update_switchsystem_settings(const CMPIContext *context, + const CMPIObjectPath *ref, + CMPIInstance *vsssd) +{ + CMPIStatus s; + EthIface iface_br, iface_ref; + EthIfacesList ifaces_list; + int ret; + char *errstr; + + eth_ifaceslist_init(&ifaces_list); + eth_iface_init(&iface_br); + eth_iface_init(&iface_ref); + eth_iface_add_br_prop(&iface_br); + + s = instance_to_vesssd(_BROKER, &iface_br, vsssd); + if (s.rc != CMPI_RC_OK || (iface_br.name == NULL)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "failed to translate settings."); + goto out; + + } + + iface_ref.name = SAFE_STRDUP(iface_br.name); + iface_ref.eth_type = iface_br.eth_type; + ret = get_host_ifaces(&ifaces_list, + eth_iface_filter_by_ref, &iface_ref); + if ((ret != 1) || (ifaces_list.count != 1)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "failed to get original vs settings," + " maybe it do not exist."); + goto out; + } + eth_iface_merge(&iface_br, ifaces_list.pifaces[0], 1); + CU_DEBUG("update switch settings as following settings:"); + eth_iface_print(&iface_br); + ret = mod_host_iface(&iface_br, 1); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + out: + eth_ifaceslist_uninit(&ifaces_list); + eth_iface_uninit(&iface_ref); + eth_iface_uninit(&iface_br); + return s; +} + +static CMPIStatus define_switch_system_parse_args(const CMPIArgs *argsin, + CMPIInstance **sys, + const char *ns, + CMPIArray **res, + CMPIObjectPath **refconf) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + + if (cu_get_inst_arg(argsin, "SystemSettings", sys) != CMPI_RC_OK) { + CU_DEBUG("No SystemSettings string argument"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing argument `SystemSettings'"); + goto out; + } + + if (cu_get_array_arg(argsin, "ResourceSettings", res) != + CMPI_RC_OK) { + CU_DEBUG("Did not get ResourceSettings arg"); + *res = NULL; + } + + if (cu_get_ref_arg(argsin, "ReferenceConfiguration", refconf) != + CMPI_RC_OK) { + CU_DEBUG("Did not get ReferenceConfiguration arg"); + *refconf = NULL; + } + out: + return s; +} + +static CMPIStatus define_system(CMPIMethodMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *vsssd; + CMPIArray *res; + CMPIObjectPath *refconf; + CMPIInstance *sys = NULL; + CMPIObjectPath *result; + uint32_t rc = CIM_SVPC_RETURN_FAILED; + + CU_DEBUG("DefineSystem"); + + s = define_switch_system_parse_args(argsin, + &vsssd, + NAMESPACE(reference), + &res, + &refconf); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + sys = create_switch_system(context, vsssd, res, reference, refconf, &s); + if (sys == NULL) { + goto out; + } + + result = CMGetObjectPath(sys, &s); + if ((result != NULL) && (s.rc == CMPI_RC_OK)) { + CMSetNameSpace(result, NAMESPACE(reference)); + CMAddArg(argsout, "ResultingSystem", &result, CMPI_ref); + } + + + out: + if (s.rc == CMPI_RC_OK) { + rc = CIM_SVPC_RETURN_COMPLETED; + } + CMReturnData(results, &rc, CMPI_uint32); + + return s; +} + +static CMPIStatus destroy_system(CMPIMethodMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + const char *br_name = NULL; + EthIface iface_br; + uint32_t rc = IM_RC_FAILED; + CMPIObjectPath *sys; + int ret; + char *errstr; + + eth_iface_init(&iface_br); + CU_DEBUG("entering destroy switch system."); + + if (cu_get_ref_arg(argsin, "AffectedSystem", &sys) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "AffectedSystem not set"); + goto out; + } + + br_name = get_key_from_ref_arg(argsin, "AffectedSystem", "Name"); + if (br_name == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed get Name of AffectedSystem"); + goto out; + } + + iface_br.name = get_iface_name_from_switch(br_name); + if (iface_br.name == NULL) { + CU_DEBUG("failed to get iface name from %s.", br_name); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to translate Name of AffectedSystem"); + goto out; + } + + iface_br.eth_type = ETH_TYPE_BRIDGE; + CU_DEBUG("Deleting Switch System as follow:"); + eth_iface_print(&iface_br); + + ret = del_host_iface(&iface_br, 1); + if (ret != 1) { + errstr = get_host_iface_error_reason(ret); + CU_DEBUG("error num %d returned, reason %s.", ret, errstr); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + errstr); + goto out; + } + + rc = IM_RC_OK; + + out: + eth_iface_uninit(&iface_br); + CMReturnData(results, &rc, CMPI_uint32); + return s; +} + + +static CMPIStatus mod_system_settings(CMPIMethodMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIInstance *inst; + CMPIStatus s; + uint32_t rc; + + if (cu_get_inst_arg(argsin, "SystemSettings", &inst) != CMPI_RC_OK) { + + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing SystemSettings"); + goto out; + } + + s = update_switchsystem_settings(context, reference, inst); + out: + if (s.rc == CMPI_RC_OK) { + rc = CIM_SVPC_RETURN_COMPLETED; + } else { + rc = CIM_SVPC_RETURN_FAILED; + } + + CMReturnData(results, &rc, CMPI_uint32); + + return s; +} + +static CMPIStatus add_resource_settings(CMPIMethodMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIArray *arr; + CMPIStatus s; + CMPIObjectPath *sys; + char *bridge = NULL; + CMPIArray *res = NULL; + struct inst_list list; + + inst_list_init(&list); + + if (cu_get_array_arg(argsin, "ResourceSettings", &arr) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing ResourceSettings"); + return s; + } + + if (cu_get_ref_arg(argsin, + "AffectedConfiguration", + &sys) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing AffectedConfiguration parameter"); + return s; + } + + if (!parse_instanceid(sys, NULL, &bridge)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "AffectedConfiguration has invalid InstanceID"); + return s; + } + + s = _update_easd_settings(context, + reference, + bridge, + arr, + results, + RESOURCE_ADD, + &list); + + free(bridge); + + res = set_result_res_vessms(&list, NAMESPACE(reference)); + inst_list_free(&list); + CMAddArg(argsout, "ResultingResourceSettings", &res, CMPI_refA); + + + return s; +} + +static CMPIStatus mod_resource_settings(CMPIMethodMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + CMPIArray *arr; + CMPIStatus s; + CMPIArray *res = NULL; + struct inst_list list; + + CU_DEBUG("Enter mod_resource_settings"); + inst_list_init(&list); + + if (cu_get_array_arg(argsin, "ResourceSettings", &arr) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing ResourceSettings"); + return s; + } + + s = _update_easd_settings(context, + reference, + NULL, + arr, + results, + RESOURCE_MOD, + &list); + + res = set_result_res_vessms(&list, NAMESPACE(reference)); + CMAddArg(argsout, "ResultingResourceSettings", &res, CMPI_refA); + inst_list_free(&list); + + return s; +} + +static CMPIStatus rm_resource_settings(CMPIMethodMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const CMPIArgs *argsin, + CMPIArgs *argsout) +{ + /* The RemoveResources case is different from either Add or + * Modify, because it takes references instead of instances + */ + + CMPIArray *arr; + CMPIArray *resource_arr = NULL; + CMPIStatus s; + struct inst_list list; + + inst_list_init(&list); + + if (cu_get_array_arg(argsin, "ResourceSettings", &arr) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Missing ResourceSettings"); + goto out; + } + + /* delete is simple, just specify the names */ + s = easd_refs_to_insts(_BROKER, context, reference, arr, + &resource_arr); + if (s.rc != CMPI_RC_OK) { + goto out; + } + + s = _update_easd_settings(context, + reference, + NULL, + resource_arr, + results, + RESOURCE_DEL, + &list); + out: + inst_list_free(&list); + + return s; +} + +static struct method_handler DefineSystem = { + .name = "DefineSystem", + .handler = define_system, + .args = {{"SystemSettings", CMPI_instance, false}, + {"ResourceSettings", CMPI_instanceA, true}, + {"ReferenceConfiguration", CMPI_ref, true}, + ARG_END + } +}; + +static struct method_handler DestroySystem = { + .name = "DestroySystem", + .handler = destroy_system, + .args = {{"AffectedSystem", CMPI_ref, false}, + ARG_END + } +}; + +static struct method_handler AddResourceSettings = { + .name = "AddResourceSettings", + .handler = add_resource_settings, + .args = {{"AffectedConfiguration", CMPI_ref, false}, + {"ResourceSettings", CMPI_instanceA, false}, + ARG_END + } +}; + +static struct method_handler ModifyResourceSettings = { + .name = "ModifyResourceSettings", + .handler = mod_resource_settings, + .args = {{"ResourceSettings", CMPI_instanceA, false}, + ARG_END + } +}; + +static struct method_handler ModifySystemSettings = { + .name = "ModifySystemSettings", + .handler = mod_system_settings, + .args = {{"SystemSettings", CMPI_instance, false}, + ARG_END + } +}; + +static struct method_handler RemoveResourceSettings = { + .name = "RemoveResourceSettings", + .handler = rm_resource_settings, + .args = {{"ResourceSettings", CMPI_refA, false}, + ARG_END + } +}; + +static struct method_handler *my_handlers[] = { + &DefineSystem, + &DestroySystem, + &AddResourceSettings, + &ModifyResourceSettings, + &ModifySystemSettings, + &RemoveResourceSettings, + NULL, +}; + +STDIM_MethodMIStub(, Virt_VirtualEthernetSwitchSystemManagementService, + _BROKER, libvirt_cim_init(), my_handlers); + + +CMPIStatus get_vessms(const CMPIObjectPath *reference, + CMPIInstance **_inst, + const CMPIBroker *broker, + const CMPIContext *context, + bool is_get_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + char host_name[256]; + CMPIArray *array; + uint16_t op_status; + + *_inst = NULL; + + inst = get_typed_instance(broker, + NETWORK_CLASS_PREFIX, + "VirtualEthernetSwitchSystemManagementService", + NAMESPACE(reference)); + + if (inst == NULL) { + CU_DEBUG("Failed to get typed instance"); + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Failed to create instance"); + goto out; + } + + CMSetProperty(inst, "Caption", + (CMPIValue *)"VLAN and VBridge services", CMPI_chars); + + CMSetProperty(inst, "Name", + (CMPIValue *)"Management Service", CMPI_chars); + + if (0 == get_fqdn(host_name, sizeof(host_name))) { + CMSetProperty(inst, "SystemName", + (CMPIValue *)host_name, CMPI_chars); + } + + CMSetProperty(inst, "SystemCreationClassName", + (CMPIValue *)"KVM_HostSystem", CMPI_chars); + + + CMSetProperty(inst, "Revision", + (CMPIValue *)LIBVIRT_CIM_RV, CMPI_chars); + + CMSetProperty(inst, "Release", + (CMPIValue *)PACKAGE_VERSION, CMPI_chars); + + array = CMNewArray(broker, 1, CMPI_uint16, &s); + if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array))) { + goto out; + } + + op_status = CIM_OPERATIONAL_STATUS; + CMSetArrayElementAt(array, 0, &op_status, CMPI_uint16); + + CMSetProperty(inst, "OperationalStatus", + (CMPIValue *)&array, CMPI_uint16A); + + if (is_get_inst) { + s = cu_validate_ref(broker, reference, inst); + if (s.rc != CMPI_RC_OK) { + goto out; + } + } + + cu_statusf(broker, &s, + CMPI_RC_OK, + ""); + out: + *_inst = inst; + + return s; +} + +static CMPIStatus return_vessms(const CMPIContext *context, + const CMPIObjectPath *reference, + const CMPIResult *results, + bool name_only, + bool is_get_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst; + + s = get_vessms(reference, &inst, _BROKER, context, is_get_inst); + if ((s.rc != CMPI_RC_OK) || (inst == NULL)) { + goto out; + } + + if (name_only) { + cu_return_instance_name(results, inst); + } else { + CMReturnInstance(results, inst); + } + out: + return s; +} + +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference) +{ + return return_vessms(context, reference, results, true, false); +} + +static CMPIStatus EnumInstances(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + + return return_vessms(context, reference, results, false, false); +} + +static CMPIStatus GetInstance(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *ref, + const char **properties) +{ + return return_vessms(context, ref, results, false, true); +} + +DEFAULT_CI(); +DEFAULT_MI(); +DEFAULT_DI(); +DEFAULT_EQ(); +DEFAULT_INST_CLEANUP(); + +STD_InstanceMIStub(, + Virt_VirtualEthernetSwitchSystemManagementService, + _BROKER, + libvirt_cim_init()); + + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/src/Virt_VirtualEthernetSwitchSystemManagementService.h b/src/Virt_VirtualEthernetSwitchSystemManagementService.h new file mode 100644 index 0000000..07c0f4e --- /dev/null +++ b/src/Virt_VirtualEthernetSwitchSystemManagementService.h @@ -0,0 +1,31 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef VESSMS_H +#define VESSMS_H + +CMPIStatus get_vessms(const CMPIObjectPath *reference, + CMPIInstance **_inst, + const CMPIBroker *broker, + const CMPIContext *context, + bool is_get_inst); + +#endif -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:45 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:45 +0800 Subject: [Libvirt-cim] [PATCH 12/15] vlan extension - function lib - add the API In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-8-git-send-email-xiawenc@linux.vnet.ibm.com> this is the API layer let the libvirt-cim call. Signed-off-by: Wayne Xia --- libxkutil/host_network_API.c | 150 ++++++++++++++++++++++++++++++++++++++++++ libxkutil/host_network_API.h | 32 +++++++++ 2 files changed, 182 insertions(+), 0 deletions(-) create mode 100644 libxkutil/host_network_API.c create mode 100644 libxkutil/host_network_API.h diff --git a/libxkutil/host_network_API.c b/libxkutil/host_network_API.c new file mode 100644 index 0000000..89a9879 --- /dev/null +++ b/libxkutil/host_network_API.c @@ -0,0 +1,150 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + + +#include "host_network_API.h" +#include "host_network_implement_cmdline.h" +#include "host_network_error.h" + +/* this layer is added to devide the abstraction and implemention, so that + different implemention could be used and switched */ + +int get_host_ifaces(EthIfacesList *plist, + eth_iface_filter_func filter_func, void *filter_opaque) +{ + return get_host_eth_ifaces_cmd_all(plist, filter_func, filter_opaque); +} + +int add_host_iface(EthIface *piface, int persist_flag) +{ + int ret = 0; + if (piface->eth_type == ETH_TYPE_BRIDGE) { + ret = add_host_br_cmd(piface, persist_flag); + } else if (piface->eth_type == ETH_TYPE_VLAN) { + + if (piface->pvlan_prop == NULL) { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } else { + if (piface->pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) { + ret = add_host_vlan_8021q_cmd(piface, persist_flag); + } else { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } + } + + } else { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } + + return ret; +} + +int del_host_iface(EthIface *piface, int persist_flag) +{ + int ret = 0; + if (piface->eth_type == ETH_TYPE_BRIDGE) { + ret = del_host_br_cmd(piface, persist_flag); + } else if (piface->eth_type == ETH_TYPE_VLAN) { + + if (piface->pvlan_prop == NULL) { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } else { + if (piface->pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) { + ret = del_host_vlan_8021q_cmd(piface, persist_flag); + } else { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } + } + + } else { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } + + return ret; +} + +int mod_host_iface(EthIface *piface, int persist_flag) +{ + int ret = 0; + if (piface->eth_type == ETH_TYPE_BRIDGE) { + ret = mod_host_br_cmd(piface, persist_flag); + } else if (piface->eth_type == ETH_TYPE_VLAN) { + + if (piface->pvlan_prop == NULL) { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } else { + if (piface->pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) { + ret = mod_host_vlan_8021q_cmd(piface, persist_flag); + } else { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } + } + + } else { + CU_DEBUG("requested an unsupported operation."); + ret = ERR_REQUEST_NOT_SUPPORT; + } + + return ret; +} + +int change_state_host_iface(EthIface *piface, int state) +{ + return change_state_host_iface_cmd(piface, state); +} + +int connect_two_ifaces(EthIface *p1, EthIface *p2, int persist_flag) +{ + if ((p1 == NULL) || (p2 == NULL)) { + return 0; + } + if ((p1->eth_type == ETH_TYPE_BRIDGE) && + (p2->eth_type != ETH_TYPE_BRIDGE)) { + return add_host_iface_to_br_cmd(p2, p1, persist_flag); + } else if ((p1->eth_type != ETH_TYPE_BRIDGE) && + (p2->eth_type == ETH_TYPE_BRIDGE)) { + return add_host_iface_to_br_cmd(p1, p2, persist_flag); + } else { + CU_DEBUG("requested an unsupported operation."); + return ERR_REQUEST_NOT_SUPPORT; + } +} + +int disconnect_two_ifaces(EthIface *p1, EthIface *p2, int persist_flag) +{ + if ((p1 == NULL) || (p2 == NULL)) { + return 0; + } + if ((p1->eth_type == ETH_TYPE_BRIDGE) && + (p2->eth_type != ETH_TYPE_BRIDGE)) { + return remove_host_iface_from_br_cmd(p2, p1, persist_flag); + } else if ((p1->eth_type != ETH_TYPE_BRIDGE) && + (p2->eth_type == ETH_TYPE_BRIDGE)) { + return remove_host_iface_from_br_cmd(p1, p2, persist_flag); + } else { + CU_DEBUG("requested an unsupported operation."); + return ERR_REQUEST_NOT_SUPPORT; + } +} + +char *get_host_iface_error_reason(int errno) +{ + return translate_error_no(errno); +} diff --git a/libxkutil/host_network_API.h b/libxkutil/host_network_API.h new file mode 100644 index 0000000..b821d58 --- /dev/null +++ b/libxkutil/host_network_API.h @@ -0,0 +1,32 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +#ifndef HOST_NETWORK_API +#define HOST_NETWORK_API + +#include "host_network_basic.h" +#include "host_network_helper.h" + +int get_host_ifaces(EthIfacesList *plist, + eth_iface_filter_func filter_func, void *filter_opaque); + +int add_host_iface(EthIface *piface, int persist_flag); +int del_host_iface(EthIface *piface, int persist_flag); +int mod_host_iface(EthIface *piface, int persist_flag); +int change_state_host_iface(EthIface *piface, int state); + +int connect_two_ifaces(EthIface *p1, EthIface *p2, int persist_flag); +int disconnect_two_ifaces(EthIface *p1, EthIface *p2, int persist_flag); + +char *get_host_iface_error_reason(int errno); + +#endif -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:44 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:44 +0800 Subject: [Libvirt-cim] [PATCH 11/15] vlan extension - CIM model - add help functions In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-7-git-send-email-xiawenc@linux.vnet.ibm.com> this patch modified some existing files to let some function could be used by the new codes, and added new help functions in network_model.c. Signed-off-by: Wayne Xia --- libxkutil/network_model.c | 466 +++++++++++++++++++++++++++++ libxkutil/network_model.h | 105 +++++++ src/Virt_HostSystem.c | 2 +- src/Virt_HostSystem.h | 2 + src/Virt_VirtualSystemManagementService.c | 17 +- src/Virt_VirtualSystemManagementService.h | 10 + 6 files changed, 592 insertions(+), 10 deletions(-) create mode 100644 libxkutil/network_model.c create mode 100644 libxkutil/network_model.h diff --git a/libxkutil/network_model.c b/libxkutil/network_model.c new file mode 100644 index 0000000..eeee1aa --- /dev/null +++ b/libxkutil/network_model.c @@ -0,0 +1,466 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "network_model.h" +#include "device_parsing.h" + +#include "cmpidt.h" +#include "cmpift.h" +#include "cmpimacs.h" + +/* this function would return a new allocated string or NULL */ +char *compare_and_switch_prefix(const char *orig_str, + const char *orig_prefix, + const char *dest_prefix) +{ + int orig_prefix_len, dest_prefix_len, asret; + char *retstr = NULL; + const char *suffix; + if (orig_str == NULL) { + goto out; + } + orig_prefix_len = strlen(orig_prefix); + dest_prefix_len = strlen(dest_prefix); + if (0 != strncmp(orig_str, orig_prefix, orig_prefix_len)) { + goto out; + } + suffix = orig_str + orig_prefix_len; + asret = asprintf(&retstr, "%s%s", dest_prefix, suffix); + if (asret == -1) { + free(retstr); + retstr = NULL; + } + out: + return retstr; +} + +char *switch_device_id_prefix(const char *whole_id, + const char *orig_prefix, + const char *dest_prefix) +{ + char *system = NULL; + char *device = NULL; + char *new_id = NULL; + char *retstr = NULL; + int asret; + + + if (0 == parse_fq_devid(whole_id, &system, &device)) { + goto out; + } + + new_id = compare_and_switch_prefix(device, + orig_prefix, dest_prefix); + + if (new_id == NULL) { + goto out; + } + asret = asprintf(&retstr, "%s/%s", system, new_id); + if (asret == -1) { + free(retstr); + retstr = NULL; + } + + out: + free(system); + free(device); + free(new_id); + return retstr; +} + +char *ep_id_to_easdea_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_PREFIX, ETHPORT_ALLOCATION_SD_PREFIX); +} + +char *easdea_id_to_ep_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_ALLOCATION_SD_PREFIX, ETHPORT_PREFIX); +} + +char *ep_id_to_easdec_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_PREFIX, ETHPORT_CONNECTION_SD_PREFIX); +} + +char *easdec_id_to_ep_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_CONNECTION_SD_PREFIX, ETHPORT_PREFIX); +} + +char *vlanid_to_connection_name(const int id) +{ + int asret; + char *str = NULL; + char *prefix = CONNECTION_VLAN_PREFIX; + asret = asprintf(&str, "%s%d", prefix, id); + if (asret == -1) { + return NULL; + } + return str; +} + +int vlanid_from_connection_name(const char *name) +{ + int id = -1; + int temp = -1; + char *prefix = CONNECTION_VLAN_PREFIX; + char *dig_start, *dig_end; + if (name == NULL) { + goto out; + } + dig_start = strstr(name, prefix); + if (dig_start == NULL) { + goto out; + } + dig_start += strlen(prefix); + temp = strtol(dig_start, &dig_end, 10); + if ((dig_start == dig_end) || (temp < 0) || (temp > 4095)) { + goto out; + } + id = temp; + out: + return id; +} + +int eth_iface_filter_cim_ethport(const EthIface *piface, + void *nouse) +{ + if (piface->eth_type == ETH_TYPE_BRIDGE) { + return 0; + } + if (piface->eth_type == ETH_TYPE_LOOPBACK) { + return 0; + } + return 1; +} + +int eth_iface_filter_cim_ethport_for_name(const EthIface *piface, + void *name) +{ + int cim_ethport_flag; + cim_ethport_flag = eth_iface_filter_cim_ethport(piface, NULL); + if (cim_ethport_flag == 1) { + if (0 == strcmp(piface->name, name)) { + return 1; + } + } + return 0; +} + +/* returned value need to be freed */ +char *get_ethportsd_name_from_iface(const char *iface_name, const int type) +{ + char *prefix; + char *name; + int size; + + if (iface_name == NULL) { + return NULL; + } + + if (type == EASD_TYPE_EA) { + prefix = ETHPORT_ALLOCATION_SD_PREFIX; + } else { + prefix = ETHPORT_CONNECTION_SD_PREFIX; + } + + size = strlen(iface_name)+strlen(prefix)+1; + SAFE_MALLOC(name, size); + snprintf(name, size, "%s%s", prefix, iface_name); + return name; +} + +/* returned value need to be freed */ +char *get_iface_name_from_ethportsd(const char *ethport_name, int *ptype) +{ + char *prefix; + char *name = NULL; + int size; + int prefix_len; + int t = -1; + + if (ethport_name == NULL) { + goto out; + } + + prefix = ETHPORT_ALLOCATION_SD_PREFIX; + prefix_len = strlen(prefix); + if (0 != strncmp(ethport_name, prefix, prefix_len)) { + prefix = ETHPORT_CONNECTION_SD_PREFIX; + prefix_len = strlen(prefix); + if (0 != strncmp(ethport_name, prefix, prefix_len)) { + goto out; + } else { + t = EASD_TYPE_EC; + } + } else { + t = EASD_TYPE_EA; + } + size = strlen(ethport_name)-strlen(prefix)+1; + SAFE_MALLOC(name, size); + snprintf(name, size, "%s", ethport_name+prefix_len); + + out: + if (ptype != NULL) { + *ptype = t; + } + return name; +} + +int eth_iface_filter_cim_switch(const EthIface *piface, + void *nouse) +{ + if (piface->eth_type == ETH_TYPE_BRIDGE) { + return 1; + } + return eth_iface_filter_peths(piface, nouse); +} + +int eth_iface_filter_cim_switch_for_name(const EthIface *piface, + void *name) +{ + int cim_switch_flag; + cim_switch_flag = eth_iface_filter_cim_switch(piface, NULL); + if (cim_switch_flag == 1) { + if (0 == strcmp(piface->name, name)) { + return 1; + } + } + return 0; +} + +/* returned value need to be freed */ +char *get_switch_name_from_iface(const char *iface_name) +{ + char *prefix = SWITCH_PREFIX; + char *name; + int size; + + size = strlen(iface_name)+strlen(prefix)+1; + SAFE_MALLOC(name, size); + snprintf(name, size, "%s%s", prefix, iface_name); + return name; +} + +/* returned value need to be freed */ +char *get_iface_name_from_switch(const char *switch_name) +{ + char *prefix = SWITCH_PREFIX; + char *name; + int size; + int prefix_len; + + prefix_len = strlen(prefix); + if (0 != strncmp(switch_name, prefix, prefix_len)) { + return NULL; + } + size = strlen(switch_name)-strlen(prefix)+1; + SAFE_MALLOC(name, size); + snprintf(name, size, "%s", switch_name+prefix_len); + return name; +} + +/* returned value need to be freed */ +char *get_ethport_name_from_iface(const char *iface_name) +{ + char *prefix; + char *name; + int size; + + if (iface_name == NULL) { + return NULL; + } + + prefix = ETHPORT_PREFIX; + size = strlen(iface_name)+strlen(prefix)+1; + SAFE_MALLOC(name, size); + snprintf(name, size, "%s%s", prefix, iface_name); + return name; +} + +/* returned value need to be freed */ +char *get_iface_name_from_ethport(const char *ethport_name) +{ + char *prefix = ETHPORT_PREFIX; + char *name = NULL; + int size; + int prefix_len; + + if (ethport_name == NULL) { + goto out; + } + + prefix = ETHPORT_PREFIX; + prefix_len = strlen(prefix); + if (0 != strncmp(ethport_name, prefix, prefix_len)) { + goto out; + } + size = strlen(ethport_name)-prefix_len+1; + SAFE_MALLOC(name, size); + snprintf(name, size, "%s", ethport_name+prefix_len); + + out: + return name; +} + +int get_possible_bridge_name_for_cim_model(EthIface *piface, + char **pbr1name, char **pbr2name) +{ + char *br1_name; + char *br2_name; + if (piface->attach_bridge != NULL) { + br1_name = get_switch_name_from_iface(piface->attach_bridge); + } else if (piface->dep_ifname != NULL) { + br1_name = get_switch_name_from_iface(piface->dep_ifname); + } else if (piface->eth_type == ETH_TYPE_PHYSICAL) { + br1_name = get_switch_name_from_iface(piface->name); + } else { + br1_name = NULL; + } + + if ((piface->attach_bridge != NULL) && (piface->dep_ifname != NULL)) { + br2_name = get_switch_name_from_iface(piface->dep_ifname); + } else { + br2_name = NULL; + } + + *pbr1name = br1_name; + *pbr2name = br2_name; + return 1; +} + +CMPIStatus get_array_uint16_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + int *ret_result, + int *ret_size, + int max_size) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIArray *array; + CMPICount array_size; + CMPIData elem; + int i, ret, count = 0; + + ret = cu_get_array_prop(inst, array_name, &array); + if (ret != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "array property not found."); + CU_DEBUG("Failed to get array property %s.", array_name); + goto out; + } + array_size = CMGetArrayCount(array, &s); + if ((s.rc != CMPI_RC_OK) || (array_size > max_size) || + (array_size <= 0)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to get size of array property," + " or its size is 0 or too big."); + CU_DEBUG("failed in getting size of %s property.", array_name); + goto out; + } + for (i = 0; i < array_size; i++) { + elem = CMGetArrayElementAt(array, i, NULL); + if (CMIsNullValue(elem)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "NULL content of array property."); + CU_DEBUG("NULL content of %s property.", array_name); + goto out; + } + if (!(elem.type & CMPI_INTEGER)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "wrong type of array property."); + CU_DEBUG("wrong type of %s property.", array_name); + goto out; + } + ret_result[count] = elem.value.uint16; + count++; + } + out: + *ret_size = count; + return s; +} + +CMPIStatus get_array_string_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + char **ret_result, + int *ret_size, + int max_size) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIArray *array; + CMPICount array_size; + CMPIData elem; + const char *str; + int i, ret, count = 0; + + ret = cu_get_array_prop(inst, array_name, &array); + if (ret != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "array property not found."); + CU_DEBUG("Failed to get array property %s.", array_name); + goto out; + } + array_size = CMGetArrayCount(array, &s); + if ((s.rc != CMPI_RC_OK) || (array_size > max_size) || + (array_size <= 0)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to get size of array property," + " or its size is 0 or too big."); + CU_DEBUG("failed in getting size of %s property.", array_name); + goto out; + } + for (i = 0; i < array_size; i++) { + elem = CMGetArrayElementAt(array, i, NULL); + if (CMIsNullValue(elem)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "NULL content of array property."); + CU_DEBUG("NULL content of %s property.", array_name); + goto out; + } + str = NULL; + str = CMGetCharPtr(elem.value.string); + if (str == NULL) { + CU_DEBUG("Could not extract char pointer from " + "CMPIArray %s.", array_name); + goto out; + } + ret_result[count] = SAFE_STRDUP(str); + count++; + } + out: + *ret_size = count; + return s; +} diff --git a/libxkutil/network_model.h b/libxkutil/network_model.h new file mode 100644 index 0000000..3452836 --- /dev/null +++ b/libxkutil/network_model.h @@ -0,0 +1,105 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef NETWORK_MODEL_H +#define NETWORK_MODEL_H + +#include "host_network_API.h" + +#define EASD_TYPE_EA 1 +#define EASD_TYPE_EC 2 + +#define NETWORK_CLASS_PREFIX "Net" + +#define SWITCH_PREFIX "VS_" +#define VESSD_SYSTEM_PREFIX "Virt" +#define ETHPORT_PREFIX "EP_" +#define ETHPORT_ALLOCATION_SD_PREFIX "EA_" +#define ETHPORT_CONNECTION_SD_PREFIX "EC_" + +#define CONNECTION_VLAN_PREFIX "VLAN" + +#define CIM_NUM_NET_ETHERNET 2 +#define CIM_NUM_SWITCH_DEDICATED 38 +#define CIM_NUM_SWITCHPORT 30 +#define CIM_NUM_VLAN_MODE_TRUNK 5 +#define CIM_NUM_CONSUMERVISIBILITY_PASSEDTHROUGH 2 +#define CIM_NUM_CONSUMERVISIBILITY_VIRTUALIZED 3 + +char *get_switch_name_from_iface(const char *iface_name); +char *get_iface_name_from_switch(const char *switch_name); + +char *get_ethport_name_from_iface(const char *iface_name); +char *get_iface_name_from_ethport(const char *ethport_name); + +char *get_ethportsd_name_from_iface(const char *iface_name, const int type); +char *get_iface_name_from_ethportsd(const char *ethport_name, int *ptype); + +char *ep_id_to_easdea_id(const char *epid); +char *easdea_id_to_ep_id(const char *epid); +char *ep_id_to_easdec_id(const char *epid); +char *easdec_id_to_ep_id(const char *epid); + +char *vlanid_to_connection_name(const int id); +int vlanid_from_connection_name(const char *name); + + + + + +int eth_iface_filter_cim_switch(const EthIface *piface, + void *nouse); +int eth_iface_filter_cim_switch_for_name(const EthIface *piface, + void *name); +int eth_iface_filter_cim_ethport(const EthIface *piface, + void *nouse); +int eth_iface_filter_cim_ethport_for_name(const EthIface *piface, + void *name); + +int get_possible_bridge_name_for_cim_model(EthIface *piface, + char **pbr1name, char **pbr2name); + + +char *compare_and_switch_prefix(const char *orig_str, + const char *orig_prefix, + const char *dest_prefix); + +char *switch_device_id_prefix(const char *whole_id, + const char *orig_prefix, + const char *dest_prefix); + +/* other help function related to CIM */ +CMPIStatus get_array_uint16_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + int *ret_result, + int *ret_size, + int max_size); + +CMPIStatus get_array_string_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + char **ret_result, + int *ret_size, + int max_size); + + +#endif diff --git a/src/Virt_HostSystem.c b/src/Virt_HostSystem.c index 724a5ea..de8ec13 100644 --- a/src/Virt_HostSystem.c +++ b/src/Virt_HostSystem.c @@ -76,7 +76,7 @@ static int resolve_host(char *host, char *buf, int size) return 0; } -static int get_fqdn(char *buf, int size) +int get_fqdn(char *buf, int size) { char host[256]; int ret = 0; diff --git a/src/Virt_HostSystem.h b/src/Virt_HostSystem.h index 53ebf1c..3b988c1 100644 --- a/src/Virt_HostSystem.h +++ b/src/Virt_HostSystem.h @@ -21,6 +21,8 @@ #ifndef __VIRT_HOSTSYSTEM_H #define __VIRT_HOSTSYSTEM_H +int get_fqdn(char *buf, int size); + CMPIStatus get_host(const CMPIBroker *broker, const CMPIContext *context, const CMPIObjectPath *reference, diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 21979c3..cd1672f 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -1,9 +1,8 @@ /* - * Copyright IBM Corp. 2007 + * Copyright IBM Corp. 2011 * * Authors: - * Dan Smith - * Jay Gagnon + * Wayne Xia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -234,11 +233,11 @@ static CMPIStatus check_uuid_in_use(const CMPIObjectPath *ref, return s; } -static CMPIStatus define_system_parse_args(const CMPIArgs *argsin, - CMPIInstance **sys, - const char *ns, - CMPIArray **res, - CMPIObjectPath **refconf) +CMPIStatus define_system_parse_args(const CMPIArgs *argsin, + CMPIInstance **sys, + const char *ns, + CMPIArray **res, + CMPIObjectPath **refconf) { CMPIStatus s = {CMPI_RC_OK, NULL}; @@ -2877,7 +2876,7 @@ static CMPIStatus _update_resources_for(const CMPIContext *context, return s; } -static CMPIStatus get_instanceid(CMPIInstance *rasd, +CMPIStatus get_instanceid(CMPIInstance *rasd, char **domain, char **devid) { diff --git a/src/Virt_VirtualSystemManagementService.h b/src/Virt_VirtualSystemManagementService.h index dbf17cb..eba7124 100644 --- a/src/Virt_VirtualSystemManagementService.h +++ b/src/Virt_VirtualSystemManagementService.h @@ -29,6 +29,16 @@ #define INC_KVM_WEIGHT 1 #define DEFAULT_KVM_WEIGHT 1024 +CMPIStatus get_instanceid(CMPIInstance *rasd, + char **domain, + char **devid); + +CMPIStatus define_system_parse_args(const CMPIArgs *argsin, + CMPIInstance **sys, + const char *ns, + CMPIArray **res, + CMPIObjectPath **refconf); + CMPIStatus get_vsms(const CMPIObjectPath *reference, CMPIInstance **_inst, const CMPIBroker *broker, -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:46 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:46 +0800 Subject: [Libvirt-cim] [PATCH 13/15] vlan extension - function lib - add the core structure In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-9-git-send-email-xiawenc@linux.vnet.ibm.com> this is the core abstraction and structure for ethernet devices. Signed-off-by: Wayne Xia --- libxkutil/host_network_basic.c | 639 ++++++++++++++++++++++++++++++++++++++++ libxkutil/host_network_basic.h | 166 +++++++++++ 2 files changed, 805 insertions(+), 0 deletions(-) create mode 100644 libxkutil/host_network_basic.c create mode 100644 libxkutil/host_network_basic.h diff --git a/libxkutil/host_network_basic.c b/libxkutil/host_network_basic.c new file mode 100644 index 0000000..3bcb32e --- /dev/null +++ b/libxkutil/host_network_basic.c @@ -0,0 +1,639 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +#include "host_network_basic.h" +#include "host_network_helper.h" + +#include +#include +#include + +static void vlan_prop_print(VLAN_Prop *pvlan_prop) +{ + VLAN_Prop_8021q *p_8021q; + char *ingress = NULL, *egress = NULL; + CMD_DEBUG(1, "--VLAN props: type %d.\n", + pvlan_prop->vlan_type); + if (pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) { + p_8021q = &(pvlan_prop->props.prop_8021q); + vlan_8021q_qos_num_to_str(&ingress, &(p_8021q->ingress)); + vlan_8021q_qos_num_to_str(&egress, &(p_8021q->egress)); + CMD_DEBUG(1, "----IEEE802.1.Q: id %d, reorder %d, priority %d, " + "ingress %s, egress %s, parent %s.\n", + p_8021q->vlan_id, p_8021q->reorder_hdr, p_8021q->priv_flag, + ingress, egress, p_8021q->parent); + } + SAFE_FREE(ingress); + SAFE_FREE(egress); +} + +static void br_prop_print(BR_Prop *pbr_prop) +{ + int i = 0; + CMD_DEBUG(1, "--Bridge props: id %s, stp %d, " + "bridge type %d, port_num %d.\n", + pbr_prop->bridge_id, pbr_prop->STP, + pbr_prop->type, pbr_prop->port_num); + if (pbr_prop->port_names != NULL) { + CMD_DEBUG(1, "----Ports attached: "); + while (i < pbr_prop->port_num) { + CMD_DEBUG(1, " %s,", *(pbr_prop->port_names+i)); + i++; + } + CMD_DEBUG(1, "\n"); + } +} + +void eth_iface_print(EthIface *piface) +{ + CMD_DEBUG(1, "Iface device: name %s.\n" + "--Main Props: parent %s, attach to %s, mac %s, ip %s, ip_mask %s," + " RX %lld, TX %lld, state %d, iface type %d.\n", + piface->name, piface->dep_ifname, piface->attach_bridge, + piface->mac, piface->ipv4_prop.ip, piface->ipv4_prop.ip_mask, + piface->run_prop.rx_bytes, piface->run_prop.tx_bytes, + piface->run_prop.state, piface->eth_type); + if (piface->pbr_prop != NULL) { + br_prop_print(piface->pbr_prop); + } + if (piface->pvlan_prop != NULL) { + vlan_prop_print(piface->pvlan_prop); + } + return; +} + +void eth_ifaceslist_print(EthIfacesList *plist) +{ + int i = 0; + CMD_DEBUG(1, "Have %d ifaces in the list:\n", plist->count); + while (i < plist->count) { + CMD_DEBUG(1, "%04d ", i); + eth_iface_print(plist->pifaces[i]); + i++; + } +} + +void vlan_prop_init(VLAN_Prop *pvlan_prop, int vlan_type) +{ + VLAN_Prop_8021q *p_8021q; + memset(pvlan_prop, 0, sizeof(VLAN_Prop)); + pvlan_prop->vlan_type = vlan_type; + if (pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) { + p_8021q = &(pvlan_prop->props.prop_8021q); + p_8021q->ingress.count = NUM_NOT_GOT; + p_8021q->egress.count = NUM_NOT_GOT; + p_8021q->vlan_id = NUM_NOT_GOT; + p_8021q->reorder_hdr = NUM_NOT_GOT; + p_8021q->priv_flag = NUM_NOT_GOT; + } +} + +void br_prop_init(BR_Prop *pbr_prop) +{ + memset(pbr_prop, 0, sizeof(BR_Prop)); + pbr_prop->STP = NUM_NOT_GOT; + pbr_prop->type = BR_TYPE_NOT_GOT; + pbr_prop->port_num = NUM_NOT_GOT; +} + +void eth_iface_init(EthIface *piface) +{ + memset(piface, 0, sizeof(EthIface)); + piface->eth_type = ETH_TYPE_NOT_GOT; + piface->run_prop.rx_bytes = NUM_NOT_GOT; + piface->run_prop.tx_bytes = NUM_NOT_GOT; + piface->run_prop.state = ETH_STATE_NOT_GOT; + return; +} + +void eth_iface_add_br_prop(EthIface *piface) +{ + SAFE_MALLOC(piface->pbr_prop, sizeof(BR_Prop)); + br_prop_init(piface->pbr_prop); +} + +void eth_iface_add_vlan_prop(EthIface *piface, int vlan_type) +{ + SAFE_MALLOC(piface->pvlan_prop, sizeof(VLAN_Prop)); + vlan_prop_init(piface->pvlan_prop, vlan_type); +} + +void vlan_prop_uninit(VLAN_Prop *pvlan_prop) +{ + VLAN_Prop_8021q *p_8021q; + if (pvlan_prop == NULL) { + return; + } + if (pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) { + p_8021q = &(pvlan_prop->props.prop_8021q); + SAFE_FREE(p_8021q->parent); + } +} + +void br_prop_uninit(BR_Prop *pbr_prop) +{ + int i; + if (pbr_prop == NULL) { + return; + } + SAFE_FREE(pbr_prop->bridge_id); + i = 0; + if (pbr_prop->port_names != NULL) { + while (i < pbr_prop->port_num) { + SAFE_FREE(pbr_prop->port_names[i]); + i++; + } + SAFE_FREE(pbr_prop->port_names); + } +} + +void eth_iface_uninit(EthIface *piface) +{ + if (piface == NULL) { + return; + } + SAFE_FREE(piface->name); + SAFE_FREE(piface->dep_ifname); + SAFE_FREE(piface->attach_bridge); + SAFE_FREE(piface->mac); + SAFE_FREE(piface->ipv4_prop.ip); + SAFE_FREE(piface->ipv4_prop.ip_mask); + br_prop_uninit(piface->pbr_prop); + SAFE_FREE(piface->pbr_prop); + vlan_prop_uninit(piface->pvlan_prop); + SAFE_FREE(piface->pvlan_prop); + return; +} + +void eth_ifaces_clear(EthIface **ppifaces, int num) +{ + EthIface **t; + int i; + if (num <= 0) { + return; + } + t = ppifaces; + i = 0; + while (i < num) { + if (*t != NULL) { + eth_iface_uninit(*t); + SAFE_FREE(*t); + } + t++; + i++; + } + return; +} + +void eth_ifaceslist_init(EthIfacesList *plist) +{ + plist->count = 0; +} + +void eth_ifaceslist_uninit(EthIfacesList *plist) +{ + eth_ifaces_clear(plist->pifaces, plist->count); +} + +static void vlan_prop_dup(VLAN_Prop *dest, const VLAN_Prop *src) +{ + VLAN_Prop_8021q *pd_8021q; + const VLAN_Prop_8021q *ps_8021q; + dest->vlan_type = src->vlan_type; + if (dest->vlan_type == VLAN_TYPE_802_1_Q) { + pd_8021q = &(dest->props.prop_8021q); + ps_8021q = &(src->props.prop_8021q); + pd_8021q->vlan_id = ps_8021q->vlan_id; + pd_8021q->reorder_hdr = ps_8021q->reorder_hdr; + pd_8021q->priv_flag = ps_8021q->priv_flag; + pd_8021q->ingress = ps_8021q->ingress; + pd_8021q->egress = ps_8021q->egress; + pd_8021q->parent = SAFE_STRDUP(ps_8021q->parent); + } +} + +static void br_prop_dup(BR_Prop *dest, const BR_Prop *src) +{ + int i; + dest->bridge_id = SAFE_STRDUP(src->bridge_id); + dest->STP = src->STP; + dest->type = src->type; + SAFE_PSTR_ARRAY_DUP(dest->port_names, dest->port_num, + src->port_names, src->port_num, i); +} + +void eth_iface_dup(EthIface *dest, const EthIface *src) +{ + dest->name = SAFE_STRDUP(src->name); + dest->dep_ifname = SAFE_STRDUP(src->dep_ifname); + dest->attach_bridge = SAFE_STRDUP(src->attach_bridge); + dest->mac = SAFE_STRDUP(src->mac); + dest->eth_type = src->eth_type; + dest->ipv4_prop.ip = SAFE_STRDUP(src->ipv4_prop.ip); + dest->ipv4_prop.ip_mask = SAFE_STRDUP(src->ipv4_prop.ip_mask); + dest->run_prop.rx_bytes = src->run_prop.rx_bytes; + dest->run_prop.tx_bytes = src->run_prop.tx_bytes; + dest->run_prop.state = src->run_prop.state; + + if (src->pbr_prop != NULL) { + SAFE_MALLOC(dest->pbr_prop, sizeof(BR_Prop)); + /* doesn't need init it for that it would be copied at once */ + br_prop_dup(dest->pbr_prop, src->pbr_prop); + } else { + dest->pbr_prop = NULL; + } + + if (src->pvlan_prop != NULL) { + SAFE_MALLOC(dest->pvlan_prop, sizeof(VLAN_Prop)); + /* doesn't need init it for that it would be copied at once */ + vlan_prop_dup(dest->pvlan_prop, src->pvlan_prop); + } else { + dest->pvlan_prop = NULL; + } + +} + +int eth_iface_compare(const EthIface *p1, const EthIface *p2) +{ + int ret = 0; + if ((p1->name != NULL) || (p2->name != NULL)) { + if (0 == strcmp(p1->name, p2->name)) { + ret = 1; + } + } + return ret; +} + +static void vlan_prop_merge(VLAN_Prop *pdest, VLAN_Prop *psrc, int style) +{ + VLAN_Prop_8021q *pd_8021q, *ps_8021q; + + NUM_MERGE(pdest->vlan_type, psrc->vlan_type, VLAN_TYPE_NOT_GOT); + + if (psrc->vlan_type == VLAN_TYPE_802_1_Q) { + pd_8021q = &(pdest->props.prop_8021q); + ps_8021q = &(psrc->props.prop_8021q); + NUM_MERGE(pd_8021q->vlan_id, ps_8021q->vlan_id, NUM_NOT_GOT); + NUM_MERGE(pd_8021q->reorder_hdr, ps_8021q->reorder_hdr, NUM_NOT_GOT); + NUM_MERGE(pd_8021q->priv_flag, ps_8021q->priv_flag, NUM_NOT_GOT); + if (pd_8021q->ingress.count == NUM_NOT_GOT) { + pd_8021q->ingress = ps_8021q->ingress; + } + if (pd_8021q->egress.count == NUM_NOT_GOT) { + pd_8021q->egress = ps_8021q->egress; + } + if (style == 0) { + CHARS_MERGE_NORMAL(pd_8021q->parent, ps_8021q->parent); + } else { + CHARS_MERGE_MOVE(pd_8021q->parent, ps_8021q->parent); + } + } +} + +static void br_prop_merge(BR_Prop *pdest, BR_Prop *psrc, int style) +{ + int i; + + if (style == 0) { + CHARS_MERGE_NORMAL(pdest->bridge_id, psrc->bridge_id); + /*merge it when dest have not been set */ + if (pdest->port_names == NULL) { + SAFE_PSTR_ARRAY_DUP(pdest->port_names, pdest->port_num, + psrc->port_names, psrc->port_num, i); + } + } else { + CHARS_MERGE_MOVE(pdest->bridge_id, psrc->bridge_id); + /*merge it when dest have not been set */ + if (pdest->port_names == NULL) { + pdest->port_names = psrc->port_names; + pdest->port_num = psrc->port_num; + psrc->port_names = NULL; + psrc->port_num = NUM_NOT_GOT; + } + } + NUM_MERGE(pdest->STP, psrc->STP, NUM_NOT_GOT); + NUM_MERGE(pdest->type, psrc->type, BR_TYPE_NOT_GOT); +} + +void eth_iface_merge(EthIface *dest, EthIface *src, int style) +{ + if (style == 0) { + CHARS_MERGE_NORMAL(dest->name, src->name); + CHARS_MERGE_NORMAL(dest->dep_ifname, src->dep_ifname); + CHARS_MERGE_NORMAL(dest->attach_bridge, src->attach_bridge); + CHARS_MERGE_NORMAL(dest->mac, src->mac); + CHARS_MERGE_NORMAL(dest->ipv4_prop.ip, src->ipv4_prop.ip); + CHARS_MERGE_NORMAL(dest->ipv4_prop.ip_mask, src->ipv4_prop.ip_mask); + } else { + CHARS_MERGE_MOVE(dest->name, src->name); + CHARS_MERGE_MOVE(dest->dep_ifname, src->dep_ifname); + CHARS_MERGE_MOVE(dest->attach_bridge, src->attach_bridge); + CHARS_MERGE_MOVE(dest->mac, src->mac); + CHARS_MERGE_MOVE(dest->ipv4_prop.ip, src->ipv4_prop.ip); + CHARS_MERGE_MOVE(dest->ipv4_prop.ip_mask, src->ipv4_prop.ip_mask); + } + NUM_MERGE(dest->eth_type, src->eth_type, ETH_TYPE_NOT_GOT); + NUM_MERGE(dest->run_prop.rx_bytes, src->run_prop.rx_bytes, + NUM_NOT_GOT); + NUM_MERGE(dest->run_prop.tx_bytes, src->run_prop.tx_bytes, + NUM_NOT_GOT); + NUM_MERGE(dest->run_prop.state, src->run_prop.state, ETH_STATE_NOT_GOT); + + if (src->pbr_prop != NULL) { + if (dest->pbr_prop == NULL) { + SAFE_MALLOC(dest->pbr_prop, sizeof(BR_Prop)); + br_prop_init(dest->pbr_prop); + } + br_prop_merge(dest->pbr_prop, src->pbr_prop, style); + } + + if (src->pvlan_prop != NULL) { + if (dest->pvlan_prop == NULL) { + SAFE_MALLOC(dest->pvlan_prop, sizeof(VLAN_Prop)); + vlan_prop_init(dest->pvlan_prop, src->pvlan_prop->vlan_type); + } + vlan_prop_merge(dest->pvlan_prop, src->pvlan_prop, style); + } + +} + +/* compare qos values */ +static int VLAN_Qos_8021q_compare_by_ref(const VLAN_Qos_8021q *pqos, + const VLAN_Qos_8021q *pref) +{ + int ret = 1; + int i, j; + if (pref->count == NUM_NOT_GOT) { + /* do not need to compare*/ + goto out; + } + if ((pref->count < 0) || (pref->count > 8)) { + ret = 0; + goto out; + } + if ((pqos->count < 0) || (pqos->count > 8)) { + ret = 0; + goto out; + } + + i = 0; + while (i < pref->count) { + j = 0; + while (j < pqos->count) { + if (pref->values[i].from == pqos->values[j].from) { + if (pref->values[i].to != pqos->values[j].to) { + ret = 0; + goto out; + } + break; + } + j++; + } + if (j == pqos->count) { + ret = 0; + goto out; + } + i++; + } + + out: + return ret; +} + +static int vlan_prop_filter_by_ref(const VLAN_Prop *pvlan_prop, void *pref) +{ + int compare_result = 1; + VLAN_Prop *ref = (VLAN_Prop *)pref; + char *p1, *p2; + const VLAN_Prop_8021q *pd_8021q; + VLAN_Prop_8021q *pref_8021q; + + NUM_COMPARE_BY_REF(pvlan_prop->vlan_type, ref->vlan_type, + compare_result, VLAN_TYPE_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + if (ref->vlan_type == VLAN_TYPE_802_1_Q) { + pd_8021q = &(pvlan_prop->props.prop_8021q); + pref_8021q = &(ref->props.prop_8021q); + + NUM_COMPARE_BY_REF(pd_8021q->vlan_id, pref_8021q->vlan_id, + compare_result, NUM_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + NUM_COMPARE_BY_REF(pd_8021q->reorder_hdr, pref_8021q->reorder_hdr, + compare_result, NUM_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + NUM_COMPARE_BY_REF(pd_8021q->priv_flag, pref_8021q->priv_flag, + compare_result, NUM_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + compare_result = VLAN_Qos_8021q_compare_by_ref(&(pd_8021q->ingress), + &(pref_8021q->ingress)); + if (compare_result == 0) { + goto out; + } + + compare_result = VLAN_Qos_8021q_compare_by_ref(&(pd_8021q->egress), + &(pref_8021q->egress)); + if (compare_result == 0) { + goto out; + } + + p1 = pd_8021q->parent; + p2 = pref_8021q->parent; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + } + + out: + return compare_result; + +} + +static int br_prop_filter_by_ref(const BR_Prop *pbr_prop, void *pref) +{ + int compare_result = 1; + BR_Prop *ref = (BR_Prop *)pref; + char *p1, *p2; + + p1 = pbr_prop->bridge_id; + p2 = ref->bridge_id; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + NUM_COMPARE_BY_REF(pbr_prop->STP, ref->STP, + compare_result, NUM_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + NUM_COMPARE_BY_REF(pbr_prop->type, ref->type, + compare_result, BR_TYPE_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + NUM_COMPARE_BY_REF(pbr_prop->port_num, ref->port_num, + compare_result, NUM_NOT_GOT); + /* skip the comparation of ports it attached, user can define + a special filter for that */ + out: + return compare_result; +} + +int eth_iface_filter_by_ref(const EthIface *piface, void *pref) +{ + int compare_result = 1; + EthIface *ref = (EthIface *)pref; + char *p1, *p2; + + p1 = piface->name; + p2 = ref->name; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + p1 = piface->dep_ifname; + p2 = ref->dep_ifname; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + p1 = piface->attach_bridge; + p2 = ref->attach_bridge; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + p1 = piface->mac; + p2 = ref->mac; + CHARS_COMPARE_CASE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + NUM_COMPARE_BY_REF(piface->eth_type, ref->eth_type, + compare_result, ETH_TYPE_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + p1 = piface->ipv4_prop.ip; + p2 = ref->ipv4_prop.ip; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + p1 = piface->ipv4_prop.ip_mask; + p2 = ref->ipv4_prop.ip_mask; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + NUM_COMPARE_BY_REF(piface->run_prop.state, ref->run_prop.state, + compare_result, ETH_STATE_NOT_GOT); + if (compare_result == 0) { + goto out; + } + + if (ref->pbr_prop != NULL) { + if (piface->pbr_prop != NULL) { + compare_result = br_prop_filter_by_ref(piface->pbr_prop, + ref->pbr_prop); + } else { + compare_result = 0; + } + if (compare_result == 0) { + goto out; + } + } + + if (ref->pvlan_prop != NULL) { + if (piface->pvlan_prop != NULL) { + compare_result = vlan_prop_filter_by_ref(piface->pvlan_prop, + ref->pvlan_prop); + + } else { + compare_result = 0; + } + if (compare_result == 0) { + goto out; + } + } + + out: + return compare_result; +} + +int eth_iface_filter_by_refname(const EthIface *piface, void *pref) +{ + int compare_result = 1; + EthIface *ref = (EthIface *)pref; + char *p1, *p2; + + p1 = piface->name; + p2 = ref->name; + CHARS_COMPARE_BY_REF(p1, p2, compare_result); + if (compare_result == 0) { + goto out; + } + + out: + return compare_result; +} + +int eth_iface_filter_vlans(const EthIface *piface, void *nouse) +{ + if (piface->name == NULL) { + return 0; + } + if (NULL == strstr(piface->name, ".")) { + return 0; + } else { + return 1; + } +} + +/* the judgement condition is weak, but I can't find a better way */ +int eth_iface_filter_peths(const EthIface *piface, void *nouse) +{ + if (piface->name == NULL) { + return 0; + } + if (NULL == strstr(piface->name, ".")) { + if (0 == strncmp(piface->name, "eth", 3)) { + return 1; + } else { + return 0; + } + } else { + return 0; + } +} diff --git a/libxkutil/host_network_basic.h b/libxkutil/host_network_basic.h new file mode 100644 index 0000000..d1dd128 --- /dev/null +++ b/libxkutil/host_network_basic.h @@ -0,0 +1,166 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +#ifndef NETWORK_BASIC_HOST_H +#define NETWORK_BASIC_HOST_H + +/* value defines */ +#define MAX_IFACE_NUM 4096 + +#define NUM_NOT_GOT -1 + +typedef enum { + ETH_STATE_NOT_GOT = NUM_NOT_GOT, + ETH_STATE_UNKNOWN = 0, + ETH_STATE_DOWN = 1, + ETH_STATE_UP = 2 +} EthState; + +typedef enum { + ETH_TYPE_NOT_GOT = NUM_NOT_GOT, + ETH_TYPE_UNKNOWN = 0, + ETH_TYPE_LOOPBACK = 1, + ETH_TYPE_PHYSICAL = 2, + ETH_TYPE_NORMAL = 4, + ETH_TYPE_BRIDGE = 8, + ETH_TYPE_VLAN = 16 +} EthType; + +typedef enum { + BR_TYPE_NOT_GOT = NUM_NOT_GOT, + BR_TYPE_UNKNOWN = 0, + BR_TYPE_SWITCH = 1, + BR_TYPE_NAT = 2 +} BrType; + +typedef enum { + VLAN_TYPE_NOT_GOT = NUM_NOT_GOT, + VLAN_TYPE_802_1_Q = 1, + VLAN_TYPE_802_1_QBG = 2, + VLAN_TYPE_802_1_QBH = 4 +} VLANType; + +/* structure defines */ +typedef struct IPV4_Prop { + char *ip; + char *ip_mask; +} IPV4_Prop; + +typedef struct BR_Prop { + char *bridge_id; + int STP; + BrType type; + char **port_names; + int port_num; +} BR_Prop; + +typedef struct Run_Prop { + long long rx_bytes; + long long tx_bytes; + EthState state; +} Run_Prop; + +typedef struct VLAN_Qos_8021q_elem { + int from; + int to; +} VLAN_Qos_8021q_elem; + +typedef struct VLAN_Qos_8021q { + VLAN_Qos_8021q_elem values[8]; + int count; +} VLAN_Qos_8021q; + +typedef struct VLAN_Prop_8021q { + int vlan_id; + int reorder_hdr; + int priv_flag; + VLAN_Qos_8021q ingress; + VLAN_Qos_8021q egress; + char *parent; +} VLAN_Prop_8021q; + +/* HP vlan standard, TBD */ +typedef struct VLAN_Prop_8021qbg { + int invalid; +} VLAN_Prop_8021qbg; + +/* Cisco and VMware vlan standard, TBD */ +typedef struct VLAN_Prop_8021qbh { + int invalid; +} VLAN_Prop_8021qbh; + +typedef struct VLAN_Prop { + int vlan_type; + union { + VLAN_Prop_8021q prop_8021q; + VLAN_Prop_8021qbg prop_8021qbg; + VLAN_Prop_8021qbh prop_8021qbh; + } props; +} VLAN_Prop; + +/* EthIface is logical devices include eth ports and bridges */ +typedef struct EthIface { + char *name; + char *dep_ifname; /* parent dev name */ + char *attach_bridge; /* bridge the iface is attached to */ + char *mac; + EthType eth_type; + Run_Prop run_prop; + IPV4_Prop ipv4_prop; + /* optional properties */ + BR_Prop *pbr_prop; + VLAN_Prop *pvlan_prop; +} EthIface; + +typedef struct EthIfacesList { + EthIface *pifaces[MAX_IFACE_NUM]; + int count; +} EthIfacesList; + +typedef int (*eth_iface_filter_func)(const EthIface *piface, void *opaque); + +/* uninit functions are only called when there is resource malloc */ +void vlan_prop_init(VLAN_Prop *pvlan_prop, int vlan_type); +void vlan_prop_uninit(VLAN_Prop *pvlan_prop); + +void br_prop_init(BR_Prop *pbr_prop); +void br_prop_uninit(BR_Prop *pbr_prop); + +void eth_iface_print(EthIface *piface); +void eth_iface_init(EthIface *piface); +void eth_iface_add_br_prop(EthIface *piface); +void eth_iface_add_vlan_prop(EthIface *piface, int vlan_type); +void eth_iface_uninit(EthIface *piface); +void eth_ifaces_clear(EthIface **ppifaces, int num); + +void eth_ifaceslist_init(EthIfacesList *plist); +void eth_ifaceslist_uninit(EthIfacesList *plist); +void eth_ifaceslist_print(EthIfacesList *plist); + +/* this function assume dest have been uninited if it was used before*/ +void eth_iface_dup(EthIface *dest, const EthIface *src); + +/* see if it is refered to the same device */ +int eth_iface_compare(const EthIface *p1, const EthIface *p2); + +/* merge the properties that dest do not have value set, if style is set to 1, + the char* properties was moved instead of copy, safely reduce the memory + fragments, but src is modified. */ +void eth_iface_merge(EthIface *dest, EthIface *src, int style); + +int eth_iface_filter_by_ref(const EthIface *piface, void *pref); +int eth_iface_filter_by_refname(const EthIface *piface, void *pref); +int eth_iface_filter_vlans(const EthIface *piface, void *nouse); +int eth_iface_filter_peths(const EthIface *piface, void *nouse); + + +#endif -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:47 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:47 +0800 Subject: [Libvirt-cim] [PATCH 14/15] vlan extension - function lib - add the helper functions In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-10-git-send-email-xiawenc@linux.vnet.ibm.com> this is the helper function for the lib. Signed-off-by: Wayne Xia --- libxkutil/host_network_error.h | 28 ++ libxkutil/host_network_helper.c | 659 +++++++++++++++++++++++++++++++++++++++ libxkutil/host_network_helper.h | 192 ++++++++++++ 3 files changed, 879 insertions(+), 0 deletions(-) create mode 100644 libxkutil/host_network_error.h create mode 100644 libxkutil/host_network_helper.c create mode 100644 libxkutil/host_network_helper.h diff --git a/libxkutil/host_network_error.h b/libxkutil/host_network_error.h new file mode 100644 index 0000000..d809033 --- /dev/null +++ b/libxkutil/host_network_error.h @@ -0,0 +1,28 @@ +#ifndef HOST_NETWORK_ERROR_H +#define HOST_NETWORK_ERROR_H + +#define ERR_REQUEST_NOT_SUPPORT -1 + +#define ERR_COMMAND_NOT_SET -11 +#define ERR_COMMAND_PIPE_ERR -12 +#define ERR_COMMAND_NOT_SUPPORT -13 +#define ERR_COMMAND_NO_PERMISSION -14 +#define ERR_COMMAND_NO_READY -15 +#define ERR_COMMAND_PARAMETER_WRONG -16 +#define ERR_COMMAND_EXECUTION -17 + +#define ERR_DEVICE_EXCEED_MAXNUM -100 +#define ERR_DEVICE_EXIST -101 +#define ERR_DEVICE_NOT_EXIST -102 +#define ERR_DEVICE_ALREADY_DONE -103 +#define ERR_DEVICE_CONNECT_OTHER -104 + +#define ERR_FILE_OP_FAIL -125 +#define ERR_FILE_EMPTY -126 +#define ERR_FILE_TOO_LARGE -127 +#define ERR_FILE_CONT_TOO_LARGE -128 +#define ERR_FILE_LOCK_FAIL -129 + +#define ERR_PERSIST_NOT_REDHAT -200 + +#endif diff --git a/libxkutil/host_network_helper.c b/libxkutil/host_network_helper.c new file mode 100644 index 0000000..dc9f775 --- /dev/null +++ b/libxkutil/host_network_helper.c @@ -0,0 +1,659 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + + + +#include +#include +#include +#include +#include + +#include "host_network_helper.h" +#include "host_network_error.h" + +#define CONFIGURE_FILE_MAX_SIZE 2048 + +#define PIPE_CMD_SUFFIX " 2>&1" + +static int g_linux_version = LINUX_UNKNOWN; + +static int compare_qos_8021q(const void *p1, const void *p2) +{ + const VLAN_Qos_8021q_elem *qos1 = (VLAN_Qos_8021q_elem *)p1; + const VLAN_Qos_8021q_elem *qos2 = (VLAN_Qos_8021q_elem *)p2; + int ret = 0; + if ((qos1->from) > (qos2->from)) { + ret = 1; + } + return ret; +} + +/* it need to be checked see whether these are the conditions */ +int vlan_8021q_qos_check_valid(VLAN_Qos_8021q *pqos) +{ + int ret = 1; + int i = 0; + int last_num = -1; + if ((pqos->count < 0) || (pqos->count > 8)) { + ret = 0; + goto out; + } else if (pqos->count == 0) { + goto out; + } + qsort((void *)pqos->values, pqos->count, sizeof(VLAN_Qos_8021q_elem), + compare_qos_8021q); + + while (i < pqos->count) { + if (pqos->values[i].from == last_num) { + CU_DEBUG("error: vlan 802.1.q qos setting have same values: " + "last is %d, new is %d", last_num, pqos->values[i].from); + ret = 0; + goto out; + } + last_num = pqos->values[i].from; + if ((pqos->values[i].from < 0) || (pqos->values[i].from >= 8)) { + CU_DEBUG("error: vlan 802.1.q qos setting have outbound value: " + "from is %d.", pqos->values[i].from); + ret = 0; + goto out; + } + if ((pqos->values[i].to < 0) || (pqos->values[i].to >= 8)) { + CU_DEBUG("error: vlan 802.1.q qos setting have outbound value: " + "to is %d.", pqos->values[i].to); + ret = 0; + goto out; + } + i++; + } + + out: + return ret; +} + +int vlan_8021q_qos_str_to_num(VLAN_Qos_8021q *pqos, const char* str) +{ + int ret = 1; + char *str_line = NULL; + char *temp; + char *saveptr = NULL; + char *invalptr1, *invalptr2; + int qos_num1, qos_num2; + VLAN_Qos_8021q qos; + + if (str == NULL) { + ret = 0; + goto out; + } + if (str[0] == '\0') { + ret = 1; + pqos->count = 0; + CU_DEBUG("empty vlan 802.1.q qos string found."); + goto out; + } + str_line = SAFE_STRDUP(str); + qos.count = 0; + + temp = strtok_r(str_line, " ", &saveptr); + while (temp != NULL) { + qos_num1 = strtol(temp, &invalptr1, 10); + if (temp == invalptr1) { + ret = 0; + goto out; + } + if (*invalptr1 != ':') { + ret = 0; + goto out; + } + invalptr1++; + qos_num2 = strtol(invalptr1, &invalptr2, 10); + if (invalptr1 == invalptr2) { + ret = 0; + goto out; + } + if (*invalptr2 != '\0') { + ret = 0; + goto out; + } + if (qos.count >= 8) { + ret = 0; + CU_DEBUG("too many settings found in vlan 802.1.q qos string [%s]", + str); + goto out; + } + qos.values[qos.count].from = qos_num1; + qos.values[qos.count].to = qos_num2; + qos.count++; + temp = strtok_r(NULL, " ", &saveptr); + } + ret = vlan_8021q_qos_check_valid(&qos); + if (ret == 1) { + *pqos = qos; + } + + out: + if (ret != 1) { + CU_DEBUG("vlan 802.1.q qos string [%s] is invalid.", str); + } + SAFE_FREE(str_line); + return ret; +} + +int vlan_8021q_qos_num_to_str(char **str, const VLAN_Qos_8021q *pqos) +{ + char temp[16]; + int i; + VLAN_Qos_8021q qos = *pqos; + int ret = vlan_8021q_qos_check_valid(&qos); + if (ret != 1) { + goto out; + } + SAFE_MALLOC(*str, 64); + *str[0] = '\0'; + if (qos.count == 0) { + goto out; + } + i = 0; + snprintf(temp, sizeof(temp), "%d:%d", + qos.values[i].from, qos.values[i].to); + strcat(*str, temp); + i++; + while (i < qos.count) { + strcat(*str, " "); + snprintf(temp, sizeof(temp), "%d:%d", + qos.values[i].from, qos.values[i].to); + strcat(*str, temp); + i++; + } + + out: + return ret; +} + +int netmask_easy_to_inaddr(struct in_addr *paddr, const char* pmask) +{ + long mask_one_num = -1; + unsigned char *p; + int bitnum; + + mask_one_num = strtol(pmask, NULL, 10); + if ((mask_one_num < 0) || (mask_one_num > 32)) { + return 0; + } + + /* use network byte order */ + p = (unsigned char *)&paddr->s_addr; + memset(p, 0, 4); + while (mask_one_num > 8) { + *(p++) = 255; + mask_one_num -= 8; + } + bitnum = 7; + while (mask_one_num > 0) { + *p = *p + (1< 0) { + /* add the property */ + if ((cont_len + target_len) >= maxsize) { + CU_DEBUG("buffer is too small for the operation."); + valid_len = -1; + goto out; + } + strcat(cont, prefix); + strcat(cont, prop); + valid_len = cont_len + target_len; + } else { + /* remove the property, but it do not exist, so skip */ + } + } else { + /* the content exist in original contents */ + /* locate the end of the property */ + pprop_end = strstr(pprop_start, endchar1); + if (pprop_end == NULL) { + /* last line */ + origin_len = strlen(pprop_start); + pprop_end = cont+cont_len; + } else { + origin_len = pprop_end - pprop_start; + } + if (target_len > 0) { + /* change the property */ + /* check the bound */ + if ((cont_len + target_len - origin_len) >= maxsize) { + CU_DEBUG("buffer is too small for the operation."); + valid_len = -1; + goto out; + } + /* move contents in the tail */ + memmove(pprop_end+target_len-origin_len, pprop_end, + cont+cont_len+1-pprop_end); + /* copy the content of the new string */ + memcpy(pprop_start+prefix_len, prop, prop_len); + head_len = pprop_start - cont + prefix_len; + } else { + /* remove the property */ + /* move contents in the tail to replace original string*/ + memmove(pprop_end+target_len-origin_len, pprop_end, + cont+cont_len+1-pprop_end); + head_len = pprop_start - cont; + } + valid_len = cont_len + target_len - origin_len; + } + + out: + if (unchanged_len != NULL) { + *unchanged_len = head_len; + } + return valid_len; +} + +int configure_file_replace_attr(const char *path, const char *prefix, + const char *prop) +{ + int fd = -1; + int fop_ret; + struct stat s; + struct flock lock; + int lock_state = -1; + char *cont = NULL; + char *pbuff; + int write_len; + int cont_len_update; + int cont_len_unchanged; + int ret = 0; + + if ((prefix == NULL) || (*prefix == '\0')) { + CU_DEBUG("no prefix for property set, could not replace the content."); + goto out; + } + + fd = open(path, O_RDWR, 0644); + if (fd < 0) { + CU_DEBUG("Unable to open [%s], it does not exist.", path); + ret = ERR_FILE_OP_FAIL; + goto out; + } + + lock.l_type = F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + lock_state = fcntl(fd, F_SETLK, &lock); + if (lock_state < 0) { + CU_DEBUG("Failed to lock file [%s], it may be locked by other.", path); + ret = ERR_FILE_LOCK_FAIL; + goto out; + } + + fstat(fd, &s); + if (s.st_size == 0) { + CU_DEBUG("file [%s] is empty, will not replace attr for it.", path); + ret = ERR_FILE_EMPTY; + goto out; + } else if (s.st_size >= CONFIGURE_FILE_MAX_SIZE) { + CU_DEBUG("file [%s] is too large, " + "it have %lld bytes, will not read it.", + path, (long long)s.st_size); + ret = ERR_FILE_TOO_LARGE; + goto out; + } + + SAFE_MALLOC(cont, CONFIGURE_FILE_MAX_SIZE); + lseek(fd, 0, SEEK_SET); + fop_ret = read(fd, cont, s.st_size); + cont[s.st_size] = '\0'; + cont_len_update = replace_prop_str(cont, CONFIGURE_FILE_MAX_SIZE, + prefix, prop, &cont_len_unchanged); + if (cont_len_update < 0) { + CU_DEBUG("file [%s] is too big to expand it with [%s%s].", + path, prefix, prop); + ret = ERR_FILE_TOO_LARGE; + goto out; + } else if (cont_len_update == 0) { + CU_DEBUG("the contents was not changed, do not need update it"); + ret = 1; + goto out; + } else { + if (ftruncate(fd, cont_len_unchanged) != 0) { + CU_DEBUG("file [%s] Unable to truncate it", path); + ret = ERR_FILE_OP_FAIL; + goto out; + } + write_len = cont_len_update-cont_len_unchanged; + if (write_len > 0) { + lseek(fd, cont_len_unchanged, SEEK_SET); + CU_DEBUG("writing file [%s] for %d bytes with offset %d," + " cont is :\n%s\n", + path, write_len, cont_len_unchanged, cont); + pbuff = cont+cont_len_unchanged; + fop_ret = write(fd, pbuff, write_len); + } + } + ret = 1; + + out: + if (fd >= 0) { + if (lock_state >= 0) { + lock.l_type = F_UNLCK; + fcntl(fd, F_SETLK, &lock); + } + close(fd); + } + SAFE_FREE(cont); + return ret; +} + +int configure_file_update(const char *path, const char *cont) +{ + int fd = -1; + int fop_ret; + struct flock lock; + int lock_state = -1; + int write_len; + int ret = 0; + + fd = open(path, O_RDWR|O_CREAT, 0644); + if (fd < 0) { + CU_DEBUG("Unable to open [%s], it does not exist.", path); + ret = ERR_FILE_OP_FAIL; + goto out; + } + + lock.l_type = F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + lock_state = fcntl(fd, F_SETLK, &lock); + if (lock_state < 0) { + CU_DEBUG("Failed to lock file [%s], it may be locked by other.", path); + ret = ERR_FILE_LOCK_FAIL; + goto out; + } + + if (ftruncate(fd, 0) != 0) { + CU_DEBUG("file [%s] Unable to truncate it", path); + ret = ERR_FILE_OP_FAIL; + goto out; + } + + write_len = strlen(cont); + if (write_len > 0) { + lseek(fd, 0, SEEK_SET); + CU_DEBUG("writing file [%s] for %d bytes with offset 0," + " cont is :\n%s\n", + path, write_len, cont); + fop_ret = write(fd, cont, write_len); + } + ret = 1; + + out: + if (fd >= 0) { + if (lock_state >= 0) { + lock.l_type = F_UNLCK; + fcntl(fd, F_SETLK, &lock); + } + close(fd); + } + return ret; +} + +int configure_file_remove(const char *path) +{ + int fd_ret; + int ret = 0; + if (access(path, F_OK) == 0) { + CU_DEBUG("Deleting %s.", path); + fd_ret = remove(path); + if (fd_ret != 0) { + CU_DEBUG("failed to remove %s.", path); + ret = ERR_FILE_OP_FAIL; + goto out; + } + } + + ret = 1; + out: + return ret; +} + +FILE *pipe_excute_command_type_read(char *cmd, const int buf_size, + const char *type, int *errno) +{ + FILE *stream = NULL; + char *suffix = PIPE_CMD_SUFFIX; + if ((strlen(cmd) + strlen(suffix)) >= buf_size) { + CU_DEBUG("cmd [%s] is too long to append the suffix", cmd); + *errno = ERR_COMMAND_NO_READY; + goto out; + } + strcat(cmd, suffix); + CU_DEBUG("excuting readonly cmd [%s].", cmd); + stream = popen(cmd, type); + if (stream == NULL) { + CU_DEBUG("Failed to open pipe to run command"); + *errno = ERR_COMMAND_PIPE_ERR; + } + +out: + return stream; +} + +FILE *pipe_excute_command_type_write(char *cmd, const int buf_size, + const char *type, int *errno) +{ + FILE *stream = NULL; + char *suffix = PIPE_CMD_SUFFIX; + if ((strlen(cmd) + strlen(suffix)) >= buf_size) { + CU_DEBUG("cmd [%s] is too long to append the suffix", cmd); + *errno = ERR_COMMAND_NO_READY; + goto out; + } + strcat(cmd, suffix); + CU_DEBUG("excuting system modification cmd [%s].", cmd); + stream = popen(cmd, type); + if (stream == NULL) { + CU_DEBUG("Failed to open pipe to run command"); + *errno = ERR_COMMAND_PIPE_ERR; + } + usleep(10000); + +out: + return stream; +} + +int get_host_linux_version(void) +{ + FILE *stream = NULL; + char cmd[64]; + char buff[256]; + int linenum; + int errno; + + if (g_linux_version != LINUX_UNKNOWN) { + goto out; + } + + cmd[0] = '\0'; + strcat(cmd, "lsb_release -a"); + stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &errno); + if (stream == NULL) { + goto out; + } + + linenum = -1; + g_linux_version = LINUX_OTHER; + while (fgets(buff, 256, stream) != NULL) { + linenum++; + if (linenum == 0) { + if (NULL == strstr(buff, "LSB")) { + CU_DEBUG("ERR: unable to get linux distribution version."); + g_linux_version = LINUX_FAIL_TO_GET; + } + } + if ((NULL != strstr(buff, "Red Hat")) || + (NULL != strstr(buff, "RedHat"))) { + g_linux_version = LINUX_REDHAT; + break; + } + } + + out: + if (stream != NULL) { + pclose(stream); + } + return g_linux_version; +} + +char *translate_error_no(int errno) +{ + char *ret = NULL; + switch (errno) { + case ERR_REQUEST_NOT_SUPPORT: + ret = "request is not supported now"; + break; + + case ERR_COMMAND_NOT_SET: + ret = "command is not set."; + break; + case ERR_COMMAND_PIPE_ERR: + ret = "failed in creating pipe to execute the command."; + break; + case ERR_COMMAND_NOT_SUPPORT: + ret = "command is not found, check u environment."; + break; + case ERR_COMMAND_NO_PERMISSION: + ret = "not enough authority to execute the command."; + break; + case ERR_COMMAND_NO_READY: + ret = "failed to build up the command line, check your input, " + "maybe it is too long."; + break; + case ERR_COMMAND_PARAMETER_WRONG: + ret = "got invalid paramenter, check your input."; + break; + case ERR_COMMAND_EXECUTION: + ret = "error happened in the excution of command."; + break; + + case ERR_DEVICE_EXCEED_MAXNUM: + ret = "too many devices found or set, check the environment."; + break; + case ERR_DEVICE_EXIST: + ret = "device already exist, can not execute the command."; + break; + case ERR_DEVICE_NOT_EXIST: + ret = "device do not exist, can not execute the command."; + break; + case ERR_DEVICE_ALREADY_DONE: + ret = "the operation you want have been done before, " + "will not do it again."; + break; + case ERR_DEVICE_CONNECT_OTHER: + ret = "the device you want to connect have been connect to another" + " device, can't change it directly."; + break; + + case ERR_FILE_OP_FAIL: + ret = "failed in accessing the file."; + break; + case ERR_FILE_EMPTY: + ret = "the file it want is empty."; + break; + case ERR_FILE_TOO_LARGE: + ret = "the file it want is too large."; + break; + case ERR_FILE_CONT_TOO_LARGE: + ret = "the content it want to combine to file is too large."; + break; + case ERR_FILE_LOCK_FAIL: + ret = "failed in locking the file, " + "check if other process is using it."; + break; + + case ERR_PERSIST_NOT_REDHAT: + ret = "host is not a RedHat distribution, can't persist the " + "configuration, it would not take effect after host is " + "rebooted. Other version would be supported in the future. " + "If you are sure host is RedHat, make sure command " + " could work."; + break; + + default: + ret = "internal error."; + break; + } + return ret; +} diff --git a/libxkutil/host_network_helper.h b/libxkutil/host_network_helper.h new file mode 100644 index 0000000..a232221 --- /dev/null +++ b/libxkutil/host_network_helper.h @@ -0,0 +1,192 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + + +#ifndef HOST_NETWORK_HELPER_H +#define HOST_NETWORK_HELPER_H + +#include +#include +#include + +#include "host_network_basic.h" + +#ifdef TESTLIB +#include "TestDefines.h" +#else +#include +#endif + +#define LINUX_FAIL_TO_GET -2 +#define LINUX_UNKNOWN -1 +#define LINUX_OTHER 0 +#define LINUX_REDHAT 1 + +#define CMD_DEBUG_LEVEL 2 + +/* macro functions */ +#define CMD_DEBUG(lvl, fmt, args...) do { \ + if (CMD_DEBUG_LEVEL && (lvl) <= CMD_DEBUG_LEVEL) { \ + debug_print(fmt, ##args); \ + } \ +} while (0) + +#define SAFE_MALLOC(p, size) \ +{ \ + (p) = malloc((size)); \ + if ((p) == NULL) { \ + CU_DEBUG("malloc failed."); \ + } \ +} + +#define SAFE_CALLOC(p, nmen, size) \ +{ \ + (p) = calloc((nmen), (size)); \ + if ((p) == NULL) { \ + CU_DEBUG("calloc failed."); \ + } \ +} + +#define SAFE_FREE(p) {free(p); (p) = NULL; } + + +/* Macro used to compare two char*, it would skip if ref is NULL. It would + only set the result when src != ref, user need to set the result to 1 by + default before use the macro. If not set, the it could be used to do + check multi times in "one fail all die" mode. Empty lines is the place + where result should be set to 1. */ +#define CHARS_COMPARE_BY_REF(src, ref, result) do { \ + if ((ref) == NULL) { \ + ; \ + } else { \ + if ((src) == NULL) { \ + (result) = 0; \ + } else { \ + if (0 == strcmp((src), (ref))) { \ + ; \ + } else { \ + (result) = 0; \ + } \ + } \ + } \ +} while (0) + +#define CHARS_COMPARE_CASE_BY_REF(src, ref, result) do { \ + if ((ref) == NULL) { \ + ; \ + } else { \ + if ((src) == NULL) { \ + (result) = 0; \ + } else { \ + if (0 == strcasecmp((src), (ref))) { \ + ; \ + } else { \ + (result) = 0; \ + } \ + } \ + } \ +} while (0) + +#define NUM_COMPARE_BY_REF(src, ref, result, default) do { \ + if ((ref) == (default)) { \ + ; \ + } else { \ + if ((src) == (ref)) { \ + ; \ + } else { \ + result = 0; \ + } \ + } \ +} while (0) + +#define CHARS_MERGE_NORMAL(dest, src) do { \ + if (((dest) == NULL) && ((src) != NULL)) { \ + (dest) = strdup((src)); \ + } \ +} while (0) + +#define CHARS_MERGE_MOVE(dest, src) do { \ + if (((dest) == NULL) && ((src) != NULL)) { \ + (dest) = (src); \ + (src) = NULL; \ + } \ +} while (0) + +#define NUM_MERGE(dest, src, default) do { \ + if ((dest) == (default)) { \ + (dest) = (src); \ + } \ +} while (0) + +/* this macro may cause "p" to be excuted twice if it is a function */ +#define SAFE_STRDUP(p) (p) == NULL ? NULL : strdup(p); + +/* this macro make sure "src" to be excuted once if it is function, so it is + safe for functions that have state logged, such as "strtok" */ +#define SAFE_STRDUP_WITH_FUNC(dest, src, iter) do { \ + (iter) = (src); \ + if ((iter) == NULL) { \ + (dest) = NULL; \ + } else { \ + (dest) = strdup((iter)); \ + } \ +} while (0) + +#define SAFE_PSTR_ARRAY_DUP(ppdest, dest_num, ppsrc, src_num, iter) do { \ + (dest_num) = (src_num); \ + (ppdest) = NULL; \ + if (((ppsrc) != NULL) && ((src_num) > 0)) { \ + SAFE_CALLOC((ppdest), (src_num), sizeof(char *)); \ + (iter) = 0; \ + while ((iter) < (src_num)) { \ + *((ppdest)+(iter)) = SAFE_STRDUP(*((ppsrc)+(iter))); \ + (iter)++; \ + } \ + } \ +} while (0) + +/* functions */ +/* this function convert ip mask "24" in "192.1.0.9/24" to real mask num as + 255.255.255.0 */ +int netmask_easy_to_inaddr(struct in_addr *paddr, const char *pmask); + +/* this function would sort the pqos and check its values. */ +int vlan_8021q_qos_check_valid(VLAN_Qos_8021q *pqos); + +/* converting qos string of 802.1.Q, it should be as "0:0 1:0 2:0" */ +int vlan_8021q_qos_str_to_num(VLAN_Qos_8021q *pqos, const char *str); +int vlan_8021q_qos_num_to_str(char **str, const VLAN_Qos_8021q *pqos); + +/* following functions would return FILE popened, so it need pclose later, + cmd would be appended so it must be writable. */ +FILE *pipe_excute_command_type_read(char *cmd, const int buf_size, + const char *type, int *errno); +FILE *pipe_excute_command_type_write(char *cmd, const int buf_size, + const char *type, int *errno); + +/* following functions would return string by malloc, so it need free later */ +char *strtok_onetime(const char *str, const char *delim); +char *combine_file_name(const char *prefix, const char *name); + +/* write the configuration file */ +int configure_file_update(const char *path, const char *cont); +/* remove the configuration file */ +int configure_file_remove(const char *path); +/* replace one attribute, the file have format with one line for one propety */ +int configure_file_replace_attr(const char *path, const char *prefix, + const char *prop); + +int get_host_linux_version(void); + +char *translate_error_no(int errno); + +#endif -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:25:48 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 7 Dec 2011 17:25:48 +0800 Subject: [Libvirt-cim] [PATCH 15/15] vlan extension - function lib - add the implemention of commandline In-Reply-To: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249948-27761-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <1323249948-27761-11-git-send-email-xiawenc@linux.vnet.ibm.com> this file use tools ip, brctl, ifconfig to provide the functionalities. Signed-off-by: Wayne Xia --- libxkutil/host_network_implement_cmdline.c | 2002 ++++++++++++++++++++++++++++ libxkutil/host_network_implement_cmdline.h | 55 + 2 files changed, 2057 insertions(+), 0 deletions(-) create mode 100644 libxkutil/host_network_implement_cmdline.c create mode 100644 libxkutil/host_network_implement_cmdline.h diff --git a/libxkutil/host_network_implement_cmdline.c b/libxkutil/host_network_implement_cmdline.c new file mode 100644 index 0000000..fc9226b --- /dev/null +++ b/libxkutil/host_network_implement_cmdline.c @@ -0,0 +1,2002 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Note: + * the string example used below is all reformed to avoid code format check + * errors, so it just says the command output format as a reference. + * char "tab" is changed to "space", tailing space is removed, lines over 80 + * characters was foldered. + */ + +#include +#include +#include + +#include "host_network_implement_cmdline.h" +#include "host_network_helper.h" +#include "host_network_error.h" + +/* macro defines */ +#define COMMAND_NOTFOUND_STRING "command not found" +#define COMMAND_NOPERMISSION_STRING "Permission denied" +#define BRCTL_EXPECT_STRING "bridge name" +#define VLAN8021Q_CAT_ETH_EXPECT_STRING "REORDER_HDR:" +#define VLAN8021Q_CONFIG_EXPECT_STRING "VLAN Dev name" + +#define IFACE_CONFIG_FILE_PREFIX_RH "/etc/sysconfig/network-scripts/ifcfg-" + +#define CONT_BUFF_SIZE 256 + +/* the bridge seems have 0 value when it is up , so adjust the value, + and found out which are physical cards */ +static int host_iface_adjust(EthIface *piface) +{ + if (piface->eth_type == ETH_TYPE_BRIDGE) { + if (piface->run_prop.state == ETH_TYPE_UNKNOWN) { + piface->run_prop.state = ETH_STATE_UP; + } + } + if (1 == eth_iface_filter_peths(piface, NULL)) { + piface->eth_type = ETH_TYPE_PHYSICAL; + } + return 1; +} + +int host_ifacelist_is_present_cmd(EthIfacesList *plist, int *retvalues, + int compare_name_only) +{ + EthIfacesList ifaces_list; + int retvalue; + int i, j; + eth_iface_filter_func func; + + eth_ifaceslist_init(&ifaces_list); + retvalue = get_host_eth_ifaces_ip_addr(ifaces_list.pifaces, + &ifaces_list.count, MAX_IFACE_NUM, NULL, NULL); + if (retvalue != 1) { + goto out; + } + + if (compare_name_only == 0) { + func = eth_iface_filter_by_refname; + } else { + func = eth_iface_filter_by_ref; + } + i = 0; + while (i < plist->count) { + retvalues[i] = 0; + j = 0; + while (j < ifaces_list.count) { + if (1 == func(ifaces_list.pifaces[j], plist->pifaces[i])) { + retvalues[i] = 1; + break; + } + j++; + } + i++; + } + + out: + eth_ifaceslist_uninit(&ifaces_list); + return retvalue; +} + +static int host_iface_is_present_cmd(EthIface *piface) +{ + EthIface *pifaces[1]; + int retvalue; + int ifaces_num; + int exist_flag = 0; + EthIface ref; + eth_iface_init(&ref); + ref.name = SAFE_STRDUP(piface->name); + + retvalue = get_host_eth_ifaces_ip_addr(pifaces, &ifaces_num, + 1, eth_iface_filter_by_ref, &ref); + + if ((retvalue == 1) && (ifaces_num == 1)) { + exist_flag = 1; + } + eth_ifaces_clear(pifaces, ifaces_num); + eth_iface_uninit(&ref); + return exist_flag; +} + +static int host_br_is_present_cmd(EthIface *piface) +{ + EthIface *pifaces[1]; + int retvalue; + int ifaces_num; + int exist_flag = 0; + EthIface ref; + eth_iface_init(&ref); + ref.name = SAFE_STRDUP(piface->name); + + retvalue = get_host_eth_ifaces_brctl(pifaces, &ifaces_num, + 1, eth_iface_filter_by_ref, &ref); + + if ((retvalue == 1) && (ifaces_num == 1)) { + exist_flag = 1; + } + eth_ifaces_clear(pifaces, ifaces_num); + eth_iface_uninit(&ref); + return exist_flag; +} + +/* 1: the bridge have the iface attached + 2: the iface is attached to other bridge + other: not found */ +int host_br_have_iface_attached_cmd(EthIface *pbr, EthIface *piface, + EthIface **ppbr_result) +{ + int ret = 0; + BR_Prop *pbr_prop; + EthIface **pifaces = NULL; + int retvalue; + int ifaces_num = 0; + int i, j; + + if (0 == host_iface_is_present_cmd(piface)) { + return -1; + } + + SAFE_CALLOC(pifaces, MAX_IFACE_NUM, sizeof(EthIface *)); + + retvalue = get_host_eth_ifaces_brctl(pifaces, &ifaces_num, + MAX_IFACE_NUM, NULL, NULL); + + if ((retvalue == 1) && (ifaces_num > 0)) { + i = 0; + while (i < ifaces_num) { + if (0 == strcmp(pbr->name, pifaces[i]->name)) { + /* found the bridge */ + pbr_prop = pifaces[i]->pbr_prop; + j = 0; + while (j < pbr_prop->port_num) { + if (0 == strcmp(piface->name, pbr_prop->port_names[j])) { + ret = 1; + break; + } + j++; + } + if (ppbr_result != NULL) { + *ppbr_result = pifaces[i]; + pifaces[i] = NULL; + } + goto out; + } else { + /* not the bridge */ + pbr_prop = pifaces[i]->pbr_prop; + j = 0; + while (j < pbr_prop->port_num) { + if (0 == strcmp(piface->name, pbr_prop->port_names[j])) { + ret = 2; + goto out; + } + j++; + } + } + i++; + } + } else { + ret = -2; + } + + out: + if (pifaces != NULL) { + eth_ifaces_clear(pifaces, ifaces_num); + SAFE_FREE(pifaces); + } + return ret; +} + +static int host_vlan_is_present_8021q_cmd(EthIface *piface) +{ + EthIface *pifaces[1]; + int retvalue; + int ifaces_num; + int exist_flag = 0; + EthIface ref; + eth_iface_init(&ref); + ref.name = SAFE_STRDUP(piface->name); + + retvalue = get_host_eth_ifaces_cat_vlan_config(pifaces, &ifaces_num, + 1, eth_iface_filter_by_ref, &ref); + + if ((retvalue == 1) && (ifaces_num == 1)) { + exist_flag = 1; + } + eth_ifaces_clear(pifaces, ifaces_num); + eth_iface_uninit(&ref); + return exist_flag; +} + +int get_host_eth_ifaces_ip_addr(EthIface **ppifaces, int *retnum, int maxnum, + eth_iface_filter_func filter_func, void *filter_opaque) +{ + FILE *stream = NULL; + char cmd[64]; + char *buff = NULL; + int ret = 0; + EthIface tcard, **ppdest; + char *temp, *temp2, *temp3; + char *search_str; + int count = 0; + int filter_ret; + int line_count = 0; + struct in_addr addr; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + cmd[0] = '\0'; + strcat(cmd, "ip addr"); + stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + eth_iface_init(&tcard); + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CMD_DEBUG(3, "%s", buff); + if (line_count == 0) { + if (NULL != strstr(buff, COMMAND_NOTFOUND_STRING)) { + CU_DEBUG("Got [%s] with command [%s], check u environment.\n", + COMMAND_NOTFOUND_STRING, cmd); + ret = ERR_COMMAND_NOT_SUPPORT; + goto out; + } + if (NULL != strstr(buff, COMMAND_NOPERMISSION_STRING)) { + CU_DEBUG("Got [%s] with command [%s], check u environment.\n", + COMMAND_NOPERMISSION_STRING, cmd); + ret = ERR_COMMAND_NO_PERMISSION; + goto out; + } + } + line_count++; + /*analysis the output, example is something like following: + +3: eth1: mtu 1500 qdisc \ +pfifo_fast run_prop.state UP qlen 1000 + link/ether 08:00:27:e3:13:f8 brd ff:ff:ff:ff:ff:ff + inet 10.0.3.15/24 brd 10.0.3.255 scope global eth1 + inet6 fe80::a00:27ff:fee3:13f8/64 scope link + valid_lft forever preferred_lft forever +4: eth1.5 at eth1: mtu 1500 qdisc \ +noqueue run_prop.state UP + link/ether 08:00:27:e3:13:f8 brd ff:ff:ff:ff:ff:ff + inet6 fe80::a00:27ff:fee3:13f8/64 scope link + valid_lft forever preferred_lft forever + + */ + /* for line that divide two devices */ + if ((0 != strncmp(buff, " ", 1)) && (0 != strncmp(buff, "\t", 1))) { + if (tcard.name != NULL) { + /* device found, copy the content */ + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(&tcard, filter_opaque); + } + /* found a device match the requirement, put it to the list */ + if (filter_ret == 1) { + if (count >= maxnum) { + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + ppdest = ppifaces + count; + SAFE_MALLOC(*ppdest, sizeof(EthIface)); + eth_iface_dup(*ppdest, &tcard); + count++; + } + eth_iface_uninit(&tcard); + eth_iface_init(&tcard); + } + /* discovery names */ + search_str = ": "; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + temp2 = strstr(temp, search_str); + if (temp2 != NULL) { + /* found string that contains names, + start point is temp, end point is temp2 */ + search_str = "@"; + temp3 = strstr(temp, search_str); + if ((temp3 != NULL) && (temp3 < temp2)) { + /* have parent dev, temp3 holds the division */ + SAFE_FREE(tcard.dep_ifname); + tcard.dep_ifname = strndup(temp3+1, temp2-temp3-1); + SAFE_FREE(tcard.name); + tcard.name = strndup(temp, temp3-temp); + } else { + SAFE_FREE(tcard.name); + tcard.name = strndup(temp, temp2-temp); + } + } + } + /* discovery run_prop.state */ + search_str = "state "; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + if (0 == strncmp(temp, "UP", 2)) { + tcard.run_prop.state = ETH_STATE_UP; + } else if (0 == strncmp(temp, "DOWN", 4)) { + tcard.run_prop.state = ETH_STATE_DOWN; + } else if (0 == strncmp(temp, "UNKNOWN", 7)) { + tcard.run_prop.state = ETH_STATE_UNKNOWN; + } + } + continue; + } + /* for lines that saying other properties */ + /* dicovering mac */ + search_str = "ether "; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + SAFE_FREE(tcard.mac); + tcard.mac = strtok_onetime(temp, " "); + } + /* dicovering ip and ip_mask for ipv4 */ + search_str = "inet "; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + temp2 = strstr(temp, "/"); + if (temp2 != NULL) { + /* found the ip and mask, temp2 holds the division */ + SAFE_FREE(tcard.ipv4_prop.ip); + tcard.ipv4_prop.ip = strndup(temp, temp2-temp); + if (1 == netmask_easy_to_inaddr(&addr, temp2+1)) { + SAFE_FREE(tcard.ipv4_prop.ip_mask); + SAFE_MALLOC(tcard.ipv4_prop.ip_mask, INET_ADDRSTRLEN); + tcard.ipv4_prop.ip_mask[INET_ADDRSTRLEN-1] = '\0'; + if (NULL == inet_ntop(AF_INET, &addr, + tcard.ipv4_prop.ip_mask, INET_ADDRSTRLEN)) { + SAFE_FREE(tcard.ipv4_prop.ip_mask); + } + } + } + } + } + + /* because the output have no indication about end, so need to try add + the latest device found to the list */ + if (tcard.name != NULL) { + /* device found, copy the content */ + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(&tcard, filter_opaque); + } + /* found a device match the requirement, put it to the list */ + if (filter_ret == 1) { + if (count >= maxnum) { + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + ppdest = ppifaces + count; + SAFE_MALLOC(*ppdest, sizeof(EthIface)); + eth_iface_dup(*ppdest, &tcard); + count++; + } + } + + ret = 1; + + out: + if (stream != NULL) { + pclose(stream); + } + eth_iface_uninit(&tcard); + SAFE_FREE(buff); + *retnum = count; + + return ret; +} + +int get_host_eth_ifaces_ifconfig(EthIface **ppifaces, int *retnum, int maxnum, + eth_iface_filter_func filter_func, void *filter_opaque) +{ + FILE *stream = NULL; + char cmd[64]; + char *buff = NULL; + int ret = 0; + EthIface tcard, **ppdest; + char *temp, *temp2; + char *search_str; + int count = 0; + int filter_ret; + int line_count = 0; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + cmd[0] = '\0'; + strcat(cmd, "ifconfig"); + stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + eth_iface_init(&tcard); + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CMD_DEBUG(3, "%s", buff); + if (line_count == 0) { + if (NULL != strstr(buff, COMMAND_NOTFOUND_STRING)) { + CU_DEBUG("Got [%s] with command [%s], check u environment.\n", + COMMAND_NOTFOUND_STRING, cmd); + ret = ERR_COMMAND_NOT_SUPPORT; + goto out; + } + if (NULL != strstr(buff, COMMAND_NOPERMISSION_STRING)) { + CU_DEBUG("Got [%s] with command [%s], check u environment.\n", + COMMAND_NOPERMISSION_STRING, cmd); + ret = ERR_COMMAND_NO_PERMISSION; + goto out; + } + } + line_count++; + /*analysis the output, example is something like following: + +eth1 Link encap:Ethernet HWaddr 08:00:27:E3:13:F8 + inet addr:10.0.3.15 Bcast:10.0.3.255 Mask:255.255.255.0 + inet6 addr: fe80::a00:27ff:fee3:13f8/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:236 errors:0 dropped:0 overruns:0 frame:0 + TX packets:346 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:100464 (98.1 KiB) TX bytes:30721 (30.0 KiB) + +eth1.5 Link encap:Ethernet HWaddr 08:00:27:E3:13:F8 + ... + + */ + /* for line that divide two devices */ + if (0 == strncmp(buff, "\n", 1)) { + /* device found, copy the content */ + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(&tcard, filter_opaque); + } + /* found a device match the requirement, put it to the list */ + if (filter_ret == 1) { + if (count >= maxnum) { + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + ppdest = ppifaces + count; + SAFE_MALLOC(*ppdest, sizeof(EthIface)); + eth_iface_dup(*ppdest, &tcard); + count++; + } + eth_iface_uninit(&tcard); + eth_iface_init(&tcard); + continue; + } + /* for line that saying other properties */ + if (0 == strncmp(buff, " ", 1)) { + /* discovery ip for ip v4 */ + search_str = "inet addr:"; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + SAFE_FREE(tcard.ipv4_prop.ip); + tcard.ipv4_prop.ip = strtok_onetime(temp, " "); + /* discovery ip mask*/ + search_str = "Mask"; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + SAFE_FREE(tcard.ipv4_prop.ip_mask); + tcard.ipv4_prop.ip_mask = strtok_onetime(temp, " "); + if (tcard.ipv4_prop.ip_mask == NULL) { + tcard.ipv4_prop.ip_mask = strtok_onetime(temp, "\n"); + } + } + } + + /* discovery RX and TX bytes */ + search_str = "RX bytes:"; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + tcard.run_prop.rx_bytes = strtoll(temp, &temp2, 10); + if (temp == temp2) { + /*failed to get the value, restore it to default */ + tcard.run_prop.rx_bytes = NUM_NOT_GOT; + } + search_str = "TX bytes:"; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + tcard.run_prop.tx_bytes = strtoll(temp, &temp2, 10); + if (temp == temp2) { + /*failed to get the value, restore it to default */ + tcard.run_prop.tx_bytes = NUM_NOT_GOT; + } + } + } + continue; + } + /* for lines that saying the device with title */ + /* discovery name */ + SAFE_FREE(tcard.name); + tcard.name = strtok_onetime(buff, " "); + /* discovery mac */ + search_str = "HWaddr "; + temp = strstr(buff, search_str); + if (temp != NULL) { + temp += strlen(search_str); + SAFE_FREE(tcard.mac); + tcard.mac = strtok_onetime(temp, " "); + if (tcard.mac == NULL) { + tcard.mac = strtok_onetime(temp, "\n"); + } + } + /* discovery type */ + search_str = "Local Loopback"; + temp = strstr(buff, search_str); + if (temp != NULL) { + tcard.eth_type = ETH_TYPE_LOOPBACK; + } + continue; + } + + ret = 1; + + out: + if (stream != NULL) { + pclose(stream); + } + eth_iface_uninit(&tcard); + SAFE_FREE(buff); + *retnum = count; + + return ret; +} + +int get_host_eth_ifaces_brctl(EthIface **ppifaces, int *retnum, int maxnum, + eth_iface_filter_func filter_func, void *filter_opaque) +{ + FILE *stream = NULL; + char cmd[64]; + char *buff = NULL; + int ret = 0; + EthIface tcard, **ppdest; + BR_Prop tbr; + char *last = NULL, *iter; + char *char_stp = NULL; + char *port_name = NULL; + int count = 0; + int filter_ret; + int line_count = 0; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + cmd[0] = '\0'; + strcat(cmd, "brctl show"); + stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + eth_iface_init(&tcard); + br_prop_init(&tbr); + tbr.port_num = 0; + port_name = NULL; + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CMD_DEBUG(3, "%s", buff); +/* output string should be something like following + +bridge name bridge id STP enabled interfaces +testbr 8000.000000000000 no +virbr0 8000.5254004ac14c yes virbr0-nic + vnet0 +virbr3 8000.5254004ac16c yes virbr3-nic +... +*/ + if (line_count == 0) { + if (NULL == strstr(buff, BRCTL_EXPECT_STRING)) { + CU_DEBUG("[%s] not found with command [%s]," + "check u environment.\n", + BRCTL_EXPECT_STRING, cmd); + ret = ERR_COMMAND_NOT_SUPPORT; + goto out; + } + line_count++; + continue; + } + if ((buff[0] == ' ') || (buff[0] == '\t')) { + /* the line saying ifaces it attached */ + port_name = strtok_r(buff, "\n", &last); + if (port_name == NULL) { + CU_DEBUG("command [%s] did not output as expected.", cmd); + continue; + } + port_name = strtok_r(buff, "\t", &last); + if (port_name == NULL) { + CU_DEBUG("command [%s] did not output as expected.", cmd); + continue; + } + /* adding the port */ + if (tbr.port_names == NULL) { + SAFE_CALLOC(tbr.port_names, MAX_IFACE_NUM, sizeof(char *)); + tbr.port_num = 0; + } + if (tbr.port_num >= MAX_IFACE_NUM) { + CU_DEBUG("bridge [%s] have too much eth attached!", + tcard.name); + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + tbr.port_names[tbr.port_num] = SAFE_STRDUP(port_name); + tbr.port_num++; + } else { + /* the line saying a new bridge */ + if (tcard.name != NULL) { + /* have a valid iface, so add it to the list */ + tcard.pbr_prop = &tbr; + tcard.eth_type = ETH_TYPE_BRIDGE; + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(&tcard, filter_opaque); + } + /* found a device match the requirement, put it to the list */ + if (filter_ret == 1) { + if (count >= maxnum) { + CU_DEBUG("too much bridge found, max is %d", + maxnum); + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + ppdest = ppifaces + count; + SAFE_MALLOC(*ppdest, sizeof(EthIface)); + eth_iface_dup(*ppdest, &tcard); + count++; + } + tcard.pbr_prop = NULL; + eth_iface_uninit(&tcard); + eth_iface_init(&tcard); + br_prop_uninit(&tbr); + br_prop_init(&tbr); + tbr.port_num = 0; + } + SAFE_STRDUP_WITH_FUNC(tcard.name, + strtok_r(buff, "\t", &last), iter); + SAFE_STRDUP_WITH_FUNC(tbr.bridge_id, + strtok_r(NULL, "\t", &last), iter); + char_stp = strtok_r(NULL, "\t", &last); + if (char_stp != NULL) { + if (0 == strcmp(char_stp, "yes")) { + tbr.STP = 1; + } else if (0 == strcmp(char_stp, "no")) { + tbr.STP = 0; + } + } + if (last != NULL) { + if ((*last == '\0') || (*(last+1) == '\0')) { + CU_DEBUG("command [%s] did not output as expected," + "string left [%s].", cmd, last); + continue; + } + last++; + } + if (*last == '\t') { + port_name = NULL; + } else { + port_name = strtok_r(NULL, "\n", &last); + if (port_name != NULL) { + /* adding the port */ + if (tbr.port_names == NULL) { + SAFE_CALLOC(tbr.port_names, + MAX_IFACE_NUM, sizeof(char *)); + tbr.port_num = 0; + } + if (tbr.port_num >= MAX_IFACE_NUM) { + CU_DEBUG("bridge [%s] have too much eth attached!", + tcard.name); + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + tbr.port_names[tbr.port_num] = SAFE_STRDUP(port_name); + tbr.port_num++; + } + } + } + line_count++; + } + + if (tcard.name != NULL) { + /* have a valid iface, so add it to the list */ + tcard.pbr_prop = &tbr; + tcard.eth_type = ETH_TYPE_BRIDGE; + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(&tcard, filter_opaque); + } + /* found a device match the requirement, put it to the list */ + if (filter_ret == 1) { + if (count >= maxnum) { + CU_DEBUG("too much bridge found, max is %d", + maxnum); + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + ppdest = ppifaces + count; + SAFE_MALLOC(*ppdest, sizeof(EthIface)); + eth_iface_dup(*ppdest, &tcard); + count++; + } + tcard.pbr_prop = NULL; + } + + ret = 1; + + out: + if (stream != NULL) { + pclose(stream); + } + br_prop_uninit(&tbr); + eth_iface_uninit(&tcard); + SAFE_FREE(buff); + *retnum = count; + + return ret; +} + +static int get_iface_cat_vlan_one_eth_8021q(EthIface *piface) +{ + FILE *stream = NULL; + char cmd[64]; + char *cmd_prefix = "cat /proc/net/vlan/"; + char *buff = NULL; + VLAN_Prop_8021q *pprop_8021q; + char *last = NULL; + char *char_temp = NULL; + char *search_str, *iter, *temp1, *temp2, *temp3, *qos; + int ret = 0; + int line_count = -1; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if ((piface->name == NULL) || + ((strlen(piface->name)+strlen(cmd_prefix)) > (sizeof(cmd)-1))) { + CU_DEBUG("error in building up cmd line, name is %s.", piface->name); + ret = ERR_COMMAND_NO_READY; + goto out; + } + memcpy(cmd, cmd_prefix, strlen(cmd_prefix)+1); + strcat(cmd, piface->name); + + stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + if (piface->pvlan_prop == NULL) { + SAFE_MALLOC(piface->pvlan_prop, sizeof(VLAN_Prop)); + vlan_prop_init(piface->pvlan_prop, VLAN_TYPE_802_1_Q); + } + if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) { + ret = 0; + goto out; + } + pprop_8021q = &(piface->pvlan_prop->props.prop_8021q); + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + line_count++; + CMD_DEBUG(3, "%s", buff); +/* output is expected some thing like following +eth1.7.7 VID: 7 REORDER_HDR: 1 dev->priv_flags: 1 + total frames received 0 + total bytes received 0 + Broadcast/Multicast Rcvd 0 + + total frames transmitted 0 + total bytes transmitted 0 + total headroom inc 0 + total encap on xmit 0 +Device: eth1.7 +INGRESS priority mappings: 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0 + EGRESS priority mappings: +*/ + if (line_count == 0) { + if (NULL == strstr(buff, VLAN8021Q_CAT_ETH_EXPECT_STRING)) { + CU_DEBUG("[%s] not found with command [%s]," + "check u environment.\n", + VLAN8021Q_CAT_ETH_EXPECT_STRING, cmd); + ret = ERR_COMMAND_NOT_SUPPORT; + goto out; + } + } + search_str = "VID: "; + temp1 = strstr(buff, search_str); + if (temp1 != NULL) { + /* first line */ + temp1 += strlen(search_str); + search_str = "REORDER_HDR: "; + temp2 = strstr(buff, search_str); + if (temp2 != NULL) { + temp2 += strlen(search_str); + } + search_str = "priv_flags: "; + temp3 = strstr(buff, search_str); + if (temp3 != NULL) { + temp3 += strlen(search_str); + } + if ((temp2 != NULL) && (temp3 != NULL)) { + char_temp = strtok_r(temp1, " ", &last); + if (char_temp != NULL) { + pprop_8021q->vlan_id = strtol(char_temp, &iter, 10); + } + char_temp = strtok_r(temp2, " ", &last); + if (char_temp != NULL) { + pprop_8021q->reorder_hdr = strtol(char_temp, &iter, 10); + } + char_temp = strtok_r(temp3, " ", &last); + if (char_temp != NULL) { + pprop_8021q->priv_flag = strtol(char_temp, &iter, 10); + } + } + continue; + } + search_str = "total bytes received"; + temp1 = strstr(buff, search_str); + if (temp1 != NULL) { + temp1 += strlen(search_str); + char_temp = strtok_r(temp1, " ", &last); + if (char_temp != NULL) { + piface->run_prop.rx_bytes = strtoll(char_temp, &iter, 10); + } + continue; + } + search_str = "total bytes transmitted"; + temp1 = strstr(buff, search_str); + if (temp1 != NULL) { + temp1 += strlen(search_str); + char_temp = strtok_r(temp1, " ", &last); + if (char_temp != NULL) { + piface->run_prop.tx_bytes = strtoll(char_temp, &iter, 10); + } + continue; + } + search_str = "Device: "; + temp1 = strstr(buff, search_str); + if (temp1 != NULL) { + temp1 += strlen(search_str); + pprop_8021q->parent = strtok_onetime(temp1, " "); + if (pprop_8021q->parent == NULL) { + pprop_8021q->parent = strtok_onetime(temp1, "\n"); + } + continue; + } + search_str = "INGRESS priority mappings: "; + temp1 = strstr(buff, search_str); + if (temp1 != NULL) { + temp1 += strlen(search_str); + if (NULL != strstr(temp1, ":")) { + qos = strtok_onetime(temp1, "\n"); + if (qos != NULL) { + vlan_8021q_qos_str_to_num(&(pprop_8021q->ingress), qos); + SAFE_FREE(qos); + } + } + continue; + } + search_str = "EGRESS priority mappings: "; + temp1 = strstr(buff, search_str); + if (temp1 != NULL) { + temp1 += strlen(search_str); + if (NULL != strstr(temp1, ":")) { + qos = strtok_onetime(temp1, "\n"); + if (qos != NULL) { + vlan_8021q_qos_str_to_num(&(pprop_8021q->egress), qos); + SAFE_FREE(qos); + } + } + continue; + } + } + piface->eth_type = ETH_TYPE_VLAN; + ret = 1; + + out: + if (stream != NULL) { + pclose(stream); + } + SAFE_FREE(buff); + + return ret; +} + +int get_host_eth_ifaces_cat_vlan_config(EthIface **ppifaces, int *retnum, + int maxnum, eth_iface_filter_func filter_func, void *filter_opaque) +{ + FILE *stream = NULL; + char cmd[64]; + char *buff = NULL; + int ret = 0; + EthIface tcard, **ppdest; + VLAN_Prop tvlan; + int count = 0; + int filter_ret; + int line_count = -1; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + cmd[0] = '\0'; + strcat(cmd, "cat /proc/net/vlan/config"); + stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + eth_iface_init(&tcard); + vlan_prop_init(&tvlan, VLAN_TYPE_802_1_Q); + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + line_count++; + CMD_DEBUG(3, "%s", buff); +/* output string should be something like following + +VLAN Dev name | VLAN ID +Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD +eth1.5 | 5 | eth1 +... +*/ + if (line_count == 0) { + if (NULL == strstr(buff, VLAN8021Q_CONFIG_EXPECT_STRING)) { + CU_DEBUG("[%s] not found with command [%s]," + "check u environment.\n", + VLAN8021Q_CONFIG_EXPECT_STRING, cmd); + ret = ERR_COMMAND_NOT_SUPPORT; + goto out; + } + continue; + } + if (line_count < 2) { + continue; + } + + /* the line saying a new bridge */ + if (tcard.name != NULL) { + /* have a valid iface, so add it to the list */ + tcard.pvlan_prop = &tvlan; + /* get additional information for this vlan */ + get_iface_cat_vlan_one_eth_8021q(&tcard); + /* filt it */ + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(&tcard, filter_opaque); + } + /* found a device match the requirement, put it to the list */ + if (filter_ret == 1) { + if (count >= maxnum) { + CU_DEBUG("too much vlan found, max is %d", + maxnum); + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + ppdest = ppifaces + count; + SAFE_MALLOC(*ppdest, sizeof(EthIface)); + eth_iface_dup(*ppdest, &tcard); + count++; + } + tcard.pvlan_prop = NULL; + eth_iface_uninit(&tcard); + eth_iface_init(&tcard); + vlan_prop_uninit(&tvlan); + vlan_prop_init(&tvlan, VLAN_TYPE_802_1_Q); + } + /* get the name, other properties would be got in special file */ + tcard.name = strtok_onetime(buff, " "); + } + + if (tcard.name != NULL) { + /* have a valid iface, so add it to the list */ + tcard.pvlan_prop = &tvlan; + /* get additional information for this vlan */ + get_iface_cat_vlan_one_eth_8021q(&tcard); + /* filt it */ + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(&tcard, filter_opaque); + } + /* found a device match the requirement, put it to the list */ + if (filter_ret == 1) { + if (count >= maxnum) { + CU_DEBUG("too much vlan found, max is %d", + maxnum); + ret = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + ppdest = ppifaces + count; + SAFE_MALLOC(*ppdest, sizeof(EthIface)); + eth_iface_dup(*ppdest, &tcard); + count++; + } + tcard.pvlan_prop = NULL; + } + + ret = 1; + + out: + if (stream != NULL) { + pclose(stream); + } + vlan_prop_uninit(&tvlan); + eth_iface_uninit(&tcard); + SAFE_FREE(buff); + *retnum = count; + + return ret; +} + +int change_state_host_iface_cmd(EthIface *piface, int state) +{ + FILE *stream = NULL; + char cmd[64]; + char *cmd_prefix = "ifconfig "; + char *cmd_suffix = NULL; + char *buff = NULL; + int ret = 0; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if (state == ETH_STATE_UP) { + cmd_suffix = " up"; + } else if (state == ETH_STATE_DOWN) { + cmd_suffix = " down"; + } + + if (cmd_suffix == NULL) { + CU_DEBUG("state change have not target state set."); + goto out; + } + + if (piface->name == NULL) { + ret = ERR_COMMAND_PARAMETER_WRONG; + CU_DEBUG("bridge name not set, direct goto out."); + goto out; + } + + if (0 == host_iface_is_present_cmd(piface)) { + CU_DEBUG("iface %s do not exist, can't change state.", piface->name); + ret = ERR_DEVICE_NOT_EXIST; + goto out; + } + + if ((strlen(cmd_prefix)+strlen(piface->name)+strlen(cmd_suffix)) + > (sizeof(cmd)-1)) { + CU_DEBUG("error in building up cmd line, name is %s.", piface->name); + ret = ERR_COMMAND_NO_READY; + goto out; + } + snprintf(cmd, sizeof(cmd), "%s%s%s", cmd_prefix, piface->name, cmd_suffix); + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_NOT_SUPPORT; + goto out; + } + + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +int add_host_br_cmd(EthIface *piface, int persist_flag) +{ + FILE *stream = NULL; + char cmd[64]; + char *cmd_prefix = "brctl addbr "; + char *path; + char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH; + char *cont, *c_stp; + char *buff = NULL; + int ret = 0; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if (piface->name == NULL) { + ret = ERR_COMMAND_PARAMETER_WRONG; + CU_DEBUG("bridge name not set, direct goto out."); + goto out; + } + + if (1 == host_iface_is_present_cmd(piface)) { + CU_DEBUG("%s already exist, cann't create it as bridge.", piface->name); + ret = ERR_DEVICE_EXIST; + goto out; + } + + if ((strlen(cmd_prefix)+strlen(piface->name)) > (sizeof(cmd)-1)) { + CU_DEBUG("error in building up cmd line, name is %s.", piface->name); + ret = ERR_COMMAND_NO_READY; + goto out; + } + snprintf(cmd, sizeof(cmd), "%s%s", cmd_prefix, piface->name); + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + if ((piface->pbr_prop != NULL) && + (piface->pbr_prop->STP == 1)) { + c_stp = "on"; + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + cmd_prefix = "brctl stp "; + if ((strlen(cmd_prefix)+strlen(piface->name) + +strlen(c_stp)) > (sizeof(cmd)-2)) { + CU_DEBUG("error in building up cmd line, name is %s.", + piface->name); + ret = ERR_COMMAND_NO_READY; + goto out; + } + snprintf(cmd, sizeof(cmd), "%s%s %s", cmd_prefix, piface->name, c_stp); + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + } else { + c_stp = "off"; + } + + if (persist_flag == 1) { + if (LINUX_REDHAT != get_host_linux_version()) { + ret = ERR_PERSIST_NOT_REDHAT; + CU_DEBUG("Host is not a RedHat version, return is %d", + get_host_linux_version()); + goto out; + } + path = combine_file_name(path_prefix, piface->name); + SAFE_CALLOC(cont, 1024, sizeof(char)); + cont[1023] = 1; + snprintf(cont, 1024, + "DEVICE=%s\nTYPE=Bridge\nBOOTPROTO=dhcp\n" + "ONBOOT=yes\nDELAY=0\nSTP=%s\n", + piface->name, c_stp); + if (cont[1023] == '\0') { + CU_DEBUG("failed to build up contents, check the parameter."); + ret = ERR_FILE_CONT_TOO_LARGE; + SAFE_FREE(path); + SAFE_FREE(cont); + goto out; + } + ret = configure_file_update(path, cont); + SAFE_FREE(path); + SAFE_FREE(cont); + if (ret != 1) { + goto out; + } + + } + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +int del_host_br_cmd(EthIface *piface, int persist_flag) +{ + FILE *stream = NULL; + char cmd[64]; + char *cmd_prefix = "brctl delbr "; + char *path; + char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH; + char *buff = NULL; + int ret = 0; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if (piface->name == NULL) { + ret = ERR_COMMAND_PARAMETER_WRONG; + CU_DEBUG("bridge name not set, direct goto out."); + goto out; + } + + if (persist_flag == 1) { + if (LINUX_REDHAT != get_host_linux_version()) { + ret = ERR_PERSIST_NOT_REDHAT; + CU_DEBUG("Host is not a RedHat version, return is %d", + get_host_linux_version()); + goto out; + } + path = combine_file_name(path_prefix, piface->name); + ret = configure_file_remove(path); + SAFE_FREE(path); + if (ret != 1) { + goto out; + } + } + + if (0 == host_br_is_present_cmd(piface)) { + CU_DEBUG("bridge %s do not exist, can't delete it.", piface->name); + ret = ERR_DEVICE_NOT_EXIST; + goto out; + } + + if ((strlen(cmd_prefix)+strlen(piface->name)) > (sizeof(cmd)-1)) { + CU_DEBUG("error in building up cmd line, name is %s.", piface->name); + ret = ERR_COMMAND_NO_READY; + goto out; + } + snprintf(cmd, sizeof(cmd), "%s%s", cmd_prefix, piface->name); + + /* bring down the iface */ + change_state_host_iface_cmd(piface, ETH_STATE_DOWN); + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +int mod_host_br_cmd(EthIface *piface, int persist_flag) +{ + FILE *stream = NULL; + char cmd[64]; + char *cmd_prefix = "brctl stp "; + char *path; + char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH; + char *c_stp; + char *buff = NULL; + int ret = 0; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if (piface->name == NULL) { + ret = ERR_COMMAND_PARAMETER_WRONG; + CU_DEBUG("bridge name not set, direct goto out."); + goto out; + } + + if (0 == host_br_is_present_cmd(piface)) { + CU_DEBUG("bridge %s do not exist, cann't modify it.", piface->name); + ret = ERR_DEVICE_EXIST; + goto out; + } + + if ((piface->pbr_prop != NULL) && + (piface->pbr_prop->STP == 1)) { + c_stp = "on"; + } else { + c_stp = "off"; + } + + if ((strlen(cmd_prefix)+strlen(piface->name) + +strlen(c_stp)) > (sizeof(cmd)-2)) { + CU_DEBUG("error in building up cmd line, name is %s.", piface->name); + ret = ERR_COMMAND_NO_READY; + goto out; + } + snprintf(cmd, sizeof(cmd), "%s%s %s", cmd_prefix, piface->name, c_stp); + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + if (persist_flag == 1) { + if (LINUX_REDHAT != get_host_linux_version()) { + ret = ERR_PERSIST_NOT_REDHAT; + CU_DEBUG("Host is not a RedHat version, return is %d", + get_host_linux_version()); + goto out; + } + path = combine_file_name(path_prefix, piface->name); + ret = configure_file_replace_attr(path, "STP=", c_stp); + SAFE_FREE(path); + if (ret != 1) { + CU_DEBUG("error happened in persisting file."); + goto out; + } + } + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +static int append_vlan_8021q_parameters(char *cmd, int cmd_size, + VLAN_Prop_8021q *p_8021q) +{ + char *reorder = NULL; + char *egress = NULL, *ingress = NULL; + char *cmd_prefix; + int ret = 0; + + if (p_8021q->reorder_hdr == 1) { + reorder = " reorder_hdr on"; + } else if (p_8021q->reorder_hdr == 0) { + reorder = " reorder_hdr off"; + } + if (reorder != NULL) { + if ((strlen(reorder)+strlen(cmd)) < (cmd_size-1)) { + strcat(cmd, reorder); + } else { + CU_DEBUG("cmd line too long, it is [%s]+[%s].", cmd, reorder); + ret = ERR_COMMAND_NO_READY; + goto out; + } + } + + vlan_8021q_qos_num_to_str(&ingress, &(p_8021q->ingress)); + if (ingress != NULL) { + cmd_prefix = " ingress-qos-map "; + if ((strlen(ingress)+strlen(cmd)+strlen(cmd_prefix)) < (cmd_size-1)) { + strcat(cmd, cmd_prefix); + strcat(cmd, ingress); + } else { + CU_DEBUG("cmd line too long, it is [%s]+[%s]+[%s].", + cmd, cmd_prefix, ingress); + ret = ERR_COMMAND_NO_READY; + goto out; + } + } + + vlan_8021q_qos_num_to_str(&egress, &(p_8021q->egress)); + if (egress != NULL) { + cmd_prefix = " egress-qos-map "; + if ((strlen(egress)+strlen(cmd)+strlen(cmd_prefix)) < (cmd_size-1)) { + strcat(cmd, cmd_prefix); + strcat(cmd, egress); + } else { + CU_DEBUG("cmd line too long, it is [%s]+[%s]+[%s].", + cmd, cmd_prefix, egress); + ret = ERR_COMMAND_NO_READY; + goto out; + } + } + + ret = 1; + + out: + SAFE_FREE(ingress); + SAFE_FREE(egress); + return ret; +} + +int add_host_vlan_8021q_cmd(EthIface *piface, int persist_flag) +{ + FILE *stream = NULL; + char cmd[192]; + char *path; + char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH; + char *cont; + char *buff = NULL; + int ret = 0; + int str_size; + EthIface iface; + VLAN_Prop_8021q *p_8021q; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + eth_iface_init(&iface); + if (piface->pvlan_prop == NULL) { + CU_DEBUG("pvlan_prop not set, direct goto out."); + goto out; + } + if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) { + CU_DEBUG("not a 802.1.q vlan, direct goto out."); + goto out; + } + p_8021q = &(piface->pvlan_prop->props.prop_8021q); + if ((p_8021q->vlan_id < 1) || (p_8021q->vlan_id > 4095)) { + CU_DEBUG("vlan_id for 802.1.q must be 0-4095, " + "and 0 is kept by system, request is %d.", p_8021q->vlan_id); + goto out; + } + if ((p_8021q->parent == NULL)) { + CU_DEBUG("creation of vlan iface for 802.1.q need parent iface set"); + goto out; + } + iface.name = p_8021q->parent; + if (0 == host_iface_is_present_cmd(&iface)) { + CU_DEBUG("iface %s do not exist, cann't use it as parent iface.", + iface.name); + iface.name = NULL; + ret = ERR_DEVICE_NOT_EXIST; + goto out; + } + + /* restrict the iface name to ethx.x, so the name would be combined here */ + str_size = strlen(p_8021q->parent)+6; + SAFE_MALLOC(iface.name, str_size); + snprintf(iface.name, str_size, "%s.%d", + p_8021q->parent, p_8021q->vlan_id); + if (1 == host_iface_is_present_cmd(&iface)) { + CU_DEBUG("iface %s already exist, cann't create it as a 802.1.q vlan.", + iface.name); + ret = ERR_DEVICE_EXIST; + goto out; + } + + /* building up command line */ + cmd[sizeof(cmd)-1] = 1; + snprintf(cmd, sizeof(cmd), "ip link add link %s name %s type vlan id %d", + p_8021q->parent, iface.name, p_8021q->vlan_id); + if (cmd[sizeof(cmd)-1] == '\0') { + CU_DEBUG("cmd line too long, it is [%s].", cmd); + ret = ERR_COMMAND_NO_READY; + goto out; + } + + ret = append_vlan_8021q_parameters(cmd, sizeof(cmd), p_8021q); + if (ret != 1) { + goto out; + } + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + if (persist_flag == 1) { + if (LINUX_REDHAT != get_host_linux_version()) { + ret = ERR_PERSIST_NOT_REDHAT; + CU_DEBUG("Host is not a RedHat version, return is %d", + get_host_linux_version()); + goto out; + } + path = combine_file_name(path_prefix, iface.name); + SAFE_CALLOC(cont, 1024, sizeof(char)); + cont[1023] = 1; + snprintf(cont, 1024, + "DEVICE=%s\nPEERDNS=yes\nVLAN=yes\n", iface.name); + if (cont[1023] == '\0') { + CU_DEBUG("failed to build up contents, check the parameter."); + ret = ERR_FILE_CONT_TOO_LARGE; + SAFE_FREE(path); + SAFE_FREE(cont); + goto out; + } + ret = configure_file_update(path, cont); + SAFE_FREE(path); + SAFE_FREE(cont); + if (ret != 1) { + goto out; + } + } + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + eth_iface_uninit(&iface); + SAFE_FREE(buff); + + return ret; +} + +int del_host_vlan_8021q_cmd(EthIface *piface, int persist_flag) +{ + FILE *stream = NULL; + char cmd[128]; + char *path; + char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH; + char *buff = NULL; + int ret = 0; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if (piface->name == NULL) { + CU_DEBUG("piface name was not set, direct goto out."); + ret = ERR_COMMAND_PARAMETER_WRONG; + goto out; + } + + if (persist_flag == 1) { + if (LINUX_REDHAT != get_host_linux_version()) { + ret = ERR_PERSIST_NOT_REDHAT; + CU_DEBUG("Host is not a RedHat version, return is %d", + get_host_linux_version()); + goto out; + } + path = combine_file_name(path_prefix, piface->name); + ret = configure_file_remove(path); + SAFE_FREE(path); + if (ret != 1) { + goto out; + } + } + + if (piface->pvlan_prop == NULL) { + CU_DEBUG("pvlan_prop not set, direct goto out."); + goto out; + } + if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) { + CU_DEBUG("not a 802.1.q vlan, direct goto out."); + goto out; + } + + if (0 == host_vlan_is_present_8021q_cmd(piface)) { + CU_DEBUG("vlan %s do not exist, cann't delete it.", piface->name); + ret = ERR_DEVICE_EXIST; + goto out; + } + + /* building up command line */ + cmd[sizeof(cmd)-1] = 1; + snprintf(cmd, sizeof(cmd), "ip link del %s", piface->name); + if (cmd[sizeof(cmd)-1] == '\0') { + CU_DEBUG("cmd line too long, it is [%s].", cmd); + ret = ERR_COMMAND_NO_READY; + goto out; + } + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + ret = ERR_COMMAND_PIPE_ERR; + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +int mod_host_vlan_8021q_cmd(EthIface *piface, int persist_flag) +{ + FILE *stream = NULL; + char cmd[192]; + char *buff = NULL; + int ret = 0; + VLAN_Prop_8021q *p_8021q; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if (piface->name == NULL) { + ret = ERR_COMMAND_PARAMETER_WRONG; + CU_DEBUG("piface name was not set, direct goto out."); + goto out; + } + if (piface->pvlan_prop == NULL) { + CU_DEBUG("pvlan_prop not set, direct goto out."); + goto out; + } + if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) { + CU_DEBUG("not a 802.1.q vlan, direct goto out."); + goto out; + } + if (0 == host_vlan_is_present_8021q_cmd(piface)) { + CU_DEBUG("vlan %s do not exist, cann't modify it.", piface->name); + ret = ERR_DEVICE_EXIST; + goto out; + } + p_8021q = &(piface->pvlan_prop->props.prop_8021q); + + /* building up command line */ + cmd[sizeof(cmd)-1] = 1; + snprintf(cmd, sizeof(cmd), "ip link set %s type vlan", + piface->name); + if (cmd[sizeof(cmd)-1] == '\0') { + CU_DEBUG("cmd line too long, it is [%s].", cmd); + ret = ERR_COMMAND_NO_READY; + goto out; + } + + ret = append_vlan_8021q_parameters(cmd, sizeof(cmd), p_8021q); + if (ret != 1) { + goto out; + } + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + if (persist_flag == 1) { + /* modification is logged by linux system itself in /proc/net/vlan */ + } + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +int add_host_iface_to_br_cmd(EthIface *piface, EthIface *pbr, + int persist_flag) +{ + FILE *stream = NULL; + char cmd[64]; + char *buff = NULL; + int ret = 0; + int check_value; + char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH; + char *path; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if ((piface->name == NULL) || (pbr->name == NULL)) { + ret = ERR_COMMAND_PARAMETER_WRONG; + CU_DEBUG("name was not set, direct goto out."); + goto out; + } + + check_value = host_br_have_iface_attached_cmd(pbr, piface, NULL); + if (check_value < 0) { + CU_DEBUG("iface %s or bridge %s do not exist, direct goto out.", + piface->name, pbr->name); + ret = ERR_DEVICE_NOT_EXIST; + goto out; + } else if (check_value == 1) { + CU_DEBUG("iface %s already attached to bridge %s, can't do it again.", + piface->name, pbr->name); + ret = ERR_DEVICE_ALREADY_DONE; + goto out; + } else if (check_value == 2) { + CU_DEBUG("iface %s is attached to another bridge, " + "can't direct change it.", + piface->name); + ret = ERR_DEVICE_CONNECT_OTHER; + goto out; + } + + /* building up command line */ + cmd[sizeof(cmd)-1] = 1; + snprintf(cmd, sizeof(cmd), "brctl addif %s %s", + pbr->name, piface->name); + if (cmd[sizeof(cmd)-1] == '\0') { + CU_DEBUG("cmd line too long, it is [%s].", cmd); + ret = ERR_COMMAND_NO_READY; + goto out; + } + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + if (persist_flag == 1) { + /* if the configuration file do not exist, would not create it */ + if (LINUX_REDHAT != get_host_linux_version()) { + ret = ERR_PERSIST_NOT_REDHAT; + CU_DEBUG("Host is not a RedHat version, return is %d", + get_host_linux_version()); + goto out; + } + path = combine_file_name(path_prefix, piface->name); + ret = configure_file_replace_attr(path, "BRIDGE=", pbr->name); + SAFE_FREE(path); + if (ret != 1) { + CU_DEBUG("error happened in persisting file."); + goto out; + } + } + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +int remove_host_iface_from_br_cmd(EthIface *piface, EthIface *pbr, + int persist_flag) +{ + FILE *stream = NULL; + char cmd[64]; + char *buff = NULL; + int ret = 0; + int check_value; + char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH; + char *path; + + SAFE_MALLOC(buff, CONT_BUFF_SIZE); + if ((piface->name == NULL) || (pbr->name == NULL)) { + ret = ERR_COMMAND_PARAMETER_WRONG; + CU_DEBUG("name was not set, direct goto out."); + goto out; + } + + check_value = host_br_have_iface_attached_cmd(pbr, piface, NULL); + if (check_value < 0) { + CU_DEBUG("iface %s or bridge %s do not exist, direct goto out.", + piface->name, pbr->name); + ret = ERR_DEVICE_NOT_EXIST; + goto out; + } else if (check_value == 0) { + CU_DEBUG("iface %s is not attached to bridge %s, can't remove it.", + piface->name, pbr->name); + ret = ERR_DEVICE_ALREADY_DONE; + goto out; + } else if (check_value == 2) { + CU_DEBUG("iface %s is attached to another device, can't remove it.", + piface->name); + ret = ERR_DEVICE_CONNECT_OTHER; + goto out; + } + + /* building up command line */ + cmd[sizeof(cmd)-1] = 1; + snprintf(cmd, sizeof(cmd), "brctl delif %s %s", + pbr->name, piface->name); + if (cmd[sizeof(cmd)-1] == '\0') { + CU_DEBUG("cmd line too long, it is [%s].", cmd); + ret = ERR_COMMAND_NO_READY; + goto out; + } + + stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret); + if (stream == NULL) { + goto out; + } + + while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) { + CU_DEBUG("get exception: %s", buff); + ret = ERR_COMMAND_EXECUTION; + goto out; + } + + if (persist_flag == 1) { + /* if the configuration file do not exist, would not create it */ + if (LINUX_REDHAT != get_host_linux_version()) { + ret = ERR_PERSIST_NOT_REDHAT; + CU_DEBUG("Host is not a RedHat version, return is %d", + get_host_linux_version()); + goto out; + } + path = combine_file_name(path_prefix, piface->name); + ret = configure_file_replace_attr(path, "BRIDGE=", NULL); + SAFE_FREE(path); + if (ret != 1) { + CU_DEBUG("error happened in persisting file."); + goto out; + } + } + ret = 1; + +out: + if (stream != NULL) { + pclose(stream); + stream = NULL; + } + SAFE_FREE(buff); + + return ret; +} + +static void merge_eth_list(EthIfacesList *pdest, EthIfacesList *psrc, int flag) +{ + int i, j; + i = 0; + while (i < pdest->count) { + j = 0; + while (j < psrc->count) { + if (1 == eth_iface_compare(pdest->pifaces[i], psrc->pifaces[j])) { + /* found the matched device, merge them */ + eth_iface_merge(pdest->pifaces[i], psrc->pifaces[j], flag); + break; + } + j++; + } + i++; + } + return; +} + +static void find_iface_attached_bridge(EthIfacesList *peth_list, EthIface *pbr) +{ + int i, j; + char *name_on_br, *name_iface; + if (pbr->pbr_prop == NULL) { + return; + } + i = 0; + while (i < pbr->pbr_prop->port_num) { + name_on_br = pbr->pbr_prop->port_names[i]; + j = 0; + while (j < peth_list->count) { + name_iface = peth_list->pifaces[j]->name; + if (0 == strcmp(name_on_br, name_iface)) { + if (peth_list->pifaces[j]->attach_bridge == NULL) { + peth_list->pifaces[j]->attach_bridge = + SAFE_STRDUP(pbr->name); + } + break; + } + j++; + } + i++; + } +} + +/* assuming that one peth would be attached to at most 1 bridge */ +static void merge_eth_list_for_bridge(EthIfacesList *peth_list, + EthIfacesList *pbr_list, + int flag) +{ + int i, j; + i = 0; + while (i < pbr_list->count) { + find_iface_attached_bridge(peth_list, pbr_list->pifaces[i]); + j = 0; + while (j < peth_list->count) { + if (1 == eth_iface_compare(peth_list->pifaces[j], + pbr_list->pifaces[i])) { + /* found the matched device, merge them */ + eth_iface_merge(peth_list->pifaces[j], + pbr_list->pifaces[i], flag); + break; + } + j++; + } + i++; + } + return; +} + +int get_host_eth_ifaces_cmd_all(EthIfacesList *plist, + eth_iface_filter_func filter_func, void *filter_opaque) +{ + int retvalue; + EthIfacesList *ifaces1, *ifaces2; + int i; + int filter_ret; + int count = 0; + SAFE_MALLOC(ifaces1, sizeof(EthIfacesList)); + SAFE_MALLOC(ifaces2, sizeof(EthIfacesList)); + eth_ifaceslist_init(ifaces1); + eth_ifaceslist_init(ifaces2); + + retvalue = get_host_eth_ifaces_ip_addr(ifaces1->pifaces, &(ifaces1->count), + MAX_IFACE_NUM, NULL, NULL); + if (retvalue != 1) { + goto out; + } + + + retvalue = get_host_eth_ifaces_ifconfig(ifaces2->pifaces, &(ifaces2->count), + MAX_IFACE_NUM, NULL, NULL); + if (retvalue != 1) { + goto out; + } + /* merge the information */ + merge_eth_list(ifaces1, ifaces2, 1); + eth_ifaceslist_uninit(ifaces2); + + retvalue = get_host_eth_ifaces_brctl(ifaces2->pifaces, &(ifaces2->count), + MAX_IFACE_NUM, NULL, NULL); + if (retvalue != 1) { + goto out; + } + /* merge the information */ + merge_eth_list_for_bridge(ifaces1, ifaces2, 1); + eth_ifaceslist_uninit(ifaces2); + + retvalue = get_host_eth_ifaces_cat_vlan_config(ifaces2->pifaces, + &(ifaces2->count), MAX_IFACE_NUM, NULL, NULL); + if (retvalue != 1) { + goto out; + } + + /* merge the information */ + merge_eth_list(ifaces1, ifaces2, 1); + eth_ifaceslist_uninit(ifaces2); + + /* filter the result */ + i = 0; + while (i < ifaces1->count) { + /* see if the result need to be put to the list */ + filter_ret = 1; + if (filter_func != NULL) { + filter_ret = filter_func(ifaces1->pifaces[i], filter_opaque); + } + if (filter_ret == 1) { + if (count >= MAX_IFACE_NUM) { + retvalue = ERR_DEVICE_EXCEED_MAXNUM; + goto out; + } + host_iface_adjust(ifaces1->pifaces[i]); + plist->pifaces[count] = ifaces1->pifaces[i]; + ifaces1->pifaces[i] = NULL; + count++; + } + i++; + } + + out: + eth_ifaceslist_uninit(ifaces1); + SAFE_FREE(ifaces1); + eth_ifaceslist_uninit(ifaces2); + SAFE_FREE(ifaces2); + plist->count = count; + return retvalue; +} diff --git a/libxkutil/host_network_implement_cmdline.h b/libxkutil/host_network_implement_cmdline.h new file mode 100644 index 0000000..90e5891 --- /dev/null +++ b/libxkutil/host_network_implement_cmdline.h @@ -0,0 +1,55 @@ +/* + * Copyright IBM Corp. 2011 + * + * Authors: + * Wenchao Xia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +#ifndef HOST_NETWORK_IMPLEMENT_CMDLINE_H +#define HOST_NETWORK_IMPLEMENT_CMDLINE_H + +#include "host_network_basic.h" + +int get_host_eth_ifaces_ip_addr(EthIface **ppifaces, int *retnum, int maxnum, + eth_iface_filter_func filter_func, void *filter_opaque); + +int get_host_eth_ifaces_ifconfig(EthIface **ppifaces, int *retnum, int maxnum, + eth_iface_filter_func filter_func, void *filter_opaque); + +int get_host_eth_ifaces_brctl(EthIface **ppifaces, int *retnum, int maxnum, + eth_iface_filter_func filter_func, void *filter_opaque); + +int get_host_eth_ifaces_cat_vlan_config(EthIface **ppifaces, int *retnum, + int maxnum, eth_iface_filter_func filter_func, void *filter_opaque); + +int get_host_eth_ifaces_cmd_all(EthIfacesList *plist, + eth_iface_filter_func filter_func, void *filter_opaque); + +int add_host_br_cmd(EthIface *piface, int persist_flag); +int del_host_br_cmd(EthIface *piface, int persist_flag); +int mod_host_br_cmd(EthIface *piface, int persist_flag); +int add_host_iface_to_br_cmd(EthIface *piface, EthIface *pbr, + int persist_flag); +int remove_host_iface_from_br_cmd(EthIface *piface, EthIface *pbr, + int persist_flag); + +int add_host_vlan_8021q_cmd(EthIface *piface, int persist_flag); +int del_host_vlan_8021q_cmd(EthIface *piface, int persist_flag); +int mod_host_vlan_8021q_cmd(EthIface *piface, int persist_flag); + +int change_state_host_iface_cmd(EthIface *piface, int state); + +int host_br_have_iface_attached_cmd(EthIface *pbr, EthIface *piface, + EthIface **ppbr_result); + +/* check a batch of iface's state with one call of get_host_ifaces, + retvalues must be allocated big enough */ +int host_ifacelist_is_present_cmd(EthIfacesList *plist, int *retvalues, + int compare_name_only); + +#endif -- 1.7.6 From xiawenc at linux.vnet.ibm.com Wed Dec 7 09:36:10 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 07 Dec 2011 17:36:10 +0800 Subject: [Libvirt-cim] test message, pls ignore Message-ID: <4EDF338A.7040103@linux.vnet.ibm.com> -- Best Regards Wayne Xia mail:xiawenc at linux.vnet.ibm.com tel:86-010-82450803 From eblima at linux.vnet.ibm.com Thu Dec 8 14:38:06 2011 From: eblima at linux.vnet.ibm.com (Eduardo Lima (Etrunko)) Date: Thu, 08 Dec 2011 12:38:06 -0200 Subject: [Libvirt-cim] [PATCH 00/15] vlan extension In-Reply-To: <1323249538-27410-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249538-27410-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <4EE0CBCE.3060507@linux.vnet.ibm.com> On 12/07/2011 07:18 AM, Wayne Xia wrote: > These patches would do following things: building up the network system CIM > model, building up basic framework and functions below to implement the > configuration, add the bridge and vlan802.1.q configuration capabilities in > CIM model and library below. > Now this patch implement the functionalities with commandline style, which > means it depends on command ip, ifconfig, brctl and /proc/net/vlan/. In this > way it is very sensitive to these command's output format. Maybe another > implemetion could avoid that in the future. What exactly do you need with those commands. If we're talking about listing network interfaces, obtaining IP/MAC addresses and like, this all should be done via standard system calls instead of parsing command line outputs. This is the basics of UNIX IPC mechanism. For instance see socket(7), ip(7), netdevice(7) and related man pages, especially the Ioctls sections. > Since libvirt-cim is not a daemon program that would always be brought up > when the emulator was up, so there lacks a mechnism to save the configuration > and set them when system reboot, so these patch uses system directory > /etc/sysconfig/network-script/ > to store the settings. > The things above means that a linux kernel later than 2.6 and RedHat > distribution is needed. Other distriution may work but not tested. If > the implemention goes to libvirt the restrict would be removed. Depending on a specific distro is very very bad. Again, what kind of configuration are you trying to store? Could the infostore implementation in libvirt-cim which could be used? And this line about implementation going to libvirt really makes me sad. IMHO, if there is work to be done in libvirt, so why don't start there instead of implementing everything in house and having to do everything once again when the necessary bits are there? [snip] > > Wayne Xia (15): > vlan extension - makefile change > vlan extension - CIM model - add class VESS > vlan extension - CIM model - add class VESSSD > vlan extension - CIM model - add class EthernetPort > vlan extension - CIM model - add class > EthernetPortAllocationSettingData > vlan extension - CIM model - add association Net_SettingsDeineState > vlan extension - CIM model - add association Net_SystemDevice > vlan extension - CIM model - add association Net_VESSSDComponent > vlan extension - CIM model - add association Net_ElementSettingData > vlan extension - CIM model - add core class VESSMS > vlan extension - CIM model - add help functions > vlan extension - function lib - add the API > vlan extension - function lib - add the core structure > vlan extension - function lib - add the helper functions > vlan extension - function lib - add the implemention of commandline > For the series, looks like you sent the patches in the opposite order, from last to first. If I apply the fist patch the build breaks. The first review for this whole series is a -1 only because of that. I think it would help a lot if you publish your code in gitorious for instance. I have set up the mirrors for libvirt-cim repositories there: http://gitorious.org/libvirt-cim Finally, for future cases which involve huge amount of work, like this one, *please please please* be gentle with us and avoid one big code drop like this one. Small and incremental changes makes the life of everyone, including yours, easier. :) Best regards, Etrunko. > Makefile.am | 16 +- > libxkutil/Makefile.am | 11 +- > libxkutil/host_network_API.c | 150 ++ > libxkutil/host_network_API.h | 32 + > libxkutil/host_network_basic.c | 639 +++++++ > libxkutil/host_network_basic.h | 166 ++ > libxkutil/host_network_error.h | 28 + > libxkutil/host_network_helper.c | 659 +++++++ > libxkutil/host_network_helper.h | 192 ++ > libxkutil/host_network_implement_cmdline.c | 2002 ++++++++++++++++++++ > libxkutil/host_network_implement_cmdline.h | 55 + > libxkutil/network_model.c | 466 +++++ > libxkutil/network_model.h | 105 + P.S.: I haven't had the chance to review the patches yet. But I have a sudden cold feeling in my spine by looking at these first stats. -- Eduardo de Barros Lima Software Engineer, Open Virtualization Linux Technology Center - IBM/Brazil eblima at br.ibm.com From snmishra at us.ibm.com Thu Dec 8 18:26:10 2011 From: snmishra at us.ibm.com (Sharad Mishra) Date: Thu, 8 Dec 2011 10:26:10 -0800 Subject: [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs support on QEMU/KVM environment In-Reply-To: <4ED8CEE9.6020307@linux.vnet.ibm.com> References: <4ED78DFC.1070406@linux.vnet.ibm.com> <4ED883EA.7070603@linux.vnet.ibm.com> <4ED8CEE9.6020307@linux.vnet.ibm.com> Message-ID: > Deepak Shetty > Sent by: libvirt-cim-bounces at redhat.com > > 12/02/2011 05:13 AM > > Please respond to > List for discussion and development of libvirt CIM > > To > > libvirt-cim at redhat.com > > cc > > Subject > > Re: [Libvirt-cim] RFC : Introducing new CIM_RES_TYPE for 9pfs > support on QEMU/KVM environment > > On 12/02/2011 01:23 PM, Deepak Shetty wrote: > > On 12/02/2011 04:32 AM, Sharad Mishra wrote: > [...] > >> > >> > >> > >> > >> > >>
>> function='0x0'/> > >> > > >> What in the above libvirt XML makes it specific to 9pfs? I am > >> looking for > >> special 'tags' or 'properties'. > >> > >> -Sharad Mishra > > type='mount' makes it specific to 9pfs. So its the type attribute of > > the filesystem tag. > > I confirmed the same by looking into libvirt code also. > > > [...] > >>> The node comes directly under the node. > >>> > >>> My approach for introducing 9pfs support in libvirt-cim is ... > >>> > >>> 1) Add a new CIM res type, eg; CIM_RES_TYPE_9PFS, is this ok ? > >>> > >>> 2) Add appropriate handlers for the above new resource type > >>> > >>> 3) Add new members in struct domain for representing this new device > >> type. > >>> 4) Add appropriate xml parsing generation tags for the new resource > >>> type. > >>> > >>> 5) I probably need to add something like > >>> KVM_9PFSResourceAllocationSettingData -- I am not very clear on this > >>> yet. > >>> Need some help on how to do this ? > >>> > > I found some more enlightment today looking at the code, so here are my > newer thoughts... > > 1) It looks like the libvirt xml node ( that comes directly > under ) is supported in a psuedo fashion, under > CIM_RES_TYPE_DISK, is this correct ? > It does res_type = ...DISK and dev_type = ..DISK_FS. That is right. So, a filesystem is a disk device with type set to DISK_FS. > > 2) The cim code is structured in such a way that for each device type > that comes under there is a virt-device and > _device (eg: disk_device, net_device) structures and they > are described by the respective RASDs. In following this tradition the > there should have been virt_device and fs_device structures to > correspond to the device type, eventually getting embedded > under 'struct domain' but I don't see it, why is this so ? Why is > treated differently in cim code ? Not sure why its treated differently. > > 3) Assuming "yes" to #1 above, i need to extend the EmulatedType in > KVM_DiskResourceAllocationSettingData to support "filesystem" as a > value, set the disk_type = DISK_FS in disk_rasd_to_vdev and then it > should probably work, as the disk_xml and disk_fs_xml code is already > present to create the xml node. Bulk of the code already exist. You may need to test it and fix some bugs. > > 4) I probably will re-use some of the members of > KVM_DiskResourceAllocationSettingData from a 9pfs perspective, source > and target will remain same as before, DriverCache, Address, may not be > relevant for 9pfs. I might need to add few more stuff in DiskRASD as > needed to support more sub-elements and attributes in for the > in 9pfs case. Depending on your requirement, you may have to add new properties. -Sharad > > Let me know if the above approach/understanding is correct. Appreciate > your inputs. > > thanx, > deepak > > _______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim > From snmishra at us.ibm.com Thu Dec 8 22:55:20 2011 From: snmishra at us.ibm.com (Sharad Mishra) Date: Thu, 8 Dec 2011 14:55:20 -0800 Subject: [Libvirt-cim] [PATCH 00/15] vlan extension In-Reply-To: <1323249538-27410-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1323249538-27410-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: libvirt-cim-bounces at redhat.com wrote on 12/07/2011 01:18:58 AM: > Wayne Xia > Sent by: libvirt-cim-bounces at redhat.com > > 12/07/2011 01:18 AM > > Please respond to > List for discussion and development of libvirt CIM > > To > > libvirt-cim at redhat.com > > cc > > luowenj at cn.ibm.com, shuming at cn.ibm.com > > Subject > > [Libvirt-cim] [PATCH 00/15] vlan extension > > These patches would do following things: building up the network system CIM > model, building up basic framework and functions below to implement the > configuration, add the bridge and vlan802.1.q configuration capabilities in > CIM model and library below. > Now this patch implement the functionalities with commandline style, which > means it depends on command ip, ifconfig, brctl and /proc/net/vlan/. In this > way it is very sensitive to these command's output format. Maybe another > implemetion could avoid that in the future. > Since libvirt-cim is not a daemon program that would always be brought up > when the emulator was up, so there lacks a mechnism to save the configuration > and set them when system reboot, so these patch uses system directory > /etc/sysconfig/network-script/ > to store the settings. > The things above means that a linux kernel later than 2.6 and RedHat > distribution is needed. Other distriution may work but not tested. If We need to test on SLES -Sharad > the implemention goes to libvirt the restrict would be removed. > Related profiles: the most important are DSP1050, DSP1097, DSP 2025 (draft), > Other are: DSP1041, DSP1014. > Typical usage: assuming you have pNIC eth0. Use following xml files passed > to wbemexec could create bridge testbr with eth0.10 attached, which means all > VMs connecting to testbr would have access to IEEE802.1.q vlan 10. > > XML 1 > > > > > > > > > > > > VALUETYPE="string">Net_VirtualEthernetSwitchSystemManagementService KEYVALUE> > Management > Service > VALUETYPE="string">KVM_HostSystem > VALUETYPE="string">unknown > > > > > > instance of Net_VirtualEthernetSwitchSystemSettingData { > VirtualSystemIdentifier ="VS_testbr1"; > STP = 1; > }; > > > > > > > > > XML 2 > > > > > > > > > > > > VALUETYPE="string">Net_VirtualEthernetSwitchSystemManagementService KEYVALUE> > Management > Service > VALUETYPE="string">KVM_HostSystem > VALUETYPE="string">unknown > > > > > > > VALUETYPE="string">Virt:VS_eth0 > > > > > > > > instance of Net_EthernetPortAllocationSettingData { > InstanceID = "VS_eth0/EA_eth0.10"; > ElementName = "EA_eth0.10"; > VLANType = 1; > Connection = {"VLAN10"}; > ReorderHdr = 0; > }; > > > instance of Net_EthernetPortAllocationSettingData { > InstanceID = "VS_eth0/EC_eth0.10"; > HostResource = {"VS_testbr1"}; > Parent = "EA_eth0.10"; > }; > > > > > > > > > > Wayne Xia (15): > vlan extension - makefile change > vlan extension - CIM model - add class VESS > vlan extension - CIM model - add class VESSSD > vlan extension - CIM model - add class EthernetPort > vlan extension - CIM model - add class > EthernetPortAllocationSettingData > vlan extension - CIM model - add association Net_SettingsDeineState > vlan extension - CIM model - add association Net_SystemDevice > vlan extension - CIM model - add association Net_VESSSDComponent > vlan extension - CIM model - add association Net_ElementSettingData > vlan extension - CIM model - add core class VESSMS > vlan extension - CIM model - add help functions > vlan extension - function lib - add the API > vlan extension - function lib - add the core structure > vlan extension - function lib - add the helper functions > vlan extension - function lib - add the implemention of commandline > > Makefile.am | 16 +- > libxkutil/Makefile.am | 11 +- > libxkutil/host_network_API.c | 150 ++ > libxkutil/host_network_API.h | 32 + > libxkutil/host_network_basic.c | 639 +++++++ > libxkutil/host_network_basic.h | 166 ++ > libxkutil/host_network_error.h | 28 + > libxkutil/host_network_helper.c | 659 +++++++ > libxkutil/host_network_helper.h | 192 ++ > libxkutil/host_network_implement_cmdline.c | 2002 +++++++++ > +++++++++++ > libxkutil/host_network_implement_cmdline.h | 55 + > libxkutil/network_model.c | 466 +++++ > libxkutil/network_model.h | 105 + > schema/ElementSettingData.mof | 16 +- > schema/ElementSettingData.registration | 4 +- > schema/EthernetPort.mof | 4 + > schema/EthernetPort.registration | 3 + > schema/EthernetPortAllocationSettingData.mof | 21 + > .../EthernetPortAllocationSettingData.registration | 3 + > schema/SettingsDefineState.mof | 9 +- > schema/SettingsDefineState.registration | 3 +- > schema/SystemDevice.mof | 18 +- > schema/SystemDevice.registration | 3 +- > schema/VESSSDComponent.mof | 8 + > schema/VESSSDComponent.registration | 3 + > schema/VirtualEthernetSwitchSystem.mof | 10 + > schema/VirtualEthernetSwitchSystem.registration | 3 + > ...irtualEthernetSwitchSystemManagementService.mof | 14 + > ...ernetSwitchSystemManagementService.registration | 3 + > schema/VirtualEthernetSwitchSystemSettingData.mof | 27 + > ...ualEthernetSwitchSystemSettingData.registration | 3 + > src/Makefile.am | 49 +- > src/Virt_EASD.c | 733 +++++++ > src/Virt_EASD.h | 61 + > src/Virt_ElementSettingData.c | 229 +++- > src/Virt_EthernetPort.c | 565 ++++++ > src/Virt_EthernetPort.h | 58 + > src/Virt_HostSystem.c | 2 +- > src/Virt_HostSystem.h | 2 + > src/Virt_SettingsDefineState.c | 256 +++ > src/Virt_SystemDevice.c | 126 ++ > src/Virt_VESSSD.c | 372 ++++ > src/Virt_VESSSD.h | 39 + > src/Virt_VESSSDComponent.c | 181 ++ > src/Virt_VirtualEthernetSwitchSystem.c | 483 +++++ > src/Virt_VirtualEthernetSwitchSystem.h | 52 + > ..._VirtualEthernetSwitchSystemManagementService.c | 1342 +++++++++++++ > ..._VirtualEthernetSwitchSystemManagementService.h | 31 + > src/Virt_VirtualSystemManagementService.c | 17 +- > src/Virt_VirtualSystemManagementService.h | 10 + > 50 files changed, 9255 insertions(+), 29 deletions(-) > create mode 100644 libxkutil/host_network_API.c > create mode 100644 libxkutil/host_network_API.h > create mode 100644 libxkutil/host_network_basic.c > create mode 100644 libxkutil/host_network_basic.h > create mode 100644 libxkutil/host_network_error.h > create mode 100644 libxkutil/host_network_helper.c > create mode 100644 libxkutil/host_network_helper.h > create mode 100644 libxkutil/host_network_implement_cmdline.c > create mode 100644 libxkutil/host_network_implement_cmdline.h > create mode 100644 libxkutil/network_model.c > create mode 100644 libxkutil/network_model.h > create mode 100644 schema/EthernetPort.mof > create mode 100644 schema/EthernetPort.registration > create mode 100644 schema/EthernetPortAllocationSettingData.mof > create mode 100644 schema/EthernetPortAllocationSettingData.registration > create mode 100644 schema/VESSSDComponent.mof > create mode 100644 schema/VESSSDComponent.registration > create mode 100644 schema/VirtualEthernetSwitchSystem.mof > create mode 100644 schema/VirtualEthernetSwitchSystem.registration > create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.mof > create mode 100644 schema/ > VirtualEthernetSwitchSystemManagementService.registration > create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.mof > create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.registration > create mode 100644 src/Virt_EASD.c > create mode 100644 src/Virt_EASD.h > create mode 100644 src/Virt_EthernetPort.c > create mode 100644 src/Virt_EthernetPort.h > create mode 100644 src/Virt_VESSSD.c > create mode 100644 src/Virt_VESSSD.h > create mode 100644 src/Virt_VESSSDComponent.c > create mode 100644 src/Virt_VirtualEthernetSwitchSystem.c > create mode 100644 src/Virt_VirtualEthernetSwitchSystem.h > create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.c > create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.h > > -- > 1.7.6 > > > _______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim > From deepakcs at linux.vnet.ibm.com Fri Dec 9 11:16:56 2011 From: deepakcs at linux.vnet.ibm.com (Deepak C Shetty) Date: Fri, 09 Dec 2011 16:46:56 +0530 Subject: [Libvirt-cim] [PATCH] Plan9fs (aka 9pfs, VirtFS) support for QEMU/KVM environment Message-ID: <20111209111656.20645.54429.stgit@deepak-ThinkPad-T60p> VirtFS is virtualization aware file system pass-through which provides the functionality to share host file system inside the guest. Its supported in libvirt via the xml node/tag. This patch introduces the filesystem support in KVM_DiskRASD and its associated changes needed to support VirtFS in libvirt-cim. For further details... Virtfs home page/wiki : http://v9fs.sourceforge.net/ Virtfs setup for QEMU : http://wiki.qemu.org/Documentation/9psetup Virtfs support in libvirt : http://libvirt.org/formatdomain.html#elementsFilesystems An example of the node in libvirt, supporting VirtFS... Signed-off-by: Deepak C Shetty --- libxkutil/device_parsing.c | 8 ++++++++ libxkutil/device_parsing.h | 1 + libxkutil/xmlgen.c | 15 +++++++++++++++ schema/ResourceAllocationSettingData.mof | 7 +++++-- src/Virt_RASD.c | 6 ++++++ src/Virt_RASD.h | 1 + src/Virt_VirtualSystemManagementService.c | 8 ++++++++ 7 files changed, 44 insertions(+), 2 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 371838f..6a09e7d 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -65,6 +65,7 @@ static void cleanup_disk_device(struct disk_device *dev) free(dev->source); free(dev->virtual_dev); free(dev->bus_type); + free(dev->access_mode); } static void cleanup_vsi_device(struct vsi_device *dev) @@ -220,6 +221,8 @@ static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs) goto err; } + ddev->access_mode = get_attr_value(dnode, "accessmode"); + for (child = dnode->children; child != NULL; child = child->next) { if (XSTREQ(child->name, "source")) { ddev->source = get_attr_value(child, "dir"); @@ -233,6 +236,8 @@ static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs) CU_DEBUG("No target dir"); goto err; } + } else if (XSTREQ(child->name, "driver")) { + ddev->driver_type = get_attr_value(child, "type"); } } @@ -870,6 +875,7 @@ struct virt_device *virt_device_dup(struct virt_device *_dev) DUP_FIELD(dev, _dev, dev.disk.source); DUP_FIELD(dev, _dev, dev.disk.virtual_dev); DUP_FIELD(dev, _dev, dev.disk.bus_type); + DUP_FIELD(dev, _dev, dev.disk.access_mode); dev->dev.disk.disk_type = _dev->dev.disk.disk_type; dev->dev.disk.readonly = _dev->dev.disk.readonly; dev->dev.disk.shareable = _dev->dev.disk.shareable; @@ -1436,6 +1442,8 @@ int disk_type_from_file(const char *path) return DISK_PHY; else if (S_ISREG(s.st_mode)) return DISK_FILE; + else if (S_ISDIR(s.st_mode)) + return DISK_FS; else return DISK_UNKNOWN; } diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index ab104d9..6bed040 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -55,6 +55,7 @@ struct disk_device { bool shareable; char *bus_type; char *cache; + char *access_mode; /* access modes for DISK_FS (filesystem) type */ }; struct net_device { diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 4cca75b..44a6158 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -152,6 +152,21 @@ static const char *disk_fs_xml(xmlNodePtr root, struct disk_device *dev) if (fs == NULL) return XML_ERROR; + /* filesystem prop 'type' not needed to be generated, as it defaults + to 'mount' in libvirt, the only supported value for now. */ + + /* filesystem prop 'accessmode' defaults to 'passthrough' in libvirt. + So generate here if specified by user, else leave it to libvirt. */ + + if (dev->access_mode) { + xmlNewProp(fs, BAD_CAST "accessmode", BAD_CAST dev->access_mode); + } + + if(dev->driver_type) { + tmp = xmlNewChild(fs, NULL, BAD_CAST "driver", NULL); + xmlNewProp(tmp, BAD_CAST "type", BAD_CAST dev->driver_type); + } + tmp = xmlNewChild(fs, NULL, BAD_CAST "source", NULL); if (tmp == NULL) return XML_ERROR; diff --git a/schema/ResourceAllocationSettingData.mof b/schema/ResourceAllocationSettingData.mof index 3da503d..108dff7 100644 --- a/schema/ResourceAllocationSettingData.mof +++ b/schema/ResourceAllocationSettingData.mof @@ -40,8 +40,8 @@ class KVM_DiskResourceAllocationSettingData : KVM_ResourceAllocationSettingData string VirtualDevice; [Description ("Device emulation type"), - ValueMap {"0", "1", "2"}, - Values {"Disk", "CDROM", "floppy"}] + ValueMap {"0", "1", "2", "3"}, + Values {"Disk", "CDROM", "floppy", "filesystem"}] uint16 EmulatedType; [Description ("Bus type of the device")] @@ -58,6 +58,9 @@ class KVM_DiskResourceAllocationSettingData : KVM_ResourceAllocationSettingData [Description ("cache setting for device")] string DriverCache; + + [Description ("filesystem access mode")] + string AccessMode; }; [Description ("LXC virtual disk configuration"), diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c index 9305c8d..29bf10d 100644 --- a/src/Virt_RASD.c +++ b/src/Virt_RASD.c @@ -397,6 +397,12 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker, (CMPIValue *)dev->dev.disk.cache, CMPI_chars); + if(dev->dev.disk.access_mode) + CMSetProperty(inst, + "AccessMode", + (CMPIValue *)dev->dev.disk.access_mode, + CMPI_chars); + virStoragePoolFree(pool); virStorageVolFree(vol); virConnectClose(conn); diff --git a/src/Virt_RASD.h b/src/Virt_RASD.h index 550543a..cef4224 100644 --- a/src/Virt_RASD.h +++ b/src/Virt_RASD.h @@ -26,6 +26,7 @@ #define VIRT_DISK_TYPE_DISK 0 #define VIRT_DISK_TYPE_CDROM 1 #define VIRT_DISK_TYPE_FLOPPY 2 +#define VIRT_DISK_TYPE_FS 3 char *rasd_to_xml(CMPIInstance *rasd); diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 21979c3..3cdca86 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -1022,6 +1022,8 @@ static const char *disk_rasd_to_vdev(CMPIInstance *inst, } else if (type == VIRT_DISK_TYPE_FLOPPY) dev->dev.disk.device = strdup("floppy"); + else if (type == VIRT_DISK_TYPE_FS) + dev->dev.disk.device = strdup("filesystem"); else return "Invalid value for EmulatedType"; @@ -1056,6 +1058,12 @@ static const char *disk_rasd_to_vdev(CMPIInstance *inst, else dev->dev.disk.cache = strdup(val); + free(dev->dev.disk.access_mode); + if (cu_get_str_prop(inst, "AccessMode", &val) != CMPI_RC_OK) + dev->dev.disk.access_mode = NULL; + else + dev->dev.disk.access_mode = strdup(val); + free(dev->id); dev->id = strdup(dev->dev.disk.virtual_dev); From xiawenc at linux.vnet.ibm.com Thu Dec 15 09:33:15 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Thu, 15 Dec 2011 17:33:15 +0800 Subject: [Libvirt-cim] [PATCH v2 00/15] libvirt-cim vlan extension Message-ID: <1323941595-30396-1-git-send-email-xiawenc@linux.vnet.ibm.com> These patches would do following things: building up the network system CIM model, building up basic framework and functions below to implement the configuration, add the bridge and vlan802.1.q configuration capabilities in CIM model and library below. Now this patch implement the functionalities with commandline style, which means it depends on command ip, ifconfig, brctl and /proc/net/vlan/. In this way it is very sensitive to these command's output format. Maybe another implemetion could avoid that in the future. Since libvirt-cim is not a daemon program that would always be brought up when the emulator was up, so there lacks a mechnism to save the configuration and set them when system reboot, so these patch uses system directory /etc/sysconfig/network-script/ to store the settings. The things above means that a linux kernel later than 2.6 and RedHat distribution is needed. Other distriution may work but not tested. If the implemention goes to libvirt the restrict would be removed. Related profiles: the most important are DSP1050, DSP1097, DSP 2025(draft), Other are: DSP1041, DSP1014. Typical usage: assuming you have pNIC eth0. Use following xml files passed to wbemexec could create bridge testbr with eth0.10 attached, which means all VMs connecting to testbr would have access to IEEE802.1.q vlan 10. v2: Changed the eth type defines to filter out lo, sit logical devices. Removed the ifconfig command. The patches could be got from following url https://gitorious.org/~xiaxia347/libvirt-cim/xiawenc direct git repo is git://gitorious.org/~xiaxia347/libvirt-cim/xiawenc.git. XML 1 Net_VirtualEthernetSwitchSystemManagementService Management Service KVM_HostSystem unknown instance of Net_VirtualEthernetSwitchSystemSettingData { VirtualSystemIdentifier ="VS_testbr1"; STP = 1; }; XML 2 Net_VirtualEthernetSwitchSystemManagementService Management Service KVM_HostSystem unknown Virt:VS_eth0 instance of Net_EthernetPortAllocationSettingData { InstanceID = "VS_eth0/EA_eth0.10"; ElementName = "EA_eth0.10"; VLANType = 1; Connection = {"VLAN10"}; ReorderHdr = 0; }; instance of Net_EthernetPortAllocationSettingData { InstanceID = "VS_eth0/EC_eth0.10"; HostResource = {"VS_testbr1"}; Parent = "EA_eth0.10"; }; Wayne Xia (15): vlan extension - Makefile change vlan extension - CIM model - add class VESS vlan extension - CIM model - add class VESSSD vlan extension - CIM model - add class EthernetPort vlan extension - CIM model - add class EASD vlan extension - CIM model - add association SDS vlan extension - CIM model - add association VESSD vlan extension - CIM model - add association VESSSDComponent vlan extension - CIM model - add association ESD vlan extension - CIM model - add core class VESSMS vlan extension - CIM model - add help functions vlan extension - function lib - add the API vlan extension - function lib - add the core structures vlan extension - function lib - add the helper vlan extension - function lib - add the implemention of cmd line Makefile.am | 16 +- libxkutil/Makefile.am | 11 +- libxkutil/host_network_API.c | 182 ++ libxkutil/host_network_API.h | 32 + libxkutil/host_network_basic.c | 657 +++++++ libxkutil/host_network_basic.h | 168 ++ libxkutil/host_network_error.h | 28 + libxkutil/host_network_helper.c | 659 +++++++ libxkutil/host_network_helper.h | 192 ++ libxkutil/host_network_implement_cmdline.c | 1835 ++++++++++++++++++++ libxkutil/host_network_implement_cmdline.h | 52 + libxkutil/network_model.c | 466 +++++ libxkutil/network_model.h | 105 ++ schema/ElementSettingData.mof | 16 +- schema/ElementSettingData.registration | 4 +- schema/EthernetPort.mof | 4 + schema/EthernetPort.registration | 3 + schema/EthernetPortAllocationSettingData.mof | 21 + .../EthernetPortAllocationSettingData.registration | 3 + schema/SettingsDefineState.mof | 9 +- schema/SettingsDefineState.registration | 3 +- schema/SystemDevice.mof | 18 +- schema/SystemDevice.registration | 3 +- schema/VESSSDComponent.mof | 8 + schema/VESSSDComponent.registration | 3 + schema/VirtualEthernetSwitchSystem.mof | 10 + schema/VirtualEthernetSwitchSystem.registration | 3 + ...irtualEthernetSwitchSystemManagementService.mof | 14 + ...ernetSwitchSystemManagementService.registration | 3 + schema/VirtualEthernetSwitchSystemSettingData.mof | 27 + ...ualEthernetSwitchSystemSettingData.registration | 3 + src/Makefile.am | 49 +- src/Virt_EASD.c | 732 ++++++++ src/Virt_EASD.h | 61 + src/Virt_ElementSettingData.c | 229 +++- src/Virt_EthernetPort.c | 565 ++++++ src/Virt_EthernetPort.h | 58 + src/Virt_HostSystem.c | 2 +- src/Virt_HostSystem.h | 2 + src/Virt_SettingsDefineState.c | 256 +++ src/Virt_SystemDevice.c | 126 ++ src/Virt_VESSSD.c | 373 ++++ src/Virt_VESSSD.h | 39 + src/Virt_VESSSDComponent.c | 181 ++ src/Virt_VirtualEthernetSwitchSystem.c | 483 +++++ src/Virt_VirtualEthernetSwitchSystem.h | 52 + ..._VirtualEthernetSwitchSystemManagementService.c | 1345 ++++++++++++++ ..._VirtualEthernetSwitchSystemManagementService.h | 31 + src/Virt_VirtualSystemManagementService.c | 17 +- src/Virt_VirtualSystemManagementService.h | 10 + 50 files changed, 9140 insertions(+), 29 deletions(-) create mode 100644 libxkutil/host_network_API.c create mode 100644 libxkutil/host_network_API.h create mode 100644 libxkutil/host_network_basic.c create mode 100644 libxkutil/host_network_basic.h create mode 100644 libxkutil/host_network_error.h create mode 100644 libxkutil/host_network_helper.c create mode 100644 libxkutil/host_network_helper.h create mode 100644 libxkutil/host_network_implement_cmdline.c create mode 100644 libxkutil/host_network_implement_cmdline.h create mode 100644 libxkutil/network_model.c create mode 100644 libxkutil/network_model.h create mode 100644 schema/EthernetPort.mof create mode 100644 schema/EthernetPort.registration create mode 100644 schema/EthernetPortAllocationSettingData.mof create mode 100644 schema/EthernetPortAllocationSettingData.registration create mode 100644 schema/VESSSDComponent.mof create mode 100644 schema/VESSSDComponent.registration create mode 100644 schema/VirtualEthernetSwitchSystem.mof create mode 100644 schema/VirtualEthernetSwitchSystem.registration create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.mof create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.registration create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.mof create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.registration create mode 100644 src/Virt_EASD.c create mode 100644 src/Virt_EASD.h create mode 100644 src/Virt_EthernetPort.c create mode 100644 src/Virt_EthernetPort.h create mode 100644 src/Virt_VESSSD.c create mode 100644 src/Virt_VESSSD.h create mode 100644 src/Virt_VESSSDComponent.c create mode 100644 src/Virt_VirtualEthernetSwitchSystem.c create mode 100644 src/Virt_VirtualEthernetSwitchSystem.h create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.c create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.h -- 1.7.6 From snmishra at us.ibm.com Thu Dec 15 17:49:03 2011 From: snmishra at us.ibm.com (Sharad Mishra) Date: Thu, 15 Dec 2011 09:49:03 -0800 Subject: [Libvirt-cim] [PATCH] Plan9fs (aka 9pfs, VirtFS) support for QEMU/KVM environment In-Reply-To: <20111209111656.20645.54429.stgit@deepak-ThinkPad-T60p> References: <20111209111656.20645.54429.stgit@deepak-ThinkPad-T60p> Message-ID: The patch looks good. Gareth is looking if we need to update SettingsDefineCapabilities for template. Regards, Sharad Mishra Open Virtualization Linux Technology Center IBM libvirt-cim-bounces at redhat.com wrote on 12/09/2011 03:16:56 AM: > Deepak C Shetty > Sent by: libvirt-cim-bounces at redhat.com > > 12/09/11 03:16 AM > > Please respond to > List for discussion and development of libvirt CIM > > To > > libvirt-cim at redhat.com > > cc > > Subject > > [Libvirt-cim] [PATCH] Plan9fs (aka 9pfs, VirtFS) support for QEMU/ > KVM environment > > VirtFS is virtualization aware file system pass-through which provides the > functionality to share host file system inside the guest. Its supported in > libvirt via the xml node/tag. This patch introduces the > filesystem support in KVM_DiskRASD and its associated changes needed to > support VirtFS in libvirt-cim. > > For further details... > Virtfs home page/wiki : http://v9fs.sourceforge.net/ > Virtfs setup for QEMU : http://wiki.qemu.org/Documentation/9psetup > Virtfs support in libvirt : > http://libvirt.org/formatdomain.html#elementsFilesystems > > An example of the node in libvirt, supporting VirtFS... > > > > > > > > Signed-off-by: Deepak C Shetty > --- > > libxkutil/device_parsing.c | 8 ++++++++ > libxkutil/device_parsing.h | 1 + > libxkutil/xmlgen.c | 15 +++++++++++++++ > schema/ResourceAllocationSettingData.mof | 7 +++++-- > src/Virt_RASD.c | 6 ++++++ > src/Virt_RASD.h | 1 + > src/Virt_VirtualSystemManagementService.c | 8 ++++++++ > 7 files changed, 44 insertions(+), 2 deletions(-) > > diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c > index 371838f..6a09e7d 100644 > --- a/libxkutil/device_parsing.c > +++ b/libxkutil/device_parsing.c > @@ -65,6 +65,7 @@ static void cleanup_disk_device(struct disk_device *dev) > free(dev->source); > free(dev->virtual_dev); > free(dev->bus_type); > + free(dev->access_mode); > } > > static void cleanup_vsi_device(struct vsi_device *dev) > @@ -220,6 +221,8 @@ static int parse_fs_device(xmlNode *dnode, > struct virt_device **vdevs) > goto err; > } > > + ddev->access_mode = get_attr_value(dnode, "accessmode"); > + > for (child = dnode->children; child != NULL; child = child-> next) { > if (XSTREQ(child->name, "source")) { > ddev->source = get_attr_value(child, "dir"); > @@ -233,6 +236,8 @@ static int parse_fs_device(xmlNode *dnode, > struct virt_device **vdevs) > CU_DEBUG("No target dir"); > goto err; > } > + } else if (XSTREQ(child->name, "driver")) { > + ddev->driver_type = get_attr_value(child, "type"); > } > } > > @@ -870,6 +875,7 @@ struct virt_device *virt_device_dup(struct > virt_device *_dev) > DUP_FIELD(dev, _dev, dev.disk.source); > DUP_FIELD(dev, _dev, dev.disk.virtual_dev); > DUP_FIELD(dev, _dev, dev.disk.bus_type); > + DUP_FIELD(dev, _dev, dev.disk.access_mode); > dev->dev.disk.disk_type = _dev->dev.disk.disk_type; > dev->dev.disk.readonly = _dev->dev.disk.readonly; > dev->dev.disk.shareable = _dev->dev.disk.shareable; > @@ -1436,6 +1442,8 @@ int disk_type_from_file(const char *path) > return DISK_PHY; > else if (S_ISREG(s.st_mode)) > return DISK_FILE; > + else if (S_ISDIR(s.st_mode)) > + return DISK_FS; > else > return DISK_UNKNOWN; > } > diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h > index ab104d9..6bed040 100644 > --- a/libxkutil/device_parsing.h > +++ b/libxkutil/device_parsing.h > @@ -55,6 +55,7 @@ struct disk_device { > bool shareable; > char *bus_type; > char *cache; > + char *access_mode; /* access modes for DISK_FS (filesystem) type */ > }; > > struct net_device { > diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c > index 4cca75b..44a6158 100644 > --- a/libxkutil/xmlgen.c > +++ b/libxkutil/xmlgen.c > @@ -152,6 +152,21 @@ static const char *disk_fs_xml(xmlNodePtr root, > struct disk_device *dev) > if (fs == NULL) > return XML_ERROR; > > + /* filesystem prop 'type' not needed to be generated, as it defaults > + to 'mount' in libvirt, the only supported value for now. */ > + > + /* filesystem prop 'accessmode' defaults to 'passthrough' in libvirt. > + So generate here if specified by user, else leave it to libvirt. */ > + > + if (dev->access_mode) { > + xmlNewProp(fs, BAD_CAST "accessmode", BAD_CAST > dev->access_mode); > + } > + > + if(dev->driver_type) { > + tmp = xmlNewChild(fs, NULL, BAD_CAST "driver", NULL); > + xmlNewProp(tmp, BAD_CAST "type", BAD_CAST dev-> driver_type); > + } > + > tmp = xmlNewChild(fs, NULL, BAD_CAST "source", NULL); > if (tmp == NULL) > return XML_ERROR; > diff --git a/schema/ResourceAllocationSettingData.mof b/schema/ > ResourceAllocationSettingData.mof > index 3da503d..108dff7 100644 > --- a/schema/ResourceAllocationSettingData.mof > +++ b/schema/ResourceAllocationSettingData.mof > @@ -40,8 +40,8 @@ class KVM_DiskResourceAllocationSettingData : > KVM_ResourceAllocationSettingData > string VirtualDevice; > > [Description ("Device emulation type"), > - ValueMap {"0", "1", "2"}, > - Values {"Disk", "CDROM", "floppy"}] > + ValueMap {"0", "1", "2", "3"}, > + Values {"Disk", "CDROM", "floppy", "filesystem"}] > uint16 EmulatedType; > > [Description ("Bus type of the device")] > @@ -58,6 +58,9 @@ class KVM_DiskResourceAllocationSettingData : > KVM_ResourceAllocationSettingData > > [Description ("cache setting for device")] > string DriverCache; > + > + [Description ("filesystem access mode")] > + string AccessMode; > }; > > [Description ("LXC virtual disk configuration"), > diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c > index 9305c8d..29bf10d 100644 > --- a/src/Virt_RASD.c > +++ b/src/Virt_RASD.c > @@ -397,6 +397,12 @@ static CMPIStatus set_disk_rasd_params(const > CMPIBroker *broker, > (CMPIValue *)dev->dev.disk.cache, > CMPI_chars); > > + if(dev->dev.disk.access_mode) > + CMSetProperty(inst, > + "AccessMode", > + (CMPIValue *)dev->dev.disk.access_mode, > + CMPI_chars); > + > virStoragePoolFree(pool); > virStorageVolFree(vol); > virConnectClose(conn); > diff --git a/src/Virt_RASD.h b/src/Virt_RASD.h > index 550543a..cef4224 100644 > --- a/src/Virt_RASD.h > +++ b/src/Virt_RASD.h > @@ -26,6 +26,7 @@ > #define VIRT_DISK_TYPE_DISK 0 > #define VIRT_DISK_TYPE_CDROM 1 > #define VIRT_DISK_TYPE_FLOPPY 2 > +#define VIRT_DISK_TYPE_FS 3 > > char *rasd_to_xml(CMPIInstance *rasd); > > diff --git a/src/Virt_VirtualSystemManagementService.c b/src/ > Virt_VirtualSystemManagementService.c > index 21979c3..3cdca86 100644 > --- a/src/Virt_VirtualSystemManagementService.c > +++ b/src/Virt_VirtualSystemManagementService.c > @@ -1022,6 +1022,8 @@ static const char *disk_rasd_to_vdev(CMPIInstance *inst, > } > else if (type == VIRT_DISK_TYPE_FLOPPY) > dev->dev.disk.device = strdup("floppy"); > + else if (type == VIRT_DISK_TYPE_FS) > + dev->dev.disk.device = strdup("filesystem"); > else > return "Invalid value for EmulatedType"; > > @@ -1056,6 +1058,12 @@ static const char *disk_rasd_to_vdev > (CMPIInstance *inst, > else > dev->dev.disk.cache = strdup(val); > > + free(dev->dev.disk.access_mode); > + if (cu_get_str_prop(inst, "AccessMode", &val) != CMPI_RC_OK) > + dev->dev.disk.access_mode = NULL; > + else > + dev->dev.disk.access_mode = strdup(val); > + > free(dev->id); > dev->id = strdup(dev->dev.disk.virtual_dev); > > > _______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim > From eblima at linux.vnet.ibm.com Fri Dec 16 13:06:49 2011 From: eblima at linux.vnet.ibm.com (Eduardo Lima (Etrunko)) Date: Fri, 16 Dec 2011 11:06:49 -0200 Subject: [Libvirt-cim] [PATCH] Update .gitignore Message-ID: <1324040809-6990-1-git-send-email-eblima@linux.vnet.ibm.com> From: Eduardo Lima (Etrunko) Signed-off-by: Eduardo Lima (Etrunko) --- .gitignore | 42 ++++++++++++++---------------------------- 1 files changed, 14 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index f68ff08..fa1066c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,12 @@ syntax: glob *.patch *~ *.o +*.la +*.lo +.libs +Makefile.in +Makefile +config.* tests/*.err doc/*.html .changeset @@ -14,31 +20,11 @@ doc/*.html xml_parse_test cim_schema_*.zip install_base_schema.sh - -syntax: regexp -.*\#.*\#$ -Makefile$ -Makefile\.in$ -^aclocal\.m4$ -autom4te\.cache/.* -config\.guess$ -config\.h$ -config\.log$ -config\.status$ -config\.sub$ -^configure$ -^install-sh$ -^ltmain.sh$ -^missing$ -\.libs/.* -\.la$ -\.lo$ -\.o$ -^stamp-h1$ -^libtool$ -.*\~$ -.*\.loT$ -^acinclude.m4.orig$ -^config.h.in$ -libcmpiutil/doc/html/.*% - +aclocal.m4 +autom4te.cache +configure +install-sh +libtool +ltmain.sh +missing +stamp-h1 -- 1.7.4.4 From bestor at us.ibm.com Tue Dec 20 12:43:15 2011 From: bestor at us.ibm.com (Gareth S. Bestor) Date: Tue, 20 Dec 2011 04:43:15 -0800 Subject: [Libvirt-cim] [PATCH] cpu cgroup patch 2 Message-ID: <1324384995-9068-1-git-send-email-bestor@us.ibm.com> Signed-off-by: Gareth S. Bestor --- libxkutil/xmlgen.c | 45 +++++++++++++++++++++++++++++ src/Virt_ComputerSystem.c | 6 ++++ src/Virt_RASD.c | 6 +++- src/Virt_VirtualSystemManagementService.c | 30 +++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 4cca75b..2fe41bf 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -365,6 +365,44 @@ static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) return NULL; } +#if LIBVIR_VERSION_NUMBER >= 9000 +static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) +{ + struct vcpu_device *vcpu; + xmlNodePtr cputune, tmp; + int ret; + char *string = NULL; + + if (dominfo->dev_vcpu == NULL) + return NULL; + + vcpu = &dominfo->dev_vcpu[0].dev.vcpu; + + /* CPU cgroup setting saved by libvirt under XML section */ + cputune = xmlNewChild(root, NULL, BAD_CAST "cputune", NULL); + if (cputune == NULL) + return XML_ERROR; + + /* Get the CPU cgroup setting from the VCPU RASD.Weight property */ + ret = asprintf(&string, + "%d", + vcpu->weight); + if (ret == -1) + return XML_ERROR; + + tmp = xmlNewChild(cputune, + NULL, + BAD_CAST "shares", + BAD_CAST string); + free(string); + + if (tmp == NULL) + return XML_ERROR; + else + return NULL; +} +#endif + static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) { struct mem_device *mem; @@ -941,6 +979,13 @@ char *system_to_xml(struct domain *dominfo) if (msg != NULL) goto out; +#if LIBVIR_VERSION_NUMBER >= 9000 + /* Recent libvirt versions add new section to XML */ + msg = cputune_xml(root, dominfo); + if (msg != NULL) + goto out; +#endif + devices = xmlNewChild(root, NULL, BAD_CAST "devices", NULL); if (devices == NULL) { msg = XML_ERROR; diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c index e1f1cec..098b07a 100644 --- a/src/Virt_ComputerSystem.c +++ b/src/Virt_ComputerSystem.c @@ -861,6 +861,11 @@ static int lxc_scheduler_params(struct infostore_ctx *ctx, static int kvm_scheduler_params(struct infostore_ctx *ctx, virSchedParameter **params) { +#if LIBVIR_VERSION_NUMBER < 9000 + /* Old versions of libvirt only support CPU cgroups for running guests */ + /* so instead read cpu cgroup setting for inactive guest from infostore. */ + /* New versions there is nothing to do because libvirt takes care of it. */ + unsigned long long value; *params = calloc(1, sizeof(virSchedParameter)); @@ -878,6 +883,7 @@ static int kvm_scheduler_params(struct infostore_ctx *ctx, return 1; } +#endif return 0; } diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c index 9305c8d..0a2de7f 100644 --- a/src/Virt_RASD.c +++ b/src/Virt_RASD.c @@ -157,8 +157,12 @@ static CMPIStatus set_proc_rasd_params(const CMPIBroker *broker, goto out; } - /* Currently only support CPU cgroups for running KVM guests */ + /* Early versions of libvirt only support CPU cgroups for *running* KVM guests */ +#if LIBVIR_VERSION_NUMBER < 9000 if (domain_online(dom) && STREQC(virConnectGetType(conn), "QEMU")) { +#else + if (STREQC(virConnectGetType(conn), "QEMU")) { +#endif char *sched; int nparams; unsigned int i; diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 21979c3..f6b191e 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -1783,7 +1783,37 @@ static CMPIStatus update_dominfo(const struct domain *dominfo, goto out; } +#if LIBVIR_VERSION_NUMBER < 9000 + /* Old libvirt versions dont save cpu cgroup setting for inactive */ + /* guests, so save in infostore instead */ infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); +#else + /* New libvirt versions save cpu cgroup setting in KVM guest config */ + if (STREQC(virConnectGetType(conn), "QEMU")) { + int ret; + virSchedParameter params; + strncpy(params.field, + "cpu_shares", + VIR_DOMAIN_SCHED_FIELD_LENGTH); + params.type = VIR_DOMAIN_SCHED_FIELD_ULLONG; + params.value.ul = dev->dev.vcpu.weight; + + CU_DEBUG("setting %s scheduler param cpu_shares=%d", + dominfo->name, + dev->dev.vcpu.weight); + ret = virDomainSetSchedulerParametersFlags(dom, ¶ms, 1, + VIR_DOMAIN_AFFECT_CONFIG); + if (ret != 0) { + CU_DEBUG("Failed to set config scheduler param"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to set config scheduler param"); + goto out; + } + } + else + infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); +#endif infostore_set_u64(ctx, "limit", dev->dev.vcpu.limit); out: -- 1.7.1 From bestor at us.ibm.com Tue Dec 20 19:53:50 2011 From: bestor at us.ibm.com (Gareth S Bestor) Date: Tue, 20 Dec 2011 11:53:50 -0800 Subject: [Libvirt-cim] [PATCH] cpu cgroup patch 2 In-Reply-To: <1324384995-9068-1-git-send-email-bestor@us.ibm.com> Message-ID: hmm. my git configuration seems to have stripped out all my comments... sorry. This should have been included: --------- Patch to earlier cpu cgroup support in libvirt-cim to accommodate support in latest versions of libvirt for persisting cpu cgroup setting for KVM guests in new section of XML config. Patch is conditionally compiled based on libvirt version built against. New libvirt versions will exploit this patch and libvirt-cim will no longer save cpu cgroup setting in infostore, and is better interoperable with virsh management commands. Older libvirt versions will continue to exploit previous libvirt-cim cpu cgroup support (ie save cpu cgroup setting in infostore, less interoperable with vish management commands). ---------- - G Dr. Gareth S. Bestor IBM Senior Software Engineer Systems & Technology Group - Systems Management Standards 971-285-6375 (mobile) bestor at us.ibm.com [PATCH] cpu cgroup patch 2 Gareth S Bestor to: libvirt-cim 12/20/11 11:48 AM Cc: Gareth S Bestor Signed-off-by: Gareth S. Bestor --- libxkutil/xmlgen.c | 45 +++++++++++++++++++++++++++++ src/Virt_ComputerSystem.c | 6 ++++ src/Virt_RASD.c | 6 +++- src/Virt_VirtualSystemManagementService.c | 30 +++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 4cca75b..2fe41bf 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -365,6 +365,44 @@ static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) return NULL; } +#if LIBVIR_VERSION_NUMBER >= 9000 +static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) +{ + struct vcpu_device *vcpu; + xmlNodePtr cputune, tmp; + int ret; + char *string = NULL; + + if (dominfo->dev_vcpu == NULL) + return NULL; + + vcpu = &dominfo->dev_vcpu[0].dev.vcpu; + + /* CPU cgroup setting saved by libvirt under XML section */ + cputune = xmlNewChild(root, NULL, BAD_CAST "cputune", NULL); + if (cputune == NULL) + return XML_ERROR; + + /* Get the CPU cgroup setting from the VCPU RASD.Weight property */ + ret = asprintf(&string, + "%d", + vcpu->weight); + if (ret == -1) + return XML_ERROR; + + tmp = xmlNewChild(cputune, + NULL, + BAD_CAST "shares", + BAD_CAST string); + free(string); + + if (tmp == NULL) + return XML_ERROR; + else + return NULL; +} +#endif + static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) { struct mem_device *mem; @@ -941,6 +979,13 @@ char *system_to_xml(struct domain *dominfo) if (msg != NULL) goto out; +#if LIBVIR_VERSION_NUMBER >= 9000 + /* Recent libvirt versions add new section to XML */ + msg = cputune_xml(root, dominfo); + if (msg != NULL) + goto out; +#endif + devices = xmlNewChild(root, NULL, BAD_CAST "devices", NULL); if (devices == NULL) { msg = XML_ERROR; diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c index e1f1cec..098b07a 100644 --- a/src/Virt_ComputerSystem.c +++ b/src/Virt_ComputerSystem.c @@ -861,6 +861,11 @@ static int lxc_scheduler_params(struct infostore_ctx *ctx, static int kvm_scheduler_params(struct infostore_ctx *ctx, virSchedParameter **params) { +#if LIBVIR_VERSION_NUMBER < 9000 + /* Old versions of libvirt only support CPU cgroups for running guests */ + /* so instead read cpu cgroup setting for inactive guest from infostore. */ + /* New versions there is nothing to do because libvirt takes care of it. */ + unsigned long long value; *params = calloc(1, sizeof(virSchedParameter)); @@ -878,6 +883,7 @@ static int kvm_scheduler_params(struct infostore_ctx *ctx, return 1; } +#endif return 0; } diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c index 9305c8d..0a2de7f 100644 --- a/src/Virt_RASD.c +++ b/src/Virt_RASD.c @@ -157,8 +157,12 @@ static CMPIStatus set_proc_rasd_params(const CMPIBroker *broker, goto out; } - /* Currently only support CPU cgroups for running KVM guests */ + /* Early versions of libvirt only support CPU cgroups for *running* KVM guests */ +#if LIBVIR_VERSION_NUMBER < 9000 if (domain_online(dom) && STREQC(virConnectGetType(conn), "QEMU")) { +#else + if (STREQC(virConnectGetType(conn), "QEMU")) { +#endif char *sched; int nparams; unsigned int i; diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 21979c3..f6b191e 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -1783,7 +1783,37 @@ static CMPIStatus update_dominfo(const struct domain *dominfo, goto out; } +#if LIBVIR_VERSION_NUMBER < 9000 + /* Old libvirt versions dont save cpu cgroup setting for inactive */ + /* guests, so save in infostore instead */ infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); +#else + /* New libvirt versions save cpu cgroup setting in KVM guest config */ + if (STREQC(virConnectGetType(conn), "QEMU")) { + int ret; + virSchedParameter params; + strncpy(params.field, + "cpu_shares", + VIR_DOMAIN_SCHED_FIELD_LENGTH); + params.type = VIR_DOMAIN_SCHED_FIELD_ULLONG; + params.value.ul = dev->dev.vcpu.weight; + + CU_DEBUG("setting %s scheduler param cpu_shares=%d", + dominfo->name, + dev->dev.vcpu.weight); + ret = virDomainSetSchedulerParametersFlags(dom, ¶ms, 1, + VIR_DOMAIN_AFFECT_CONFIG); + if (ret != 0) { + CU_DEBUG("Failed to set config scheduler param"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to set config scheduler param"); + goto out; + } + } + else + infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); +#endif infostore_set_u64(ctx, "limit", dev->dev.vcpu.limit); out: -- 1.7.1 -------------- next part -------------- An HTML attachment was scrubbed... URL: From xiawenc at linux.vnet.ibm.com Wed Dec 21 01:59:31 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 21 Dec 2011 09:59:31 +0800 Subject: [Libvirt-cim] [PATCH] cpu cgroup patch 2 In-Reply-To: <1324384995-9068-1-git-send-email-bestor@us.ibm.com> References: <1324384995-9068-1-git-send-email-bestor@us.ibm.com> Message-ID: <4EF13D83.1060705@linux.vnet.ibm.com> Seems it choose the function at compile time, I guess this result in two RPMs with different configuration of libvirt-cim. Could we use the latest the libvirt to compile the codes, but choose the function at runtime? That would be better to maintain and for user who are not developer. ? 2011-12-20 20:43, Gareth S. Bestor ??: > Signed-off-by: Gareth S. Bestor > --- > libxkutil/xmlgen.c | 45 +++++++++++++++++++++++++++++ > src/Virt_ComputerSystem.c | 6 ++++ > src/Virt_RASD.c | 6 +++- > src/Virt_VirtualSystemManagementService.c | 30 +++++++++++++++++++ > 4 files changed, 86 insertions(+), 1 deletions(-) > > diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c > index 4cca75b..2fe41bf 100644 > --- a/libxkutil/xmlgen.c > +++ b/libxkutil/xmlgen.c > @@ -365,6 +365,44 @@ static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) > return NULL; > } > > +#if LIBVIR_VERSION_NUMBER>= 9000 > +static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) > +{ > + struct vcpu_device *vcpu; > + xmlNodePtr cputune, tmp; > + int ret; > + char *string = NULL; > + > + if (dominfo->dev_vcpu == NULL) > + return NULL; > + > + vcpu =&dominfo->dev_vcpu[0].dev.vcpu; > + > + /* CPU cgroup setting saved by libvirt under XML section */ > + cputune = xmlNewChild(root, NULL, BAD_CAST "cputune", NULL); > + if (cputune == NULL) > + return XML_ERROR; > + > + /* Get the CPU cgroup setting from the VCPU RASD.Weight property */ > + ret = asprintf(&string, > + "%d", > + vcpu->weight); > + if (ret == -1) > + return XML_ERROR; > + > + tmp = xmlNewChild(cputune, > + NULL, > + BAD_CAST "shares", > + BAD_CAST string); > + free(string); > + > + if (tmp == NULL) > + return XML_ERROR; > + else > + return NULL; > +} > +#endif > + > static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) > { > struct mem_device *mem; > @@ -941,6 +979,13 @@ char *system_to_xml(struct domain *dominfo) > if (msg != NULL) > goto out; > > +#if LIBVIR_VERSION_NUMBER>= 9000 > + /* Recent libvirt versions add new section to XML */ > + msg = cputune_xml(root, dominfo); > + if (msg != NULL) > + goto out; > +#endif > + > devices = xmlNewChild(root, NULL, BAD_CAST "devices", NULL); > if (devices == NULL) { > msg = XML_ERROR; > diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c > index e1f1cec..098b07a 100644 > --- a/src/Virt_ComputerSystem.c > +++ b/src/Virt_ComputerSystem.c > @@ -861,6 +861,11 @@ static int lxc_scheduler_params(struct infostore_ctx *ctx, > static int kvm_scheduler_params(struct infostore_ctx *ctx, > virSchedParameter **params) > { > +#if LIBVIR_VERSION_NUMBER< 9000 > + /* Old versions of libvirt only support CPU cgroups for running guests */ > + /* so instead read cpu cgroup setting for inactive guest from infostore. */ > + /* New versions there is nothing to do because libvirt takes care of it. */ > + > unsigned long long value; > > *params = calloc(1, sizeof(virSchedParameter)); > @@ -878,6 +883,7 @@ static int kvm_scheduler_params(struct infostore_ctx *ctx, > > return 1; > } > +#endif > > return 0; > } > diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c > index 9305c8d..0a2de7f 100644 > --- a/src/Virt_RASD.c > +++ b/src/Virt_RASD.c > @@ -157,8 +157,12 @@ static CMPIStatus set_proc_rasd_params(const CMPIBroker *broker, > goto out; > } > > - /* Currently only support CPU cgroups for running KVM guests */ > + /* Early versions of libvirt only support CPU cgroups for *running* KVM guests */ > +#if LIBVIR_VERSION_NUMBER< 9000 > if (domain_online(dom)&& STREQC(virConnectGetType(conn), "QEMU")) { > +#else > + if (STREQC(virConnectGetType(conn), "QEMU")) { > +#endif > char *sched; > int nparams; > unsigned int i; > diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c > index 21979c3..f6b191e 100644 > --- a/src/Virt_VirtualSystemManagementService.c > +++ b/src/Virt_VirtualSystemManagementService.c > @@ -1783,7 +1783,37 @@ static CMPIStatus update_dominfo(const struct domain *dominfo, > goto out; > } > > +#if LIBVIR_VERSION_NUMBER< 9000 > + /* Old libvirt versions dont save cpu cgroup setting for inactive */ > + /* guests, so save in infostore instead */ > infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > +#else > + /* New libvirt versions save cpu cgroup setting in KVM guest config */ > + if (STREQC(virConnectGetType(conn), "QEMU")) { > + int ret; > + virSchedParameter params; > + strncpy(params.field, > + "cpu_shares", > + VIR_DOMAIN_SCHED_FIELD_LENGTH); > + params.type = VIR_DOMAIN_SCHED_FIELD_ULLONG; > + params.value.ul = dev->dev.vcpu.weight; > + > + CU_DEBUG("setting %s scheduler param cpu_shares=%d", > + dominfo->name, > + dev->dev.vcpu.weight); > + ret = virDomainSetSchedulerParametersFlags(dom,¶ms, 1, > + VIR_DOMAIN_AFFECT_CONFIG); > + if (ret != 0) { > + CU_DEBUG("Failed to set config scheduler param"); > + cu_statusf(_BROKER,&s, > + CMPI_RC_ERR_FAILED, > + "Failed to set config scheduler param"); > + goto out; > + } > + } > + else > + infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > +#endif > infostore_set_u64(ctx, "limit", dev->dev.vcpu.limit); > > out: -- Best Regards Wayne Xia mail:xiawenc at linux.vnet.ibm.com tel:86-010-82450803 From xiawenc at linux.vnet.ibm.com Wed Dec 21 02:01:02 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 21 Dec 2011 10:01:02 +0800 Subject: [Libvirt-cim] [PATCH] cpu cgroup patch 2 In-Reply-To: <1324384995-9068-1-git-send-email-bestor@us.ibm.com> References: <1324384995-9068-1-git-send-email-bestor@us.ibm.com> Message-ID: <4EF13DDE.7080905@linux.vnet.ibm.com> Seems it choose the function at compile time, I guess this result in two RPMs with different configuration of libvirt-cim. Could we use the latest the libvirt to compile the codes, but choose the function at runtime? ? 2011-12-20 20:43, Gareth S. Bestor ??: > Signed-off-by: Gareth S. Bestor > --- > libxkutil/xmlgen.c | 45 +++++++++++++++++++++++++++++ > src/Virt_ComputerSystem.c | 6 ++++ > src/Virt_RASD.c | 6 +++- > src/Virt_VirtualSystemManagementService.c | 30 +++++++++++++++++++ > 4 files changed, 86 insertions(+), 1 deletions(-) > > diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c > index 4cca75b..2fe41bf 100644 > --- a/libxkutil/xmlgen.c > +++ b/libxkutil/xmlgen.c > @@ -365,6 +365,44 @@ static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) > return NULL; > } > > +#if LIBVIR_VERSION_NUMBER>= 9000 > +static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) > +{ > + struct vcpu_device *vcpu; > + xmlNodePtr cputune, tmp; > + int ret; > + char *string = NULL; > + > + if (dominfo->dev_vcpu == NULL) > + return NULL; > + > + vcpu =&dominfo->dev_vcpu[0].dev.vcpu; > + > + /* CPU cgroup setting saved by libvirt under XML section */ > + cputune = xmlNewChild(root, NULL, BAD_CAST "cputune", NULL); > + if (cputune == NULL) > + return XML_ERROR; > + > + /* Get the CPU cgroup setting from the VCPU RASD.Weight property */ > + ret = asprintf(&string, > + "%d", > + vcpu->weight); > + if (ret == -1) > + return XML_ERROR; > + > + tmp = xmlNewChild(cputune, > + NULL, > + BAD_CAST "shares", > + BAD_CAST string); > + free(string); > + > + if (tmp == NULL) > + return XML_ERROR; > + else > + return NULL; > +} > +#endif > + > static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) > { > struct mem_device *mem; > @@ -941,6 +979,13 @@ char *system_to_xml(struct domain *dominfo) > if (msg != NULL) > goto out; > > +#if LIBVIR_VERSION_NUMBER>= 9000 > + /* Recent libvirt versions add new section to XML */ > + msg = cputune_xml(root, dominfo); > + if (msg != NULL) > + goto out; > +#endif > + > devices = xmlNewChild(root, NULL, BAD_CAST "devices", NULL); > if (devices == NULL) { > msg = XML_ERROR; > diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c > index e1f1cec..098b07a 100644 > --- a/src/Virt_ComputerSystem.c > +++ b/src/Virt_ComputerSystem.c > @@ -861,6 +861,11 @@ static int lxc_scheduler_params(struct infostore_ctx *ctx, > static int kvm_scheduler_params(struct infostore_ctx *ctx, > virSchedParameter **params) > { > +#if LIBVIR_VERSION_NUMBER< 9000 > + /* Old versions of libvirt only support CPU cgroups for running guests */ > + /* so instead read cpu cgroup setting for inactive guest from infostore. */ > + /* New versions there is nothing to do because libvirt takes care of it. */ > + > unsigned long long value; > > *params = calloc(1, sizeof(virSchedParameter)); > @@ -878,6 +883,7 @@ static int kvm_scheduler_params(struct infostore_ctx *ctx, > > return 1; > } > +#endif > > return 0; > } > diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c > index 9305c8d..0a2de7f 100644 > --- a/src/Virt_RASD.c > +++ b/src/Virt_RASD.c > @@ -157,8 +157,12 @@ static CMPIStatus set_proc_rasd_params(const CMPIBroker *broker, > goto out; > } > > - /* Currently only support CPU cgroups for running KVM guests */ > + /* Early versions of libvirt only support CPU cgroups for *running* KVM guests */ > +#if LIBVIR_VERSION_NUMBER< 9000 > if (domain_online(dom)&& STREQC(virConnectGetType(conn), "QEMU")) { > +#else > + if (STREQC(virConnectGetType(conn), "QEMU")) { > +#endif > char *sched; > int nparams; > unsigned int i; > diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c > index 21979c3..f6b191e 100644 > --- a/src/Virt_VirtualSystemManagementService.c > +++ b/src/Virt_VirtualSystemManagementService.c > @@ -1783,7 +1783,37 @@ static CMPIStatus update_dominfo(const struct domain *dominfo, > goto out; > } > > +#if LIBVIR_VERSION_NUMBER< 9000 > + /* Old libvirt versions dont save cpu cgroup setting for inactive */ > + /* guests, so save in infostore instead */ > infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > +#else > + /* New libvirt versions save cpu cgroup setting in KVM guest config */ > + if (STREQC(virConnectGetType(conn), "QEMU")) { > + int ret; > + virSchedParameter params; > + strncpy(params.field, > + "cpu_shares", > + VIR_DOMAIN_SCHED_FIELD_LENGTH); > + params.type = VIR_DOMAIN_SCHED_FIELD_ULLONG; > + params.value.ul = dev->dev.vcpu.weight; > + > + CU_DEBUG("setting %s scheduler param cpu_shares=%d", > + dominfo->name, > + dev->dev.vcpu.weight); > + ret = virDomainSetSchedulerParametersFlags(dom,¶ms, 1, > + VIR_DOMAIN_AFFECT_CONFIG); > + if (ret != 0) { > + CU_DEBUG("Failed to set config scheduler param"); > + cu_statusf(_BROKER,&s, > + CMPI_RC_ERR_FAILED, > + "Failed to set config scheduler param"); > + goto out; > + } > + } > + else > + infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > +#endif > infostore_set_u64(ctx, "limit", dev->dev.vcpu.limit); > > out: -- Best Regards Wayne Xia mail:xiawenc at linux.vnet.ibm.com tel:86-010-82450803 From bestor at us.ibm.com Wed Dec 21 02:30:46 2011 From: bestor at us.ibm.com (Gareth S Bestor) Date: Tue, 20 Dec 2011 18:30:46 -0800 Subject: [Libvirt-cim] [PATCH] cpu cgroup patch 2 In-Reply-To: <4EF13DDE.7080905@linux.vnet.ibm.com> Message-ID: Correct. libvirt behaves very differently when it comes to handling cgroup settings for *inactive* guests between recent ("yes it does") and older ("no it doesn't") versions, which means turning on/off code in libvirt-cim to compensate. It seemed simpler to compile libvirt-cim accordingly, and we have some existing libvirt version-based compile-time directives already. Or is there a better, more established approach to handling such matters in libvirt-cim? - Gareth Dr. Gareth S. Bestor IBM Senior Software Engineer Systems & Technology Group - Systems Management Standards 971-285-6375 (mobile) bestor at us.ibm.com Re: [Libvirt-cim] [PATCH] cpu cgroup patch 2 Wayne Xia to: libvirt-cim, Gareth S Bestor 12/20/11 06:01 PM Seems it choose the function at compile time, I guess this result in two RPMs with different configuration of libvirt-cim. Could we use the latest the libvirt to compile the codes, but choose the function at runtime? ? 2011-12-20 20:43, Gareth S. Bestor ??: > Signed-off-by: Gareth S. Bestor > --- > libxkutil/xmlgen.c | 45 +++++++++++++++++++++++++++++ > src/Virt_ComputerSystem.c | 6 ++++ > src/Virt_RASD.c | 6 +++- > src/Virt_VirtualSystemManagementService.c | 30 +++++++++++++++++++ > 4 files changed, 86 insertions(+), 1 deletions(-) > > diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c > index 4cca75b..2fe41bf 100644 > --- a/libxkutil/xmlgen.c > +++ b/libxkutil/xmlgen.c > @@ -365,6 +365,44 @@ static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) > return NULL; > } > > +#if LIBVIR_VERSION_NUMBER>= 9000 > +static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) > +{ > + struct vcpu_device *vcpu; > + xmlNodePtr cputune, tmp; > + int ret; > + char *string = NULL; > + > + if (dominfo->dev_vcpu == NULL) > + return NULL; > + > + vcpu =&dominfo->dev_vcpu[0].dev.vcpu; > + > + /* CPU cgroup setting saved by libvirt under XML section */ > + cputune = xmlNewChild(root, NULL, BAD_CAST "cputune", NULL); > + if (cputune == NULL) > + return XML_ERROR; > + > + /* Get the CPU cgroup setting from the VCPU RASD.Weight property */ > + ret = asprintf(&string, > + "%d", > + vcpu->weight); > + if (ret == -1) > + return XML_ERROR; > + > + tmp = xmlNewChild(cputune, > + NULL, > + BAD_CAST "shares", > + BAD_CAST string); > + free(string); > + > + if (tmp == NULL) > + return XML_ERROR; > + else > + return NULL; > +} > +#endif > + > static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) > { > struct mem_device *mem; > @@ -941,6 +979,13 @@ char *system_to_xml(struct domain *dominfo) > if (msg != NULL) > goto out; > > +#if LIBVIR_VERSION_NUMBER>= 9000 > + /* Recent libvirt versions add new section to XML */ > + msg = cputune_xml(root, dominfo); > + if (msg != NULL) > + goto out; > +#endif > + > devices = xmlNewChild(root, NULL, BAD_CAST "devices", NULL); > if (devices == NULL) { > msg = XML_ERROR; > diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c > index e1f1cec..098b07a 100644 > --- a/src/Virt_ComputerSystem.c > +++ b/src/Virt_ComputerSystem.c > @@ -861,6 +861,11 @@ static int lxc_scheduler_params(struct infostore_ctx *ctx, > static int kvm_scheduler_params(struct infostore_ctx *ctx, > virSchedParameter **params) > { > +#if LIBVIR_VERSION_NUMBER< 9000 > + /* Old versions of libvirt only support CPU cgroups for running guests */ > + /* so instead read cpu cgroup setting for inactive guest from infostore. */ > + /* New versions there is nothing to do because libvirt takes care of it. */ > + > unsigned long long value; > > *params = calloc(1, sizeof(virSchedParameter)); > @@ -878,6 +883,7 @@ static int kvm_scheduler_params(struct infostore_ctx *ctx, > > return 1; > } > +#endif > > return 0; > } > diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c > index 9305c8d..0a2de7f 100644 > --- a/src/Virt_RASD.c > +++ b/src/Virt_RASD.c > @@ -157,8 +157,12 @@ static CMPIStatus set_proc_rasd_params(const CMPIBroker *broker, > goto out; > } > > - /* Currently only support CPU cgroups for running KVM guests */ > + /* Early versions of libvirt only support CPU cgroups for *running* KVM guests */ > +#if LIBVIR_VERSION_NUMBER< 9000 > if (domain_online(dom)&& STREQC(virConnectGetType(conn), "QEMU")) { > +#else > + if (STREQC(virConnectGetType(conn), "QEMU")) { > +#endif > char *sched; > int nparams; > unsigned int i; > diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c > index 21979c3..f6b191e 100644 > --- a/src/Virt_VirtualSystemManagementService.c > +++ b/src/Virt_VirtualSystemManagementService.c > @@ -1783,7 +1783,37 @@ static CMPIStatus update_dominfo(const struct domain *dominfo, > goto out; > } > > +#if LIBVIR_VERSION_NUMBER< 9000 > + /* Old libvirt versions dont save cpu cgroup setting for inactive */ > + /* guests, so save in infostore instead */ > infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > +#else > + /* New libvirt versions save cpu cgroup setting in KVM guest config */ > + if (STREQC(virConnectGetType(conn), "QEMU")) { > + int ret; > + virSchedParameter params; > + strncpy(params.field, > + "cpu_shares", > + VIR_DOMAIN_SCHED_FIELD_LENGTH); > + params.type = VIR_DOMAIN_SCHED_FIELD_ULLONG; > + params.value.ul = dev->dev.vcpu.weight; > + > + CU_DEBUG("setting %s scheduler param cpu_shares=%d", > + dominfo->name, > + dev->dev.vcpu.weight); > + ret = virDomainSetSchedulerParametersFlags(dom,¶ms, 1, > + VIR_DOMAIN_AFFECT_CONFIG); > + if (ret != 0) { > + CU_DEBUG("Failed to set config scheduler param"); > + cu_statusf(_BROKER,&s, > + CMPI_RC_ERR_FAILED, > + "Failed to set config scheduler param"); > + goto out; > + } > + } > + else > + infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > +#endif > infostore_set_u64(ctx, "limit", dev->dev.vcpu.limit); > > out: -- Best Regards Wayne Xia mail:xiawenc at linux.vnet.ibm.com tel:86-010-82450803 -------------- next part -------------- An HTML attachment was scrubbed... URL: From xiawenc at linux.vnet.ibm.com Wed Dec 21 02:52:50 2011 From: xiawenc at linux.vnet.ibm.com (Wayne Xia) Date: Wed, 21 Dec 2011 10:52:50 +0800 Subject: [Libvirt-cim] [PATCH] cpu cgroup patch 2 In-Reply-To: References: Message-ID: <4EF14A02.8000001@linux.vnet.ibm.com> seems there is an API in libvirt: int virConnectGetLibVersion (virConnectPtr conn, unsigned long * libVer) using it may resulting in one rpm for all. But if there is already libvirt-version based codes at compile time exist, then I am OK with the code, we could change the version depending codes together later. ? 2011-12-21 10:30, Gareth S Bestor ??: > > Correct. libvirt behaves very differently when it comes to handling > cgroup settings for *inactive* guests between recent ("yes it does") and > older ("no it doesn't") versions, which means turning on/off code in > libvirt-cim to compensate. It seemed simpler to compile libvirt-cim > accordingly, and we have some existing libvirt version-based > compile-time directives already. Or is there a better, more established > approach to handling such matters in libvirt-cim? > > - Gareth > > Dr. Gareth S. Bestor > IBM Senior Software Engineer > Systems & Technology Group - Systems Management Standards > 971-285-6375 (mobile) > bestor at us.ibm.com > > > > *Re: [Libvirt-cim] [PATCH] cpu cgroup patch 2* > > > *Wayne Xia * to: libvirt-cim, Gareth S Bestor > 12/20/11 06:01 PM > > > > > > > > Seems it choose the function at compile time, I guess this result > in two RPMs with different configuration of libvirt-cim. Could we use > the latest the libvirt to compile the codes, but choose the function at > runtime? > > ? 2011-12-20 20:43, Gareth S. Bestor ??: > > Signed-off-by: Gareth S. Bestor > > --- > > libxkutil/xmlgen.c | 45 +++++++++++++++++++++++++++++ > > src/Virt_ComputerSystem.c | 6 ++++ > > src/Virt_RASD.c | 6 +++- > > src/Virt_VirtualSystemManagementService.c | 30 +++++++++++++++++++ > > 4 files changed, 86 insertions(+), 1 deletions(-) > > > > diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c > > index 4cca75b..2fe41bf 100644 > > --- a/libxkutil/xmlgen.c > > +++ b/libxkutil/xmlgen.c > > @@ -365,6 +365,44 @@ static const char *vcpu_xml(xmlNodePtr root, > struct domain *dominfo) > > return NULL; > > } > > > > +#if LIBVIR_VERSION_NUMBER>= 9000 > > +static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) > > +{ > > + struct vcpu_device *vcpu; > > + xmlNodePtr cputune, tmp; > > + int ret; > > + char *string = NULL; > > + > > + if (dominfo->dev_vcpu == NULL) > > + return NULL; > > + > > + vcpu =&dominfo->dev_vcpu[0].dev.vcpu; > > + > > + /* CPU cgroup setting saved by libvirt under XML section */ > > + cputune = xmlNewChild(root, NULL, BAD_CAST "cputune", NULL); > > + if (cputune == NULL) > > + return XML_ERROR; > > + > > + /* Get the CPU cgroup setting from the VCPU RASD.Weight property */ > > + ret = asprintf(&string, > > + "%d", > > + vcpu->weight); > > + if (ret == -1) > > + return XML_ERROR; > > + > > + tmp = xmlNewChild(cputune, > > + NULL, > > + BAD_CAST "shares", > > + BAD_CAST string); > > + free(string); > > + > > + if (tmp == NULL) > > + return XML_ERROR; > > + else > > + return NULL; > > +} > > +#endif > > + > > static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) > > { > > struct mem_device *mem; > > @@ -941,6 +979,13 @@ char *system_to_xml(struct domain *dominfo) > > if (msg != NULL) > > goto out; > > > > +#if LIBVIR_VERSION_NUMBER>= 9000 > > + /* Recent libvirt versions add new section to XML */ > > + msg = cputune_xml(root, dominfo); > > + if (msg != NULL) > > + goto out; > > +#endif > > + > > devices = xmlNewChild(root, NULL, BAD_CAST "devices", NULL); > > if (devices == NULL) { > > msg = XML_ERROR; > > diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c > > index e1f1cec..098b07a 100644 > > --- a/src/Virt_ComputerSystem.c > > +++ b/src/Virt_ComputerSystem.c > > @@ -861,6 +861,11 @@ static int lxc_scheduler_params(struct > infostore_ctx *ctx, > > static int kvm_scheduler_params(struct infostore_ctx *ctx, > > virSchedParameter **params) > > { > > +#if LIBVIR_VERSION_NUMBER< 9000 > > + /* Old versions of libvirt only support CPU cgroups for running > guests */ > > + /* so instead read cpu cgroup setting for inactive guest from > infostore. */ > > + /* New versions there is nothing to do because libvirt takes care > of it. */ > > + > > unsigned long long value; > > > > *params = calloc(1, sizeof(virSchedParameter)); > > @@ -878,6 +883,7 @@ static int kvm_scheduler_params(struct > infostore_ctx *ctx, > > > > return 1; > > } > > +#endif > > > > return 0; > > } > > diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c > > index 9305c8d..0a2de7f 100644 > > --- a/src/Virt_RASD.c > > +++ b/src/Virt_RASD.c > > @@ -157,8 +157,12 @@ static CMPIStatus set_proc_rasd_params(const > CMPIBroker *broker, > > goto out; > > } > > > > - /* Currently only support CPU cgroups for running KVM guests */ > > + /* Early versions of libvirt only support CPU cgroups for *running* > KVM guests */ > > +#if LIBVIR_VERSION_NUMBER< 9000 > > if (domain_online(dom)&& STREQC(virConnectGetType(conn), "QEMU")) { > > +#else > > + if (STREQC(virConnectGetType(conn), "QEMU")) { > > +#endif > > char *sched; > > int nparams; > > unsigned int i; > > diff --git a/src/Virt_VirtualSystemManagementService.c > b/src/Virt_VirtualSystemManagementService.c > > index 21979c3..f6b191e 100644 > > --- a/src/Virt_VirtualSystemManagementService.c > > +++ b/src/Virt_VirtualSystemManagementService.c > > @@ -1783,7 +1783,37 @@ static CMPIStatus update_dominfo(const struct > domain *dominfo, > > goto out; > > } > > > > +#if LIBVIR_VERSION_NUMBER< 9000 > > + /* Old libvirt versions dont save cpu cgroup setting for inactive */ > > + /* guests, so save in infostore instead */ > > infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > > +#else > > + /* New libvirt versions save cpu cgroup setting in KVM guest config */ > > + if (STREQC(virConnectGetType(conn), "QEMU")) { > > + int ret; > > + virSchedParameter params; > > + strncpy(params.field, > > + "cpu_shares", > > + VIR_DOMAIN_SCHED_FIELD_LENGTH); > > + params.type = VIR_DOMAIN_SCHED_FIELD_ULLONG; > > + params.value.ul = dev->dev.vcpu.weight; > > + > > + CU_DEBUG("setting %s scheduler param cpu_shares=%d", > > + dominfo->name, > > + dev->dev.vcpu.weight); > > + ret = virDomainSetSchedulerParametersFlags(dom,¶ms, 1, > > + VIR_DOMAIN_AFFECT_CONFIG); > > + if (ret != 0) { > > + CU_DEBUG("Failed to set config scheduler param"); > > + cu_statusf(_BROKER,&s, > > + CMPI_RC_ERR_FAILED, > > + "Failed to set config scheduler param"); > > + goto out; > > + } > > + } > > + else > > + infostore_set_u64(ctx, "weight", dev->dev.vcpu.weight); > > +#endif > > infostore_set_u64(ctx, "limit", dev->dev.vcpu.limit); > > > > out: > > > -- > Best Regards > > Wayne Xia > mail:xiawenc at linux.vnet.ibm.com > tel:86-010-82450803 > > -- Best Regards Wayne Xia mail:xiawenc at linux.vnet.ibm.com tel:86-010-82450803 From deepakcs at linux.vnet.ibm.com Thu Dec 22 05:49:42 2011 From: deepakcs at linux.vnet.ibm.com (Deepak C Shetty) Date: Thu, 22 Dec 2011 11:19:42 +0530 Subject: [Libvirt-cim] [PATCH] Plan9fs (aka 9pfs, VirtFS) support for QEMU/KVM environment In-Reply-To: References: <20111209111656.20645.54429.stgit@deepak-ThinkPad-T60p> Message-ID: <4EF2C4F6.1080206@linux.vnet.ibm.com> On 12/15/2011 11:19 PM, Sharad Mishra wrote: > The patch looks good. > Gareth is looking if we need to update SettingsDefineCapabilities for > template. > > Regards, > Sharad Mishra > Open Virtualization > Linux Technology Center > IBM > Hi, any outlook on when this patch be merged ? Let me know if anything else is needed from my side. thanx deepak -------------- next part -------------- An HTML attachment was scrubbed... URL: From cvincent at linux.vnet.ibm.com Fri Dec 23 17:48:42 2011 From: cvincent at linux.vnet.ibm.com (Chip Vincent) Date: Fri, 23 Dec 2011 12:48:42 -0500 Subject: [Libvirt-cim] [PATCH 1/2] Build: Remove tests subdirs from source In-Reply-To: <1321985413-28025-2-git-send-email-eblima@linux.vnet.ibm.com> References: <1321985413-28025-1-git-send-email-eblima@linux.vnet.ibm.com> <1321985413-28025-2-git-send-email-eblima@linux.vnet.ibm.com> Message-ID: <4EF4BEFA.8090606@linux.vnet.ibm.com> +1. Code is for all intents and purposes obsolete. If we determine we need tests for primitives in the future, we can do it properly. On 11/22/2011 01:10 PM, Eduardo Lima (Etrunko) wrote: > From: Eduardo Lima (Etrunko) > > This is the first step trying to comply with make distcheck. Those files don't > even compile for quite some time, I wonder if they are used by anyone. > > Signed-off-by: Eduardo Lima (Etrunko) > --- > configure.ac | 2 - > libxkutil/Makefile.am | 1 - > libxkutil/tests/Makefile.am | 10 -- > libxkutil/tests/infostore.c | 80 ----------- > libxkutil/tests/xml_devices.c | 293 ----------------------------------------- > libxkutil/tests/xml_dominfo.c | 73 ---------- > libxkutil/tests/xml_tag.c | 95 ------------- > libxkutil/tests/xmlgen.c | 58 -------- > src/Makefile.am | 1 - > src/tests/Makefile.am | 6 - > src/tests/test_link.sh | 17 --- > 11 files changed, 0 insertions(+), 636 deletions(-) > delete mode 100644 libxkutil/tests/Makefile.am > delete mode 100644 libxkutil/tests/infostore.c > delete mode 100644 libxkutil/tests/xml_devices.c > delete mode 100644 libxkutil/tests/xml_dominfo.c > delete mode 100644 libxkutil/tests/xml_tag.c > delete mode 100644 libxkutil/tests/xmlgen.c > delete mode 100644 src/tests/Makefile.am > delete mode 100644 src/tests/test_link.sh > > diff --git a/configure.ac b/configure.ac > index 3a7bcff..a1dc3ca 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -141,9 +141,7 @@ AC_CONFIG_FILES([ > base_schema/install_base_schema.sh > base_schema/Makefile > libxkutil/Makefile > - libxkutil/tests/Makefile > src/Makefile > - src/tests/Makefile > doc/Makefile > Makefile > ]) > diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am > index f6abce5..f1adc03 100644 > --- a/libxkutil/Makefile.am > +++ b/libxkutil/Makefile.am > @@ -1,5 +1,4 @@ > # Copyright IBM Corp. 2007 > -SUBDIRS = tests > > AM_CFLAGS = $(CFLAGS_STRICT) \ > -DLIBVIRTCIM_CONF=\"@sysconfdir@/@PACKAGE at .conf\" > diff --git a/libxkutil/tests/Makefile.am b/libxkutil/tests/Makefile.am > deleted file mode 100644 > index 7c0cdc6..0000000 > --- a/libxkutil/tests/Makefile.am > +++ /dev/null > @@ -1,10 +0,0 @@ > -# Copyright IBM Corp. 2007 > -TESTS = xml_tag.test xml_devices.test xmlgen.test xml_dominfo.test infostore.test > - > -CFLAGS += -g > - > -%.test: %.c > - $(CC) -o $@ $^ $(CFLAGS) -lvirt `xml2-config --libs` -L../.libs -lxkutil > - > -clean-local: > - rm -f *.test > diff --git a/libxkutil/tests/infostore.c b/libxkutil/tests/infostore.c > deleted file mode 100644 > index df625bb..0000000 > --- a/libxkutil/tests/infostore.c > +++ /dev/null > @@ -1,80 +0,0 @@ > -/* > - * Copyright IBM Corp. 2008 > - * > - * Authors: > - * Dan Smith > - * > - * This library is free software; you can redistribute it and/or > - * modify it under the terms of the GNU Lesser General Public > - * License as published by the Free Software Foundation; either > - * version 2.1 of the License, or (at your option) any later version. > - * > - * This library is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > - * Lesser General Public License for more details. > - * > - * You should have received a copy of the GNU Lesser General Public > - * License along with this library; if not, write to the Free Software > - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > - */ > - > -#include > -#include > - > -#include > - > -#include "../infostore.h" > - > -int main(int argc, char **argv) > -{ > - struct infostore_ctx *ctx = NULL; > - virConnectPtr conn = NULL; > - virDomainPtr dom = NULL; > - > - if (argc != 2) { > - printf("Usage: %s\n", argv[0]); > - return 1; > - } > - > - conn = virConnectOpen(NULL); > - if (conn == NULL) { > - printf("Unable to open connection\n"); > - goto out; > - } > - > - dom = virDomainLookupByName(conn, argv[1]); > - if (dom == NULL) { > - printf("Unable to lookup domain `%s'\n", argv[1]); > - goto out; > - } > - > - ctx = infostore_open(dom); > - if (ctx == NULL) { > - printf("Unable to open infostore for `%s'\n", argv[1]); > - goto out; > - } > - > - printf("Foo: %" PRIu64 "\n", infostore_get_u64(ctx, "foo")); > - > - infostore_set_u64(ctx, "foo", 321); > - infostore_set_u64(ctx, "bar", 987); > - printf("Should be (null): %s\n", infostore_get_str(ctx, "baz")); > - > - out: > - infostore_close(ctx); > - virDomainFree(dom); > - virConnectClose(conn); > - > - return 0; > -} > - > -/* > - * Local Variables: > - * mode: C > - * c-set-style: "K&R" > - * tab-width: 8 > - * c-basic-offset: 8 > - * indent-tabs-mode: nil > - * End: > - */ > diff --git a/libxkutil/tests/xml_devices.c b/libxkutil/tests/xml_devices.c > deleted file mode 100644 > index 08b9f04..0000000 > --- a/libxkutil/tests/xml_devices.c > +++ /dev/null > @@ -1,293 +0,0 @@ > -/* > - * Copyright IBM Corp. 2007 > - * > - * Authors: > - * Dan Smith > - * Zhengang Li > - * > - * This library is free software; you can redistribute it and/or > - * modify it under the terms of the GNU Lesser General Public > - * License as published by the Free Software Foundation; either > - * version 2.1 of the License, or (at your option) any later version. > - * > - * This library is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > - * Lesser General Public License for more details. > - * > - * You should have received a copy of the GNU Lesser General Public > - * License along with this library; if not, write to the Free Software > - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > - */ > -#include > - > -#include "../device_parsing.h" > -#include "../device_parsing.c" > - > -#define STREQ(x, y) (strcmp(x, y) == 0) > - > -static void print_disk(struct disk_device *dev) > -{ > - fprintf(stderr, > - "type: %s\n" > - "device: %s\n" > - "driver: %s\n" > - "source: %s\n" > - "vdev: %s\n", > - dev->type, dev->device, dev->driver, > - dev->source, dev->virtual_dev); > -} > - > -static void print_net(struct net_device *dev) > -{ > - fprintf(stderr, > - "type: %s\n" > - "mac: %s\n", > - dev->type, dev->mac); > -} > - > -static void print_dev(struct virt_device *dev) > -{ > - if (dev->type == VIRT_DEV_DISK) > - print_disk(&dev->dev.disk); > - else if (dev->type == VIRT_DEV_NET) > - print_net(&dev->dev.net); > - else > - printf("ERROR: Unknown device type %i\n", dev->type); > -} > - > -int main(int argc, char **argv) > -{ > - struct virt_device *devs; > - int count; > - char *conf1 = > - "\n" > - "sles10foo\n" > - "7c42b545ffc4eb4441d1be3936516de3\n" > - "/usr/lib/xen/boot/domUloader.py\n" > - "\n" > - "linux\n" > - "/var/lib/xen/tmp/kernel.0F29se\n" > - "/var/lib/xen/tmp/ramdisk.qGK5v5\n" > - "TERM=xterm\n" > - "\n" > - "524288\n" > - "1\n" > - "destroy\n" > - "restart\n" > - "destroy\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n"; > - char *conf2 = > - "\n" > - "sles10foo\n" > - "7c42b545ffc4eb4441d1be3936516de3\n" > - "/usr/lib/xen/boot/domUloader.py\n" > - "\n" > - "linux\n" > - "/var/lib/xen/tmp/kernel.0F29se\n" > - "/var/lib/xen/tmp/ramdisk.qGK5v5\n" > - "TERM=xterm\n" > - "\n" > - "524288\n" > - "1\n" > - "destroy\n" > - "restart\n" > - "destroy\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n"; > - char *conf3 = "snarf"; > - char *conf4 = > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n" > - "\n"; > - > - count = parse_devices(conf1,&devs, VIRT_DEV_DISK); > - if (count != 1) { > - fprintf(stderr, "Failed to find disk in config\n"); > - return 1; > - } > - > - if (! (STREQ(devs->dev.disk.type, "file")&& > - STREQ(devs->dev.disk.device, "disk")&& > - STREQ(devs->dev.disk.driver, "file")&& > - STREQ(devs->dev.disk.source, "/var/lib/xen/images/sles10/disk0")&& > - STREQ(devs->dev.disk.virtual_dev, "xvda"))) { > - fprintf(stderr, "Failed to validate domain contents:\n"); > - print_dev(devs); > - return 1; > - } > - > - cleanup_virt_device(devs); > - free(devs); > - > - count = parse_devices(conf2,&devs, VIRT_DEV_DISK); > - if (count != 2) { > - fprintf(stderr, "Failed to find both disks in config\n"); > - return 1; > - } > - > - if (! (STREQ(devs[0].dev.disk.type, "file")&& > - STREQ(devs[0].dev.disk.device, "disk")&& > - STREQ(devs[0].dev.disk.driver, "file")&& > - STREQ(devs[0].dev.disk.source, "/var/lib/xen/images/foo/bar")&& > - STREQ(devs[0].dev.disk.virtual_dev, "xvdb"))) { > - fprintf(stderr, "Failed to validate domain contents:\n"); > - print_dev(&devs[0]); > - return 1; > - } > - > - if (! (STREQ(devs[1].dev.disk.type, "file")&& > - STREQ(devs[1].dev.disk.device, "disk")&& > - STREQ(devs[1].dev.disk.driver, "file")&& > - STREQ(devs[1].dev.disk.source, "/var/lib/xen/images/sles10/disk0")&& > - STREQ(devs[1].dev.disk.virtual_dev, "xvda"))) { > - fprintf(stderr, "Failed to validate domain contents:\n"); > - print_dev(&devs[1]); > - return 1; > - } > - > - cleanup_virt_devices(&devs, count); > - free(devs); > - > - count = parse_devices(conf4,&devs, VIRT_DEV_DISK); > - if (count != 1) { > - fprintf(stderr, "Failed to bypass non-valid disk node.%d\n", count); > - return 1; > - } > - > - if (! (STREQ(devs[0].dev.disk.type, "file")&& > - STREQ(devs[0].dev.disk.device, "disk")&& > - STREQ(devs[0].dev.disk.driver, "file")&& > - STREQ(devs[0].dev.disk.source, "/disk0")&& > - STREQ(devs[0].dev.disk.virtual_dev, "xvda"))) { > - fprintf(stderr, "Failed to validate valide disk info:\n"); > - print_dev(&devs[0]); > - return 1; > - } > - > - cleanup_virt_devices(&devs, count); > - free(devs); > - > - count = parse_devices(conf3,&devs, VIRT_DEV_DISK); > - if ((count != 0) || (devs != NULL)) { > - fprintf(stderr, "Failed to fail on bad config string\n"); > - return 1; > - } > - > - > - count = parse_devices(conf1,&devs, VIRT_DEV_NET); > - if (count != 1) { > - fprintf(stderr, "Failed to find interface in config\n"); > - return 1; > - } > - > - if (! (STREQ(devs->dev.net.type, "ethernet")&& > - STREQ(devs->dev.net.mac, "00:16:3e:62:d1:bd"))) { > - fprintf(stderr, "Failed to validate interface config:\n"); > - print_dev(devs); > - } > - > - cleanup_virt_device(devs); > - free(devs); > - > - count = parse_devices(conf2,&devs, VIRT_DEV_NET); > - if (count != 2) { > - fprintf(stderr, "Failed to find both interfaces in config\n"); > - return 1; > - } > - > - if (! (STREQ(devs[0].dev.net.type, "ethernet")&& > - STREQ(devs[0].dev.net.mac, "00:16:3e:62:d1:bd"))) { > - fprintf(stderr, "Failed to validate interface config:\n"); > - print_dev(&devs[0]); > - return 1; > - } > - > - if (! (STREQ(devs[1].dev.net.type, "ethernet")&& > - STREQ(devs[1].dev.net.mac, "00:11:22:33:44:55"))) { > - fprintf(stderr, "Failed to validate interface config:\n"); > - print_dev(&devs[1]); > - return 1; > - } > - > - cleanup_virt_devices(&devs, count); > - free(devs); > - > - count = parse_devices(conf4,&devs, VIRT_DEV_NET); > - if (count !=1) { > - fprintf(stderr, "Failed to bypass non-valid interface info.\n"); > - return 1; > - } > - > - if (! (STREQ(devs[0].dev.net.type, "ethernet")&& > - STREQ(devs[0].dev.net.mac, "00:16:3e:62:d1:bd"))) { > - fprintf(stderr, "Failed to validate interface config:\n"); > - print_dev(&devs[0]); > - return 1; > - } > - cleanup_virt_devices(&devs, count); > - free(devs); > - > - count = parse_devices(conf3,&devs, VIRT_DEV_NET); > - if ((count != 0) || (devs != NULL)) { > - fprintf(stderr, "Failed to fail on bad config string\n"); > - return 1; > - } > - > - return 0; > -} > - > -/* > - * Local Variables: > - * mode: C > - * c-set-style: "K&R" > - * tab-width: 8 > - * c-basic-offset: 8 > - * indent-tabs-mode: nil > - * End: > - */ > diff --git a/libxkutil/tests/xml_dominfo.c b/libxkutil/tests/xml_dominfo.c > deleted file mode 100644 > index eb39a84..0000000 > --- a/libxkutil/tests/xml_dominfo.c > +++ /dev/null > @@ -1,73 +0,0 @@ > -/* > - * Copyright IBM Corp. 2007 > - * > - * Authors: > - * Dan Smith > - * > - * This library is free software; you can redistribute it and/or > - * modify it under the terms of the GNU Lesser General Public > - * License as published by the Free Software Foundation; either > - * version 2.1 of the License, or (at your option) any later version. > - * > - * This library is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > - * Lesser General Public License for more details. > - * > - * You should have received a copy of the GNU Lesser General Public > - * License along with this library; if not, write to the Free Software > - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > - */ > -#include "../device_parsing.h" > -#include "../device_parsing.c" > - > -const char *xml = > -"" > -"pv1" > -"a3be4e7c539a3fb734648b11819bd9c3" > -"/usr/lib/xen/boot/domUloader.py" > -"--entry=xvda2:/boot/vmlinuz-xen,/boot/initrd-xen" > -"" > -"linux" > -"/var/lib/xen/tmp/kernel.5ihM-L" > -"/var/lib/xen/tmp/ramdisk.G2vsaq" > -"TERM=xterm" > -"" > -"524288" > -"1" > -"destroy" > -"restart" > -"destroy" > -"" > -"" > -"" > -"