Skip to contentSkip to conversation

multiple cpumask and vcpu-pin all keyword

PATCH In review Ryan Harper 2 participants 10 messages Aug 16, 2006

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 multiple cpumask and vcpu-pin all keyword

This series of patches relates to the cpus parameter and pinning vcpus. The first patch is a clean-up of getVcpuInfo, which previously only returned the vcpu to cpu mapping. This was insufficient for extracting affinity information. The patch extends getVcpuInfo to return a dict of all the fields in xm vcpu-list for a domain. It also fixes a couple users of the function and moves them to a new vcpu_to_cpu function which retains the old behavior of getVcpuInfo.

The second patch adds multiple cpumask support to the cpus variable. We currently support two formats:

cpus = [ "0", "2-4" ] and cpus = "0|2-4". The documentation encourages the use of the python list notation.

The third patch introduces a testcase for the cpus parameter in the create subset.

The forth patch adds support for the keyword 'all' to the vcpu-pin operation. Using 'all' in place of a specific vcpu will apply the cpumask to all vcpus in the domain.

The fifth patch creates a testcase for the 'all' keyword in the vcpu-pin subset.

17 files changed, 278 insertions(+), 60 deletions(-)
docs/man/xm.pod.1                                             |    4 
tools/examples/xmexample.hvm                                  |    9 -
tools/examples/xmexample.vti                                  |    9 -
tools/examples/xmexample1                                     |    9 -
tools/examples/xmexample2                                     |   11 +
tools/examples/xmexample3                                     |   12 -
tools/python/xen/xend/XendDomain.py                           |   17 +-
tools/python/xen/xend/XendDomainInfo.py                       |   64 +++++--
tools/python/xen/xend/server/SrvDomain.py                     |    2 
tools/python/xen/xm/main.py                                   |    9 -
tools/xm-test/lib/XmTestLib/Xm.py                             |   31 +++
tools/xm-test/tests/create/17_create_cpusparm_pos.py          |   81 ++++++++++
tools/xm-test/tests/create/Makefile.am                        |    3 
tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py |   16 +
tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py         |    4 
tools/xm-test/tests/vcpu-pin/02_vcpu-pin_all_pos.py           |   54 ++++++
tools/xm-test/tests/vcpu-pin/Makefile.am                      |    3 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#1 lore raw

PATCH 1/1 Change getVcpuInfo to return more information

3 files changed, 41 insertions(+), 10 deletions(-)
tools/xm-test/lib/XmTestLib/Xm.py                             |   31 ++++++++--
tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py |   16 ++++-
tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py         |    4 -

# HG changeset patch
# User Ryan Harper <[email protected]>
# Date 1155579355 18000
# Node ID 889b941effc8d050057a7edf3575067014e36d18 # Parent ec03b24a2d83273ec62db8596506b80577a0e41e Change getVcpuInfo to return more information

tools/xm-test/lib/XmTestLib/Xm.py +25 -6
diff -r ec03b24a2d83 -r 889b941effc8 tools/xm-test/lib/XmTestLib/Xm.py
@@ -170,16 +170,35 @@ def getVcpuInfo(domain):
 
     lines = output.split("\n")
 
-    vcpus = {}
-
+    vcpus = []
     for line in lines[1:]:
         cols = re.split(" +", line)
+        info = {}
+        info['domain'] = cols[0]
+        info['id'] = cols[1]
+        info['vcpu'] = cols[2]
         if cols[3] == '-':
-            vcpus[int(cols[2])] = None
+            info['cpu'] = None
         else:
-            vcpus[int(cols[2])] = int(cols[3])
+            info['cpu'] = cols[3]
+        info['state'] = cols[4]
+        info['time'] = cols[5]
+        # make sure we join 'any' 'cpu' into single value
+        info['affinity'] = " ".join(cols[6:])
+        vcpus.append(info)
 
     return vcpus
