From b226b7bc5544eaf6c89d01551ea6776a5d5208e8 Mon Sep 17 00:00:00 2001 From: BenjiReis Date: Thu, 13 Jul 2023 10:46:21 +0200 Subject: [PATCH] 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 9524111f..88ea368f 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