1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_ZONE_H
#define _SYS_ZONE_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
#include <sys/mutex.h>
#include <sys/param.h>
#include <sys/rctl.h>
#include <sys/ipc_rctl.h>
#include <sys/pset.h>
#include <sys/tsol/label.h>
#include <sys/uadmin.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* NOTE
*
* The contents of this file are private to the implementation of
* Solaris and are subject to change at any time without notice.
* Applications and drivers using these interfaces may fail to
* run on future releases.
*/
/* Available both in kernel and for user space */
/* zone id restrictions and special ids */
#define MAX_ZONEID 9999
#define MIN_USERZONEID 1 /* lowest user-creatable zone ID */
#define MIN_ZONEID 0 /* minimum zone ID on system */
#define GLOBAL_ZONEID 0
#define ZONEID_WIDTH 4 /* for printf */
/*
* Special zoneid_t token to refer to all zones.
*/
#define ALL_ZONES (-1)
/* system call subcodes */
#define ZONE_CREATE 0
#define ZONE_DESTROY 1
#define ZONE_GETATTR 2
#define ZONE_ENTER 3
#define ZONE_LIST 4
#define ZONE_SHUTDOWN 5
#define ZONE_LOOKUP 6
#define ZONE_BOOT 7
#define ZONE_VERSION 8
#define ZONE_SETATTR 9
/* zone attributes */
#define ZONE_ATTR_ROOT 1
#define ZONE_ATTR_NAME 2
#define ZONE_ATTR_STATUS 3
#define ZONE_ATTR_PRIVSET 4
#define ZONE_ATTR_UNIQID 5
#define ZONE_ATTR_POOLID 6
#define ZONE_ATTR_INITPID 7
#define ZONE_ATTR_SLBL 8
#define ZONE_ATTR_INITNAME 9
#define ZONE_ATTR_BOOTARGS 10
#define ZONE_EVENT_CHANNEL "com.sun:zones:status"
#define ZONE_EVENT_STATUS_CLASS "status"
#define ZONE_EVENT_STATUS_SUBCLASS "change"
#define ZONE_EVENT_UNINITIALIZED "uninitialized"
#define ZONE_EVENT_READY "ready"
#define ZONE_EVENT_RUNNING "running"
#define ZONE_EVENT_SHUTTING_DOWN "shutting_down"
#define ZONE_CB_NAME "zonename"
#define ZONE_CB_NEWSTATE "newstate"
#define ZONE_CB_OLDSTATE "oldstate"
#define ZONE_CB_TIMESTAMP "when"
#define ZONE_CB_ZONEID "zoneid"
#ifdef _SYSCALL32
typedef struct {
caddr32_t zone_name;
caddr32_t zone_root;
caddr32_t zone_privs;
size32_t zone_privssz;
caddr32_t rctlbuf;
size32_t rctlbufsz;
caddr32_t extended_error;
caddr32_t zfsbuf;
size32_t zfsbufsz;
int match; /* match level */
uint32_t doi; /* DOI for label */
caddr32_t label; /* label associated with zone */
} zone_def32;
#endif
typedef struct {
const char *zone_name;
const char *zone_root;
const struct priv_set *zone_privs;
size_t zone_privssz;
const char *rctlbuf;
size_t rctlbufsz;
int *extended_error;
const char *zfsbuf;
size_t zfsbufsz;
int match; /* match level */
uint32_t doi; /* DOI for label */
const bslabel_t *label; /* label associated with zone */
} zone_def;
/* extended error information */
#define ZE_UNKNOWN 0 /* No extended error info */
#define ZE_CHROOTED 1 /* tried to zone_create from chroot */
#define ZE_AREMOUNTS 2 /* there are mounts within the zone */
/* zone_status */
typedef enum {
ZONE_IS_UNINITIALIZED = 0,
ZONE_IS_READY,
ZONE_IS_BOOTING,
ZONE_IS_RUNNING,
ZONE_IS_SHUTTING_DOWN,
ZONE_IS_EMPTY,
ZONE_IS_DOWN,
ZONE_IS_DYING,
ZONE_IS_DEAD
} zone_status_t;
#define ZONE_MIN_STATE ZONE_IS_UNINITIALIZED
#define ZONE_MAX_STATE ZONE_IS_DEAD
/*
* Valid commands which may be issued by zoneadm to zoneadmd. The kernel also
* communicates with zoneadmd, but only uses Z_REBOOT and Z_HALT.
*/
typedef enum zone_cmd {
Z_READY, Z_BOOT, Z_REBOOT, Z_HALT, Z_NOTE_UNINSTALLING,
Z_MOUNT, Z_UNMOUNT
} zone_cmd_t;
/*
* The structure of a request to zoneadmd.
*/
typedef struct zone_cmd_arg {
uint64_t uniqid; /* unique "generation number" */
zone_cmd_t cmd; /* requested action */
uint32_t _pad; /* need consistent 32/64 bit alignmt */
char locale[MAXPATHLEN]; /* locale in which to render messages */
char bootbuf[BOOTARGS_MAX]; /* arguments passed to zone_boot() */
} zone_cmd_arg_t;
/*
* Structure of zoneadmd's response to a request. A NULL return value means
* the caller should attempt to restart zoneadmd and retry.
*/
typedef struct zone_cmd_rval {
int rval; /* return value of request */
char errbuf[1]; /* variable-sized buffer containing error messages */
} zone_cmd_rval_t;
/*
* The zone support infrastructure uses the zone name as a component
* of unix domain (AF_UNIX) sockets, which are limited to 108 characters
* in length, so ZONENAME_MAX is limited by that.
*/
#define ZONENAME_MAX 64
#define GLOBAL_ZONENAME "global"
/*
* Extended Regular expression (see regex(5)) which matches all valid zone
* names.
*/
#define ZONENAME_REGEXP "[a-zA-Z0-9][-_.a-zA-Z0-9]{0,62}"
/*
* Where the zones support infrastructure places temporary files.
*/
#define ZONES_TMPDIR "/var/run/zones"
/*
* The path to the door used by clients to communicate with zoneadmd.
*/
#define ZONE_DOOR_PATH ZONES_TMPDIR "/%s.zoneadmd_door"
#ifdef _KERNEL
/*
* We need to protect the definition of 'list_t' from userland applications and
* libraries which may be defining ther own versions.
*/
#include <sys/list.h>
#define GLOBAL_ZONEUNIQID 0 /* uniqid of the global zone */
/* zone_flags */
#define ZF_DESTROYED 0x1 /* ZSD destructor callbacks run */
#define ZF_HASHED_LABEL 0x2 /* zone has a unique label */
#define ZF_IS_SCRATCH 0x4 /* scratch zone */
struct pool;
/*
* Structure to record list of ZFS datasets exported to a zone.
*/
typedef struct zone_dataset {
char *zd_dataset;
list_node_t zd_linkage;
} zone_dataset_t;
typedef struct zone {
/*
* zone_name is never modified once set.
*/
char *zone_name; /* zone's configuration name */
/*
* zone_nodename and zone_domain are never freed once allocated.
*/
char *zone_nodename; /* utsname.nodename equivalent */
char *zone_domain; /* srpc_domain equivalent */
/*
* zone_lock protects the following fields of a zone_t:
* zone_ref
* zone_cred_ref
* zone_ntasks
* zone_flags
* zone_zsd
*/
kmutex_t zone_lock;
/*
* zone_linkage is the zone's linkage into the active or
* death-row list. The field is protected by zonehash_lock.
*/
list_node_t zone_linkage;
zoneid_t zone_id; /* ID of zone */
uint_t zone_ref; /* count of zone_hold()s on zone */
uint_t zone_cred_ref; /* count of zone_hold_cred()s on zone */
/*
* zone_rootvp and zone_rootpath can never be modified once set.
*/
struct vnode *zone_rootvp; /* zone's root vnode */
char *zone_rootpath; /* Path to zone's root + '/' */
ushort_t zone_flags; /* misc flags */
zone_status_t zone_status; /* protected by zone_status_lock */
uint_t zone_ntasks; /* number of tasks executing in zone */
kmutex_t zone_nlwps_lock; /* protects zone_nlwps, and *_nlwps */
/* counters in projects and tasks */
/* that are within the zone */
rctl_qty_t zone_nlwps; /* number of lwps in zone */
rctl_qty_t zone_nlwps_ctl; /* protected by zone_rctls->rcs_lock */
rctl_qty_t zone_shmmax; /* System V shared memory usage */
ipc_rqty_t zone_ipc; /* System V IPC id resource usage */
uint_t zone_rootpathlen; /* strlen(zone_rootpath) + 1 */
uint32_t zone_shares; /* FSS shares allocated to zone */
rctl_set_t *zone_rctls; /* zone-wide (zone.*) rctls */
list_t zone_zsd; /* list of Zone-Specific Data values */
kcondvar_t zone_cv; /* used to signal state changes */
struct proc *zone_zsched; /* Dummy kernel "zsched" process */
pid_t zone_proc_initpid; /* pid of "init" for this zone */
char *zone_initname; /* fs path to 'init' */
int zone_boot_err; /* for zone_boot() if boot fails */
char *zone_bootargs; /* arguments passed via zone_boot() */
/*
* zone_kthreads is protected by zone_status_lock.
*/
kthread_t *zone_kthreads; /* kernel threads in zone */
struct priv_set *zone_privset; /* limit set for zone */
/*
* zone_vfslist is protected by vfs_list_lock().
*/
struct vfs *zone_vfslist; /* list of FS's mounted in zone */
uint64_t zone_uniqid; /* unique zone generation number */
struct cred *zone_kcred; /* kcred-like, zone-limited cred */
/*
* zone_pool is protected by pool_lock().
*/
struct pool *zone_pool; /* pool the zone is bound to */
hrtime_t zone_pool_mod; /* last pool bind modification time */
/* zone_psetid is protected by cpu_lock */
psetid_t zone_psetid; /* pset the zone is bound to */
/*
* The following two can be read without holding any locks. They are
* updated under cpu_lock.
*/
int zone_ncpus; /* zone's idea of ncpus */
int zone_ncpus_online; /* zone's idea of ncpus_online */
/*
* List of ZFS datasets exported to this zone.
*/
list_t zone_datasets; /* list of datasets */
ts_label_t *zone_slabel; /* zone sensitivity label */
int zone_match; /* require label match for packets */
tsol_mlp_list_t zone_mlps; /* MLPs on zone-private addresses */
} zone_t;
/*
* Special value of zone_psetid to indicate that pools are disabled.
*/
#define ZONE_PS_INVAL PS_MYID
extern zone_t zone0;
extern zone_t *global_zone;
extern uint_t maxzones;
extern rctl_hndl_t rc_zone_nlwps;
extern const char * const zone_initname;
extern long zone(int, void *, void *, void *, void *);
extern void zone_zsd_init(void);
extern void zone_init(void);
extern void zone_hold(zone_t *);
extern void zone_rele(zone_t *);
extern void zone_cred_hold(zone_t *);
extern void zone_cred_rele(zone_t *);
extern void zone_task_hold(zone_t *);
extern void zone_task_rele(zone_t *);
extern zone_t *zone_find_by_id(zoneid_t);
extern zone_t *zone_find_by_label(const ts_label_t *);
extern zone_t *zone_find_by_name(char *);
extern zone_t *zone_find_by_any_path(const char *, boolean_t);
extern zone_t *zone_find_by_path(const char *);
extern zoneid_t getzoneid(void);
/*
* Zone-specific data (ZSD) APIs
*/
/*
* The following is what code should be initializing its zone_key_t to if it
* calls zone_getspecific() without necessarily knowing that zone_key_create()
* has been called on the key.
*/
#define ZONE_KEY_UNINITIALIZED 0
typedef uint_t zone_key_t;
extern void zone_key_create(zone_key_t *, void *(*)(zoneid_t),
void (*)(zoneid_t, void *), void (*)(zoneid_t, void *));
extern int zone_key_delete(zone_key_t);
extern void *zone_getspecific(zone_key_t, zone_t *);
extern int zone_setspecific(zone_key_t, zone_t *, const void *);
/*
* The definition of a zsd_entry is truly private to zone.c and is only
* placed here so it can be shared with mdb.
*/
struct zsd_entry {
zone_key_t zsd_key; /* Key used to lookup value */
void *zsd_data; /* Caller-managed value */
/*
* Callbacks to be executed when a zone is created, shutdown, and
* destroyed, respectively.
*/
void *(*zsd_create)(zoneid_t);
void (*zsd_shutdown)(zoneid_t, void *);
void (*zsd_destroy)(zoneid_t, void *);
list_node_t zsd_linkage;
};
/*
* Macros to help with zone visibility restrictions.
*/
/*
* Is process in the global zone?
*/
#define INGLOBALZONE(p) \
((p)->p_zone == global_zone)
/*
* Can process view objects in given zone?
*/
#define HASZONEACCESS(p, zoneid) \
((p)->p_zone->zone_id == (zoneid) || INGLOBALZONE(p))
/*
* Convenience macro to see if a resolved path is visible from within a
* given zone.
*
* The basic idea is that the first (zone_rootpathlen - 1) bytes of the
* two strings must be equal. Since the rootpathlen has a trailing '/',
* we want to skip everything in the path up to (but not including) the
* trailing '/'.
*/
#define ZONE_PATH_VISIBLE(path, zone) \
(strncmp((path), (zone)->zone_rootpath, \
(zone)->zone_rootpathlen - 1) == 0)
/*
* Convenience macro to go from the global view of a path to that seen
* from within said zone. It is the responsibility of the caller to
* ensure that the path is a resolved one (ie, no '..'s or '.'s), and is
* in fact visible from within the zone.
*/
#define ZONE_PATH_TRANSLATE(path, zone) \
(ASSERT(ZONE_PATH_VISIBLE(path, zone)), \
(path) + (zone)->zone_rootpathlen - 2)
/*
* Special processes visible in all zones.
*/
#define ZONE_SPECIALPID(x) ((x) == 0 || (x) == 1)
/*
* Zone-safe version of thread_create() to be used when the caller wants to
* create a kernel thread to run within the current zone's context.
*/
extern kthread_t *zthread_create(caddr_t, size_t, void (*)(), void *, size_t,
pri_t);
extern void zthread_exit(void);
/*
* Functions for an external observer to register interest in a zone's status
* change. Observers will be woken up when the zone status equals the status
* argument passed in (in the case of zone_status_timedwait, the function may
* also return because of a timeout; zone_status_wait_sig may return early due
* to a signal being delivered; zone_status_timedwait_sig may return for any of
* the above reasons).
*
* Otherwise these behave identically to cv_timedwait(), cv_wait(), and
* cv_wait_sig() respectively.
*/
extern clock_t zone_status_timedwait(zone_t *, clock_t, zone_status_t);
extern clock_t zone_status_timedwait_sig(zone_t *, clock_t, zone_status_t);
extern void zone_status_wait(zone_t *, zone_status_t);
extern int zone_status_wait_sig(zone_t *, zone_status_t);
/*
* Get the status of the zone (at the time it was called). The state may
* have progressed by the time it is returned.
*/
extern zone_status_t zone_status_get(zone_t *);
/*
* Get the "kcred" credentials corresponding to the given zone.
*/
extern struct cred *zone_get_kcred(zoneid_t);
/*
* Get/set the pool the zone is currently bound to.
*/
extern struct pool *zone_pool_get(zone_t *);
extern void zone_pool_set(zone_t *, struct pool *);
/*
* Get/set the pset the zone is currently using.
*/
extern psetid_t zone_pset_get(zone_t *);
extern void zone_pset_set(zone_t *, psetid_t);
/*
* Get the number of cpus/online-cpus visible from the given zone.
*/
extern int zone_ncpus_get(zone_t *);
extern int zone_ncpus_online_get(zone_t *);
/*
* Returns true if the named pool/dataset is visible in the current zone.
*/
extern int zone_dataset_visible(const char *, int *);
/*
* zone version of kadmin()
*/
extern int zone_kadmin(int, int, const char *, cred_t *);
extern void zone_shutdown_global(void);
extern void mount_in_progress(void);
extern void mount_completed(void);
extern int zone_walk(int (*)(zone_t *, void *), void *);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_ZONE_H */
|