+
+def vcpu_to_cpu(domain):
+
+    vcpuinfo = getVcpuInfo(domain)
+    vcpus = {}
+
+    for info in vcpuinfo:
+        vcpus[int(info['vcpu'])] = info['cpu']
+
+    return vcpus
+
 
 def getInfo(key):
 
@@ -240,6 +259,6 @@ if __name__ == "__main__":
     print "Domain-0 CPU: " + cpu
     print "Domain-0 state: " + state
     
-    v = getVcpuInfo("Domain-0")
+    v = vcpu_to_cpu("Domain-0")
     for key in v.keys():
-        print "VCPU%i is on CPU %i" % (key, v[key])
+        print "VCPU%i is on CPU %s" % (key, v[key])
tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py +14 -2
diff -r ec03b24a2d83 -r 889b941effc8 tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py
@@ -49,6 +49,18 @@ except DomainError, e:
         print e.extra
     FAIL(str(e))
 
+# wait for both vcpus to come up
+vcpus_up = 0
+start = int(time.time())
+print "waiting for all VCPUS to come up"
+while vcpus_up != 2:
+    vcpus_up = len(filter(lambda x: x is not None, vcpu_to_cpu(domain.getName())))
+    # 20 second timeout
+    if int(time.time()) >= start+20:
+       FAIL("Failed to bring all VCPUS online for test");
+    time.sleep(1)
+    
+
 # Disable VCPU 1
 cmd = "xm vcpu-set %s 1" % domain.getName()
 status, output = safecmd(cmd)
@@ -57,7 +69,7 @@ if check_status and status != 0:
 
 # Wait for the change to become active
 for i in [1,2,3,4,5,6,7,8,9,10]:
-    domUvcpu1 = getVcpuInfo(domain.getName())[1]
+    domUvcpu1 = vcpu_to_cpu(domain.getName())[1]
     status, output = traceCommand("xm vcpu-list")
     if domUvcpu1 is None:
         break
@@ -74,7 +86,7 @@ if check_status and status != 0:
     FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))
 
 for i in [1,2,3,4,5,6,7,8,9,10]:
-    domUvcpu1 = getVcpuInfo(domain.getName())[1]
+    domUvcpu1 = vcpu_to_cpu(domain.getName())[1]
     if domUvcpu1 is not None:
         break
     time.sleep(1)
tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py +2 -2
diff -r ec03b24a2d83 -r 889b941effc8 tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py
@@ -32,7 +32,7 @@ if status != 0:
 if status != 0:
     FAIL("xm vcpu-pin returned invalid %i != 0" % status)
 
-cpu = getVcpuInfo(domain.getName())[0]
+cpu = int(vcpu_to_cpu(domain.getName())[0])
 
 if cpu != 0:
     FAIL("failed to switch VCPU 0 to CPU 0")
@@ -42,7 +42,7 @@ if status != 0:
 if status != 0:
     FAIL("xm vcpu-pin returned invalid %i != 0" % status)
 
-cpu = getVcpuInfo(domain.getName())[0]
+cpu = int(vcpu_to_cpu(domain.getName())[0])
 
 if cpu != 1:
     FAIL("failed to switch VCPU 0 to CPU 1")
#2 lore raw

PATCH 1/1 Add support for specifying multi cpumasks in cpus parameter

In reply to Ryan Harper
6 files changed, 74 insertions(+), 40 deletions(-)
tools/examples/xmexample.hvm            |    9 ++--
tools/examples/xmexample.vti            |    9 ++--
tools/examples/xmexample1               |    9 ++--
tools/examples/xmexample2               |   11 ++++-
tools/examples/xmexample3               |   12 +++--
tools/python/xen/xend/XendDomainInfo.py |   64 ++++++++++++++++++++-----------

# HG changeset patch
# User Ryan Harper <[email protected]>
# Date 1155579390 18000
# Node ID 7281c7aa89220b5bb20c9275a65dee37be6da298 # Parent 889b941effc8d050057a7edf3575067014e36d18 Add support for specifying multi cpumasks in cpus parameter

