.\" $NetBSD: libquota.3,v 1.5 2012/02/13 13:23:29 wiz Exp $
.\"
.\" Copyright (c) 2012 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by David A. Holland.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.Dd February 13, 2012
.Dt LIBQUOTA 3
.Os
.Sh NAME
.Nm libquota ,
.Nm quota_open ,
.Nm quota_close ,
.Nm quota_getmountdevice ,
.Nm quota_getmountpoint ,
.Nm quota_getimplname ,
.Nm quota_getrestrictions ,
.Nm quota_getnumidtypes ,
.Nm quota_getnumobjtypes ,
.Nm quota_idtype_getname ,
.Nm quota_objtype_getname ,
.Nm quota_objtype_isbytes ,
.Nm quota_get ,
.Nm quota_put ,
.Nm quota_delete ,
.Nm quota_opencursor ,
.Nm quotacursor_close ,
.Nm quotacursor_skipidtype ,
.Nm quotacursor_get ,
.Nm quotacursor_getn ,
.Nm quotacursor_atend ,
.Nm quotacursor_rewind ,
.Nm quota_quotaon ,
.Nm quota_quotaoff ,
.Nm quotaval_clear
.Nd disk quota access and control library
.Sh LIBRARY
.Lb libquota
.Sh SYNOPSIS
.In quota.h
.Ft struct quotahandle *
.Fn quota_open "const char *path"
.Ft void
.Fn quota_close "struct quotahandle *qh"
.Ft const char *
.Fn quota_getmountdevice "struct quotahandle *qh"
.Ft const char *
.Fn quota_getmountpoint "struct quotahandle *qh"
.Ft const char *
.Fn quota_getimplname "struct quotahandle *qh"
.Ft unsigned
.Fn quota_getrestrictions "struct quotahandle *qh"
.Ft int
.Fn quota_getnumidtypes "struct quotahandle *qh"
.Ft int
.Fn quota_getnumobjtypes "struct quotahandle *qh"
.Ft const char *
.Fn quota_idtype_getname "struct quotahandle *qh" "int idtype"
.Ft const char *
.Fn quota_objtype_getname "struct quotahandle *qh" "int objtype"
.Ft int
.Fn quota_objtype_isbytes "struct quotahandle *qh" "int objtype"
.Ft int
.Fn quota_get "struct quotahandle *qh" "const struct quotakey *key" "struct quotaval *val"
.Ft int
.Fn quota_put "struct quotahandle *qh" "const struct quotakey *key" "const struct quotaval *val"
.Ft int
.Fn quota_delete "struct quotahandle *qh" "const struct quotakey *key"
.Ft struct quotacursor *
.Fn quota_opencursor "struct quotahandle *qh"
.Ft void
.Fn quotacursor_close "struct quotacursor *qc"
.Ft int
.Fn quotacursor_skipidtype "struct quotacursor *qc" "int idtype"
.Ft int
.Fn quotacursor_get "struct quotacursor *qc" "struct quotakey *key" "const struct quotaval *val"
.Ft int
.Fn quotacursor_getn "struct quotacursor *qc" "struct quotakey *keys" "const struct quotaval *vals" "unsigned maxnum"
.Ft int
.Fn quotacursor_atend "struct quotacursor *qc"
.Ft int
.Fn quotacursor_rewind "struct quotacursor *qc"
.Ft int
.Fn quota_quotaon "struct quotahandle *qh" "int idtype"
.Ft int
.Fn quota_quotaoff "struct quotahandle *qh" "int idtype"
.Ft void
.Fn quotaval_clear "struct quotaval *qv"
.Sh DESCRIPTION
The
.Nm
library provides uniform access to disk quota functionality across all
file systems and file system types.
Programs should be linked with
.Fl lquota lrpcsvc .
.Pp
Quota information is organized as a key/value store, where the key
names a particular limit and the value contains information about that
limit.
The information includes a configured
.Em soft limit ,
.Em hard limit ,
and
.Em grace time ,
as well as the current usage and the expire time of any pending grace
period.
The soft limit may be exceeded temporarily, but only for the length of
time specified; after that further usage is rejected.
The hard limit may not be exceeded.
.Pp
Each mounted file system that supports quotas contains its own
key/value store for quota information.
.Pq The underlying representation may vary.
The library supports get, put, and delete operations, as well as a
cursor interface for iterating an entire store.
It also provides functions for inspecting the properties of a
particular file system's quota implementation.
.Pp
All functionality is accessed by first calling
.Fn quota_open
on a particular volume to get a handle for that volume's quota
information.
Other operations can be called at this point.
The
.Fn quota_close
function should be called when done to release internal resources.
.Ss Data Structures
The key part of the key/value schema is defined as
.Dv struct quotakey ,
which contains the following members:
.Bl -tag -width 4n
.It int qk_idtype
The type of principal (user, group, etc.) to retrieve quota
information for.
.It id_t qk_id
The ID number (uid, gid, etc.) to retrieve quota information for.
.It int qk_objtype
The type of file system resource (blocks, files, etc.) to retrieve
quota information for.
.El
The value part of the key/value schema is defined as
.Dv struct quotaval ,
which contains the following members:
.Bl -tag -width 4n
.It uint64_t qv_softlimit
The soft limit.
.It uint64_t qv_hardlimit
The hard limit.
.It uint64_t qv_usage
The current usage.
.It int64_t qv_expiretime
The time
.Pq in time_t terms
at which the current grace period, if any, expires.
.It int64_t qv_grace
The configured length of grace period.
.El
.Ss Constants
The basic ID and object types are predefined.
.Dv QUOTA_IDTYPE_USER
is the code number for quotas on users;
.Dv QUOTA_IDTYPE_GROUP
is the code number for quotas on groups.
Similarly,
.Dv QUOTA_OBJTYPE_BLOCKS
retrieves limits on file system blocks, while
.Dv QUOTA_OBJTYPE_FILES
retrieves limits on the number of existing files.
.Pp
Some backends support a default configuration; this can be accessed by
using
.Dv QUOTA_DEFAULTID
as the ID number.
.Pp
When no limit is in place, the value
.Dv QUOTA_NOLIMIT
appears in the limit fields of struct quotaval, and if no time is
indicated the value
.Dv QUOTA_NOTIME
appears in the time fields.
.Ss Quota v1
The historic BSD quota implementation for FFS, known as
.Dq quota v1 ,
has additional restrictions and requirements.
All file systems to be mounted with v1 quotas
.Em must
be listed in
.Xr fstab 5
with the
.Dv userquota
and/or
.Dv groupquota
mount options specified.
The tools
.Xr quotacheck 8
and
.Xr quotaon 8
must be used on quota v1 volumes before quotas become fully
operational, and
.Xr quotaoff 8
must be used at system shutdown time.
The
.Nm
library provides access to quota v1 data even before
.Xr quotaon 8
is called by direct access to the on-disk quota information.
However, this method is not recommended.
Note that the
.Dv userquota
and
.Dv groupquota
mount options are read and interpreted at quotaon time, not
.Xr mount 8
time.
This allowed historic implementations to avoid storing the path in the
kernel.
.Ss Semantic Restrictions
Some quota implementations are restricted in their functionality or
semantics.
The following restriction codes are defined to allow
.Nm libquota
client code to adapt or to provide more helpful diagnostic messages.
.Bl -tag -width 4n
.It QUOTA_RESTRICT_NEEDSQUOTACHECK
The quota implementation is a quota v1 system and requires the
old-style quota check and mount process as described in the
previous section.
.It QUOTA_RESTRICT_UNIFORMGRACE
The grace period for how long a quota can be over the soft limit can
be specified only once, globally, for all principals.
It is set via the default
.Pq Dv QUOTA_DEFAULTID
quota entry.
.It QUOTA_RESTRICT_32BIT
The values in struct quotaval are limited to 32 bits wide.
Larger values will be treated as
.Dv QUOTA_NOLIMIT .
.It QUOTA_RESTRICT_READONLY
The quota information is read-only.
Attempts to update it using
.Fn quota_put
or other functions will fail.
.El
.Ss Function Descriptions
.Bl -tag -width 4n
.It Fn quota_open
Open a volume for access with the quota library.
The
.Fa path
may be any file or file system object on the desired volume.
On success, returns a quota handle for further use.
On failure, returns
.Dv NULL
and sets
.Dv errno .
.It Fn quota_close
Close a quota handle previously created with
.Fn quota_open .
.It Fn quota_getmountdevice
Return the path of the device the target volume is mounted from.
This is retrieved with
.Xr statvfs 2 .
.It Fn quota_getmountpoint
Return the path in the directory tree where the target volume is
mounted.
This is retrieved with
.Xr statvfs 2 .
.It Fn quota_getimplname
Return a human-readable string describing the underlying quota
implementation.
Client programs should not attempt to interpret this string.
.It Fn quota_getrestrictions
Return the semantic restriction flags for the underlying quota
implementation.
The possible flags are described above.
.It Fn quota_getnumidtypes
Return the number of ID types supported by this volume.
Will ordinarily be two; ideally code using this library should be
prepared for other values, including possibly one.
However, as of this writing it is difficult to foresee any other
likely ID types beyond users and groups.
.It Fn quota_getnumobjtypes
Return the number of object types supported by this volume.
Will ordinarily be two; ideally code using this library should be
prepared for larger values.
As of this writing there are deployed file systems
.Pq though not in Nx
that support quotas for more than two object types.
.It Fn quota_idtype_getname
Return a printable name for an ID type.
.It Fn quota_objtype_getname
Return a printable name for an object type.
.It Fn quota_objtype_isbytes
Return true if the object type refers to something measured in bytes.
.Pq This can be used for calling Xr humanize_number 3 .
.It Fn quota_get
Return, in
.Fa val ,
the quota information associated with the quota key
.Fa key .
On failure, returns \-1 and sets
.Dv errno .
.It Fn quota_put
Update the quota information associated with the quota key
.Fa key
from the value
.Fa val .
Note that the current usage
.Pq which is maintained by the file system
cannot be updated via
.Nm .
If it becomes incorrect or corrupted,
.Xr quotacheck 8
or
.Xr fsck 8
must be used.
Also note that sufficient privilege is required.
On failure, returns \-1 and sets
.Dv errno .
.It Fn quota_delete
Remove the quota information associated with the quota key
.Fa key .
Depending on the backend implementation this might just blank it out
or might physically remove the quota record from disk.
Note that sufficient privilege is required.
On failure, returns \-1 and sets
.Dv errno .
.It Fn quota_opencursor
Prepare to iterate the store by creating a cursor.
The cursor starts at the beginning of the store.
On success, returns a pointer to a cursor object that can be used with
the quotacursor calls.
On failure, returns
.Dv NULL
and sets
.Dv errno .
.It Fn quotacursor_close
Destroy a cursor previously created with
.Fn quota_opencursor .
This releases internal storage.
.It Fn quotacursor_skipidtype
Hint to the implementation that the caller is not interested in
retrieving records with ID type
.Fa idtype .
As this is a hint, the implementation may ignore it; the caller should
still be prepared to receive and ignore such records.
On failure, returns \-1 and sets
.Dv errno .
.It Fn quotacursor_get
Retrieve the next record
.Pq key and value
from a cursor.
Note that records are not guaranteed to be returned in any particular
order.
On failure, returns \-1 and sets
.Dv errno .
.It Fn quotacursor_getn
Retrieve the next several keys and values from a cursor.
Up to
.Fa maxnum
keys and values will be stored in the arrays pointed to by the
.Fa keys
and
.Fa vals
arguments.
Returns the number of records retrieved.
On failure, returns \-1 and sets
.Dv errno .
.It Fn quotacursor_atend
Returns true if the cursor has reached the end of the quota store.
.It Fn quotacursor_rewind
Resets a cursor to point to the beginning of the quota store, allowing
another pass over the data.
.It Fn quota_quotaon
For old-style quota v1 implementations, this function enables quotas
for the specified ID type.
To ensure that the quota files are consistent with the file system
state,
.Xr quotacheck 8
must have been run beforehand.
As described above, the file system volume must be listed in
.Xr fstab 5
and the corresponding old-style mount option,
.Dv userquota
or
.Dv groupquota ,
must be set therein.
The path name for the quota file is retrieved from
.Xr fstab 5
and passed to the kernel.
This function will fail if used on newer quota implementations with
in-file-system quotas.
.It Fn quota_quotaoff
For old-style quotas, this function disables quotas for the specified
ID type.
This function will fail if used on newer quota implementations with
in-file-system quotas.
.It Fn quotaval_clear
A convenience function for initializing a struct quotaval instance
to the default empty state.
.El
.\" .Sh EXAMPLES
.\" XXX would be nice to have an example, particularly of iteration.
.Sh ERRORS
.\" XXX this is woefully incomplete, particularly about errors that
.\" can be generated inside file systems.
Error conditions include:
.Bl -tag -width Er
.\" .It Bq Er EBUSY
.\" .Fn quota_quotaon
.\" was attempted on a volume that is not a quota v1 volume.
.It Bq Er EDEADLK
An inconsistency was detected during
.Fn quotacursor_get
or
.Fn quotacursor_getn .
The application should discard information collected so far and use
.Fn quotacursor_rewind
to start the iteration over.
.It Bq Er ENOENT
The quota information requested from
.Fn quota_get
does not exist.
.It Bq Er ENXIO
The
.Fa path
passed to
.Fn quota_open
was on a volume whose quota support is not enabled.
.It Bq Er EOPNOTSUPP
The
.Fa path
passed to
.Fn quota_open
was on a volume that has no quota support.
Or, the iterator functions,
.Fn quota_put ,
or other unsupported operations were attempted on an NFS volume,
or on some other volume type that does not support the full
semantic range of quota information.
.El
.Sh SEE ALSO
.Xr quota 1 ,
.Xr edquota 8 ,
.Xr mount_ffs 8 ,
.Xr mount_nfs 8 ,
.Xr quotacheck 8 ,
.Xr quotaon 8 ,
.Xr repquota 8 ,
.Xr rpc.rquotad 8
.Sh HISTORY
The
.Nm
library first appeared in
.Nx 6.0 .
.Sh AUTHORS
The
.Nm
library was written by
.An David A. Holland .