ipc_namespace.h 3.3 KB
Newer Older
1 2 3 4
#ifndef __IPC_NAMESPACE_H__
#define __IPC_NAMESPACE_H__

#include <linux/err.h>
5 6
#include <linux/idr.h>
#include <linux/rwsem.h>
7 8 9 10 11 12
#include <linux/notifier.h>

/*
 * ipc namespace events
 */
#define IPCNS_MEMCHANGED   0x00000001   /* Notify lowmem size changed */
13 14
#define IPCNS_CREATED  0x00000002   /* Notify new ipc namespace created */
#define IPCNS_REMOVED  0x00000003   /* Notify ipc namespace removed */
15 16 17

#define IPCNS_CALLBACK_PRI 0

18 19 20 21 22 23 24 25

struct ipc_ids {
	int in_use;
	unsigned short seq;
	unsigned short seq_max;
	struct rw_semaphore rw_mutex;
	struct idr ipcs_idr;
};
26 27 28

struct ipc_namespace {
	struct kref	kref;
29
	struct ipc_ids	ids[3];
30 31 32 33 34 35 36 37 38

	int		sem_ctls[4];
	int		used_sems;

	int		msg_ctlmax;
	int		msg_ctlmnb;
	int		msg_ctlmni;
	atomic_t	msg_bytes;
	atomic_t	msg_hdrs;
39
	int		auto_msgmni;
40 41 42 43 44

	size_t		shm_ctlmax;
	size_t		shm_ctlall;
	int		shm_ctlmni;
	int		shm_tot;
45 46

	struct notifier_block ipcns_nb;
47 48 49 50 51 52 53 54 55 56 57 58

	/* The kern_mount of the mqueuefs sb.  We take a ref on it */
	struct vfsmount	*mq_mnt;

	/* # queues in this ns, protected by mq_lock */
	unsigned int    mq_queues_count;

	/* next fields are set through sysctl */
	unsigned int    mq_queues_max;   /* initialized to DFLT_QUEUESMAX */
	unsigned int    mq_msg_max;      /* initialized to DFLT_MSGMAX */
	unsigned int    mq_msgsize_max;  /* initialized to DFLT_MSGSIZEMAX */

59 60 61
};

extern struct ipc_namespace init_ipc_ns;
62
extern atomic_t nr_ipc_ns;
63

64
#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
65
#define INIT_IPC_NS(ns)		.ns		= &init_ipc_ns,
66 67 68
#else
#define INIT_IPC_NS(ns)
#endif
69

70
#ifdef CONFIG_SYSVIPC
71
extern int register_ipcns_notifier(struct ipc_namespace *);
72
extern int cond_register_ipcns_notifier(struct ipc_namespace *);
73
extern void unregister_ipcns_notifier(struct ipc_namespace *);
74 75
extern int ipcns_notify(unsigned long);
#else /* CONFIG_SYSVIPC */
76 77 78 79 80 81
static inline int register_ipcns_notifier(struct ipc_namespace *ns)
{ return 0; }
static inline int cond_register_ipcns_notifier(struct ipc_namespace *ns)
{ return 0; }
static inline void unregister_ipcns_notifier(struct ipc_namespace *ns) { }
static inline int ipcns_notify(unsigned long l) { return 0; }
82
#endif /* CONFIG_SYSVIPC */
83

84 85 86 87 88 89 90 91 92 93 94 95
#ifdef CONFIG_POSIX_MQUEUE
extern void mq_init_ns(struct ipc_namespace *ns);
/* default values */
#define DFLT_QUEUESMAX 256     /* max number of message queues */
#define DFLT_MSGMAX    10      /* max number of messages in each queue */
#define HARD_MSGMAX    (131072/sizeof(void *))
#define DFLT_MSGSIZEMAX 8192   /* max message size */
#else
#define mq_init_ns(ns) ((void) 0)
#endif

#if defined(CONFIG_IPC_NS)
96 97
extern void free_ipc_ns(struct kref *kref);
extern struct ipc_namespace *copy_ipcs(unsigned long flags,
98 99 100 101
				       struct ipc_namespace *ns);
extern void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
		      void (*free)(struct ipc_namespace *,
				   struct kern_ipc_perm *));
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
{
	if (ns)
		kref_get(&ns->kref);
	return ns;
}

static inline void put_ipc_ns(struct ipc_namespace *ns)
{
	kref_put(&ns->kref, free_ipc_ns);
}
#else
static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
		struct ipc_namespace *ns)
{
	if (flags & CLONE_NEWIPC)
		return ERR_PTR(-EINVAL);

	return ns;
}

static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
{
	return ns;
}

static inline void put_ipc_ns(struct ipc_namespace *ns)
{
}
#endif
#endif