tools/examples/xmexample.hvm +5 -4
diff -r 889b941effc8 -r 7281c7aa8922 tools/examples/xmexample.hvm
@@ -47,10 +47,11 @@ name = "ExampleHVMDomain"
 # enable/disable HVM guest APIC, default=0 (disabled)
 #apic=0
 
-# List of which CPUS this domain is allowed to use, default Xen picks
-#cpus = ""         # leave to Xen to pick
-#cpus = "0"        # all vcpus run on CPU0
-#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
+# Specify which CPUS the domains' vcpus can use
+#cpus = ""               # leave to Xen to pick
+#cpus = "0"              # all vcpus run on CPU0
+#cpus = "0-3,5,^1"       # all vcpus run on cpus 0,2,3,5
+#cpus = [ "0-1", "2-3" ] # VCPU0 on CPU0-1, VCPU1 on CPU2-3
 
 # Optionally define mac and/or bridge for the network interfaces.
 # Random MACs are assigned if not given.
tools/examples/xmexample.vti +5 -4
diff -r 889b941effc8 -r 7281c7aa8922 tools/examples/xmexample.vti
@@ -30,10 +30,11 @@ name = "ExampleVTIDomain"
 # the number of cpus guest platform has, default=1
 #vcpus=1
 
-# List of which CPUS this domain is allowed to use, default Xen picks
-#cpus = ""         # leave to Xen to pick
-#cpus = "0"        # all vcpus run on CPU0
-#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
+# Specify which CPUS the domains' vcpus can use
+#cpus = ""               # leave to Xen to pick
+#cpus = "0"              # all vcpus run on CPU0
+#cpus = "0-3,5,^1"       # all vcpus run on cpus 0,2,3,5
+#cpus = [ "0-1", "2-3" ] # VCPU0 on CPU0-1, VCPU1 on CPU2-3
 
 # Optionally define mac and/or bridge for the network interfaces.
 # Random MACs are assigned if not given.
tools/examples/xmexample1 +5 -4
diff -r 889b941effc8 -r 7281c7aa8922 tools/examples/xmexample1
@@ -30,10 +30,11 @@ name = "ExampleDomain"
 # on each call to 'xm create'.
 #uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
 
-# List of which CPUS this domain is allowed to use, default Xen picks
-#cpus = ""         # leave to Xen to pick
-#cpus = "0"        # all vcpus run on CPU0
-#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
+# Specify which CPUS the domains' vcpus can use
+#cpus = ""               # leave to Xen to pick
+#cpus = "0"              # all vcpus run on CPU0
+#cpus = "0-3,5,^1"       # all vcpus run on cpus 0,2,3,5
+#cpus = [ "0-1", "2-3" ] # VCPU0 on CPU0-1, VCPU1 on CPU2-3
 
 # Number of Virtual CPUS to use, default is 1
 #vcpus = 1
tools/examples/xmexample2 +9 -2
diff -r 889b941effc8 -r 7281c7aa8922 tools/examples/xmexample2
@@ -59,11 +59,18 @@ name = "VM%d" % vmid
 # on each call to 'xm create'.
 #uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
 
-# List of which CPUS this domain is allowed to use, default Xen picks
+# List of which CPUS vcpus are allowed to use, default Xen picks
 #cpus = ""         # leave to Xen to pick
 #cpus = "0"        # all vcpus run on CPU0
 #cpus = "0-3,5,^1" # run on cpus 0,2,3,5
-#cpus = "%s" % vmid # set based on vmid (mod number of CPUs)
+#cpus = "0-1, 2-3" # run VCPU0 on CPU0-1, VCPU1 on CPU2-3
+
+# Specify which CPUS the domains' vcpus can use
+#cpus = ""               # leave to Xen to pick
+#cpus = "0"              # all vcpus run on CPU0
+#cpus = "0-3,5,^1"       # all vcpus run on cpus 0,2,3,5
+#cpus = [ "0-1", "2-3" ] # VCPU0 on CPU0-1, VCPU1 on CPU2-3
+#cpus = "%s" % vmid      # all vcpus run on CPU(vmid) (mod number of CPUs)
 
 # Number of Virtual CPUS to use, default is 1
 #vcpus = 1
