2005-04-17 02:20:36 +04:00
/*
* linux / ipc / util . h
* Copyright ( C ) 1999 Christoph Rohland
*
2006-01-15 04:43:54 +03:00
* ipc helper functions ( c ) 1999 Manfred Spraul < manfred @ colorfullife . com >
2006-10-02 13:18:20 +04:00
* namespaces support . 2006 OpenVZ , SWsoft Inc .
* Pavel Emelianov < xemul @ openvz . org >
2005-04-17 02:20:36 +04:00
*/
# ifndef _IPC_UTIL_H
# define _IPC_UTIL_H
2007-10-19 10:40:51 +04:00
# include <linux/err.h>
2007-10-19 10:40:48 +04:00
2005-04-17 02:20:36 +04:00
# define SEQ_MULTIPLIER (IPCMNI)
void sem_init ( void ) ;
void msg_init ( void ) ;
void shm_init ( void ) ;
2008-02-08 15:18:22 +03:00
struct ipc_namespace ;
2008-02-08 15:18:57 +03:00
void sem_init_ns ( struct ipc_namespace * ns ) ;
void msg_init_ns ( struct ipc_namespace * ns ) ;
void shm_init_ns ( struct ipc_namespace * ns ) ;
2006-10-02 13:18:20 +04:00
void sem_exit_ns ( struct ipc_namespace * ns ) ;
void msg_exit_ns ( struct ipc_namespace * ns ) ;
void shm_exit_ns ( struct ipc_namespace * ns ) ;
2007-10-19 10:40:49 +04:00
/*
* Structure that holds the parameters needed by the ipc operations
* ( see after )
*/
struct ipc_params {
key_t key ;
int flg ;
union {
size_t size ; /* for shared memories */
int nsems ; /* for semaphores */
} u ; /* holds the getnew() specific param */
} ;
/*
* Structure that holds some ipc operations . This structure is used to unify
* the calls to sys_msgget ( ) , sys_semget ( ) , sys_shmget ( )
* . routine to call to create a new ipc object . Can be one of newque ,
* newary , newseg
2007-10-19 10:40:53 +04:00
* . routine to call to check permissions for a new ipc object .
2007-10-19 10:40:49 +04:00
* Can be one of security_msg_associate , security_sem_associate ,
* security_shm_associate
* . routine to call for an extra check if needed
*/
struct ipc_ops {
int ( * getnew ) ( struct ipc_namespace * , struct ipc_params * ) ;
2007-10-19 10:40:51 +04:00
int ( * associate ) ( struct kern_ipc_perm * , int ) ;
int ( * more_checks ) ( struct kern_ipc_perm * , struct ipc_params * ) ;
2007-10-19 10:40:49 +04:00
} ;
2005-09-07 02:17:09 +04:00
struct seq_file ;
2008-02-08 15:18:57 +03:00
struct ipc_ids ;
2007-07-16 10:40:58 +04:00
2007-10-19 10:40:48 +04:00
void ipc_init_ids ( struct ipc_ids * ) ;
2005-09-07 02:17:09 +04:00
# ifdef CONFIG_PROC_FS
void __init ipc_init_proc_interface ( const char * path , const char * header ,
2006-10-02 13:18:20 +04:00
int ids , int ( * show ) ( struct seq_file * , void * ) ) ;
2005-09-07 02:17:09 +04:00
# else
# define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
# endif
2005-04-17 02:20:36 +04:00
2006-10-02 13:18:20 +04:00
# define IPC_SEM_IDS 0
# define IPC_MSG_IDS 1
# define IPC_SHM_IDS 2
2007-10-19 10:40:52 +04:00
# define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
2007-10-19 10:40:54 +04:00
/* must be called with ids->rw_mutex acquired for writing */
2007-10-19 10:40:48 +04:00
int ipc_addid ( struct ipc_ids * , struct kern_ipc_perm * , int ) ;
2007-10-19 10:40:54 +04:00
/* must be called with ids->rw_mutex acquired for reading */
2007-10-19 10:40:48 +04:00
int ipc_get_maxid ( struct ipc_ids * ) ;
2005-04-17 02:20:36 +04:00
/* must be called with both locks acquired. */
2007-10-19 10:40:48 +04:00
void ipc_rmid ( struct ipc_ids * , struct kern_ipc_perm * ) ;
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:53 +04:00
/* must be called with ipcp locked */
int ipcperms ( struct kern_ipc_perm * ipcp , short flg ) ;
2005-04-17 02:20:36 +04:00
/* for rare, potentially huge allocations.
* both function can sleep
*/
void * ipc_alloc ( int size ) ;
void ipc_free ( void * ptr , int size ) ;
/*
* For allocation that need to be freed by RCU .
* Objects are reference counted , they start with reference count 1.
* getref increases the refcount , the putref call that reduces the recount
* to 0 schedules the rcu destruction . Caller must guarantee locking .
*/
void * ipc_rcu_alloc ( int size ) ;
void ipc_rcu_getref ( void * ptr ) ;
void ipc_rcu_putref ( void * ptr ) ;
2007-10-19 10:40:51 +04:00
struct kern_ipc_perm * ipc_lock ( struct ipc_ids * , int ) ;
2005-04-17 02:20:36 +04:00
void kernel_to_ipc64_perm ( struct kern_ipc_perm * in , struct ipc64_perm * out ) ;
void ipc64_perm_to_ipc_perm ( struct ipc64_perm * in , struct ipc_perm * out ) ;
2008-04-29 12:00:51 +04:00
void ipc_update_perm ( struct ipc64_perm * in , struct kern_ipc_perm * out ) ;
2008-04-29 12:00:54 +04:00
struct kern_ipc_perm * ipcctl_pre_down ( struct ipc_ids * ids , int id , int cmd ,
struct ipc64_perm * perm , int extra_perm ) ;
2005-04-17 02:20:36 +04:00
2005-07-13 00:58:25 +04:00
# if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__) || defined(__XTENSA__)
2005-04-17 02:20:36 +04:00
/* On IA-64, we always use the "64-bit version" of the IPC structures. */
# define ipc_parse_version(cmd) IPC_64
# else
int ipc_parse_version ( int * cmd ) ;
# endif
extern void free_msg ( struct msg_msg * msg ) ;
extern struct msg_msg * load_msg ( const void __user * src , int len ) ;
extern int store_msg ( void __user * dest , struct msg_msg * msg , int len ) ;
2007-10-19 10:40:49 +04:00
2008-04-29 12:00:42 +04:00
extern void recompute_msgmni ( struct ipc_namespace * ) ;
2007-10-19 10:40:55 +04:00
static inline int ipc_buildid ( int id , int seq )
2007-10-19 10:40:52 +04:00
{
return SEQ_MULTIPLIER * seq + id ;
}
2007-10-19 10:40:53 +04:00
/*
* Must be called with ipcp locked
*/
2007-10-19 10:40:55 +04:00
static inline int ipc_checkid ( struct kern_ipc_perm * ipcp , int uid )
2007-10-19 10:40:51 +04:00
{
if ( uid / SEQ_MULTIPLIER ! = ipcp - > seq )
return 1 ;
return 0 ;
}
static inline void ipc_lock_by_ptr ( struct kern_ipc_perm * perm )
{
rcu_read_lock ( ) ;
spin_lock ( & perm - > lock ) ;
}
static inline void ipc_unlock ( struct kern_ipc_perm * perm )
{
spin_unlock ( & perm - > lock ) ;
rcu_read_unlock ( ) ;
}
2008-02-08 15:18:54 +03:00
struct kern_ipc_perm * ipc_lock_check ( struct ipc_ids * ids , int id ) ;
int ipcget ( struct ipc_namespace * ns , struct ipc_ids * ids ,
struct ipc_ops * ops , struct ipc_params * params ) ;
2005-04-17 02:20:36 +04:00
# endif