Vinzenz Feenstra has uploaded a new change for review.

Change subject: Support for mapping image ids to physical devices
......................................................................

Support for mapping image ids to physical devices

This patch uses libudev through ctypes for systems providing
libudev due to the instable nature of sysfs. While on RHEL5
we're using sysfs we cannot for example use it on Fedora 20
with kernel 3.15 since the serial values seem not to be exposed
by sysfs.

This patch extends the disks-usage message with the 'mapping' field.
The value of the mapping field is an object {'$serial': {'name': '$devname'}}

Change-Id: Ie8961b3703703df573dbf2f0fca2143b463ae76b
Bug-Url: https://bugzilla.redhat.com/1127607
Signed-off-by: Vinzenz Feenstra <[email protected]>
(cherry picked from commit 692b3ea13a7b4ea5a5426424d6aaf13a0f45ba32)
---
M configure.ac
M ovirt-guest-agent.rhel6.spec
M ovirt-guest-agent.spec
M ovirt-guest-agent/GuestAgentLinux2.py
M ovirt-guest-agent/GuestAgentWin32.py
M ovirt-guest-agent/Makefile.el5
M ovirt-guest-agent/OVirtAgentLogic.py
M scripts/Makefile.am
A scripts/diskmapper/Makefile.am
A scripts/diskmapper/diskmapper.el5
A scripts/diskmapper/diskmapper.libudev
11 files changed, 239 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-guest-agent 
refs/changes/24/31724/1

diff --git a/configure.ac b/configure.ac
index a5564f7..6f465be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,6 +235,7 @@
     ovirt-guest-agent/consoleapps/Makefile
     ovirt-guest-agent/pam/Makefile
     scripts/Makefile
+    scripts/diskmapper/Makefile
     scripts/wrappers/Makefile
     tests/Makefile
     windows-credprov/Makefile
diff --git a/ovirt-guest-agent.rhel6.spec b/ovirt-guest-agent.rhel6.spec
index 4a3e5d1..936eca6 100644
--- a/ovirt-guest-agent.rhel6.spec
+++ b/ovirt-guest-agent.rhel6.spec
@@ -125,6 +125,7 @@
 
 %attr (644,root,root) %{_datadir}/ovirt-guest-agent/default.conf
 %attr (644,root,root) %{_datadir}/ovirt-guest-agent/default-logger.conf
+%attr (755,root,root) %{_datadir}/ovirt-guest-agent/diskmapper
 
 %attr (755,root,root) %{_datadir}/ovirt-guest-agent/LockActiveSession.py*
 %attr (755,root,root) %{_datadir}/ovirt-guest-agent/hibernate
diff --git a/ovirt-guest-agent.spec b/ovirt-guest-agent.spec
index 8b9d521..724faf9 100644
--- a/ovirt-guest-agent.spec
+++ b/ovirt-guest-agent.spec
@@ -199,6 +199,7 @@
 
 %attr (644,root,root) %{_datadir}/ovirt-guest-agent/default.conf
 %attr (644,root,root) %{_datadir}/ovirt-guest-agent/default-logger.conf
+%attr (755,root,root) %{_datadir}/ovirt-guest-agent/diskmapper
 
 %{_unitdir}/ovirt-guest-agent.service
 
diff --git a/ovirt-guest-agent/GuestAgentLinux2.py 
b/ovirt-guest-agent/GuestAgentLinux2.py
index 87ff63a..e54eb82 100644
--- a/ovirt-guest-agent/GuestAgentLinux2.py
+++ b/ovirt-guest-agent/GuestAgentLinux2.py
@@ -1,5 +1,5 @@
 #
-# Copyright 2010-2012 Red Hat, Inc. and/or its affiliates.
+# Copyright 2010-2014 Hat, Inc. and/or its affiliates.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -36,6 +36,21 @@
             pass
     CredServer = CredServerFake
 
+
+def _readLinesFromProcess(cmdline):
+    try:
+        process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
+                                   stderr=subprocess.PIPE)
+    except OSError:
+        logging.exception("Failed to run process %s", cmdline)
+        return []
+
+    out, err = process.communicate()
+    if process.returncode != 0:
+        logging.error("Process %s returned err code %d", cmdline,
+                      process.returncode)
+        return []
+    return out.splitlines()
 
 class PkgMgr(object):
 
@@ -272,6 +287,19 @@
 
         return usages
 