tools/examples/xmexample3 +7 -5
diff -r 889b941effc8 -r 7281c7aa8922 tools/examples/xmexample3
@@ -59,11 +59,13 @@ name = "VM%d" % vmid
 # on each call to 'xm create'.
 #uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
 
-# List of which CPUS this domain is allowed to use, default Xen picks
-#cpus = ""         # leave to Xen to pick
-#cpus = "0"        # all vcpus run on CPU0
-#cpus = "0-3,5,^1" # run on cpus 0,2,3,5
-cpus = "%s" % vmid # set based on vmid (mod number of CPUs)
+# Specify which CPUS the domains' vcpus can use
+#cpus = ""               # leave to Xen to pick
+#cpus = "0"              # all vcpus run on CPU0
+#cpus = "0-3,5,^1"       # all vcpus run on cpus 0,2,3,5
+#cpus = [ "0-1", "2-3" ] # VCPU0 on CPU0-1, VCPU1 on CPU2-3
+cpus = "%s" % vmid       # all vcpus run on CPU(vmid) (mod number of CPUs)
+
 
 #----------------------------------------------------------------------------
 # Define network interfaces.
tools/python/xen/xend/XendDomainInfo.py +43 -21

77 lines not on this page · raw message

#3 lore raw

PATCH 1/1 Add testcase for multi-cpumask cpus parameter

In reply to Ryan Harper
2 files changed, 83 insertions(+), 1 deletion(-)

tools/xm-test/tests/create/17_create_cpusparm_pos.py | 81 ++++++++++++++++++
tools/xm-test/tests/create/Makefile.am | 3

# HG changeset patch
# User Ryan Harper <[email protected]>
# Date 1155579423 18000
# Node ID 734570be7e0592f20e6f97089c89541feed03abc # Parent 7281c7aa89220b5bb20c9275a65dee37be6da298 Add testcase for multi-cpumask cpus parameter

tools/xm-test/tests/create/Makefile.am +2 -1
diff -r 7281c7aa8922 -r 734570be7e05 tools/xm-test/tests/create/Makefile.am
@@ -14,7 +14,8 @@ TESTS = 01_create_basic_pos.test \
 	13_create_multinic_pos.test \
 	14_create_blockroot_pos.test \
 	15_create_smallmem_pos.test \
-	16_create_smallmem_neg.test
+	16_create_smallmem_neg.test \
+	17_create_cpusparm_pos.py
 
 EXTRA_DIST = $(TESTS)
 
tools/xm-test/tests/create/17_create_cpusparm_pos.py new file +81 -0

81 lines not on this page · raw message

#4 lore raw

PATCH 1/1 Add keyword 'all' to vcpu-pin

In reply to Ryan Harper
4 files changed, 24 insertions(+), 8 deletions(-)
docs/man/xm.pod.1                         |    4 +++-
tools/python/xen/xend/XendDomain.py       |   17 +++++++++++++----
tools/python/xen/xend/server/SrvDomain.py |    2 +-
tools/python/xen/xm/main.py               |    9 +++++++--

# HG changeset patch
# User Ryan Harper <[email protected]>
# Date 1155579483 18000
# Node ID 556a93b6cca9b99b2ad0a2d6dcc24dc1a3a581ad # Parent 734570be7e0592f20e6f97089c89541feed03abc Add keyword 'all' to vcpu-pin

docs/man/xm.pod.1 +3 -1
diff -r 734570be7e05 -r 556a93b6cca9 docs/man/xm.pod.1
@@ -393,7 +393,9 @@ specified, VCPU information for all doma
 
 =item B<vcpu-pin> I<domain-id> I<vcpu> I<cpus>
 
