From 8ae6230ef787cea6d2e0067dd73c13463e5191a6 Mon Sep 17 00:00:00 2001 From: Michal Bielecki Date: Sat, 26 Jan 2013 11:43:35 +0100 Subject: [PATCH 1/4] Adding get_uuid method for reading UUID of drive --- README.rst | 11 +++++++++++ libmount/fstab.py | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/README.rst b/README.rst index 1df343a..3b6b419 100644 --- a/README.rst +++ b/README.rst @@ -46,6 +46,17 @@ To update the on-disk filesystem table, call ``save()``:: fs.options.add('user_xattr') fstab.save() +UUIDs +----- + +You can get UUID of drives in fstab (if those have uuid) by using get_uuid method, like this: + + with FilesystemTable() as fstab: + for fs in fstab: + print "%s = %s" % (fs.source, fs.get_uuid()) + +Be getting proper results from get_uuid() requires root access on some systems. If drive does +not have UUID, or you don't have permissions to read it, get_uuid will return empty string. Limitations ----------- diff --git a/libmount/fstab.py b/libmount/fstab.py index f4fb186..b772589 100644 --- a/libmount/fstab.py +++ b/libmount/fstab.py @@ -1,6 +1,7 @@ import ctypes import functools import os +import subprocess __all__ = ['FilesystemTable'] @@ -90,6 +91,22 @@ def _set_options(self, value): del self._options options = property(_get_options, _set_options) + + def get_uuid(self): + """ Returns UUID of self.source drive + depends on 'blkid' command present in system (part of util-linux package), + additionally on some installations requires root permissions + """ + uuid = '' + if self.source[0:5].lower() == 'uuid=': + return self.source[5:].lower() + try: + uuid = subprocess.check_output( ["blkid %s | grep -o 'UUID=\"[^\"]*\"' | grep -o '[^UUID=\"].*[^\"]'" % self.source], shell=True).strip() + except subprocess.CalledProcessError: + pass + + return uuid.lower() + def __unicode__(self): return "%s on %s type %s (%s)" % (self.source, self.target, From 2f009973d501186dde273311c1273429ef9b6783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bielecki?= Date: Sat, 26 Jan 2013 11:46:17 +0100 Subject: [PATCH 2/4] Update README.rst fixing wrong formatting of readme --- README.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 3b6b419..b776f89 100644 --- a/README.rst +++ b/README.rst @@ -46,10 +46,7 @@ To update the on-disk filesystem table, call ``save()``:: fs.options.add('user_xattr') fstab.save() -UUIDs ------ - -You can get UUID of drives in fstab (if those have uuid) by using get_uuid method, like this: +You can get UUID of drives in fstab (if those have uuid) by using get_uuid method, like this:: with FilesystemTable() as fstab: for fs in fstab: @@ -58,6 +55,7 @@ You can get UUID of drives in fstab (if those have uuid) by using get_uuid metho Be getting proper results from get_uuid() requires root access on some systems. If drive does not have UUID, or you don't have permissions to read it, get_uuid will return empty string. + Limitations ----------- From 0e885e67e834bf245d872dd06e63a8437f85740e Mon Sep 17 00:00:00 2001 From: Michal Bielecki Date: Sat, 26 Jan 2013 14:52:35 +0100 Subject: [PATCH 3/4] Switching from blkid command, to libblkid through ctypes for UUID detection --- README.rst | 7 ++++--- libmount/fstab.py | 35 ++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/README.rst b/README.rst index b776f89..476161b 100644 --- a/README.rst +++ b/README.rst @@ -46,14 +46,15 @@ To update the on-disk filesystem table, call ``save()``:: fs.options.add('user_xattr') fstab.save() -You can get UUID of drives in fstab (if those have uuid) by using get_uuid method, like this:: +You can get UUID of drive by using ``get_uuid()`` method, like this:: with FilesystemTable() as fstab: for fs in fstab: print "%s = %s" % (fs.source, fs.get_uuid()) -Be getting proper results from get_uuid() requires root access on some systems. If drive does -not have UUID, or you don't have permissions to read it, get_uuid will return empty string. +Getting proper results from get_uuid() requires root access on some systems. If drive does +not have UUID, or you don't have permissions to read it, get_uuid() will return empty string. +UUID detection requires libblkid installed in your system. Limitations diff --git a/libmount/fstab.py b/libmount/fstab.py index b772589..854c75e 100644 --- a/libmount/fstab.py +++ b/libmount/fstab.py @@ -1,7 +1,6 @@ import ctypes import functools import os -import subprocess __all__ = ['FilesystemTable'] @@ -15,6 +14,18 @@ else: raise ImportError("Could not find libmount shared object. Is libmount installed?") + +libnames = ('libblkid.so', 'libblkid.so.1') +for libname in libnames: + try: + _libblkid = ctypes.cdll.LoadLibrary(libname) + except OSError: + continue + break +else: + _libblkid = False + + class FilesystemTable(list): class Options(set): """A sub-type of set for maintaining filesystem options.""" @@ -94,18 +105,20 @@ def _set_options(self, value): def get_uuid(self): """ Returns UUID of self.source drive - depends on 'blkid' command present in system (part of util-linux package), - additionally on some installations requires root permissions + requires root permissions """ - uuid = '' + if not _libblkid: + return '' if self.source[0:5].lower() == 'uuid=': return self.source[5:].lower() - try: - uuid = subprocess.check_output( ["blkid %s | grep -o 'UUID=\"[^\"]*\"' | grep -o '[^UUID=\"].*[^\"]'" % self.source], shell=True).strip() - except subprocess.CalledProcessError: - pass - - return uuid.lower() + pr = _libblkid.blkid_new_probe_from_filename( self.source ) + if pr == 0: + return '' + uuid = ctypes.c_char_p('') + _libblkid.blkid_do_probe(pr); + _libblkid.blkid_probe_lookup_value(pr, 'UUID', ctypes.byref(uuid), None); + _libblkid.blkid_free_probe(pr); + return uuid.value.lower() def __unicode__(self): return "%s on %s type %s (%s)" % (self.source, @@ -190,4 +203,4 @@ def save(self): def get_fstab_readonly(): return FilesystemTable('/etc/fstab', readonly=True) def get_current_mounts(): - return FilesystemTable('/proc/mounts', readonly=True) \ No newline at end of file + return FilesystemTable('/proc/mounts', readonly=True) From 27593766b833155a62d5854b9f5b7058aa7246f9 Mon Sep 17 00:00:00 2001 From: Michal Bielecki Date: Sat, 26 Jan 2013 19:34:36 +0100 Subject: [PATCH 4/4] Returning empty string for empty device name --- libmount/fstab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmount/fstab.py b/libmount/fstab.py index 854c75e..eef3197 100644 --- a/libmount/fstab.py +++ b/libmount/fstab.py @@ -107,7 +107,7 @@ def get_uuid(self): """ Returns UUID of self.source drive requires root permissions """ - if not _libblkid: + if not _libblkid or not self.source: return '' if self.source[0:5].lower() == 'uuid=': return self.source[5:].lower()