Generic Properties


1	Summary

There are many places in the kernel where the association of a set of variform
properties with some type of object is desireable.  While this is less
efficient than embedding the data in fixed data structures, it provides much
greater flexibility and modularity without being required to modify public
data structures to provide private,or machine dependent functionality.

Generic Properties proposes to solve these issues by providing generic kernel
database management infrastructure for such information.  The primitives
provided can be used either directly or as building blocks for more complex
semantics.

The database infrastructure operates on 5 entities: 

    Databases contain segregated collections of information associated with a
    collection of objects.

    Objects provide a database key for sorting instances of discrete
    properties.

    Properties are ( Object , Name , Data ) tuples contained within separate
    databases.

    Names are Nul terminated strings to identify particular properties.

    Data is an arbitrary aggregation of opaque data.


2	Synopsis

2.0	Public Data Structures

Two new opaque types are defined:

typedef void *kdatabase_t;	-- Database container object.
typedef void *opaque_t;		-- Container for opaque identifier.

2.1	Property Types

PROP_STRING			-- Property is a string.
PROP_INT			-- Property is an integer value.
PROP_ARRAY			-- Property is an array of the 
				   same type of values.
PROP_AGREGATE			-- Property is an agregation of 
				   different types of values.
PROP_CONST			-- Property is constant, do not 
				   allocate storage for the data.

2.3	Functions


   kdatabase_t createpropdb(const char *name);
   void delpropdb(kdatabase_t db);
   int setprop(kdatabase_t db, opaque_t object, const char *name, 
		void *val, size_t len, int type, int wait);
   size_t listobjs(kdatabase_t db, opaque_t *objects, size_t len);
   size_t listprops(kdatabase_t db, opaque_t object, char *names, 
		size_t len);
   size_t getprop(kdatabase_t db, opaque_t object, const char *name,
		void *val, size_t len, int *type);
   int delprop(kdatabase_t db, opaque_t object, const char *name);
   int copyprops(kdatabase_t db, opaque_t source, opaque_t dest, 
			int wait);


3	Description

A database is a container for a set of properties.  It is created with
createpropdb(9) and discarded with delpropdb(9);

A property is a tuple that consists of an opaque identifier (often a pointer
to a kernel data structure), string, and an arbitrary amount of data.  This
tuple is established by setprop(9), retrieved by getprop(9), and destroyed by
delprop(9).

Similar interfaces are provided for manipulating kernel databases for both
inside the kernel as well as a system call interface.  Only root can create or
modify property values, but anyone can query properties.


3.1	New Functionality

kdatabase_t createpropdb(const char *name);

Allocate and initialize a kernel database object, and associate `name' with
the database.  `name' may later be used to access this database from userland
throught the userland database query interface.  This operation may block.
Returns NULL on failure.


void delpropdb(kdatabase_t db);

Destroy and deallocate a kernel database objects and all data within.  This
routine deallocates all properties contained within the database.


int setprop(kdatabase_t db, opaque_t object, const char *name, 
		void *val, size_t len, int type, int wait);

Create a property `name' associated with `object' inside database `db', with a
`len' byte value copied from location `val'.  The database must already have
been initialized with createpropdb(9).  `object' is treated as an opaque
value.  The type field is used to identify what the format of the object is.
This value is usually only used to help programs dump property values into
human readable formats.  If `wait' is zero specified then setprop(9) will not
sleep for resource shortage.  If PROP_CONST is specified in the `type' field,
no storage is allocated for the value, and when the property is queried it
will copy `len' bytes from the location specified by `val', so that data
cannot be freed or the kernel may panic.  Returns 0 on success or an error
value.


size_t listobjs(kdatabase_t db, opaque_t *objects, size_t len);

Get a list of objects from a database.  A list of objects will be copied
into the buffer pointed to by `objects' up to `len' bytes.  It returns
the amount of memory needed to store the entire list.


size_t listprops(kdatabase_t db, opaque_t object, char *names, size_t len);