-Pins the the VCPU to only run on the specific CPUs.  
+Pins the the VCPU to only run on the specific CPUs.  The keyword
+I<all> can be used to apply the I<cpus> list to all VCPUs in the
+domain.
 
 Normally VCPUs can float between available CPUs whenever Xen deems a
 different run state is appropriate.  Pinning can be used to restrict
tools/python/xen/xend/XendDomain.py +13 -4
diff -r 734570be7e05 -r 556a93b6cca9 tools/python/xen/xend/XendDomain.py
@@ -466,10 +466,19 @@ class XendDomain:
         if not dominfo:
             raise XendInvalidDomain(str(domid))
 
-        try:
-            return xc.vcpu_setaffinity(dominfo.getDomid(), vcpu, cpumap)
-        except Exception, ex:
-            raise XendError(str(ex))
+        # if vcpu is keyword 'all', apply the cpumap to all vcpus
+        vcpus = [ vcpu ]
+        if str(vcpu).lower() == "all":
+            vcpus = range(0, int(dominfo.getVCpuCount()))
+       
+        # set the same cpumask for all vcpus
+        rc = 0
+        for v in vcpus:
+            try:
+                rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap)
+            except Exception, ex:
+                raise XendError(str(ex))
+        return rc
 
     def domain_cpu_bvt_set(self, domid, mcuadv, warpback, warpvalue, warpl,
                            warpu):
