1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2016 Joyent, Inc.
14 */
15
16 #ifndef _LXCGRPS_H
17 #define _LXCGRPS_H
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /*
24 * cgrps.h: declarations, data structures and macros for lx_cgroup
25 */
26
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <sys/policy.h>
30 #include <sys/dirent.h>
31 #include <sys/errno.h>
32 #include <sys/kmem.h>
33 #include <sys/pathname.h>
34 #include <sys/systm.h>
35 #include <sys/var.h>
36 #include <sys/sysmacros.h>
37 #include <sys/cred.h>
38 #include <sys/priv.h>
39 #include <sys/vnode.h>
40 #include <sys/vfs.h>
41 #include <sys/statvfs.h>
42 #include <sys/cmn_err.h>
43 #include <sys/zone.h>
44 #include <sys/uio.h>
45 #include <sys/utsname.h>
46 #include <sys/atomic.h>
47 #include <vm/anon.h>
48
49 /*
50 * cgrpmgr ioctl interface.
51 */
52 #define CGRPFS_IOC ('C' << 16 | 'G' << 8)
53 #define CGRPFS_GETEVNT (CGRPFS_IOC | 1)
54
55 typedef struct cgrpmgr_info {
56 pid_t cgmi_pid;
57 char *cgmi_rel_agent_path;
58 char *cgmi_cgroup_path;
59 } cgrpmgr_info_t;
60
61 #if defined(_KERNEL)
62
63 #include <sys/lx_brand.h>
64
65 typedef struct cgrpmgr_info32 {
66 pid_t cgmi_pid;
67 caddr32_t cgmi_rel_agent_path;
68 caddr32_t cgmi_cgroup_path;
69 } cgrpmgr_info32_t;
70
71 #define CG_PSNSIZE 256 /* max size of pseudo file name entries */
72 #define CG_PSDSIZE 16 /* pretend that a dir entry takes 16 bytes */
73
74 /*
75 * The order of these entries must be in sync with the cg_ssde_dir array.
76 */
77 typedef enum cgrp_ssid {
78 CG_SSID_GENERIC = 1,
79 CG_SSID_NUM /* last ssid for range checking */
80 } cgrp_ssid_t;
81
82 typedef enum cgrp_nodetype {
83 CG_CGROUP_DIR = 1, /* cgroup directory entry */
84 CG_NOTIFY, /* notify_on_release file */
85 CG_PROCS, /* cgroup.procs file */
86 CG_REL_AGENT, /* release_agent file */
87 CG_TASKS, /* tasks file */
88 } cgrp_nodetype_t;
89
90 typedef struct cgrp_subsys_dirent {
91 cgrp_nodetype_t cgrp_ssd_type;
92 char *cgrp_ssd_name;
93 } cgrp_subsys_dirent_t;
94
95 #define N_DIRENTS(m) (cgrp_num_pseudo_ents((m)->cg_ssid) + 2)
96
97 /*
98 * A modern systemd-based Linux system typically has 50-60 cgroups so
99 * we size the hash for 2x that number.
100 */
101 #define CGRP_HASH_SZ 128
102 #define CGRP_AGENT_LEN (MAXPATHLEN + 1)
103
104 /*
105 * cgroups per-mount data structure.
106 *
107 * All but the event related fields are protected by cg_contents.
108 * The evnt_list and counter is protected by cg_events.
109 */
110 typedef struct cgrp_mnt {
111 struct vfs *cg_vfsp; /* filesystem's vfs struct */
112 struct cgrp_node *cg_rootnode; /* root cgrp_node */
113 char *cg_mntpath; /* name of cgroup mount point */
114 cgrp_ssid_t cg_ssid; /* subsystem type */
115 dev_t cg_dev; /* unique dev # of mounted `device' */
116 uint_t cg_gen; /* node ID source for files */
117 uint_t cg_grp_gen; /* ID source for cgroups */
118 kmutex_t cg_contents; /* global lock for most fs activity */
119 char cg_agent[CGRP_AGENT_LEN]; /* release_agent path */
120 /* ptr to zone data for containing zone */
121 lx_zone_data_t *cg_lxzdata;
122 struct cgrp_node **cg_grp_hash; /* hash list of cgroups in the fs */
123 } cgrp_mnt_t;
124
125 /*
126 * cgrp_node is the file system dependent node for cgroups.
127 *
128 * The node is used to represent both directories (a cgroup) and pseudo files
129 * within the directory.
130 *
131 * Members are tagged in the comment to note which type of node they apply to:
132 * A - all
133 * D - dir (i.e. a cgroup)
134 * F - pseudo file
135 */
136
137 typedef struct cgrp_node {
138 struct cgrp_node *cgn_back; /* A lnked lst of cgrp_nodes */
139 struct cgrp_node *cgn_forw; /* A lnked lst of cgrp_nodes */
140 struct cgrp_dirent *cgn_dir; /* D dirent list */
141 struct cgrp_node *cgn_parent; /* A dir containing this node */
142 struct cgrp_node *cgn_next; /* D link in per-mount cgroup */
143 /* hash table */
144 uint_t cgn_dirents; /* D number of dirents */
145 cgrp_nodetype_t cgn_type; /* A type for this node */
146 uint_t cgn_notify; /* D notify_on_release value */
147 uint_t cgn_task_cnt; /* D number of threads in grp */
148 struct vnode *cgn_vnode; /* A vnode for this cgrp_node */
149 uint_t cgn_id; /* D ID number for the cgroup */
150 struct vattr cgn_attr; /* A attributes */
151 } cgrp_node_t;
152
153 /*
154 * File system independent to cgroups conversion macros
155 */
156 #define VFSTOCGM(vfsp) ((cgrp_mnt_t *)(vfsp)->vfs_data)
157 #define VTOCGM(vp) ((cgrp_mnt_t *)(vp)->v_vfsp->vfs_data)
158 #define VTOCGN(vp) ((struct cgrp_node *)(vp)->v_data)
159 #define CGNTOV(cn) ((cn)->cgn_vnode)
160 #define cgnode_hold(cn) VN_HOLD(CGNTOV(cn))
161 #define cgnode_rele(cn) VN_RELE(CGNTOV(cn))
162
163 /*
164 * Attributes
165 */
166 #define cgn_mask cgn_attr.va_mask
167 #define cgn_mode cgn_attr.va_mode
168 #define cgn_uid cgn_attr.va_uid
169 #define cgn_gid cgn_attr.va_gid
170 #define cgn_fsid cgn_attr.va_fsid
171 #define cgn_nodeid cgn_attr.va_nodeid
172 #define cgn_nlink cgn_attr.va_nlink
173 #define cgn_size cgn_attr.va_size
174 #define cgn_atime cgn_attr.va_atime
175 #define cgn_mtime cgn_attr.va_mtime
176 #define cgn_ctime cgn_attr.va_ctime
177 #define cgn_rdev cgn_attr.va_rdev
178 #define cgn_blksize cgn_attr.va_blksize
179 #define cgn_nblocks cgn_attr.va_nblocks
180 #define cgn_seq cgn_attr.va_seq
181
182 /*
183 * cgroup directories are made up of a linked list of cg_dirent structures
184 * hanging off directory cgrp_nodes. File names are not fixed length,
185 * but are null terminated.
186 */
187 typedef struct cgrp_dirent {
188 struct cgrp_node *cgd_cgrp_node; /* cg node for this file */
189 struct cgrp_dirent *cgd_next; /* next directory entry */
190 struct cgrp_dirent *cgd_prev; /* prev directory entry */
191 uint_t cgd_offset; /* "offset" of dir entry */
192 uint_t cgd_hash; /* a hash of cgd_name */
193 struct cgrp_dirent *cgd_link; /* linked via hash table */
194 struct cgrp_node *cgd_parent; /* parent, dir we are in */
195 char *cgd_name; /* null terminated */
196 } cgrp_dirent_t;
197
198 enum de_op { DE_CREATE, DE_MKDIR, DE_RENAME }; /* direnter ops */
199 enum dr_op { DR_REMOVE, DR_RMDIR, DR_RENAME }; /* dirremove ops */
200
201 extern struct vnodeops *cgrp_vnodeops;
202
203 int cgrp_dirdelete(cgrp_node_t *, cgrp_node_t *, char *, enum dr_op, cred_t *);
204 int cgrp_direnter(cgrp_mnt_t *, cgrp_node_t *, char *, enum de_op,
205 cgrp_node_t *, struct vattr *, cgrp_node_t **, cred_t *);
206 void cgrp_dirinit(cgrp_node_t *, cgrp_node_t *, cred_t *);
207 int cgrp_dirlookup(cgrp_node_t *, char *, cgrp_node_t **, cred_t *);
208 void cgrp_dirtrunc(cgrp_node_t *);
209 void cgrp_node_init(cgrp_mnt_t *, cgrp_node_t *, vattr_t *, cred_t *);
210 int cgrp_taccess(void *, int, cred_t *);
211 ino_t cgrp_inode(cgrp_nodetype_t, unsigned int);
212 int cgrp_num_pseudo_ents(cgrp_ssid_t);
213 cgrp_node_t *cgrp_cg_hash_lookup(cgrp_mnt_t *, uint_t);
214 void cgrp_rel_agent_event(cgrp_mnt_t *, cgrp_node_t *, boolean_t);
215
216 #endif /* KERNEL */
217
218 #ifdef __cplusplus
219 }
220 #endif
221
222 #endif /* _LXCGRPS_H */