[27524] in Source-Commits

home help back first fref pref prev next nref lref last post

python-afs commit: Add a low-level "fs whereis" function

daemon@ATHENA.MIT.EDU (Jonathan D Reed)
Tue Nov 12 18:27:55 2013

Date: Tue, 12 Nov 2013 18:27:48 -0500
From: Jonathan D Reed <jdreed@MIT.EDU>
Message-Id: <201311122327.rACNRmJs018668@drugstore.mit.edu>
To: source-commits@MIT.EDU

https://github.com/mit-athena/python-afs/commits/df644a5cfd5ed3c399ed6d179b3322f4717967d1
commit df644a5cfd5ed3c399ed6d179b3322f4717967d1
Author: Jonathan Reed <jdreed@mit.edu>
Date:   Wed Oct 30 15:23:25 2013 -0400

    Add a low-level "fs whereis" function
    
    Implement "fs whereis", returning a list of IP addresses (representing
    file servers).  This requires AFS_MAXHOSTS to unpack the list and
    the VIOCWHEREIS pioctl.

 afs/_fs.pyx   |   29 +++++++++++++++++++++++++++++
 afs/_util.pxd |    3 ++-
 2 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/afs/_fs.pyx b/afs/_fs.pyx
index b97a9cd..38f8dc5 100644
--- a/afs/_fs.pyx
+++ b/afs/_fs.pyx
@@ -1,5 +1,7 @@
 from afs._util cimport *
 from afs._util import pyafs_error
+import socket
+import struct
 
 __all__ = ['whichcell',
            '_lsmount',
@@ -82,3 +84,30 @@ def _fid(char *path):
     py_fid['Unique'] = vfid.Fid.Unique
     py_fid['Cell'] = vfid.Cell
     return py_fid
+
+def _whereis(char* path):
+    """
+    _whereis(path) -> list()
+
+    Low-level implementation of the "whereis" command.  Raises
+    OSError, and EINVAL usually indicates the path isn't in AFS.
+    Returns a list of IP addresses.  It is the caller's responsibility
+    to get hostnames if that's desired.  If anything goes wrong converting
+    the 32-bit network numbers into IP addresses, that network number is
+    skipped.  That's probably less than ideal.
+    """
+    cdef char whereis_buf[AFS_PIOCTL_MAXSIZE]
+    cdef object py_result
+
+    py_result = list()
+    pioctl_read(path, VIOCWHEREIS, whereis_buf, sizeof(whereis_buf), 1)
+    hosts = <afs_uint32 *>whereis_buf
+    for j in range(0, AFS_MAXHOSTS):
+        if hosts[j] == 0:
+            break
+        try:
+            py_result.append(socket.inet_ntoa(struct.pack('!L', socket.htonl(hosts[j]))))
+        except:
+            # Oh well
+            pass
+    return py_result
diff --git a/afs/_util.pxd b/afs/_util.pxd
index 94a5943..0263443 100644
--- a/afs/_util.pxd
+++ b/afs/_util.pxd
@@ -36,6 +36,7 @@ cdef extern from "afs/dirpath.h":
 cdef extern from "afs/afs_consts.h":
     enum:
         AFS_PIOCTL_MAXSIZE
+        AFS_MAXHOSTS
 
 cdef extern from "afs/cellconfig.h":
     enum:
@@ -165,7 +166,7 @@ cdef extern from "afs/venus.h":
     enum:
         # PIOCTLS to Venus that we use
         VIOCGETAL, VIOC_GETVCXSTATUS2, VIOCSETAL, VIOC_FILE_CELL_NAME,
-        VIOC_AFS_STAT_MT_PT, VIOCGETVOLSTAT, VIOCGETFID
+        VIOC_AFS_STAT_MT_PT, VIOCGETVOLSTAT, VIOCGETFID, VIOCWHEREIS,
 
 # This is probably a terrible idea, since afsint.h is generated,
 # Specifically, the "real" definition is in afsint.xg, but this

home help back first fref pref prev next nref lref last post