From 410853d619f76ffef0248c8699087bcff64303d8 Mon Sep 17 00:00:00 2001 From: BenjiReis Date: Tue, 2 May 2023 15:16:00 +0200 Subject: [PATCH 1/4] Support NFSv4 only environment NFSv4 only environments don't support `rpcinfo` and `showmount` calls as they're missing NFSv3 services. When `rpcinfo` or `showmount` fails, try to mount NFSv4 pseudo FS '/' to add '4' to supported NFS versions and run `ls` on the mounted pseudo FS to offer the first folder level of exports. See: https://github.com/xapi-project/sm/issues/551 And: https://github.com/xcp-ng/xcp/issues/135 Signed-off-by: BenjiReis --- drivers/NFSSR.py | 10 +-- drivers/nfs.py | 148 ++++++++++++++++++++++++++++---------------- tests/test_NFSSR.py | 2 +- tests/test_nfs.py | 49 +++++++-------- 4 files changed, 121 insertions(+), 88 deletions(-) diff --git a/drivers/NFSSR.py b/drivers/NFSSR.py index a0c3d2446..6ef697784 100755 --- a/drivers/NFSSR.py +++ b/drivers/NFSSR.py @@ -113,11 +113,13 @@ def validate_remotepath(self, scan): def check_server(self): try: if PROBEVERSION in self.dconf: - sv = nfs.get_supported_nfs_versions(self.remoteserver) + sv = nfs.get_supported_nfs_versions(self.remoteserver, self.transport) if len(sv): self.nfsversion = sv[0] else: - nfs.check_server_tcp(self.remoteserver, self.nfsversion) + if not nfs.check_server_tcp(self.remoteserver, self.transport, self.nfsversion): + raise nfs.NfsException("Unsupported NFS version: %s" % self.nfsversion) + except nfs.NfsException as exc: raise xs_errors.XenError('NFSVersion', opterr=exc.errstr) @@ -163,7 +165,7 @@ def probe(self): self.mount(temppath, self.remotepath) try: - return nfs.scan_srlist(temppath, self.dconf) + return nfs.scan_srlist(temppath, self.transport, self.dconf) finally: try: nfs.unmount(temppath, True) @@ -250,7 +252,7 @@ def vdi(self, uuid, loadLocked=False): def scan_exports(self, target): util.SMlog("scanning2 (target=%s)" % target) - dom = nfs.scan_exports(target) + dom = nfs.scan_exports(target, self.transport) print(dom.toprettyxml(), file=sys.stderr) def set_transport(self): diff --git a/drivers/nfs.py b/drivers/nfs.py index 461698584..79be8a154 100644 --- a/drivers/nfs.py +++ b/drivers/nfs.py @@ -41,6 +41,7 @@ RPCINFO_BIN = "/usr/sbin/rpcinfo" SHOWMOUNT_BIN = "/usr/sbin/showmount" +NFS_STAT = "/usr/sbin/nfsstat" DEFAULT_NFSVERSION = '3' @@ -50,34 +51,41 @@ NFS_SERVICE_WAIT = 30 NFS_SERVICE_RETRY = 6 +NSFv4_PSEUDOFS = "/" +NFS4_TMP_MOUNTPOINT = "/tmp/mnt" class NfsException(Exception): def __init__(self, errstr): self.errstr = errstr - -def check_server_tcp(server, nfsversion=DEFAULT_NFSVERSION): +def check_server_tcp(server, transport, nfsversion=DEFAULT_NFSVERSION): """Make sure that NFS over TCP/IP V3 is supported on the server. Returns True if everything is OK False otherwise. """ + try: - sv = get_supported_nfs_versions(server) - return (True if nfsversion in sv else False) + sv = get_supported_nfs_versions(server, transport) + return (nfsversion[0] in sv) except util.CommandException as inst: raise NfsException("rpcinfo failed or timed out: return code %d" % inst.code) -def check_server_service(server): +def check_server_service(server, transport): """Ensure NFS service is up and available on the remote server. Returns False if fails to detect service after NFS_SERVICE_RETRY * NFS_SERVICE_WAIT """ + sv = get_supported_nfs_versions(server, transport) + # Services are not present in NFS4 only, this doesn't mean there's no NFS + if sv == ['4']: + return True + retries = 0 errlist = [errno.EPERM, errno.EPIPE, errno.EIO] @@ -129,18 +137,6 @@ def soft_mount(mountpoint, remoteserver, remotepath, transport, useroptions='', raise NfsException("Failed to make directory: code is %d" % inst.code) - - # Wait for NFS service to be available - try: - if not check_server_service(remoteserver): - raise util.CommandException( - code=errno.EOPNOTSUPP, - reason='No NFS service on server: `%s`' % remoteserver - ) - except util.CommandException as inst: - raise NfsException("Failed to detect NFS service on server `%s`" - % remoteserver) - mountcommand = 'mount.nfs' options = "soft,proto=%s,vers=%s" % ( @@ -186,43 +182,75 @@ def unmount(mountpoint, rmmountpoint): raise NfsException("rmdir failed with error '%s'" % inst.strerror) -def scan_exports(target): +def scan_exports(target, transport): """Scan target and return an XML DOM with target, path and accesslist.""" util.SMlog("scanning") - cmd = [SHOWMOUNT_BIN, "--no-headers", "-e", target] dom = xml.dom.minidom.Document() element = dom.createElement("nfs-exports") dom.appendChild(element) - for val in util.pread2(cmd).split('\n'): - if not len(val): - continue - entry = dom.createElement('Export') - element.appendChild(entry) - - subentry = dom.createElement("Target") - entry.appendChild(subentry) - textnode = dom.createTextNode(target) - subentry.appendChild(textnode) - - # Access is not always provided by showmount return - # If none is provided we need to assume "*" - array = val.split() - path = array[0] - access = array[1] if len(array) >= 2 else "*" - subentry = dom.createElement("Path") - entry.appendChild(subentry) - textnode = dom.createTextNode(path) - subentry.appendChild(textnode) - - subentry = dom.createElement("Accesslist") - entry.appendChild(subentry) - textnode = dom.createTextNode(access) - subentry.appendChild(textnode) - - return dom - - -def scan_srlist(path, dconf): + try: + cmd = [SHOWMOUNT_BIN, "--no-headers", "-e", target] + for val in util.pread2(cmd).split('\n'): + if not len(val): + continue + entry = dom.createElement('Export') + element.appendChild(entry) + + subentry = dom.createElement("Target") + entry.appendChild(subentry) + textnode = dom.createTextNode(target) + subentry.appendChild(textnode) + + # Access is not always provided by showmount return + # If none is provided we need to assume "*" + array = val.split() + path = array[0] + access = array[1] if len(array) >= 2 else "*" + subentry = dom.createElement("Path") + entry.appendChild(subentry) + textnode = dom.createTextNode(path) + subentry.appendChild(textnode) + + subentry = dom.createElement("Accesslist") + entry.appendChild(subentry) + textnode = dom.createTextNode(access) + subentry.appendChild(textnode) + return dom + except Exception: + util.SMlog("Unable to scan exports with %s, trying NFSv4" % SHOWMOUNT_BIN) + + # NFSv4 only + try: + mountpoint = "%s/%s" % (NFS4_TMP_MOUNTPOINT, target) + soft_mount(mountpoint, target, NSFv4_PSEUDOFS, transport, nfsversion='4') + paths = os.listdir(mountpoint) + unmount(mountpoint, NSFv4_PSEUDOFS) + for path in paths: + entry = dom.createElement('Export') + element.appendChild(entry) + + subentry = dom.createElement("Target") + entry.appendChild(subentry) + textnode = dom.createTextNode(target) + subentry.appendChild(textnode) + subentry = dom.createElement("Path") + entry.appendChild(subentry) + textnode = dom.createTextNode(path) + subentry.appendChild(textnode) + + subentry = dom.createElement("Accesslist") + entry.appendChild(subentry) + # Assume everyone as we do not have any info about it + textnode = dom.createTextNode("*") + subentry.appendChild(textnode) + return dom + except Exception: + util.SMlog("Unable to scan exports with NFSv4 pseudo FS mount") + + raise NfsException('Failed to read NFS export paths from server %s' % + (target)) + +def scan_srlist(path, transport, dconf): """Scan and report SR, UUID.""" dom = xml.dom.minidom.Document() element = dom.createElement("SRlist") @@ -245,7 +273,7 @@ def scan_srlist(path, dconf): if PROBEVERSION in dconf: util.SMlog("Add supported nfs versions to sr-probe") try: - supported_versions = get_supported_nfs_versions(dconf.get('server')) + supported_versions = get_supported_nfs_versions(dconf.get('server'), transport) supp_ver = dom.createElement("SupportedVersions") element.appendChild(supp_ver) @@ -261,7 +289,7 @@ def scan_srlist(path, dconf): return dom.toprettyxml() -def get_supported_nfs_versions(server): +def get_supported_nfs_versions(server, transport): """Return list of supported nfs versions.""" valid_versions = set(['3', '4']) cv = set() @@ -274,11 +302,21 @@ def get_supported_nfs_versions(server): for j in range(len(cvi)): cv.add(cvi[j]) return sorted(cv & valid_versions) - except: - util.SMlog("Unable to obtain list of valid nfs versions") - raise NfsException('Failed to read supported NFS version from server %s' % - (server)) + except Exception: + util.SMlog("Unable to obtain list of valid nfs versions with %s, trying NSFv4" % RPCINFO_BIN) + # NFSv4 only + try: + mountpoint = "%s/%s" % (NFS4_TMP_MOUNTPOINT, server) + soft_mount(mountpoint, server, NSFv4_PSEUDOFS, transport, nfsversion='4') + util.pread2([NFS_STAT, '-m']) + unmount(mountpoint, NSFv4_PSEUDOFS) + return ['4'] + except Exception: + util.SMlog("Unable to obtain list of valid nfs versions with NSFv4 pseudo FS mount") + + raise NfsException('Failed to read supported NFS version from server %s' % + (server)) def get_nfs_timeout(other_config): nfs_timeout = 100 diff --git a/tests/test_NFSSR.py b/tests/test_NFSSR.py index 9d3877b56..eeab24724 100644 --- a/tests/test_NFSSR.py +++ b/tests/test_NFSSR.py @@ -121,7 +121,7 @@ def test_attach(self, validate_nfsversion, check_server_tcp, _testhost, nfssr.attach(None) - check_server_tcp.assert_called_once_with('aServer', + check_server_tcp.assert_called_once_with('aServer', 'tcp', 'aNfsversionChanged') soft_mount.assert_called_once_with('/var/run/sr-mount/UUID', 'aServer', diff --git a/tests/test_nfs.py b/tests/test_nfs.py index d86b37341..6842f016d 100644 --- a/tests/test_nfs.py +++ b/tests/test_nfs.py @@ -9,13 +9,13 @@ class Test_nfs(unittest.TestCase): @mock.patch('util.pread', autospec=True) def test_check_server_tcp(self, pread): - nfs.check_server_tcp('aServer') + nfs.check_server_tcp('aServer', 'tcp') pread.assert_called_once_with(['/usr/sbin/rpcinfo', '-s', 'aServer'], quiet=False, text=True) @mock.patch('util.pread', autospec=True) def test_check_server_tcp_nfsversion(self, pread): - nfs.check_server_tcp('aServer', 'aNfsversion') + nfs.check_server_tcp('aServer', 'tcp', 'aNfsversion') pread.assert_called_once_with(['/usr/sbin/rpcinfo', '-s', 'aServer'], quiet=False, text=True) @@ -24,16 +24,17 @@ def test_check_server_tcp_nfsversion_error(self, pread): pread.side_effect = util.CommandException with self.assertRaises(nfs.NfsException): - nfs.check_server_tcp('aServer', 'aNfsversion') + nfs.check_server_tcp('aServer', 'tcp', 'aNfsversion') - pread.assert_called_once_with(['/usr/sbin/rpcinfo', '-s', 'aServer'], quiet=False, text=True) + self.assertEqual(len(pread.mock_calls), 2) @mock.patch('time.sleep', autospec=True) + @mock.patch('nfs.get_supported_nfs_versions', autospec=True) # Can't use autospec due to http://bugs.python.org/issue17826 @mock.patch('util.pread') - def test_check_server_service(self, pread, sleep): + def test_check_server_service(self, pread, get_supported_nfs_versions, sleep): pread.side_effect = [" 100003 4,3,2 udp6,tcp6,udp,tcp nfs superuser"] - service_found = nfs.check_server_service('aServer') + service_found = nfs.check_server_service('aServer', 'tcp') self.assertTrue(service_found) self.assertEqual(len(pread.mock_calls), 1) @@ -47,7 +48,7 @@ def test_check_server_service_with_retries(self, pread, sleep): pread.side_effect = ["", "", " 100003 4,3,2 udp6,tcp6,udp,tcp nfs superuser"] - service_found = nfs.check_server_service('aServer') + service_found = nfs.check_server_service('aServer', 'tcp') self.assertTrue(service_found) self.assertEqual(len(pread.mock_calls), 3) @@ -58,25 +59,27 @@ def test_check_server_service_with_retries(self, pread, sleep): def test_check_server_service_not_available(self, pread, sleep): pread.return_value = "" - service_found = nfs.check_server_service('aServer') + service_found = nfs.check_server_service('aServer', 'tcp') self.assertFalse(service_found) @mock.patch('time.sleep', autospec=True) + @mock.patch('nfs.get_supported_nfs_versions', autospec=True) # Can't use autospec due to http://bugs.python.org/issue17826 @mock.patch('util.pread') - def test_check_server_service_exception(self, pread, sleep): + def test_check_server_service_exception(self, pread, sleep, get_supported_nfs_versions): pread.side_effect = [util.CommandException(errno.ENOMEM)] with self.assertRaises(util.CommandException): - nfs.check_server_service('aServer') + nfs.check_server_service('aServer', 'tcp') @mock.patch('time.sleep', autospec=True) + @mock.patch('nfs.get_supported_nfs_versions', autospec=True) # Can't use autospec due to http://bugs.python.org/issue17826 @mock.patch('util.pread') - def test_check_server_service_first_call_exception(self, pread, sleep): + def test_check_server_service_first_call_exception(self, pread, sleep, get_supported_nfs_versions): pread.side_effect = [util.CommandException(errno.EPIPE), " 100003 4,3,2 udp6,tcp6,udp,tcp nfs superuser"] - service_found = nfs.check_server_service('aServer') + service_found = nfs.check_server_service('aServer', 'tcp') self.assertTrue(service_found) self.assertEqual(len(pread.mock_calls), 2) @@ -85,7 +88,7 @@ def test_check_server_service_first_call_exception(self, pread, sleep): @mock.patch('util.pread2') def test_get_supported_nfs_versions(self, pread2): pread2.side_effect = [" 100003 4,3,2 udp6,tcp6,udp,tcp nfs superuser"] - versions = nfs.get_supported_nfs_versions('aServer') + versions = nfs.get_supported_nfs_versions('aServer', 'tcp') self.assertEqual(versions, ['3', '4']) self.assertEqual(len(pread2.mock_calls), 1) @@ -98,48 +101,38 @@ def get_soft_mount_pread(self, binary, vers, ipv6=False): 'soft,proto=%s,vers=%s,acdirmin=0,acdirmax=0' % (transport, vers)]) @mock.patch('util.makedirs', autospec=True) - @mock.patch('nfs.check_server_service', autospec=True) @mock.patch('util.pread', autospec=True) - def test_soft_mount(self, pread, check_server_service, makedirs): + def test_soft_mount(self, pread, makedirs): nfs.soft_mount('mountpoint', 'remoteserver', 'remotepath', 'transport', timeout=None) - check_server_service.assert_called_once_with('remoteserver') pread.assert_called_once_with(self.get_soft_mount_pread('mount.nfs', '3')) @mock.patch('util.makedirs', autospec=True) - @mock.patch('nfs.check_server_service', autospec=True) @mock.patch('util.pread', autospec=True) - def test_soft_mount_ipv6(self, pread, check_server_service, makedirs): + def test_soft_mount_ipv6(self, pread, makedirs): nfs.soft_mount('mountpoint', 'remoteserver', 'remotepath', 'tcp6', timeout=None) - check_server_service.assert_called_once_with('remoteserver') pread.assert_called_once_with(self.get_soft_mount_pread('mount.nfs', '3', True)) @mock.patch('util.makedirs', autospec=True) - @mock.patch('nfs.check_server_service', autospec=True) @mock.patch('util.pread', autospec=True) - def test_soft_mount_nfsversion_3(self, pread, - check_server_service, makedirs): + def test_soft_mount_nfsversion_3(self, pread, makedirs): nfs.soft_mount('mountpoint', 'remoteserver', 'remotepath', 'transport', timeout=None, nfsversion='3') - check_server_service.assert_called_once_with('remoteserver') pread.assert_called_with(self.get_soft_mount_pread('mount.nfs', '3')) @mock.patch('util.makedirs', autospec=True) - @mock.patch('nfs.check_server_service', autospec=True) @mock.patch('util.pread', autospec=True) - def test_soft_mount_nfsversion_4(self, pread, - check_server_service, makedirs): + def test_soft_mount_nfsversion_4(self, pread, makedirs): nfs.soft_mount('mountpoint', 'remoteserver', 'remotepath', 'transport', timeout=None, nfsversion='4') - check_server_service.assert_called_once_with('remoteserver') pread.assert_called_with(self.get_soft_mount_pread('mount.nfs', '4')) @@ -166,7 +159,7 @@ def test_validate_nfsversion_valid(self): @mock.patch('util.pread2') def test_scan_exports(self, pread2): pread2.side_effect = ["/srv/nfs\n/srv/nfs2 *\n/srv/nfs3 127.0.0.1/24"] - res = nfs.scan_exports('aServer') + res = nfs.scan_exports('aServer', 'tcp') expected = """ From df5b89245500ae57844694fbf45af234f61f3719 Mon Sep 17 00:00:00 2001 From: BenjiReis Date: Thu, 13 Jul 2023 10:46:21 +0200 Subject: [PATCH 2/4] rebase me: split methods for NFS3+/NFS4 only Signed-off-by: BenjiReis --- drivers/nfs.py | 167 ++++++++++++++++++++++++++++++------------------- 1 file changed, 102 insertions(+), 65 deletions(-) diff --git a/drivers/nfs.py b/drivers/nfs.py index 79be8a154..c98145fac 100644 --- a/drivers/nfs.py +++ b/drivers/nfs.py @@ -182,6 +182,70 @@ def unmount(mountpoint, rmmountpoint): raise NfsException("rmdir failed with error '%s'" % inst.strerror) +def _scan_exports_nfs3(target, dom, element): + """ Scan target and return an XML DOM with target, path and accesslist. + Using NFS3 services. + """ + + cmd = [SHOWMOUNT_BIN, "--no-headers", "-e", target] + for val in util.pread2(cmd).split('\n'): + if not len(val): + continue + entry = dom.createElement('Export') + element.appendChild(entry) + + subentry = dom.createElement("Target") + entry.appendChild(subentry) + textnode = dom.createTextNode(target) + subentry.appendChild(textnode) + + # Access is not always provided by showmount return + # If none is provided we need to assume "*" + array = val.split() + path = array[0] + access = array[1] if len(array) >= 2 else "*" + subentry = dom.createElement("Path") + entry.appendChild(subentry) + textnode = dom.createTextNode(path) + subentry.appendChild(textnode) + + subentry = dom.createElement("Accesslist") + entry.appendChild(subentry) + textnode = dom.createTextNode(access) + subentry.appendChild(textnode) + return dom + + +def _scan_exports_nfs4_only(target, transport, dom, element): + """ Scan target and return an XML DOM with target, path and accesslist. + Using NFS4 only pseudo FS. + """ + + mountpoint = "%s/%s" % (NFS4_TMP_MOUNTPOINT, target) + soft_mount(mountpoint, target, NSFv4_PSEUDOFS, transport, nfsversion='4') + paths = os.listdir(mountpoint) + unmount(mountpoint, NSFv4_PSEUDOFS) + for path in paths: + entry = dom.createElement('Export') + element.appendChild(entry) + + subentry = dom.createElement("Target") + entry.appendChild(subentry) + textnode = dom.createTextNode(target) + subentry.appendChild(textnode) + subentry = dom.createElement("Path") + entry.appendChild(subentry) + textnode = dom.createTextNode(path) + subentry.appendChild(textnode) + + subentry = dom.createElement("Accesslist") + entry.appendChild(subentry) + # Assume everyone as we do not have any info about it + textnode = dom.createTextNode("*") + subentry.appendChild(textnode) + return dom + + def scan_exports(target, transport): """Scan target and return an XML DOM with target, path and accesslist.""" util.SMlog("scanning") @@ -189,67 +253,20 @@ def scan_exports(target, transport): element = dom.createElement("nfs-exports") dom.appendChild(element) try: - cmd = [SHOWMOUNT_BIN, "--no-headers", "-e", target] - for val in util.pread2(cmd).split('\n'): - if not len(val): - continue - entry = dom.createElement('Export') - element.appendChild(entry) - - subentry = dom.createElement("Target") - entry.appendChild(subentry) - textnode = dom.createTextNode(target) - subentry.appendChild(textnode) - - # Access is not always provided by showmount return - # If none is provided we need to assume "*" - array = val.split() - path = array[0] - access = array[1] if len(array) >= 2 else "*" - subentry = dom.createElement("Path") - entry.appendChild(subentry) - textnode = dom.createTextNode(path) - subentry.appendChild(textnode) - - subentry = dom.createElement("Accesslist") - entry.appendChild(subentry) - textnode = dom.createTextNode(access) - subentry.appendChild(textnode) - return dom + return _scan_exports_nfs3(target, dom, element) except Exception: util.SMlog("Unable to scan exports with %s, trying NFSv4" % SHOWMOUNT_BIN) # NFSv4 only try: - mountpoint = "%s/%s" % (NFS4_TMP_MOUNTPOINT, target) - soft_mount(mountpoint, target, NSFv4_PSEUDOFS, transport, nfsversion='4') - paths = os.listdir(mountpoint) - unmount(mountpoint, NSFv4_PSEUDOFS) - for path in paths: - entry = dom.createElement('Export') - element.appendChild(entry) - - subentry = dom.createElement("Target") - entry.appendChild(subentry) - textnode = dom.createTextNode(target) - subentry.appendChild(textnode) - subentry = dom.createElement("Path") - entry.appendChild(subentry) - textnode = dom.createTextNode(path) - subentry.appendChild(textnode) - - subentry = dom.createElement("Accesslist") - entry.appendChild(subentry) - # Assume everyone as we do not have any info about it - textnode = dom.createTextNode("*") - subentry.appendChild(textnode) - return dom + return _scan_exports_nfs4_only(target, transport, dom, element) except Exception: util.SMlog("Unable to scan exports with NFSv4 pseudo FS mount") raise NfsException('Failed to read NFS export paths from server %s' % (target)) + def scan_srlist(path, transport, dconf): """Scan and report SR, UUID.""" dom = xml.dom.minidom.Document() @@ -289,35 +306,55 @@ def scan_srlist(path, transport, dconf): return dom.toprettyxml() -def get_supported_nfs_versions(server, transport): - """Return list of supported nfs versions.""" +def _get_supported_nfs_version_rpcinfo(server): + """ Return list of supported nfs versions. + Using NFS3 services. + """ + valid_versions = set(['3', '4']) cv = set() - try: - ns = util.pread2([RPCINFO_BIN, "-s", "%s" % server]) - ns = ns.split("\n") - for i in range(len(ns)): - if ns[i].find("nfs") > 0: - cvi = ns[i].split()[1].split(",") - for j in range(len(cvi)): - cv.add(cvi[j]) - return sorted(cv & valid_versions) - except Exception: - util.SMlog("Unable to obtain list of valid nfs versions with %s, trying NSFv4" % RPCINFO_BIN) + ns = util.pread2([RPCINFO_BIN, "-s", "%s" % server]) + ns = ns.split("\n") + for i in range(len(ns)): + if ns[i].find("nfs") > 0: + cvi = ns[i].split()[1].split(",") + for j in range(len(cvi)): + cv.add(cvi[j]) + return sorted(cv & valid_versions) + + +def _is_nfs4_supported(server, transport): + """ Return list of supported nfs versions. + Using NFS4 pseudo FS. + """ - # NFSv4 only try: mountpoint = "%s/%s" % (NFS4_TMP_MOUNTPOINT, server) soft_mount(mountpoint, server, NSFv4_PSEUDOFS, transport, nfsversion='4') util.pread2([NFS_STAT, '-m']) unmount(mountpoint, NSFv4_PSEUDOFS) - return ['4'] + return True + except Exception: + return False + + +def get_supported_nfs_versions(server, transport): + """Return list of supported nfs versions.""" + try: + return _get_supported_nfs_version_rpcinfo(server) except Exception: + util.SMlog("Unable to obtain list of valid nfs versions with %s, trying NSFv4" % RPCINFO_BIN) + + # NFSv4 only + if _is_nfs4_supported(server, transport): + return ['4'] + else: util.SMlog("Unable to obtain list of valid nfs versions with NSFv4 pseudo FS mount") raise NfsException('Failed to read supported NFS version from server %s' % (server)) + def get_nfs_timeout(other_config): nfs_timeout = 100 From 332cc6810d81410f554c0929dd559394a474c9df Mon Sep 17 00:00:00 2001 From: BenjiReis Date: Thu, 13 Jul 2023 10:56:31 +0200 Subject: [PATCH 3/4] rebaseme: fix typos and coding style Signed-off-by: BenjiReis --- drivers/nfs.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/nfs.py b/drivers/nfs.py index c98145fac..e41c1ac79 100644 --- a/drivers/nfs.py +++ b/drivers/nfs.py @@ -51,7 +51,7 @@ NFS_SERVICE_WAIT = 30 NFS_SERVICE_RETRY = 6 -NSFv4_PSEUDOFS = "/" +NFS4_PSEUDOFS = "/" NFS4_TMP_MOUNTPOINT = "/tmp/mnt" class NfsException(Exception): @@ -191,7 +191,7 @@ def _scan_exports_nfs3(target, dom, element): for val in util.pread2(cmd).split('\n'): if not len(val): continue - entry = dom.createElement('Export') + entry = dom.createElement("Export") element.appendChild(entry) subentry = dom.createElement("Target") @@ -222,11 +222,11 @@ def _scan_exports_nfs4_only(target, transport, dom, element): """ mountpoint = "%s/%s" % (NFS4_TMP_MOUNTPOINT, target) - soft_mount(mountpoint, target, NSFv4_PSEUDOFS, transport, nfsversion='4') + soft_mount(mountpoint, target, NFS4_PSEUDOFS, transport, nfsversion="4") paths = os.listdir(mountpoint) - unmount(mountpoint, NSFv4_PSEUDOFS) + unmount(mountpoint, NFS4_PSEUDOFS) for path in paths: - entry = dom.createElement('Export') + entry = dom.createElement("Export") element.appendChild(entry) subentry = dom.createElement("Target") @@ -263,7 +263,7 @@ def scan_exports(target, transport): except Exception: util.SMlog("Unable to scan exports with NFSv4 pseudo FS mount") - raise NfsException('Failed to read NFS export paths from server %s' % + raise NfsException("Failed to read NFS export paths from server %s" % (target)) @@ -311,7 +311,7 @@ def _get_supported_nfs_version_rpcinfo(server): Using NFS3 services. """ - valid_versions = set(['3', '4']) + valid_versions = set(["3", "4"]) cv = set() ns = util.pread2([RPCINFO_BIN, "-s", "%s" % server]) ns = ns.split("\n") @@ -330,9 +330,9 @@ def _is_nfs4_supported(server, transport): try: mountpoint = "%s/%s" % (NFS4_TMP_MOUNTPOINT, server) - soft_mount(mountpoint, server, NSFv4_PSEUDOFS, transport, nfsversion='4') - util.pread2([NFS_STAT, '-m']) - unmount(mountpoint, NSFv4_PSEUDOFS) + soft_mount(mountpoint, server, NFS4_PSEUDOFS, transport, nfsversion='4') + util.pread2([NFS_STAT, "-m"]) + unmount(mountpoint, NFS4_PSEUDOFS) return True except Exception: return False @@ -343,15 +343,15 @@ def get_supported_nfs_versions(server, transport): try: return _get_supported_nfs_version_rpcinfo(server) except Exception: - util.SMlog("Unable to obtain list of valid nfs versions with %s, trying NSFv4" % RPCINFO_BIN) + util.SMlog("Unable to obtain list of valid nfs versions with %s, trying NFSv4" % RPCINFO_BIN) # NFSv4 only if _is_nfs4_supported(server, transport): - return ['4'] + return ["4"] else: - util.SMlog("Unable to obtain list of valid nfs versions with NSFv4 pseudo FS mount") + util.SMlog("Unable to obtain list of valid nfs versions with NFSv4 pseudo FS mount") - raise NfsException('Failed to read supported NFS version from server %s' % + raise NfsException("Failed to read supported NFS version from server %s" % (server)) From 7b86cb3e70e7d1782a1adcb783078fbc703acf3d Mon Sep 17 00:00:00 2001 From: BenjiReis Date: Tue, 25 Jul 2023 15:09:06 +0200 Subject: [PATCH 4/4] rebaseme: noramlize naming Signed-off-by: BenjiReis --- drivers/nfs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nfs.py b/drivers/nfs.py index e41c1ac79..817456e4f 100644 --- a/drivers/nfs.py +++ b/drivers/nfs.py @@ -216,7 +216,7 @@ def _scan_exports_nfs3(target, dom, element): return dom -def _scan_exports_nfs4_only(target, transport, dom, element): +def _scan_exports_nfs4(target, transport, dom, element): """ Scan target and return an XML DOM with target, path and accesslist. Using NFS4 only pseudo FS. """ @@ -259,7 +259,7 @@ def scan_exports(target, transport): # NFSv4 only try: - return _scan_exports_nfs4_only(target, transport, dom, element) + return _scan_exports_nfs4(target, transport, dom, element) except Exception: util.SMlog("Unable to scan exports with NFSv4 pseudo FS mount")