UKFS(3)

UKFS(3) | Library Functions Manual | UKFS(3)

# NAME

`ukfs` —
user kernel file system library interface

# LIBRARY

ukfs Library (libukfs, -lukfs)

# SYNOPSIS

`#include <rump/ukfs.h>`

# DESCRIPTION

The `ukfs` library provides direct access to file systems without having to specially mount a file system. Therefore, accessing a file system through `ukfs` requires no special kernel support apart from standard POSIX functionality. As `ukfs` is built upon rump(3) kernels, all kernel file systems which are supported by rump kernels are available. It allows to write utilities for accessing file systems without having to duplicate file system internals knowledge already present in kernel file system drivers.

`ukfs` provides a high-level pathname based interface for accessing file systems. If a lower level interface it desired, rump(3) kernels should be used directly. However, much like system calls, the interfaces of `ukfs` 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.

# INITIALIZATION

int
  `ukfs_init`()
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 *mountpath, int mntflags, void *arg, size_t alen)
struct ukfs *
  `ukfs_mount_disk`(const char *vfsname, const char *devpath, int partition, const char *mountpath, int mntflags, void *arg, size_t alen)
int
  `ukfs_release`(struct ukfs *ukfs, int flags)

`ukfs_init`() initializes the library and must be called once per process using `ukfs`.

`ukfs_modload`() is used at runtime to dynamically load a library which contains a file system module. For this to succeed, the rump(3) kernel 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) kernel file system components 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 `ukfs`. 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`() initializes 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:

vfsname
  Name of the file system to be used, e.g. `MOUNT_FFS`.
devpath
  Path of file system image. It can be either a regular file, device or, if the file system does not support the concept of a device, an abitrary string, e.g. network address.
mountpath
  Path where the file system is mounted to. This parameter is used only by the file system being mounted. Most of the time `UKFS_DEFAULTMP` is the correct path.
mntflags
  Flags as passed to the mount(2) system call, for example `MNT_RDONLY`. In addition to generic parameters, file system specific parameters such as `MNT_LOG` (ffs) may be passed here.
arg
  File system private argument structure. This is passed directly to the file system. It must match what vfsname expects.
alen
  Size of said structure.

The `ukfs_mount_disk`() function must be used to mount disk-based file systems. It takes the same arguments as `ukfs_mount`(), except for an additional argument signifying the partition number. If the image devpath contains a disklabel, this value specifies the number of the partition within the image used as the file system backend. If devpath does not contain a disklabel, the value `UKFS_PARTITION_NONE` must be used to signal that the file system backend is the entire image.

`ukfs_release`() unmounts the file system and releases the resources associated with ukfs. The return value signals the return value of the unmount operation. If non-zero, ukfs will continue to remain valid. The possible values for flags are:

`UKFS_RELFLAG_NOUNMOUNT`
  Do not unmount file system, just release ukfs handle. Release always succeeds.
`UKFS_RELFLAG_FORCE`
  Forcefully unmount the file system. This means that any busy nodes (due to e.g. `ukfs_chdir`()) will be ignored. Release always succeeds.

# OPERATION

int
  `ukfs_chdir`(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 ukfs, but it might be later changed to be thread private.

# UTILITIES

int
  `ukfs_util_builddirs`(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.

# SEE ALSO

rump(3)

# HISTORY

`ukfs` first appeared in NetBSD 5.0.

# AUTHORS

Antti Kantee <pooka@cs.hut.fi>

# NOTES

`ukfs` was an early attempt at an interface for kernel file systems running in userspace.

March 12, 2018 | NetBSD 9.5