tools/python/xen/xend/server/SrvDomain.py +1 -1
diff -r 734570be7e05 -r 556a93b6cca9 tools/python/xen/xend/server/SrvDomain.py
@@ -97,7 +97,7 @@ class SrvDomain(SrvDir):
     def op_pincpu(self, _, req):
         fn = FormFn(self.xd.domain_pincpu,
                     [['dom', 'int'],
-                     ['vcpu', 'int'],
+                     ['vcpu', 'str'],
                      ['cpumap', 'str']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
tools/python/xen/xm/main.py +7 -2
diff -r 734570be7e05 -r 556a93b6cca9 tools/python/xen/xm/main.py
@@ -613,7 +613,12 @@ def cpu_make_map(cpulist):
             for i in range(int(x),int(y)+1):
                 cpus.append(int(i))
         else:
-            cpus.append(int(c))
+            # remove this element from the list
+            if c[0] == '^':
+                cpus = [x for x in cpus if x != int(c[1:])]
+            else:
+                cpus.append(int(c))
+
     cpus.sort()
     return cpus
 
@@ -621,7 +626,7 @@ def xm_vcpu_pin(args):
     arg_check(args, "vcpu-pin", 3)
 
     dom  = args[0]
-    vcpu = int(args[1])
+    vcpu = args[1]
     cpumap = cpu_make_map(args[2])
     
     server.xend.domain.pincpu(dom, vcpu, cpumap)
#5 lore raw

PATCH 1/1 Add testcase for vcpu-pin all

In reply to Ryan Harper
2 files changed, 56 insertions(+), 1 deletion(-)

tools/xm-test/tests/vcpu-pin/02_vcpu-pin_all_pos.py | 54 +++++++++++++++++++
tools/xm-test/tests/vcpu-pin/Makefile.am | 3 -

# HG changeset patch
# User Ryan Harper <[email protected]>
# Date 1155579519 18000
# Node ID 27fdbe03de014cf640190081d2a61da246dac7a1 # Parent 556a93b6cca9b99b2ad0a2d6dcc24dc1a3a581ad Add testcase for vcpu-pin all

tools/xm-test/tests/vcpu-pin/Makefile.am +2 -1
diff -r 556a93b6cca9 -r 27fdbe03de01 tools/xm-test/tests/vcpu-pin/Makefile.am
@@ -1,7 +1,8 @@
 
 SUBDIRS =
 
-TESTS = 01_vcpu-pin_basic_pos.test
+TESTS = 01_vcpu-pin_basic_pos.test \
+	02_vcpu-pin_all_pos.py
 
 XFAIL_TESTS = 
 
tools/xm-test/tests/vcpu-pin/02_vcpu-pin_all_pos.py new file +54 -0

54 lines not on this page · raw message

#6 lore raw
In reply to Ryan Harper
Quoted 7 lines · Ryan Harper

This series of patches relates to the cpus parameter and pinning vcpus. The first patch is a clean-up of getVcpuInfo, which previously only returned the vcpu to cpu mapping. This was insufficient for extracting affinity information. The patch extends getVcpuInfo to return a dict of all the fields in xm vcpu-list for a domain. It also fixes a couple users of the function and moves them to a new vcpu_to_cpu function which retains the old behavior of getVcpuInfo.

How is that affecting the xend sxp API ? This may break libvirt 0.1.4
which uses those.

Daniel

Signature · 4 lines
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard      | virtualization library  http://libvirt.org/
[email protected]  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/
#7 lore raw
Quoted 11 lines · Daniel Veillard
Quoted 7 lines · Ryan Harper

This series of patches relates to the cpus parameter and pinning vcpus. The first patch is a clean-up of getVcpuInfo, which previously only returned the vcpu to cpu mapping. This was insufficient for extracting affinity information. The patch extends getVcpuInfo to return a dict of all the fields in xm vcpu-list for a domain. It also fixes a couple users of the function and moves them to a new vcpu_to_cpu function which retains the old behavior of getVcpuInfo.

How is that affecting the xend sxp API ? This may break libvirt 0.1.4
which uses those.

This change is to XmTestLib, ie, for the test cases only. Sorry for not being more clear on that.

Signature · 5 lines
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
[email protected]
#8 lore raw
Quoted 10 lines · Ryan Harper
Quoted 9 lines · Daniel Veillard
Quoted 7 lines · Ryan Harper

This series of patches relates to the cpus parameter and pinning vcpus. The first patch is a clean-up of getVcpuInfo, which previously only returned the vcpu to cpu mapping. This was insufficient for extracting affinity information. The patch extends getVcpuInfo to return a dict of all the fields in xm vcpu-list for a domain. It also fixes a couple users of the function and moves them to a new vcpu_to_cpu function which retains the old behavior of getVcpuInfo.

Quoted 2 lines
Quoted 2 lines

How is that affecting the xend sxp API ? This may break libvirt 0.1.4
which uses those.

The cpus parameter and vcpu 'all' changes add new behavior and do not modify any existing behavior, so no changes to the sxp API.

Quoted 3 lines

This change is to XmTestLib, ie, for the test cases only. Sorry for not being more clear on that.

I misread your question, but the above was referring to the getVcpuInfo change, which was in XmTestLib.

Quoted 7 lines
Signature · 6 lines
-- 
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
[email protected]
Signature · 5 lines
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
[email protected]
#9 lore raw
Quoted 11 lines · Ryan Harper
Quoted 10 lines · Ryan Harper
Quoted 9 lines · Daniel Veillard
Quoted 7 lines · Ryan Harper

This series of patches relates to the cpus parameter and pinning vcpus. The first patch is a clean-up of getVcpuInfo, which previously only returned the vcpu to cpu mapping. This was insufficient for extracting affinity information. The patch extends getVcpuInfo to return a dict of all the fields in xm vcpu-list for a domain. It also fixes a couple users of the function and moves them to a new vcpu_to_cpu function which retains the old behavior of getVcpuInfo.

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines

How is that affecting the xend sxp API ? This may break libvirt 0.1.4
which uses those.

The cpus parameter and vcpu 'all' changes add new behavior and do not modify any existing behavior, so no changes to the sxp API.

Okay, thanks :-)

Daniel

Signature · 4 lines
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard      | virtualization library  http://libvirt.org/
[email protected]  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/