+    def getDiskMapping(self):
+        CMD = '/usr/share/ovirt-guest-agent/diskmapper'
+        mapping = {}
+        for line in _readLinesFromProcess([CMD]):
+            try:
+                name, serial = line.split('|', 1)
+            except ValueError:
+                logging.exception("diskmapper tool used an invalid format")
+                return {}
+
+            mapping[serial] = {'name': name}
+        return mapping
+
     def getMemoryStats(self):
         try:
             self._get_meminfo()
@@ -372,6 +400,8 @@
     print "Active User:", dr.getActiveUser()
     print "Disks Usage:",
     pprint(dr.getDisksUsage())
+    print "Disk Mapping:",
+    pprint(dr.getDiskMapping())
     print "Memory Stats:", dr.getMemoryStats()
 
 if __name__ == '__main__':
diff --git a/ovirt-guest-agent/GuestAgentWin32.py 
b/ovirt-guest-agent/GuestAgentWin32.py
index e42a101..0845f02 100644
--- a/ovirt-guest-agent/GuestAgentWin32.py
+++ b/ovirt-guest-agent/GuestAgentWin32.py
@@ -460,6 +460,23 @@
             logging.exception("Error retrieving disks usages.")
         return usages
 
+    def getDiskMapping(self):
+        result = {}
+        try:
+            strComputer = "."
+            objWMIService = \
+                win32com.client.Dispatch("WbemScripting.SWbemLocator")
+            objSWbemServices = \
+                objWMIService.ConnectServer(strComputer, "root\cimv2")
+            colItems = \
+                objSWbemServices.ExecQuery(
+                    "SELECT * FROM Win32_DiskDrive")
+            for objItem in colItems:
+                result[objItem.SerialNumber] = {'name': objItem.DeviceID}
+        except Exception:
+            logging.exception("Failed to retrieve disk mapping")
+        return result
+
     def _getSwapStats(self):
         try:
             strComputer = "."
diff --git a/ovirt-guest-agent/Makefile.el5 b/ovirt-guest-agent/Makefile.el5
index 3c43975..00d1a4c 100644
--- a/ovirt-guest-agent/Makefile.el5
+++ b/ovirt-guest-agent/Makefile.el5
@@ -5,7 +5,7 @@
 
 FILES=ovirt-guest-agent.py OVirtAgentLogic.py VirtIoChannel.py \
        GuestAgentLinux2.py hibernate bytesio.py ../configurations/default.conf 
\
-       ../configurations/default-logger.conf
+       ../configurations/default-logger.conf 
../scripts/diskmapper/diskmapper.el5
 
 AGENTDIR=/usr/share/ovirt-guest-agent
 CONFDIR=/etc
diff --git a/ovirt-guest-agent/OVirtAgentLogic.py 
b/ovirt-guest-agent/OVirtAgentLogic.py
index 5cfcfff..a1f4f47 100644
--- a/ovirt-guest-agent/OVirtAgentLogic.py
+++ b/ovirt-guest-agent/OVirtAgentLogic.py
@@ -136,6 +136,9 @@
     def getDisksUsage(self):
         pass
 
+    def getDiskMapping(self):
+        pass
+
     def getMemoryStats(self):
         pass
 
@@ -346,7 +349,8 @@
         self._send('applications', {'applications': self.dr.getApplications()})
 
     def sendDisksUsages(self):
-        self._send('disks-usage', {'disks': self.dr.getDisksUsage()})
+        self._send('disks-usage', {'disks': self.dr.getDisksUsage(),
+                                   'mapping': self.dr.getDiskMapping()})
 
     def sendMemoryStats(self):
         self._send('memory-stats', {'memory': self.dr.getMemoryStats()})
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 83b8cb4..58e002a 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -1,5 +1,24 @@
-SUBDIRS =    \
-    wrappers \
+#
+# Copyright 2014 Red Hat, Inc. and/or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Refer to the README and COPYING files for full details of the license.
+#
+
+SUBDIRS =        \
+    diskmapper   \
+    wrappers     \
     $(NULL)
 
 EXTRA_DIST=                    \
