NAME
Net::LibNFS - User-land NFS in Perl via libnfs
SYNOPSIS
Create an NFS context and configure it:
my $nfs = Net::LibNFS->new()->set(
version => 4,
client_name => 'my-nfs-client-name',
);
Blocking I/O:
# Connect to the NFS server:
#
$nfs->mount('some.server.name', '/the-mount-path');
# Open a directory:
#
my $dh = $nfs->opendir('path/to/dir');
# Print the names of directory members.
#
while (my $dir_obj = $dh->read()) { # NB: read() returns an object!
print "Name: ", $dir_obj->name(), $/;
}
$nfs->umount();
Non-blocking I/O, using IO::Async:
my $loop = IO::Async::Loop->new();
my $nfsa = $nfs->io_async($loop);
$nfsa->mount('some.server.name', '/the-mount-path')->then( sub {
return $nfsa->opendir('path/to/dir');
} )->then( sub ($dh) {
while (my $dir_obj = $dh->read()) {
print "Name: ", $dir_obj->name(), $/;
}
} )->then( sub {
$nfsa->umount();
} )->finally( sub { $loop->stop() } );
$loop->run();
(AnyEvent and Mojolicious are also supported.)
DESCRIPTION
libnfs allows you to access NFS shares in user-space. Thus you can read & write files via NFS even if you can’t (or just would rather not) mount(8) them locally.
LINKING
If a shared libnfs is available and is version 5.0.0 or later we’ll link (dynamically) against that. Otherwise we try to compile our own libnfs and bundle it (statically).
A shared libnfs is usually preferable because it can receive updates on its own; a static libnfs locks you into that version of the library until you rebuild Net::LibNFS.
If you have a usable shared libnfs but for some reason still want to bundle a custom-built static one, set NET_LIBNFS_LINK_STATIC
to a truthy value in the environment as you run this distribution’s Makefile.PL.
CHARACTER ENCODING
All strings for Net::LibNFS are byte strings. Take care to decode/encode appropriately, and be sure to test with non-ASCII text (like thîß
).
Of note: NFSv4’s official specification stipulates that filesystem paths should be valid UTF-8, which suggests that this library might express paths as character strings rather than byte strings. (This assumedly facilitates better interoperability with Windows and other OSes whose filesystems are conceptually Unicode.) In practice, however, some NFS servers appear not to care about UTF-8 validity. In that light, and for consistency with general POSIX practice, we stick to byte strings.
Nonetheless, for best results, ensure all filesystem paths are valid UTF-8.
STATIC FUNCTIONS
@exports = mount_getexports( $SERVERNAME [, $TIMEOUT] )
Returns a list of hashrefs. Each hashref has dir
(string) and groups
(array of strings).
@addresses = find_local_servers()
Returns a list of addresses (as strings).
METHODS: GENERAL
$obj = CLASS->new()
Instantiates this class.
$obj = OBJ->set( @OPTS_KV )
A setter for multiple settings; e.g., where libnfs exposes nfs_set_version()
, here you pass version
with the appropriate value.
Recognized options are as follows. (Some may be unavailable if you use an older, shared libnfs.)
version
client_name
andverifier
(NFSv4 only)tcp_syncnt
,uid
,gid
,debug
,auto_traverse_mounts
,dircache
,autoreconnect
,timeout
,nfsport
,mountport
unix_authn
(arrayref) - Sets UID, GID, and auxiliary GIDs at once. Clobbers (and is clobbered by)uid
andgid
.pagecache
,pagecache_ttl
,readahead
readmax
,writemax
readdir_buffer
- Sets the maximum buffer size forREADDIRPLUS
(which is used by OBJ->opendir). Can be a two-element arrayref to setdircount
andmaxcount
independently or an unsigned integer to set both to the same value.
$old_umask = OBJ->umask( $NEW_UMASK )
Like Perl’s built-in.
$cwd = OBJ->getcwd()
Returns OBJ’s current directory.
METHODS: NON-BLOCKING I/O
This library implements non-blocking I/O by deriving a separate NFS context object from the “plain” (blocking-I/O) one.
The following methods all return a Net::LibNFS::Async instance:
$ASYNC_OBJ = OBJ->io_async( $LOOP )
$LOOP is an IO::Async::Loop instance.
$ASYNC_OBJ = OBJ->anyevent()
Unlike io_async()
, this doesn’t require a loop object because AnyEvent’s context is a singleton.
$ASYNC_OBJ = OBJ->mojo( [$REACTOR] )
$REACTOR (a Mojo::Reactor instance) is optional; the default is Mojo’s default reactor.
METHODS: GETTERS
queue_length()
get_readmax()
,get_writemax()
get_version()
(i.e., the active NFS version)getcwd()
CONSTANTS
NFS4_F_SETLK
,NFS4_F_SETLKW
,F_RDLCK
,F_WRLCK
, &F_UNLCK
- See Net::LibNFS::Filehandle’sfcntl()
.
METHODS: BLOCKING I/O
$obj = OBJ->mount( $SERVERNAME, $EXPORTNAME )
Attempts to contact $SERVERNAME and set OBJ to access $EXPORTNAME.
Returns OBJ.
$obj = OBJ->umount()
Releases the current NFS connection.
Returns OBJ.
$stat_obj = OBJ->stat( $PATH )
Like Perl’s stat()
but returns a Net::LibNFS::Stat instance.
$stat_obj = OBJ->lstat( $PATH )
Like stat()
above but won’t follow symbolic links.
$nfs_fh = OBJ->open( $PATH, $FLAGS [, $MODE] )
Opens a file and returns a Net::LibNFS::Filehandle instance to interact with it.
$obj = OBJ->mkdir( $PATH [, $MODE] )
Creates a directory.
Returns OBJ.
$obj = OBJ->rmdir( $PATH )
Deletes a directory.
Returns OBJ.
$obj = OBJ->chdir( $PATH )
Changes OBJ’s directory.
Returns OBJ.
$obj = OBJ->mknod( $PATH, $MODE, $DEV )
Like mknod(2).
Returns OBJ.
$obj = OBJ->unlink( $PATH )
Deletes a file.
Returns OBJ.
$nfs_dh = OBJ->opendir( $PATH )
Opens a directory and returns a Net::LibNFS::Dirhandle instance to read from it.
$statvfs_obj = OBJ->statvfs( $PATH )
Like statvfs(2). Returns a Net::LibNFS::StatVFS instance.
$destination = OBJ->readlink( $PATH )
Reads a symlink directly.
$obj = OBJ->chmod( $PATH, $MODE )
Sets a path’s mode.
Returns OBJ.
$obj = OBJ->lchmod( $PATH, $MODE )
Like chmod()
above but won’t follow symbolic links.
Returns OBJ.
$obj = OBJ->chown( $PATH, $UID, $GID )
Sets a path’s ownership.
Returns OBJ.
$obj = OBJ->utime( $PATH, $ATIME, $MTIME )
Updates $PATH’s atime & mtime. A time can be specified as either:
A nonnegative number (not necessarily an integer).
A reference to a 2-member array of nonnegative integers: seconds and microseconds.
Returns OBJ.
$obj = OBJ->lutime( $PATH, $ATIME, $MTIME )
Like utime()
above but can operate on symlinks.
Returns OBJ.
$obj = OBJ->lchown( $PATH, $MODE )
Like chown()
above but won’t follow symbolic links.
Returns OBJ.
$obj = OBJ->link( $OLDPATH, $NEWPATH )
Creates a hard link.
Returns OBJ.
$obj = OBJ->symlink( $OLDPATH, $NEWPATH )
Creates a symbolic link.
Returns OBJ.
$obj = OBJ->rename( $OLDPATH, $NEWPATH )
Renames a filesystem path.
Returns OBJ.
UNIMPLEMENTED
The following libnfs features are unimplemented here:
Authentication: Would be nice!
URL parsing: Seems redundant with URI.
creat()
&create()
: These are redundant withopen()
.access()
&access2()
: Merely knowing whether a given file/directory is accessible isn’t as useful as it may seem because by the time you actually use the resource the permissions/ownership could have changed. To prevent that race condition it’s better just toopen()
/opendir()
and handle errors accordingly.lockf()
: Apparently redundant withfcntl()
-based locks save for the lock-test functionality, which is generally a misstep for the same reason asaccess()
above: by the time you use the resource—in this case, request a lock on the file—the system state may have changed.
SEE ALSO
RFC 7530 is, as of this writing, NFSv4’s official definition.
LICENSE & COPYRIGHT
Copyright 2022 Gasper Software Consulting. All rights reserved.
Net::LibNFS is licensed under the same terms as Perl itself (cf. perlartistic); HOWEVER, since Net::LibNFS links to libnfs, use of Net::LibNFS may imply acceptance of libnfs’s own copyright terms. See libnfs/COPYING in this distribution for details.