ukfs
provides a high-level pathname based interface for accessing file systems.
If a lower level interface it desired,
rump(3)
should be used directly.
However, much like system calls, the interfaces of
,
are self-contained and require no tracking and release of resources.
The only exception is the file system handle
struct
ukfs
which should be released after use.
int
)
int
ukfs_modload(const char *fname
)
int
ukfs_modload_dir(const char *dirname
)
ssize_t
ukfs_vfstypes(char *buf, size_t buflen
)
struct
ukfs
*
ukfs_mount(
const char *vfsname
const char *devpath
const char *mounpath
int mntflags
void *arg
size_t alen
)
void
ukfs_release(struct ukfs *ukfs
, int flags
)
ukfs_init()
intializes the library and must be called once per process using
.
ukfs_modload()
is used at runtime to dynamically load a library which contains a
file system module.
For this to succeed, the
rump(3)
library and the module targetted must be compiled with compatible kernel
versions and the application must be dynamically linked.
Additionally, since this routine does not handle dependencies, all the
dependencies of the library must be loaded beforehand.
The routine returns -1 for fatal error, 0 for dependency failure and 1
for success.
ukfs_modload_dir()
loads all
rump(3)
file system modules in directory
dirname
.
It looks for libraries which begin with
librumpfs_
and end in
.so
.
The routine tries to handle dependencies by retrying to load libraries
which failed due to dependencies.
ukfs_modload_dir()
returns the number of vfs modules loaded or sets errno and
returns -1 in case of a fatal error in directory searching.
In case a fatal error occurs after some modules have already been
loaded, the number of loaded module is returned.
Fatal errors in loading the modules themselves are ignored and
ukfs_modload(
)
should be used directly if finegrained error reporting is desired.
It should be noted that the above routines affect the whole process, not just a specific instance of . It is preferable to call them from only one thread, as the underlying dynamic library interfaces may not be threadsafe.
ukfs_vfstypes()
queries the available file system types and returns a nul-terminated
list of types separated by spaces in
buf
.
The format of the list is equivalent to the one returned by
sysctl(3)
on the name
vfs.generic.fstypes
.
The function returns the length of the string without the trailing nul
or -1 for error.
Notably, the return value 0 means there are no file systems available.
If there is not enough room in the caller's buffer for all file system
types, as many as fit will be returned.
ukfs_mount()
intializes a file system image.
The handle resulting from the operation is passed to all other routines
and identifies the instance of the mount analoguous to what a pathname
specifies in a normally mounted file system.
The parameters are the following:
MOUNT_FFS
.
UKFS_DEFAULTMP
is the correct path.
MNT_RDONLY
.
In addition to generic parameters, file system specific parameters such as
MNT_SOFTDEP
(ffs) may be passed here.
vfsname
expects.
ukfs_release()
releases the resources associated with
ukfs
.
If
flags
is
UKFS_RELFLAG_NOUNMOUNT
,
the file system is not unmounted.
This is required if the file system has already been unmounted due
to prior activity, otherwise 0 should be passed.
int
struct ukfs *ukfs
, const char *path
)
int
ukfs_getdents(
struct ukfs *ukfs
const char *dirname
off_t *off
uint8_t *buf
size_t bufsize
)
ssize_t
ukfs_read(
struct ukfs *ukfs
const char *filename
off_t off
uint8_t *buf
size_t bufsize
)
ssize_t
ukfs_write(
struct ukfs *ukfs
const char *filename
off_t off
uint8_t *buf
size_t bufsize
)
int
ukfs_create(struct ukfs *ukfs
, const char *filename
, mode_t mode
)
int
ukfs_mknod(struct ukfs *ukfs
, const char *path
, mode_t mode
, dev_t dev
)
int
ukfs_mkfifo(struct ukfs *ukfs
, const char *path
, mode_t mode
)
int
ukfs_mkdir(struct ukfs *ukfs
, const char *filename
, mode_t mode
)
int
ukfs_remove(struct ukfs *ukfs
, const char *filename
)
int
ukfs_rmdir(struct ukfs *ukfs
, const char *filename
)
int
ukfs_link(struct ukfs *ukfs
, const char *filename
, const char *f_create
)
int
ukfs_symlink(
struct ukfs *ukfs
const char *filename
const char *linkname
)
ssize_t
ukfs_readlink(
struct ukfs *ukfs
const char *filename
char *linkbuf
size_t buflen
)
int
ukfs_rename(struct ukfs *ukfs
, const char *from
, const char *to
)
int
ukfs_stat(
struct ukfs *ukfs
const char *filename
struct stat *file_stat
)
int
ukfs_lstat(
struct ukfs *ukfs
const char *filename
struct stat *file_stat
)
int
ukfs_chmod(struct ukfs *ukfs
, const char *filename
, mode_t mode
)
int
ukfs_lchmod(struct ukfs *ukfs
, const char *filename
, mode_t mode
)
int
ukfs_chown(
struct ukfs *ukfs
const char *filename
uid_t uid
gid_t gid
)
int
ukfs_lchown(
struct ukfs *ukfs
const char *filename
uid_t uid
gid_t gid
)
int
ukfs_chflags(struct ukfs *ukfs
, const char *filename
, u_long flags
)
int
ukfs_lchflags(struct ukfs *ukfs
, const char *filename
, u_long flags
)
int
ukfs_utimes(
struct ukfs *ukfs
const char *filename
const struct timeval *tptr
)
int
ukfs_lutimes(
struct ukfs *ukfs
const char *filename
const struct timeval *tptr
)
The above routines operate like their system call counterparts and the system call manual pages without the ukfs_ prefix should be referred to for further information on the parameters.
The only call which modifies
ukfs
state is
ukfs_chdir().
It works like
chdir(2)
in the sense that it affects the interpretation of relative paths.
If succesful, all relative pathnames will be resolved starting from the
current directory.
Currently the call affects all accesses to that particular
,
but it might be later changed to be thread private.
int
struct ukfs *ukfs
, const char *pathname
, mode_t mode
)
Builds a directory hierarchy.
Unlike mkdir, the
pathname
argument may contain multiple levels of hierarchy.
It is not considered an error if any of the directories specified exist
already.