diff --git a/scripts/diskmapper/Makefile.am b/scripts/diskmapper/Makefile.am
new file mode 100644
index 0000000..27cbf9c
--- /dev/null
+++ b/scripts/diskmapper/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Copyright 2014 Red Hat, Inc. and/or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Refer to the README and COPYING files for full details of the license.
+#
+
+EXTRA_DIST=\
+    diskmapper.el5     \
+    diskmapper.libudev \
+    $(NULL)
+
+install-data-hook:
+       $(MKDIR_P) $(DESTDIR)/$(pkgdatadir)
+       $(INSTALL) -m 755 diskmapper.libudev $(DESTDIR)/$(pkgdatadir)/diskmapper
diff --git a/scripts/diskmapper/diskmapper.el5 
b/scripts/diskmapper/diskmapper.el5
new file mode 100755
index 0000000..4b7b464
--- /dev/null
+++ b/scripts/diskmapper/diskmapper.el5
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# Copyright 2014 Red Hat, Inc. and/or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Refer to the README and COPYING files for full details of the license.
+#
+
+
+for devname in `ls /sys/block`; do
+    if [ -f /sys/block/$devname/device/serial ]; then
+        serial=`cat /sys/block/$devname/device/serial`
+        echo "/dev/$devname|$serial"
+    fi
+done
diff --git a/scripts/diskmapper/diskmapper.libudev 
b/scripts/diskmapper/diskmapper.libudev
new file mode 100755
index 0000000..ad0abc8
--- /dev/null
+++ b/scripts/diskmapper/diskmapper.libudev
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# Copyright 2014 Red Hat, Inc. and/or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Refer to the README and COPYING files for full details of the license.
+#
+
+from ctypes import CDLL, POINTER, c_ulonglong, c_char_p, c_int, Structure
+from ctypes.util import find_library
+
+
+class udev(Structure):
+    pass
+
+
+class udev_enumerate(Structure):
+    pass
+
+
+class udev_list_entry(Structure):
+    pass
+
+
+class udev_device(Structure):
+    pass
+
+
+udev_p = POINTER(udev)
+udev_enumerate_p = POINTER(udev_enumerate)
+udev_list_entry_p = POINTER(udev_list_entry)
+udev_device_p = POINTER(udev_device)
+dev_t = c_ulonglong
+
+
+_SIGNATURES = {
+    'udev': dict(
+        new=([], udev_p),
+        unref=([udev_p], None),
+    ),
+    'udev_enumerate': dict(
+        new=([udev_p], udev_enumerate_p),
+        unref=([udev_enumerate_p], None),
+        add_match_subsystem=([udev_enumerate_p, c_char_p], c_int),
+        add_match_property=([udev_enumerate_p, c_char_p, c_char_p], c_int),
+        scan_devices=([udev_enumerate_p], c_int),
+        get_list_entry=([udev_enumerate_p], udev_list_entry_p)
+    ),
+    'udev_list_entry': dict(
+        get_next=([udev_list_entry_p], udev_list_entry_p),
+        get_name=([udev_list_entry_p], c_char_p),
+    ),
+    'udev_device': dict(
+        new_from_syspath=([udev_p, c_char_p], udev_device_p),
+        unref=([udev_device_p], None),
+        get_devtype=([udev_device_p], c_char_p),
+        get_devnode=([udev_device_p], c_char_p),
+        get_property_value=([udev_device_p, c_char_p], c_char_p)
+    )
+}
+
+
+def load_udev():
+    libudev_name = find_library("udev")
+    ludev = CDLL(libudev_name, use_errno=True)
+    for cls, funcs in _SIGNATURES.iteritems():
+        for name, signature in funcs.iteritems():
+            f = getattr(ludev, '%s_%s' % (cls, name))
+            if f:
+                (argtypes, restype) = signature
+                f.argtypes = argtypes
+                f.restype = restype
+            else:
+                print 'Couldn\'t load', '%s_%s' % (cls, name)
+    return ludev
+
+if __name__ == '__main__':
+    ludev = load_udev()
+    udev = ludev.udev_new()
+    udevenum = ludev.udev_enumerate_new(udev)
+    try:
+        ludev.udev_enumerate_add_match_subsystem(udevenum, "block")
+        ludev.udev_enumerate_scan_devices(udevenum)
+        devices = ludev.udev_enumerate_get_list_entry(udevenum)
+        entry = devices
+        while entry:
+            name = ludev.udev_list_entry_get_name(entry)
+            dev = ludev.udev_device_new_from_syspath(udev, name)
+            devtype = ludev.udev_device_get_devtype(dev)
+            if devtype == "disk":
+                devnode = ludev.udev_device_get_devnode(dev)
+                serial = ludev.udev_device_get_property_value(dev, "ID_SERIAL")
+                if serial:
+                    print '%s|%s' % (devnode, serial)
+            entry = ludev.udev_list_entry_get_next(entry)
+    finally:
+        ludev.udev_enumerate_unref(udevenum)
+        ludev.udev_unref(udev)


-- 
To view, visit http://gerrit.ovirt.org/31724
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie8961b3703703df573dbf2f0fca2143b463ae76b
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-guest-agent
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Vinzenz Feenstra <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to