summaryrefslogtreecommitdiff
path: root/libhurd-cap-server/cap-server.h
diff options
context:
space:
mode:
Diffstat (limited to 'libhurd-cap-server/cap-server.h')
-rw-r--r--libhurd-cap-server/cap-server.h573
1 files changed, 0 insertions, 573 deletions
diff --git a/libhurd-cap-server/cap-server.h b/libhurd-cap-server/cap-server.h
deleted file mode 100644
index e12e986..0000000
--- a/libhurd-cap-server/cap-server.h
+++ /dev/null
@@ -1,573 +0,0 @@
-/* cap-server.h - Server interface to the Hurd capability library.
- Copyright (C) 2004 Free Software Foundation, Inc.
- Written by Marcus Brinkmann <marcus@gnu.org>
-
- This file is part of the GNU Hurd.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#ifndef _HURD_CAP_SERVER_H
-#define _HURD_CAP_SERVER_H 1
-
-#include <stdbool.h>
-#include <errno.h>
-#include <pthread.h>
-
-/* FIXME: This is not a public header file! So we may have to ship
- a <hurd/atomic.h>. */
-#include <atomic.h>
-
-#include <hurd/slab.h>
-#include <hurd/types.h>
-
-
-/* Internal declarations. */
-
-/* This is a simple list item, used to maintain lists of pending RPC
- worker threads in a capability class, client, or object. */
-struct _hurd_cap_list_item;
-typedef struct _hurd_cap_list_item *_hurd_cap_list_item_t;
-
-
-/* The state of a capability class, client, or object. */
-typedef enum _hurd_cap_state
- {
- _HURD_CAP_STATE_GREEN,
- _HURD_CAP_STATE_YELLOW,
- _HURD_CAP_STATE_RED,
- _HURD_CAP_STATE_BLACK
- }
-_hurd_cap_state_t;
-
-
-/* Public interface. */
-
-/* Forward declarations. */
-struct _hurd_cap_bucket;
-typedef struct _hurd_cap_bucket *hurd_cap_bucket_t;
-struct _hurd_cap_client;
-typedef struct _hurd_cap_client *_hurd_cap_client_t;
-struct hurd_cap_class;
-typedef struct hurd_cap_class *hurd_cap_class_t;
-struct hurd_cap_obj;
-typedef struct hurd_cap_obj *hurd_cap_obj_t;
-
-
-typedef error_t (*hurd_cap_obj_init_t) (hurd_cap_class_t cap_class,
- hurd_cap_obj_t obj);
-typedef error_t (*hurd_cap_obj_alloc_t) (hurd_cap_class_t cap_class,
- hurd_cap_obj_t obj);
-typedef void (*hurd_cap_obj_reinit_t) (hurd_cap_class_t cap_class,
- hurd_cap_obj_t obj);
-typedef void (*hurd_cap_obj_destroy_t) (hurd_cap_class_t cap_class,
- hurd_cap_obj_t obj);
-
-
-/* The RPC context contains various information for the RPC handler
- and the support functions. */
-struct hurd_cap_rpc_context
-{
- /* Public members. */
-
- /* The task which contained the sender of the message. */
- hurd_task_id_t sender;
-
- /* The bucket through which the message was received. */
- hurd_cap_bucket_t bucket;
-
- /* The capability object on which the RPC was invoked. */
- hurd_cap_obj_t obj;
-
- /* The capability handle on which the RPC was invoked. */
- hurd_cap_handle_t handle;
-
- /* Private members. */
-
- /* The sender of the message. */
- l4_thread_id_t from;
-
- /* The client corresponding to FROM. */
- _hurd_cap_client_t client;
-
- /* The message. */
- l4_msg_t msg;
-};
-typedef struct hurd_cap_rpc_context *hurd_cap_rpc_context_t;
-
-/* FIXME: Add documentation. */
-typedef error_t (*hurd_cap_class_demuxer_t) (hurd_cap_rpc_context_t ctx);
-
-
-/* A capability class is a group of capability objects of the same
- type. */
-struct hurd_cap_class
-{
- /* Capability object management for the class. */
-
- /* The following callbacks are used to adjust the state of an object
- during its lifetime:
-
- 1. Object is constructed in the cache OBJ_INIT
- 2.1. Object is instantiated and removed from the free list OBJ_ALLOC
- 2.2. Object is deallocated and put back on the free list OBJ_REINIT
- 3. Object is destroyed and removed from the cache OBJ_DESTROY
-
- Note that step 2 can occur several times, or not at all.
- This is the state diagram for each object:
-
- (START) --(1.)-> initialized --(3.)--> destroyed (END)
- | ^
- | |
- (2.1.) (2.2.)
- | |
- v |
- allocated
-
- Note that OBJ_INIT will be called in bursts for pre-allocation of
- several objects. */
-
- /* This callback is invoked whenever a new object is pre-allocated
- in the cache. It is usually called in bursts when a new slab
- page is allocated. You can put all initialization in it that
- should be cached. */
- hurd_cap_obj_init_t obj_init;
-
- /* This callback is called whenever an object in the cache is going
- to be instantiated and used. You can put further initialization
- in it that is not suitable for caching (for example, because it
- can not be safely reinitialized by OBJ_REINIT). If OBJ_ALLOC
- fails, then it must leave the object in its initialized
- state! */
- hurd_cap_obj_alloc_t obj_alloc;
-
- /* This callback is invoked whenever a used object is deallocated
- and returned to the cache. It should revert the used object to
- its initialized state, this means as if OBJ_INIT had been called
- on a freshly constructed object. This also means that you have
- to deallocate all resources that have been allocated by
- OBJ_ALLOC. Note that this function can not fail. Initialization
- that can not be safely (error-free) reverted to its original
- state must be put into the OBJ_ALLOC callback, rather than in the
- OBJ_INIT callback. */
- hurd_cap_obj_reinit_t obj_reinit;
-
- /* This callback is invoked whenever an initialized, but unused
- object is removed from the cache and destroyed. You should
- release all resources that have been allocated for this object by
- a previous OBJ_INIT invocation. */
- hurd_cap_obj_destroy_t obj_destroy;
-
- /* The slab space containing the capabilities in this class. */
- struct hurd_slab_space obj_space;
-
- /* The following condition is used in conjunction with the state
- predicate of a capability object. */
- pthread_cond_t obj_cond;
-
- /* The following mutex is associated with the obj_cond
- condition. Note that this mutex does _not_ protect the predicate
- of the condition: The predicate is the state of the respective
- client and that is protected by the lock of each capability
- object itself. */
- pthread_mutex_t obj_cond_lock;
-
-
- /* The class management. */
-
- /* The demuxer for this class. */
- hurd_cap_class_demuxer_t demuxer;
-
- /* The lock protecting all the following members. */
- pthread_mutex_t lock;
-
- /* The state of the class. */
- _hurd_cap_state_t state;
-
- /* The condition used for waiting on state changes. The associated
- mutex is LOCK. */
- pthread_cond_t cond;
-
- /* The current waiter thread. This is only valid if state is
- _HURD_CAP_STATE_YELLOW. Used by _hurd_cap_class_cond_busy (). */
- pthread_t cond_waiter;
-
- /* The pending RPC worker threads for this class. */
- _hurd_cap_list_item_t pending_rpcs;
-};
-
-
-/* Server-side objects that are accessible via capabilities. */
-struct hurd_cap_obj
-{
- /* The class which contains this capability. */
- hurd_cap_class_t cap_class;
-
- /* The lock protecting all the members of the capability object. */
- pthread_mutex_t lock;
-
- /* The reference counter for this object. */
- uatomic32_t refs;
-
- /* The state of the capability object.
-
- If STATE is _HURD_CAP_STATE_GREEN, you can use the capability
- object. Otherwise, you must wait on the condition
- CAP_CLASS->OBJ_COND for it return to _HURD_CAP_STATE_GREEN.
-
- If the state is _HURD_CAP_STATE_YELLOW, a thread wants the state
- to be _HURD_CAP_STATE_RED (and it has canceled all other pending
- RPC threads on this object). The last worker thread for this
- capability object (other than the thread waiting for the
- condition to become _HURD_CAP_STATE_RED) must broadcast the
- obj_state_cond condition.
-
- Every worker thread that blocks on the capability object state
- until it reverts to _HURD_CAP_STATE_GREEN must perform a
- reauthentication when it is unblocked (ie, verify that the client
- still has access to the capability object), in case the
- capability of the client for this object was revoked in the
- meantime.
-
- _HURD_CAP_STATE_BLACK is not used for capability objects. */
- _hurd_cap_state_t state;
-
- /* The pending RPC worker threads for this capability object. */
- _hurd_cap_list_item_t pending_rpcs;
-
- /* The current waiter thread. This is only valid if STATE is
- _HURD_CAP_STATE_YELLOW. Used by _hurd_cap_obj_cond_busy (). */
- pthread_t cond_waiter;
-
- /* The list items in the capability entries of the clients using
- this capability. */
- _hurd_cap_list_item_t clients;
-};
-
-
-/* Operations on capability classes. */
-
-/* Create a new capability class for objects with the size SIZE and
- alignment requirement ALIGNMENT (which must be a power of 2).
-
- The callback OBJ_INIT is used whenever a capability object in this
- class is created. The callback OBJ_REINIT is used whenever a
- capability object in this class is deallocated and returned to the
- slab. OBJ_REINIT should bring back a capability object that is not
- used anymore into the same state as OBJ_INIT does for a freshly
- allocated object. OBJ_DESTROY should deallocate all resources for
- this capablity object. Note that OBJ_REINIT can not fail: If you
- have resources that can not safely be restored into their initial
- state, you cannot use OBJ_INIT to allocate them. Furthermore, note
- that OBJ_INIT will usually be called in bursts for advanced
- allocation.
-
- The new capability class is returned in R_CLASS. If the creation
- fails, an error value will be returned. */
-error_t hurd_cap_class_create_untyped (size_t size, size_t alignment,
- hurd_cap_obj_init_t obj_init,
- hurd_cap_obj_alloc_t obj_alloc,
- hurd_cap_obj_reinit_t obj_reinit,
- hurd_cap_obj_destroy_t obj_destroy,
- hurd_cap_class_demuxer_t demuxer,
- hurd_cap_class_t *r_class);
-
-/* Define a capability class for the pointer type TYPE. */
-#define hurd_cap_class_create(type,init,alloc,reinit,destroy,demuxer,r_class) \
- hurd_cap_class_create_untyped (({ type t; sizeof (*t); }), \
- ({ type t; __alignof__ (*t); }), \
- init, alloc, reinit, destroy, demuxer, \
- r_class);
-
-
-/* Destroy the capability class CAP_CLASS and release all associated
- resources. Note that this is only allowed if there are no
- capability objects in use, and if the capability class is not used
- by a capability server. This function assumes that the class was
- created with hurd_cap_class_create. */
-error_t hurd_cap_class_free (hurd_cap_class_t cap_class);
-
-
-/* Same as hurd_cap_class_create, but doesn't allocate the storage for
- CAP_CLASS. Instead, you have to provide it. */
-error_t hurd_cap_class_init_untyped (hurd_cap_class_t cap_class,
- size_t size, size_t alignment,
- hurd_cap_obj_init_t obj_init,
- hurd_cap_obj_alloc_t obj_alloc,
- hurd_cap_obj_reinit_t obj_reinit,
- hurd_cap_obj_destroy_t obj_destroy,
- hurd_cap_class_demuxer_t demuxer);
-
-/* Define a capability class for the pointer type TYPE. */
-#define hurd_cap_class_init(cclass,type,init,alloc,reinit,destroy,demuxer) \
- hurd_cap_class_init_untyped (cclass, ({ type t; sizeof (*t); }), \
- ({ type t; __alignof__ (*t); }), \
- init, alloc, reinit, destroy, demuxer);
-
-
-/* Destroy the capability class CAP_CLASS and release all associated
- resources. Note that this is only allowed if there are no
- capability objects in use, and if the capability class is not used
- by a capability server. This function assumes that the class has
- been initialized with hurd_cap_class_init. */
-error_t hurd_cap_class_destroy (hurd_cap_class_t cap_class);
-
-
-/* Allocate a new capability object in the class CAP_CLASS. The new
- capability object is locked and has one reference. It will be
- returned in R_OBJ. If the allocation fails, an error value will be
- returned. The object will be destroyed as soon as its last
- reference is dropped. */
-error_t hurd_cap_class_alloc (hurd_cap_class_t cap_class,
- hurd_cap_obj_t *r_obj);
-
-
-/* Get the offset of the user object following a capability.
- ALIGNMENT is the alignment requirements of the user object as
- supplied to hurd_cap_class_init, hurd_cap_class_init_untyped,
- hurd_cap_class_create or hurd_cap_class_create_untyped. */
-static inline size_t
-__attribute__((__always_inline__))
-hurd_cap_obj_user_offset (size_t alignment)
-{
- size_t offset = sizeof (struct hurd_cap_obj);
- size_t rest = sizeof (struct hurd_cap_obj) % alignment;
-
- if (rest)
- offset += alignment - rest;
-
- return offset;
-}
-
-
-/* Find the user object of the pointer type TYPE after the capability
- object OBJ. Note that in conjunction with the hurd_cap_obj_to_user
- macro below, all of this can and will be computed at compile time,
- if optimization is enabled. OBJ already fulfills the alignment
- requirement ALIGNMENT. */
-static inline void *
-__attribute__((__always_inline__))
-hurd_cap_obj_to_user_untyped (hurd_cap_obj_t obj, size_t alignment)
-{
- uintptr_t obj_addr = (uintptr_t) obj;
-
- obj_addr += hurd_cap_obj_user_offset (alignment);
-
- return (void *) obj_addr;
-}
-
-#define hurd_cap_obj_to_user(type,obj) \
- ((type) hurd_cap_obj_to_user_untyped (obj, ({ type t; __alignof__ (*t); })))
-
-
-/* Find the hurd cap object before the user object OBJ of the pointer
- type TYPE. Note that in conjunction with the hurd_cap_obj_from_user
- macro below, all of this can and will be computed at compile time,
- if optimization is enabled. OBJ already fulfills the alignment
- requirement ALIGNMENT. */
-static inline hurd_cap_obj_t
-__attribute__((__always_inline__))
-hurd_cap_obj_from_user_untyped (void *obj, size_t alignment)
-{
- uintptr_t obj_addr = (uintptr_t) obj;
-
- obj_addr -= hurd_cap_obj_user_offset (alignment);
-
- return (hurd_cap_obj_t) obj_addr;
-}
-
-#define hurd_cap_obj_from_user(type,obj) \
- hurd_cap_obj_from_user_untyped (obj, ({ type t; __alignof__ (*t); }))
-
-
-/* Inhibit all RPCs on the capability class CAP_CLASS (which must not
- be locked). You _must_ follow up with a hurd_cap_class_resume
- operation, and hold at least one reference to the object
- continuously until you did so. */
-error_t hurd_cap_class_inhibit (hurd_cap_class_t cap_class);
-
-
-/* Resume RPCs on the class CAP_CLASS and wake-up all waiters. */
-void hurd_cap_class_resume (hurd_cap_class_t cap_class);
-
-
-/* Operations on capability objects. */
-
-/* Lock the object OBJ. */
-static inline void
-hurd_cap_obj_lock (hurd_cap_obj_t obj)
-{
- pthread_mutex_lock (&obj->lock);
-}
-
-/* Unlock the object OBJ, which must be locked. */
-static inline void
-hurd_cap_obj_unlock (hurd_cap_obj_t obj)
-{
- pthread_mutex_unlock (&obj->lock);
-}
-
-
-/* Add a reference to the capability object OBJ. */
-static inline void
-hurd_cap_obj_ref (hurd_cap_obj_t obj)
-{
- atomic_increment (&obj->refs);
-}
-
-
-/* Remove one reference for the capability object OBJ, which must be
- locked. Note that the caller must have at least two references for
- this capability object when using this function. If this reference
- is potentially the last reference (i.e. the caller does not hold
- either directly or indirectly another reference to OBJ),
- hurd_cap_obj_drop must be used instead. */
-static inline void
-hurd_cap_obj_rele (hurd_cap_obj_t obj)
-{
- atomic_decrement (&obj->refs);
-}
-
-
-/* Remove one reference for the capability object OBJ, which must be
- locked, and will be unlocked when the function returns. If this
- was the last user of this object, the object is deallocated. */
-void hurd_cap_obj_drop (hurd_cap_obj_t obj);
-
-
-/* Inhibit all RPCs on the capability object OBJ (which must not be
- locked). You _must_ follow up with a hurd_cap_obj_resume
- operation, and hold at least one reference to the object
- continuously until you did so. */
-error_t hurd_cap_obj_inhibit (hurd_cap_obj_t obj);
-
-
-/* Resume RPCs on the capability object OBJ and wake-up all
- waiters. */
-void hurd_cap_obj_resume (hurd_cap_obj_t obj);
-
-
-/* Buckets are a set of capabilities, on which RPCs are managed
- collectively. */
-
-/* Create a new bucket and return it in R_BUCKET. */
-error_t hurd_cap_bucket_create (hurd_cap_bucket_t *r_bucket);
-
-
-/* Free the bucket BUCKET, which must not be used. */
-void hurd_cap_bucket_free (hurd_cap_bucket_t bucket);
-
-
-/* Copy out a capability for the capability OBJ to the client with the
- task ID TASK_ID. Returns the capability (valid only for this user)
- in *R_CAP, or an error. It is not safe to call this from outside
- an RPC on OBJ while the manager is running. */
-error_t hurd_cap_bucket_inject (hurd_cap_bucket_t bucket, hurd_cap_obj_t obj,
- hurd_task_id_t task_id,
- hurd_cap_handle_t *r_cap);
-
-
-/* If ASYNC is true, allocate worker threads asynchronously whenever
- the number of worker threads is exhausted. This is only actually
- required for physmem (the physical memory server), to allow to
- break out of a dead-lock between physmem and the task server. It
- should be unnecessary for any other server.
-
- The default is to false, which means that worker threads are
- allocated synchronously by the manager thread.
-
- This function should be called before the manager is started with
- hurd_cap_bucket_manage_mt. It is only used for the multi-threaded
- RPC manager. */
-error_t hurd_cap_bucket_worker_alloc (hurd_cap_bucket_t bucket, bool async);
-
-
-/* Start managing RPCs on the bucket BUCKET. The ROOT capability
- object, which must be unlocked and have one reference throughout
- the whole time this function runs, is used for bootstrapping client
- connections. The GLOBAL_TIMEOUT parameter specifies the number of
- seconds until the manager times out (if there are no active users
- of capability objects in precious classes). The WORKER_TIMEOUT
- parameter specifies the number of seconds until each worker thread
- times out (if there are no RPCs processed by the worker thread).
-
- If this returns ECANCELED, then hurd_cap_bucket_end was called with
- the force flag being true while there were still active users. If
- this returns without any error, then the timeout expired, or
- hurd_cap_bucket_end was called without active users of capability
- objects in precious classes. */
-error_t hurd_cap_bucket_manage_mt (hurd_cap_bucket_t bucket,
- hurd_cap_obj_t root,
- unsigned int global_timeout,
- unsigned int worker_timeout);
-
-
-/* Inhibit all RPCs on the capability bucket BUCKET (which must not be
- locked). You _must_ follow up with a hurd_cap_bucket_resume (or
- hurd_cap_bucket_end) operation. */
-error_t hurd_cap_bucket_inhibit (hurd_cap_bucket_t bucket);
-
-
-/* Resume RPCs on the class CAP_CLASS and wake-up all waiters. */
-void hurd_cap_bucket_resume (hurd_cap_bucket_t bucket);
-
-
-/* Exit from the server loop of the managed capability bucket BUCKET.
- This will only succeed if there are no active users, or if the
- FORCE flag is set (otherwise it will fail with EBUSY). The bucket
- must be inhibited. */
-error_t hurd_cap_bucket_end (hurd_cap_bucket_t bucket, bool force);
-
-
-/* If you want to use other capabilities in an RPC handler beside the
- one on which the RPC was invoked, you need to make sure that
- inhibition works on those other capabilities and cancel your
- operation. For this, the following interfaces are provided. */
-
-/* Forward. */
-struct hurd_cap_ctx_cap_use;
-
-/* Return the number of bytes required for a hurd_cap_ctx_cap_use
- structure. */
-size_t hurd_cap_ctx_size (void) __attribute__ ((const));
-
-/* The calling thread wishes to execute an RPC on the the handle
- HANDLE. The calling thread must already be registered as executing
- an RPC. RPC_CTX is the cooresponding RPC context. The function
- uses the structure CAP_USE, which must point to the number of bytes
- returned by hurd_cap_ctx_size, to store data required by
- hurd_cap_ctx_end_cap_use. The capability object corresponding to
- HANDLE is locked and returned in *OBJP.
-
- Returns EINVAL if the capability handle is invalid for the client.
-
- Returns ENOENT if there is no object associated with handle HANDLE.
-
- Returns EBAD if the capability is dead.
-
- Returns EDOM if the object associated with HANDLE is not in class
- REQUIRED_CLASS. If no type check is required, it will be skipped
- if REQURIED_CLASS is NULL. */
-error_t hurd_cap_ctx_start_cap_use (hurd_cap_rpc_context_t rpc_ctx,
- hurd_cap_handle_t handle,
- hurd_cap_class_t required_class,
- struct hurd_cap_ctx_cap_use *cap_use,
- hurd_cap_obj_t *objp);
-
-/* End the use of the object CAP_USE->OBJ, which must be locked. */
-void hurd_cap_ctx_end_cap_use (hurd_cap_rpc_context_t rpc_ctx,
- struct hurd_cap_ctx_cap_use *cap_use);
-
-#endif /* _HURD_CAP_SERVER_H */