Get a list of an object's properties from the database.  It queries the
database and copies up to `len' bytes of NUL terminated property names into
the buffer pointed to by `names'.  Another NUL character terminates the list,
and partial strings are not copied.  It returns the size needed to hold the
entire list.


size_t getprop(kdatabase_t db, opaque_t object, const char *name, 
	void *val, size_t len, int *type);

Retrieve a property called `name' associated with `object'.  Name is a pointer
to a string.  The property that matches both `object' and `name' will be
selected, and the data and type associated with that property will be returned
in the buffers pointed to by `val' and `type' as appropriate.

Returns -1 if the property cannot be found, otherwise it returns the length of
the value data and if `val' is not NULL it copies up to `len' bytes of the
property data to the location pointed to by `val'.  The type value associated
with that property is stored in the location pointed to by `type' if it is not
NULL.


int delprop(kdatabase_t db, opaque_t object, const char *name);

Remove a property from a database.  If a NULL is supplied for the name,
dev_delprop(9) will remove all properties associated with `object'.  It
returns the number of properties deleted.


int copyprops(kdatabase_t db, opaque_t source, opaque_t dest, 
		int wait);

Copy all properties associated with `source' to `dest' structure.  If `wait'
is zero then dev_copyprops(9) will not sleep for resource shortage.  Returns 0
on success or an error value.  The state of properties is undefined if the
operation fails.


4	Sysctl Interface

A sysctl(3) interface is being provided to allow users to query and to a
limited extent modify kernel property databases.  Databases, objects, and
properties can be queried, and properties can be created, modified, or
destroyed.


4.2	Sysctl Structures


struct kinfo_kdb {
	char		ki_name[MAX_KDBNAME];
	u_int64_t	ki_id;		/* Kernel database id */
};

/* A single property */
struct kinfo_prop {
	int	kip_len;		/* total len of this prop */
	int	kip_type;		/* type of this prop */
	int	kip_valoff;		/* offset of start of value */
	int	kip_vallen;		/* length of value */
	char	kip_name[1];		/* name of this property */
};


4.2	Sysctl MIBs

A new KERN_DB MIB is provides the following:

	Third level name	Type			Changeable
	----------------	------			----------
	KERN_DB_ALL		struct kinfo_kdb[]	no
	KERN_OBJ_ALL		quad[]			no
	KERN_PROP_ALL		struct kinfo_prop[]	no
	KERN_GETPROP		struct kinfo_prop	no
	KERN_SETPROP		struct kinfo_prop	yes
	KERN_DELPROP		struct kinfo_prop	yes


KERN_DB_ALL

Returns an array of kinfo_kdb structures describing all existing in-kernel
databases.  The ki_id field is the identifier to that should be provided when
using sysctl to query that database.


KERN_OBJ_ALL

The fourth and fifth-level MIBs should be the kernel database identifier for a
particular database that was provided in the ki_id field from an earlier
KERN_DB_ALL query.  It returns an array of 64-bit object identifiers.


KERN_PROP_ALL

The fourth and fifth-level MIBs should be the kernel database identifier, and
the sixth and seventh-level MIBs should be the object identifier.  This
returns an array of kinfo_prop structures for each property associated with
that database identifier and object identifier.


KERN_GETPROP

The fourth and fifth-level MIBs should be the kernel database identifier, and
the sixth and seventh-level MIBs should be the object identifier.  A
kinfo_prop structure should be filled out with valid kip_len and kip_name
fields.  The property associated with the specified database and object with
the specified name is returned.


KERN_SETPROP

The fourth and fifth-level MIBs should be the kernel database identifier, and
the sixth and seventh-level MIBs should be the object identifier.  A
kinfo_prop structure should be completely filled out.  The old property
associated with the specified database and object with the specified name is
returned, and is replaced with the property provided.


KERN_DELPROP

The fourth and fifth-level MIBs should be the kernel database identifier, and
the sixth and seventh-level MIBs should be the object identifier.  A
kinfo_prop structure should be filled out with valid kip_len and kip_name
fields.  The property associated with the specified database and object with
the specified name is returned and removed from the database.