NFS_UTIL(3)
π NFS_UTIL(3) π
bestie welcome to the manual page for nfs_util, straight out of nfs_util 2.9. it's giving reference material. it's giving "i will read this at 2am while my test is failing." let's go π«Ά
β¨ NAME β¨
nfstest.nfs_util β the NFS utilities module. iconic. no notes. π
πΈ DESCRIPTION πΈ
okay so this module hands you a whole little toolkit for testing NFS, and honestly? it's a lot and it's good.
it gives you methods to start a packet trace, stop the packet trace, and then open the packet trace back up for analysis. it also gives you a mechanism to enable NFS/RPC kernel debug and save the log messages so you can dig into them later. iykyk.
on top of that? it's got methods for finding specific NFSv4 operations inside the packet trace. yeah. it's that girl. π₯
π CLASSES π
class NFSUtil(nfstest.host.Host)
NFSUtil object β¨
NFSUtil() -> New NFSUtil object
π« Usage
from nfstest.nfs_util import NFSUtil
# Create object for local host
x = NFSUtil()
# Create client host object
clientobj = x.create_host('192.168.0.11')
# Use buffered matching on packets
x.set_pktlist()
# Get the next LOOKUP packets
pktcall, pktreply = x.find_nfs_op(OP_LOOKUP)
# Get OPEN information for the given file name
fh, open_stid, deleg_stid = x.find_open(filename="file1")
# Get address and port number from universal address string
ipaddr, port = x.get_addr_port(addr)
# Get packets and DS list for GETDEVICEINFO
pktcall, pktreply, dslist = x.find_getdeviceinfo()
# Get packets for EXCHANGE_ID
pktcall, pktreply = x.find_exchange_id()
# Get the NFS operation object from the given packet
getfh = x.getop(x.pktreply, OP_GETFH)
# Get the stateid which must be used by I/O operations
stateid = x.get_stateid("file1")
# Get the client id
clientid = x.get_clientid()
# Get the session id for the given clientid
sessionid = x.get_sessionid(clientid=clientid)
# Get the root file handle from PUTROOTFH for the given session id
x.get_rootfh(sessionid=sessionid)
# Get the file handle for the given path
dirfh = x.get_pathfh("/vol1/data")
# Display the state id in CRC32 format
stidstr = x.stid_str(stateid)
# Get the number of bytes available in the given directory
freebytes = x.get_freebytes("/mnt/t")
π οΈ Methods defined here π οΈ
__del__(self)
Destructor. it's the goodbye method. the farewell era. π¦
__init__(self, **kwargs)
Constructor.
Initialize the object's private data. very "let me set up my little world first." π
cleanup(self)
Gracefully stop the packet trace and un-reference all client objects. tidy bestie behavior. we love a clean exit. β¨
create_host(self, host, **kwargs)
Create a client host object and set defaults. boom, new host, welcome to the party π
find_exchange_id(self, **kwargs)
Find the call and its corresponding reply for the NFSv4 EXCHANGE_ID going to the server specified by the ipaddr and port.
ipaddrβ Destination IP address [default:self.server_ipaddr]portβ Destination port [default:self.port]
Store the callback IP/TCP expression in object attribute cb_dst.
Return a tuple: (pktcall, pktreply).
find_getdeviceinfo(self, deviceid=None, usecache=True)
Find the call and its corresponding reply for the NFSv4 GETDEVICEINFO going to the server specified by the ipaddr for self.server and port given by self.port.
deviceidβ Look for an specificdeviceid[default: anydeviceid]usecacheβ IfGETDEVICEINFOis not found, look for it in the cache, and ifdeviceidisNoneuse the one found inself.layout. [default:True]
Return a tuple: (pktcall, pktreply, dslist).
find_layoutget(self, filehandle, status=0)
Find the call and its corresponding reply for the NFSv4 LAYOUTGET of the given file handle going to the server specified by the ipaddr for self.server and port given by self.port.
Return a tuple: (layoutget, layoutget_res).
Layout information is stored in object attribute "layout".
find_layoutrecall(self, status=0)
Find the NFSv4 CB_LAYOUTRECALL call and return its reply.
The reply must also match the given status. π
find_nfs_op(self, op, **kwargs)
Find the call and its corresponding reply for the specified NFSv4 operation going to the server specified by the ipaddr and port.
The reply must also match the given status. Also the following object attributes are defined: pktcall referencing the packet call, while pktreply referencing the packet reply.
opβ NFS operation to findipaddrβ Destination IP address [default:self.server_ipaddr]. A value ofNonematches any IP addressportβ Destination port [default:self.port]. A value ofNonematches any destination portprotoβ Protocol [default:self.proto]matchβ Match string to include [default:'']statusβ Match the status of the operation [default:0]. A value ofNonematches any statussrc_ipaddrβ Source IP address [default:None]. A value ofNonematches any IP addressmaxindexβ The match fails if packet index hits this limit [default:None]. A value ofNonemeans there is no limitcall_onlyβ Find the call only [default:False]first_callβ Return on first call even if reply is not found [default:False]last_callβ Return last call even if reply is not found [default:False]nfs_versionβ NFS version to use in search [default: mounted NFS version]
Return a tuple: (pktcall, pktreply).
find_open(self, **kwargs)
Find the call and its corresponding reply for the NFSv4 OPEN of the given file going to the server specified by the ipaddr and port.
The following object attributes are defined: opencall and pktcall, both referencing the packet call, while openreply and pktreply, both referencing the packet reply.
In the case for NFSv3, search for LOOKUP or CREATE to get the file handle.
filenameβ Find open call and reply for this file [default:None]claimfhβ Find open call and reply for this file handle usingCLAIM_FH[default:None]ipaddrβ Destination IP address [default:self.server_ipaddr]portβ Destination port [default:self.port]protoβ Protocol [default:self.proto]deleg_typeβ Expected delegation type on reply [default:None]deleg_stateidβ Delegation stateid expected on call indelegate_cur_info[default:None]fhβ Find open call and reply for this file handle when usingdeleg_stateid, or as the directory FH whendeleg_stateidis not set [default:None]src_ipaddrβ Source IP address [default: any IP address]maxindexβ The match fails if packet index hits this limit [default: no limit]anyclaimβ Find open for either regular open or usingdelegate_cur_info[default:False]nfs_versionβ NFS version to use in search [default: mounted NFS version]
bestie, you must specify eitherfilename,claimfh, or both. no skipping this one. π
Return a tuple: (filehandle, open_stateid, deleg_stateid).
get_abs_offset(self, offset, ds_index=None)
Get the real file offset given by the (read/write) offset on the given data server index, taking into account the type of layout (dense/sparse), the stripe_size, first stripe index and the number of filehandles.
The layout information is taken from object attribute layout.
get_addr_port(self, addr)
Get address and port number from a universal address string. π«
get_clientid(self, **kwargs)
Return the client id for the given IP address and port number.
ipaddrβ Destination IP address [default:self.server_ipaddr]portβ Destination port [default:self.port]
get_filehandle(self, ds_index)
Return the filehandle from the layout list of filehandles. π
get_freebytes(self, dir=None)
Get the number of bytes available in the given directory.
It takes into account the effective user running the test. The root user is allowed to use all the available disk space on the device; on the other hand, a regular user is allowed a little bit less. β¨
get_pathfh(self, path, **kwargs)
Return the file handle for the given path by searching the packet trace for every component in the path.
The file handle for each component is used to search for the file handle in the next component. one by one, bestie, we get there π§
pathβ File system pathdirfhβ Directory file handle to start with [default:None]ipaddrβ Destination IP address [default:self.server_ipaddr]portβ Destination port [default:self.port]protoβ Protocol [default:self.proto]
get_rootfh(self, **kwargs)
Return the root file handle from PUTROOTFH.
sessionidβ Search thePUTROOTFHtied to this session id [default:None]ipaddrβ Destination IP address [default:self.server_ipaddr]portβ Destination port [default:self.port]
get_sessionid(self, **kwargs)
Return the session id for the given IP address and port number.
clientidβ Search theCREATE_SESSIONtied to this client id [default:None]ipaddrβ Destination IP address [default:self.server_ipaddr]portβ Destination port [default:self.port]
get_stateid(self, filename, **kwargs)
Search the packet trace for the filename given to get the OPEN, so all related state ids can be searched.
A couple of object attributes are defined: one is the correct state id that should be used by I/O operations. The second is a dictionary table which maps the state id to a string identifying if the state id is an open, lock or delegation state id. π
ipaddrβ Destination IP address [default:self.server_ipaddr]portβ Destination port [default:self.port]noresetβ Do not reset the state id map [default:False]writeβ Search for a write delegation/lock stateid ifTrue, or a read delegation/lock stateid ifFalse. Default is to search for any type [default:None]
getop(self, pkt, op)
Get the NFS operation object from the given packet. β
match_nfs_version(self, nfs_version, post=True)
Return the match string to search for the correct NFS version.
nfs_versionβ NFS version to use in search.postβ Add"and"conjunction at the end of the matching string if this is true. Add it at the beginning if it is false. If this is set toNonejust return the matching string.
okay and that's part one bestie, we're not done yet β more is coming so don't go anywhere π
nfs_op(self, nfs4, nfs3)
hands you back the right item depending on what NFS version is actually mounted π
nfs_op_name(self, op)
give it an op and it returns the name for the given NFSv4 operation or NFSv3 procedure. slay.
set_pktlist(self, **kwargs)
Sets the current packet list for buffered matching β and the way this works is that the match method will only use this list instead of getting the next packet from the packet trace file. The default vibe is to get all packets unless any of the arguments is given. β¨
NOTE: all READ reply data and all WRITE request data is discarded to avoid having memory issues. π like, it's for your own good bestie.
layerβ Comma separated list of layers to include [default:'nfs']opsβ List of NFSv4 operations to include in the packet list [default:None]cbsβ List of NFSv4 callback operations to include in the packet list [default:None]procsβ List of NFSv3 procedures to include in the packet list [default:None]maxindexβ Include packets up to but not including the packet indexed by this argument [default:None]. A value ofNonemeans there is no limit π¦pktdispβ Display all cached packets [default:False]
stid_str(self, stateid)
Displays the state id in CRC32 format. cute and compact, we love.
verify_close(self, filehandle, stateid, pindex=None)
Verifies CLOSE is sent to the server. Also makes sure there's only one CLOSE call sent. Also, the following object attributes get defined: pktcall references the first CLOSE call while pktreply references the first CLOSE reply. two attributes, one iconic duo π«Ά
filehandleβ Find CLOSE for this file handlestateidβ Open stateid expectedpindexβ Packet index where to start the search [default:None]
verify_commit(self, ipaddr, port, filehandle, init=False)
Verifies commits are properly sent to the server specified by the given ipaddr and port. fr fr.
ipaddrβ Destination IP address of MDS or DSportβ Destination port number of MDS or DSfilehandleβ Find commits for this file handleinitβ Initialized test variables [default:False]- Return the number of commits sent to the server.
verify_create_session(self, ipaddr, port, ds=False, nocreate=False, ds_index=None, exchid_status=0, cs_status=0)
Verifies the initial connection to the metadata server (MDS)/data server (DS). Then it verifies whether EXCHANGE_ID, CREATE_SESSION, RECLAIM_COMPLETE, GETATTR asking for FATTR4_LEASE_TIME, and GETATTR asking for FATTR4_FS_LAYOUT_TYPES are all sent or not to the server. it's giving thorough π
ipaddrβ Destination IP address of MDS or DSportβ Destination port number of MDS or DSdsβTrueifipaddr/portdefines a DS, otherwise MDS [default:False]nocreateβTrueif expecting the client NOT to sendEXCHANGE_ID,CREATE_SESSION, andRECLAIM_COMPLETE. Otherwise, verify all these operations are sent by the client [default:False]ds_indexβ DS index used for displaying purposes only [default:None]exchid_statusβ Expected status forEXCHANGE_ID[default:0]cs_statusβ Expected status forCREATE_SESSION[default:0]- Return the
sessionidβ and it's also stored in the object attributesessionid. bestie keeps a copy, obviously π
verify_io(self, iomode, stateid, ipaddr=None, port=None, proto=None, src_ipaddr=None, filehandle=None, ds_index=None, init=False, maxindex=None, pattern=None)
Verifies I/O is sent to the server specified by the ipaddr and port.
iomodeβ Verify reads (iomode == 1) or writes (iomode == 2)stateidβ Expected stateid to use in all I/O requestsipaddrβ Destination IP address of MDS or DS [default: do not match destination]portβ Destination port number of MDS or DS [default: do not match destination port]protoβ Protocol [default:self.proto]src_ipaddrβ Source IP address of request [default: do not match source]filehandleβ Find I/O for this file handle. This option is used when verifying I/O sent to the MDS [default: usefilehandlegiven byds_index]ds_indexβ Data server index. This option is used when verifying I/O sent to the DS βfilehandleis taken fromx.layoutfor this index [default:None]initβ Initialized test variables [default:False]maxindexβ The match fails if packet index hits this limit [default: no limit]patternβ Data pattern to compare [default: default data pattern]- Return the number of I/O operations sent to the server.
verify_layoutcommit(self, filehandle, filesize)
Verifies layoutcommit is properly sent to the server specified by the ipaddr for self.server and port given by self.port. Verifies a GETATTR asking for file size is sent within the same compound as the LAYOUTCOMMIT. Verifies GETATTR returns the correct size for the file. no cap, all three checks.
filehandleβ Findlayoutcommitfor this file handlefilesizeβ Expected size of file
verify_layoutget(self, filehandle, iomode, riomode=None, status=0, offset=None, length=None, openfh={})
Verifies the client sends a LAYOUTGET for the given file handle.
filehandleβ FindLAYOUTGETfor this file handleiomodeβ Expected I/O mode forLAYOUTGETcallriomodeβ Expected I/O mode forLAYOUTGETreply if specified, else verify reply I/O mode is equal to call I/O mode ifiomode == 2. Ifiomode == 1, the reply I/O mode could be equal to1or2statusβ Expected status forLAYOUTGETreply [default:0]offsetβ Expected layout range forLAYOUTGETreply [default:None]lengthβ Expected layout range forLAYOUTGETreply [default:None]openfhβ Open information for file (filehandle, open/delegation/lock stateids, and delegation type) if file has been previously opened [default:{}]
If both offset and length are not given, verify LAYOUTGET reply should be a full layout [0, NFS4_UINT64_MAX]. If only one is provided, the following defaults are used: offset = 0, length = NFS4_UINT64_MAX.
Return True if a layout is found and it is supported. β¨
verify_layoutreturn(self, layout_list)
Verifies layoutreturn is properly sent to the server specified by the ipaddr for self.server and port given by self.port.
layout_listβ List of layouts
verify_pnfs_supported(self, filehandle, server_type, path=None, fstype=False)
Verifies pNFS is supported in the given server path. Finds the GETATTR asking for FATTR4_SUPPORTED_ATTRS (bit 0) and its reply to verify FATTR4_FS_LAYOUT_TYPES is supported for the path. Then it finds the GETATTR asking for FATTR4_FS_LAYOUT_TYPES (bit 62) to verify LAYOUT4_NFSV4_1_FILES is returned in fs_layout_types. the way it digs through those bitmaps π§
verify_stripe(self, offset, size, ds_index)
Verifies if read/write is sent to the correct data server according to stripe size, first stripe index and the number of filehandles. The layout information is taken from object attribute layout.
offsetβ Real file offsetsizeβ I/O sizeds_indexβ Data server index- Return
Trueif stripe is correctly verified,Falseotherwise.
Static methods defined here
bitmap_str(bitmap, count, bmap, blist)
Returns the string representation of bitmap.
bitmapβ Bitmap to convertcountβ Number of occurrences ofbitmapbmapβ Dictionary mapping the bits to stringsblistβ List of all possible bit combinations
iomode_str(iomode)
Returns a string representation of iomode. This could be run as an instance or class method β flexible queen π
π SEE ALSO π
baseobj(3), formatstr(3), nfstest.host(3), nfstest.utils(3), packet.nfs.nfs3_const(3), packet.nfs.nfs4(3), packet.nfs.nfs4_const(3), packet.unpack(3)
π¦ BUGS π¦
No known bugs. periodt. π β¨
π AUTHOR π
Jorge Mora (mora@netapp.com)
and that's a wrap on the whole NFS_UTIL(3) page bestie π«Ά this was NFStest 3.2, dated 21 March 2023 β go forth and verify those packets, you absolute icon ππΈ
π¦ where this page comes from
- debian trixie: nfstest 3.2-3
- fedora 43: NFStest 3.2-14.fc43 Β· GPL-2.0-or-later
- fedora 44: NFStest 3.2-16.fc44 Β· GPL-2.0-or-later
- ubuntu noble: nfstest 3.2-2
- ubuntu questing: nfstest 3.2-3
- ubuntu resolute: nfstest 3.2-3build1
- ubuntu stonking: nfstest 3.2-5
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms