Print this page
Code review comments from pmooney (sundry), and igork (screwups in zonecfg refactoring)
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/zonecfg/zonecfg.c
+++ new/usr/src/cmd/zonecfg/zonecfg.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 25 * Copyright 2014 Gary Mills
26 26 */
27 27
28 28 /*
29 29 * zonecfg is a lex/yacc based command interpreter used to manage zone
30 30 * configurations. The lexer (see zonecfg_lex.l) builds up tokens, which
31 31 * the grammar (see zonecfg_grammar.y) builds up into commands, some of
32 32 * which takes resources and/or properties as arguments. See the block
33 33 * comments near the end of zonecfg_grammar.y for how the data structures
34 34 * which keep track of these resources and properties are built up.
35 35 *
36 36 * The resource/property data structures are inserted into a command
37 37 * structure (see zonecfg.h), which also keeps track of command names,
38 38 * miscellaneous arguments, and function handlers. The grammar selects
39 39 * the appropriate function handler, each of which takes a pointer to a
40 40 * command structure as its sole argument, and invokes it. The grammar
41 41 * itself is "entered" (a la the Matrix) by yyparse(), which is called
42 42 * from read_input(), our main driving function. That in turn is called
43 43 * by one of do_interactive(), cmd_file() or one_command_at_a_time(), each
44 44 * of which is called from main() depending on how the program was invoked.
45 45 *
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
46 46 * The rest of this module consists of the various function handlers and
47 47 * their helper functions. Some of these functions, particularly the
48 48 * X_to_str() functions, which maps command, resource and property numbers
49 49 * to strings, are used quite liberally, as doing so results in a better
50 50 * program w/rt I18N, reducing the need for translation notes.
51 51 */
52 52
53 53 #include <sys/mntent.h>
54 54 #include <sys/varargs.h>
55 55 #include <sys/sysmacros.h>
56 +#include <sys/secflags.h>
56 57
57 58 #include <errno.h>
58 59 #include <fcntl.h>
59 60 #include <strings.h>
60 61 #include <unistd.h>
61 62 #include <ctype.h>
62 63 #include <stdlib.h>
63 64 #include <assert.h>
64 65 #include <sys/stat.h>
65 66 #include <zone.h>
66 67 #include <arpa/inet.h>
67 68 #include <netdb.h>
68 69 #include <locale.h>
69 70 #include <libintl.h>
70 71 #include <alloca.h>
71 72 #include <signal.h>
72 73 #include <wait.h>
73 74 #include <libtecla.h>
74 75 #include <libzfs.h>
75 76 #include <sys/brand.h>
76 77 #include <libbrand.h>
77 78 #include <sys/systeminfo.h>
78 79 #include <libdladm.h>
79 80 #include <libinetutil.h>
80 81 #include <pwd.h>
81 82 #include <inet/ip.h>
82 83
83 84 #include <libzonecfg.h>
84 85 #include "zonecfg.h"
85 86
86 87 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
87 88 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
88 89 #endif
89 90
90 91 #define PAGER "/usr/bin/more"
91 92 #define EXEC_PREFIX "exec "
92 93 #define EXEC_LEN (strlen(EXEC_PREFIX))
93 94
94 95 struct help {
95 96 uint_t cmd_num;
96 97 char *cmd_name;
97 98 uint_t flags;
98 99 char *short_usage;
99 100 };
100 101
101 102 extern int yyparse(void);
102 103 extern int lex_lineno;
103 104
104 105 #define MAX_LINE_LEN 1024
105 106 #define MAX_CMD_HIST 1024
106 107 #define MAX_CMD_LEN 1024
107 108
108 109 #define ONE_MB 1048576
109 110
110 111 /*
111 112 * Each SHELP_ should be a simple string.
112 113 */
113 114
114 115 #define SHELP_ADD "add <resource-type>\n\t(global scope)\n" \
115 116 "add <property-name> <property-value>\n\t(resource scope)"
116 117 #define SHELP_CANCEL "cancel"
117 118 #define SHELP_CLEAR "clear <property-name>"
118 119 #define SHELP_COMMIT "commit"
119 120 #define SHELP_CREATE "create [-F] [ -a <path> | -b | -t <template> ]"
120 121 #define SHELP_DELETE "delete [-F]"
121 122 #define SHELP_END "end"
122 123 #define SHELP_EXIT "exit [-F]"
123 124 #define SHELP_EXPORT "export [-f output-file]"
124 125 #define SHELP_HELP "help [commands] [syntax] [usage] [<command-name>]"
125 126 #define SHELP_INFO "info [<resource-type> [property-name=property-value]*]"
126 127 #define SHELP_REMOVE "remove [-F] <resource-type> " \
127 128 "[ <property-name>=<property-value> ]*\n" \
128 129 "\t(global scope)\n" \
129 130 "remove <property-name> <property-value>\n" \
130 131 "\t(resource scope)"
131 132 #define SHELP_REVERT "revert [-F]"
132 133 #define SHELP_SELECT "select <resource-type> { <property-name>=" \
133 134 "<property-value> }"
134 135 #define SHELP_SET "set <property-name>=<property-value>"
135 136 #define SHELP_VERIFY "verify"
136 137
137 138 static struct help helptab[] = {
138 139 { CMD_ADD, "add", HELP_RES_PROPS, SHELP_ADD, },
139 140 { CMD_CANCEL, "cancel", 0, SHELP_CANCEL, },
140 141 { CMD_CLEAR, "clear", HELP_PROPS, SHELP_CLEAR, },
141 142 { CMD_COMMIT, "commit", 0, SHELP_COMMIT, },
142 143 { CMD_CREATE, "create", 0, SHELP_CREATE, },
143 144 { CMD_DELETE, "delete", 0, SHELP_DELETE, },
144 145 { CMD_END, "end", 0, SHELP_END, },
145 146 { CMD_EXIT, "exit", 0, SHELP_EXIT, },
146 147 { CMD_EXPORT, "export", 0, SHELP_EXPORT, },
147 148 { CMD_HELP, "help", 0, SHELP_HELP },
148 149 { CMD_INFO, "info", HELP_RES_PROPS, SHELP_INFO, },
149 150 { CMD_REMOVE, "remove", HELP_RES_PROPS, SHELP_REMOVE, },
150 151 { CMD_REVERT, "revert", 0, SHELP_REVERT, },
151 152 { CMD_SELECT, "select", HELP_RES_PROPS, SHELP_SELECT, },
152 153 { CMD_SET, "set", HELP_PROPS, SHELP_SET, },
153 154 { CMD_VERIFY, "verify", 0, SHELP_VERIFY, },
154 155 { 0 },
155 156 };
156 157
157 158 #define MAX_RT_STRLEN 16
158 159
159 160 /* These *must* match the order of the RT_ define's from zonecfg.h */
160 161 char *res_types[] = {
161 162 "unknown",
162 163 "zonename",
163 164 "zonepath",
164 165 "autoboot",
165 166 "pool",
166 167 "fs",
167 168 "net",
168 169 "device",
169 170 "rctl",
170 171 "attr",
171 172 "dataset",
172 173 "limitpriv",
173 174 "bootargs",
174 175 "brand",
175 176 "dedicated-cpu",
176 177 "capped-memory",
177 178 ALIAS_MAXLWPS,
178 179 ALIAS_MAXSHMMEM,
179 180 ALIAS_MAXSHMIDS,
↓ open down ↓ |
114 lines elided |
↑ open up ↑ |
180 181 ALIAS_MAXMSGIDS,
181 182 ALIAS_MAXSEMIDS,
182 183 ALIAS_SHARES,
183 184 "scheduling-class",
184 185 "ip-type",
185 186 "capped-cpu",
186 187 "hostid",
187 188 "admin",
188 189 "fs-allowed",
189 190 ALIAS_MAXPROCS,
191 + "security-flags",
190 192 NULL
191 193 };
192 194
193 195 /* These *must* match the order of the PT_ define's from zonecfg.h */
194 196 char *prop_types[] = {
195 197 "unknown",
196 198 "zonename",
197 199 "zonepath",
198 200 "autoboot",
199 201 "pool",
200 202 "dir",
201 203 "special",
202 204 "type",
203 205 "options",
204 206 "address",
205 207 "physical",
206 208 "name",
207 209 "value",
208 210 "match",
209 211 "priv",
210 212 "limit",
211 213 "action",
212 214 "raw",
213 215 "limitpriv",
214 216 "bootargs",
215 217 "brand",
216 218 "ncpus",
217 219 "importance",
218 220 "swap",
219 221 "locked",
220 222 ALIAS_SHARES,
221 223 ALIAS_MAXLWPS,
222 224 ALIAS_MAXSHMMEM,
223 225 ALIAS_MAXSHMIDS,
224 226 ALIAS_MAXMSGIDS,
225 227 ALIAS_MAXSEMIDS,
226 228 ALIAS_MAXLOCKEDMEM,
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
227 229 ALIAS_MAXSWAP,
228 230 "scheduling-class",
229 231 "ip-type",
230 232 "defrouter",
231 233 "hostid",
232 234 "user",
233 235 "auths",
234 236 "fs-allowed",
235 237 ALIAS_MAXPROCS,
236 238 "allowed-address",
239 + "default",
240 + "lower",
241 + "upper",
237 242 NULL
238 243 };
239 244
240 245 /* These *must* match the order of the PROP_VAL_ define's from zonecfg.h */
241 246 static char *prop_val_types[] = {
242 247 "simple",
243 248 "complex",
244 249 "list",
245 250 };
246 251
247 252 /*
248 253 * The various _cmds[] lists below are for command tab-completion.
249 254 */
250 255
251 256 /*
252 257 * remove has a space afterwards because it has qualifiers; the other commands
253 258 * that have qualifiers (add, select, etc.) don't need a space here because
254 259 * they have their own _cmds[] lists below.
255 260 */
256 261 static const char *global_scope_cmds[] = {
257 262 "add",
258 263 "clear",
259 264 "commit",
260 265 "create",
261 266 "delete",
262 267 "exit",
263 268 "export",
264 269 "help",
265 270 "info",
266 271 "remove ",
267 272 "revert",
268 273 "select",
269 274 "set",
270 275 "verify",
271 276 NULL
272 277 };
273 278
274 279 static const char *add_cmds[] = {
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
275 280 "add fs",
276 281 "add net",
277 282 "add device",
278 283 "add rctl",
279 284 "add attr",
280 285 "add dataset",
281 286 "add dedicated-cpu",
282 287 "add capped-cpu",
283 288 "add capped-memory",
284 289 "add admin",
290 + "add security-flags",
285 291 NULL
286 292 };
287 293
288 294 static const char *clear_cmds[] = {
289 295 "clear autoboot",
290 296 "clear pool",
291 297 "clear limitpriv",
292 298 "clear bootargs",
293 299 "clear scheduling-class",
294 300 "clear ip-type",
295 301 "clear " ALIAS_MAXLWPS,
296 302 "clear " ALIAS_MAXSHMMEM,
297 303 "clear " ALIAS_MAXSHMIDS,
298 304 "clear " ALIAS_MAXMSGIDS,
299 305 "clear " ALIAS_MAXSEMIDS,
300 306 "clear " ALIAS_SHARES,
301 307 "clear " ALIAS_MAXPROCS,
302 308 NULL
303 309 };
304 310
305 311 static const char *remove_cmds[] = {
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
306 312 "remove fs ",
307 313 "remove net ",
308 314 "remove device ",
309 315 "remove rctl ",
310 316 "remove attr ",
311 317 "remove dataset ",
312 318 "remove dedicated-cpu ",
313 319 "remove capped-cpu ",
314 320 "remove capped-memory ",
315 321 "remove admin ",
322 + "remove security-flags",
316 323 NULL
317 324 };
318 325
319 326 static const char *select_cmds[] = {
320 327 "select fs ",
321 328 "select net ",
322 329 "select device ",
323 330 "select rctl ",
324 331 "select attr ",
325 332 "select dataset ",
326 333 "select dedicated-cpu",
327 334 "select capped-cpu",
328 335 "select capped-memory",
329 336 "select admin",
337 + "select security-flags",
330 338 NULL
331 339 };
332 340
333 341 static const char *set_cmds[] = {
334 342 "set zonename=",
335 343 "set zonepath=",
336 344 "set brand=",
337 345 "set autoboot=",
338 346 "set pool=",
339 347 "set limitpriv=",
340 348 "set bootargs=",
341 349 "set scheduling-class=",
342 350 "set ip-type=",
343 351 "set " ALIAS_MAXLWPS "=",
344 352 "set " ALIAS_MAXSHMMEM "=",
345 353 "set " ALIAS_MAXSHMIDS "=",
346 354 "set " ALIAS_MAXMSGIDS "=",
347 355 "set " ALIAS_MAXSEMIDS "=",
348 356 "set " ALIAS_SHARES "=",
349 357 "set hostid=",
350 358 "set fs-allowed=",
351 359 "set " ALIAS_MAXPROCS "=",
352 360 NULL
353 361 };
354 362
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
355 363 static const char *info_cmds[] = {
356 364 "info fs ",
357 365 "info net ",
358 366 "info device ",
359 367 "info rctl ",
360 368 "info attr ",
361 369 "info dataset ",
362 370 "info capped-memory",
363 371 "info dedicated-cpu",
364 372 "info capped-cpu",
373 + "info security-flags",
365 374 "info zonename",
366 375 "info zonepath",
367 376 "info autoboot",
368 377 "info pool",
369 378 "info limitpriv",
370 379 "info bootargs",
371 380 "info brand",
372 381 "info scheduling-class",
373 382 "info ip-type",
374 383 "info max-lwps",
375 384 "info max-shm-memory",
376 385 "info max-shm-ids",
377 386 "info max-msg-ids",
378 387 "info max-sem-ids",
379 388 "info cpu-shares",
380 389 "info hostid",
381 390 "info admin",
382 391 "info fs-allowed",
383 392 "info max-processes",
384 393 NULL
385 394 };
386 395
387 396 static const char *fs_res_scope_cmds[] = {
388 397 "add options ",
389 398 "cancel",
390 399 "end",
391 400 "exit",
392 401 "help",
393 402 "info",
394 403 "remove options ",
395 404 "set dir=",
396 405 "set raw=",
397 406 "set special=",
398 407 "set type=",
399 408 "clear raw",
400 409 NULL
401 410 };
402 411
403 412 static const char *net_res_scope_cmds[] = {
404 413 "cancel",
405 414 "end",
406 415 "exit",
407 416 "help",
408 417 "info",
409 418 "set address=",
410 419 "set physical=",
411 420 "set defrouter=",
412 421 NULL
413 422 };
414 423
415 424 static const char *device_res_scope_cmds[] = {
416 425 "cancel",
417 426 "end",
418 427 "exit",
419 428 "help",
420 429 "info",
421 430 "set match=",
422 431 NULL
423 432 };
424 433
425 434 static const char *attr_res_scope_cmds[] = {
426 435 "cancel",
427 436 "end",
428 437 "exit",
429 438 "help",
430 439 "info",
431 440 "set name=",
432 441 "set type=",
433 442 "set value=",
434 443 NULL
435 444 };
436 445
437 446 static const char *rctl_res_scope_cmds[] = {
438 447 "add value ",
439 448 "cancel",
440 449 "end",
441 450 "exit",
442 451 "help",
443 452 "info",
444 453 "remove value ",
445 454 "set name=",
446 455 NULL
447 456 };
448 457
449 458 static const char *dataset_res_scope_cmds[] = {
450 459 "cancel",
451 460 "end",
452 461 "exit",
453 462 "help",
454 463 "info",
455 464 "set name=",
456 465 NULL
457 466 };
458 467
459 468 static const char *pset_res_scope_cmds[] = {
460 469 "cancel",
461 470 "end",
462 471 "exit",
463 472 "help",
464 473 "info",
465 474 "set ncpus=",
466 475 "set importance=",
467 476 "clear importance",
468 477 NULL
469 478 };
470 479
471 480 static const char *pcap_res_scope_cmds[] = {
472 481 "cancel",
473 482 "end",
474 483 "exit",
475 484 "help",
476 485 "info",
477 486 "set ncpus=",
478 487 NULL
479 488 };
480 489
481 490 static const char *mcap_res_scope_cmds[] = {
482 491 "cancel",
483 492 "end",
484 493 "exit",
485 494 "help",
486 495 "info",
487 496 "set physical=",
488 497 "set swap=",
489 498 "set locked=",
490 499 "clear physical",
491 500 "clear swap",
492 501 "clear locked",
493 502 NULL
494 503 };
495 504
496 505 static const char *admin_res_scope_cmds[] = {
↓ open down ↓ |
122 lines elided |
↑ open up ↑ |
497 506 "cancel",
498 507 "end",
499 508 "exit",
500 509 "help",
501 510 "info",
502 511 "set user=",
503 512 "set auths=",
504 513 NULL
505 514 };
506 515
516 +static const char *secflags_res_scope_cmds[] = {
517 + "cancel",
518 + "end",
519 + "exit",
520 + "set default=",
521 + "set lower=",
522 + "set upper=",
523 + NULL
524 +};
525 +
507 526 struct xif {
508 527 struct xif *xif_next;
509 528 char xif_name[LIFNAMSIZ];
510 529 boolean_t xif_has_address;
511 530 boolean_t xif_has_defrouter;
512 531 };
513 532
514 533 /* Global variables */
515 534
516 535 /* list of network interfaces specified for exclusive IP zone */
517 536 struct xif *xif;
518 537
519 538 /* set early in main(), never modified thereafter, used all over the place */
520 539 static char *execname;
521 540
522 541 /* set in main(), used all over the place */
523 542 static zone_dochandle_t handle;
524 543
525 544 /* used all over the place */
526 545 static char zone[ZONENAME_MAX];
527 546 static char revert_zone[ZONENAME_MAX];
528 547
529 548 /* global brand operations */
530 549 static brand_handle_t brand;
531 550
532 551 /* set in modifying functions, checked in read_input() */
533 552 static boolean_t need_to_commit = B_FALSE;
534 553 boolean_t saw_error;
535 554
536 555 /* set in yacc parser, checked in read_input() */
537 556 boolean_t newline_terminated;
538 557
539 558 /* set in main(), checked in lex error handler */
540 559 boolean_t cmd_file_mode;
541 560
542 561 /* set in exit_func(), checked in read_input() */
543 562 static boolean_t time_to_exit = B_FALSE, force_exit = B_FALSE;
544 563
545 564 /* used in short_usage() and zerr() */
546 565 static char *cmd_file_name = NULL;
547 566
548 567 /* checked in read_input() and other places */
549 568 static boolean_t ok_to_prompt = B_FALSE;
550 569
551 570 /* set and checked in initialize() */
552 571 static boolean_t got_handle = B_FALSE;
553 572
554 573 /* initialized in do_interactive(), checked in initialize() */
555 574 static boolean_t interactive_mode;
556 575
557 576 /* set if configuring the global zone */
558 577 static boolean_t global_zone = B_FALSE;
559 578
560 579 /* set in main(), checked in multiple places */
561 580 static boolean_t read_only_mode;
562 581
563 582 /* scope is outer/global or inner/resource */
564 583 static boolean_t global_scope = B_TRUE;
565 584 static int resource_scope; /* should be in the RT_ list from zonecfg.h */
566 585 static int end_op = -1; /* operation on end is either add or modify */
567 586
568 587 int num_prop_vals; /* for grammar */
569 588
570 589 /*
571 590 * These are for keeping track of resources as they are specified as part of
572 591 * the multi-step process. They should be initialized by add_resource() or
573 592 * select_func() and filled in by add_property() or set_func().
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
574 593 */
575 594 static struct zone_fstab old_fstab, in_progress_fstab;
576 595 static struct zone_nwiftab old_nwiftab, in_progress_nwiftab;
577 596 static struct zone_devtab old_devtab, in_progress_devtab;
578 597 static struct zone_rctltab old_rctltab, in_progress_rctltab;
579 598 static struct zone_attrtab old_attrtab, in_progress_attrtab;
580 599 static struct zone_dstab old_dstab, in_progress_dstab;
581 600 static struct zone_psettab old_psettab, in_progress_psettab;
582 601 static struct zone_mcaptab old_mcaptab, in_progress_mcaptab;
583 602 static struct zone_admintab old_admintab, in_progress_admintab;
603 +static struct zone_secflagstab old_secflagstab, in_progress_secflagstab;
584 604
585 605 static GetLine *gl; /* The gl_get_line() resource object */
586 606
587 607 static void bytes_to_units(char *str, char *buf, int bufsize);
588 608
589 609 /* Functions begin here */
590 610
591 611 static boolean_t
592 612 initial_match(const char *line1, const char *line2, int word_end)
593 613 {
594 614 if (word_end <= 0)
595 615 return (B_TRUE);
596 616 return (strncmp(line1, line2, word_end) == 0);
597 617 }
598 618
599 619 static int
600 620 add_stuff(WordCompletion *cpl, const char *line1, const char **list,
601 621 int word_end)
602 622 {
603 623 int i, err;
604 624
605 625 for (i = 0; list[i] != NULL; i++) {
606 626 if (initial_match(line1, list[i], word_end)) {
607 627 err = cpl_add_completion(cpl, line1, 0, word_end,
608 628 list[i] + word_end, "", "");
609 629 if (err != 0)
610 630 return (err);
611 631 }
612 632 }
613 633 return (0);
614 634 }
615 635
616 636 static
617 637 /* ARGSUSED */
618 638 CPL_MATCH_FN(cmd_cpl_fn)
619 639 {
620 640 if (global_scope) {
621 641 /*
622 642 * The MAX/MIN tests below are to make sure we have at least
623 643 * enough characters to distinguish from other prefixes (MAX)
624 644 * but only check MIN(what we have, what we're checking).
625 645 */
626 646 if (strncmp(line, "add ", MAX(MIN(word_end, 4), 1)) == 0)
627 647 return (add_stuff(cpl, line, add_cmds, word_end));
628 648 if (strncmp(line, "clear ", MAX(MIN(word_end, 6), 2)) == 0)
629 649 return (add_stuff(cpl, line, clear_cmds, word_end));
630 650 if (strncmp(line, "select ", MAX(MIN(word_end, 7), 3)) == 0)
631 651 return (add_stuff(cpl, line, select_cmds, word_end));
632 652 if (strncmp(line, "set ", MAX(MIN(word_end, 4), 3)) == 0)
633 653 return (add_stuff(cpl, line, set_cmds, word_end));
634 654 if (strncmp(line, "remove ", MAX(MIN(word_end, 7), 1)) == 0)
635 655 return (add_stuff(cpl, line, remove_cmds, word_end));
636 656 if (strncmp(line, "info ", MAX(MIN(word_end, 5), 1)) == 0)
637 657 return (add_stuff(cpl, line, info_cmds, word_end));
638 658 return (add_stuff(cpl, line, global_scope_cmds, word_end));
639 659 }
640 660 switch (resource_scope) {
641 661 case RT_FS:
642 662 return (add_stuff(cpl, line, fs_res_scope_cmds, word_end));
643 663 case RT_NET:
644 664 return (add_stuff(cpl, line, net_res_scope_cmds, word_end));
645 665 case RT_DEVICE:
646 666 return (add_stuff(cpl, line, device_res_scope_cmds, word_end));
647 667 case RT_RCTL:
648 668 return (add_stuff(cpl, line, rctl_res_scope_cmds, word_end));
649 669 case RT_ATTR:
650 670 return (add_stuff(cpl, line, attr_res_scope_cmds, word_end));
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
651 671 case RT_DATASET:
652 672 return (add_stuff(cpl, line, dataset_res_scope_cmds, word_end));
653 673 case RT_DCPU:
654 674 return (add_stuff(cpl, line, pset_res_scope_cmds, word_end));
655 675 case RT_PCAP:
656 676 return (add_stuff(cpl, line, pcap_res_scope_cmds, word_end));
657 677 case RT_MCAP:
658 678 return (add_stuff(cpl, line, mcap_res_scope_cmds, word_end));
659 679 case RT_ADMIN:
660 680 return (add_stuff(cpl, line, admin_res_scope_cmds, word_end));
681 + case RT_SECFLAGS:
682 + return (add_stuff(cpl, line, secflags_res_scope_cmds,
683 + word_end));
684 +
661 685 }
662 686 return (0);
663 687 }
664 688
665 689 /*
666 690 * For the main CMD_func() functions below, several of them call getopt()
667 691 * then check optind against argc to make sure an extra parameter was not
668 692 * passed in. The reason this is not caught in the grammar is that the
669 693 * grammar just checks for a miscellaneous TOKEN, which is *expected* to
670 694 * be "-F" (for example), but could be anything. So (for example) this
671 695 * check will prevent "create bogus".
672 696 */
673 697
674 698 cmd_t *
675 699 alloc_cmd(void)
676 700 {
677 701 return (calloc(1, sizeof (cmd_t)));
678 702 }
679 703
680 704 void
681 705 free_cmd(cmd_t *cmd)
682 706 {
683 707 int i;
684 708
685 709 for (i = 0; i < MAX_EQ_PROP_PAIRS; i++)
686 710 if (cmd->cmd_property_ptr[i] != NULL) {
687 711 property_value_ptr_t pp = cmd->cmd_property_ptr[i];
688 712
689 713 switch (pp->pv_type) {
690 714 case PROP_VAL_SIMPLE:
691 715 free(pp->pv_simple);
692 716 break;
693 717 case PROP_VAL_COMPLEX:
694 718 free_complex(pp->pv_complex);
695 719 break;
696 720 case PROP_VAL_LIST:
697 721 free_list(pp->pv_list);
698 722 break;
699 723 }
700 724 }
701 725 for (i = 0; i < cmd->cmd_argc; i++)
702 726 free(cmd->cmd_argv[i]);
703 727 free(cmd);
704 728 }
705 729
706 730 complex_property_ptr_t
707 731 alloc_complex(void)
708 732 {
709 733 return (calloc(1, sizeof (complex_property_t)));
710 734 }
711 735
712 736 void
713 737 free_complex(complex_property_ptr_t complex)
714 738 {
715 739 if (complex == NULL)
716 740 return;
717 741 free_complex(complex->cp_next);
718 742 if (complex->cp_value != NULL)
719 743 free(complex->cp_value);
720 744 free(complex);
721 745 }
722 746
723 747 list_property_ptr_t
724 748 alloc_list(void)
725 749 {
726 750 return (calloc(1, sizeof (list_property_t)));
727 751 }
728 752
729 753 void
730 754 free_list(list_property_ptr_t list)
731 755 {
732 756 if (list == NULL)
733 757 return;
734 758 if (list->lp_simple != NULL)
735 759 free(list->lp_simple);
736 760 free_complex(list->lp_complex);
737 761 free_list(list->lp_next);
738 762 free(list);
739 763 }
740 764
741 765 void
742 766 free_outer_list(list_property_ptr_t list)
743 767 {
744 768 if (list == NULL)
745 769 return;
746 770 free_outer_list(list->lp_next);
747 771 free(list);
748 772 }
749 773
750 774 static struct zone_rctlvaltab *
751 775 alloc_rctlvaltab(void)
752 776 {
753 777 return (calloc(1, sizeof (struct zone_rctlvaltab)));
754 778 }
755 779
756 780 static char *
757 781 rt_to_str(int res_type)
758 782 {
759 783 assert(res_type >= RT_MIN && res_type <= RT_MAX);
760 784 return (res_types[res_type]);
761 785 }
762 786
763 787 static char *
764 788 pt_to_str(int prop_type)
765 789 {
766 790 assert(prop_type >= PT_MIN && prop_type <= PT_MAX);
767 791 return (prop_types[prop_type]);
768 792 }
769 793
770 794 static char *
771 795 pvt_to_str(int pv_type)
772 796 {
773 797 assert(pv_type >= PROP_VAL_MIN && pv_type <= PROP_VAL_MAX);
774 798 return (prop_val_types[pv_type]);
775 799 }
776 800
777 801 static char *
778 802 cmd_to_str(int cmd_num)
779 803 {
780 804 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
781 805 return (helptab[cmd_num].cmd_name);
782 806 }
783 807
784 808 /* PRINTFLIKE1 */
785 809 static void
786 810 zerr(const char *fmt, ...)
787 811 {
788 812 va_list alist;
789 813 static int last_lineno;
790 814
791 815 /* lex_lineno has already been incremented in the lexer; compensate */
792 816 if (cmd_file_mode && lex_lineno > last_lineno) {
793 817 if (strcmp(cmd_file_name, "-") == 0)
794 818 (void) fprintf(stderr, gettext("On line %d:\n"),
795 819 lex_lineno - 1);
796 820 else
797 821 (void) fprintf(stderr, gettext("On line %d of %s:\n"),
798 822 lex_lineno - 1, cmd_file_name);
799 823 last_lineno = lex_lineno;
800 824 }
801 825 va_start(alist, fmt);
802 826 (void) vfprintf(stderr, fmt, alist);
803 827 (void) fprintf(stderr, "\n");
804 828 va_end(alist);
805 829 }
806 830
807 831 /*
808 832 * This is a separate function rather than a set of define's because of the
809 833 * gettext() wrapping.
810 834 */
811 835
812 836 /*
813 837 * TRANSLATION_NOTE
814 838 * Each string below should have \t follow \n whenever needed; the
815 839 * initial \t and the terminal \n will be provided by the calling function.
816 840 */
817 841
818 842 static char *
819 843 long_help(int cmd_num)
820 844 {
821 845 static char line[1024]; /* arbitrary large amount */
822 846
823 847 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
824 848 switch (cmd_num) {
825 849 case CMD_HELP:
826 850 return (gettext("Prints help message."));
827 851 case CMD_CREATE:
828 852 (void) snprintf(line, sizeof (line),
829 853 gettext("Creates a configuration for the "
830 854 "specified zone. %s should be\n\tused to "
831 855 "begin configuring a new zone. If overwriting an "
832 856 "existing\n\tconfiguration, the -F flag can be "
833 857 "used to force the action. If\n\t-t template is "
834 858 "given, creates a configuration identical to the\n"
835 859 "\tspecified template, except that the zone name "
836 860 "is changed from\n\ttemplate to zonename. '%s -a' "
837 861 "creates a configuration from a\n\tdetached "
838 862 "zonepath. '%s -b' results in a blank "
839 863 "configuration.\n\t'%s' with no arguments applies "
840 864 "the Sun default settings."),
841 865 cmd_to_str(CMD_CREATE), cmd_to_str(CMD_CREATE),
842 866 cmd_to_str(CMD_CREATE), cmd_to_str(CMD_CREATE));
843 867 return (line);
844 868 case CMD_EXIT:
845 869 return (gettext("Exits the program. The -F flag can "
846 870 "be used to force the action."));
847 871 case CMD_EXPORT:
848 872 return (gettext("Prints configuration to standard "
849 873 "output, or to output-file if\n\tspecified, in "
850 874 "a form suitable for use in a command-file."));
851 875 case CMD_ADD:
852 876 return (gettext("Add specified resource to "
853 877 "configuration."));
854 878 case CMD_DELETE:
855 879 return (gettext("Deletes the specified zone. The -F "
856 880 "flag can be used to force the\n\taction."));
857 881 case CMD_REMOVE:
858 882 return (gettext("Remove specified resource from "
859 883 "configuration. The -F flag can be used\n\tto "
860 884 "force the action."));
861 885 case CMD_SELECT:
862 886 (void) snprintf(line, sizeof (line),
863 887 gettext("Selects a resource to modify. "
864 888 "Resource modification is completed\n\twith the "
865 889 "command \"%s\". The property name/value pairs "
866 890 "must uniquely\n\tidentify a resource. Note that "
867 891 "the curly braces ('{', '}') mean one\n\tor more "
868 892 "of whatever is between them."),
869 893 cmd_to_str(CMD_END));
870 894 return (line);
871 895 case CMD_SET:
872 896 return (gettext("Sets property values."));
873 897 case CMD_CLEAR:
874 898 return (gettext("Clears property values."));
875 899 case CMD_INFO:
876 900 return (gettext("Displays information about the "
877 901 "current configuration. If resource\n\ttype is "
878 902 "specified, displays only information about "
879 903 "resources of\n\tthe relevant type. If resource "
880 904 "id is specified, displays only\n\tinformation "
881 905 "about that resource."));
882 906 case CMD_VERIFY:
883 907 return (gettext("Verifies current configuration "
884 908 "for correctness (some resource types\n\thave "
885 909 "required properties)."));
886 910 case CMD_COMMIT:
887 911 (void) snprintf(line, sizeof (line),
888 912 gettext("Commits current configuration. "
889 913 "Configuration must be committed to\n\tbe used by "
890 914 "%s. Until the configuration is committed, "
891 915 "changes \n\tcan be removed with the %s "
892 916 "command. This operation is\n\tattempted "
893 917 "automatically upon completion of a %s "
894 918 "session."), "zoneadm", cmd_to_str(CMD_REVERT),
895 919 "zonecfg");
896 920 return (line);
897 921 case CMD_REVERT:
898 922 return (gettext("Reverts configuration back to the "
899 923 "last committed state. The -F flag\n\tcan be "
900 924 "used to force the action."));
901 925 case CMD_CANCEL:
902 926 return (gettext("Cancels resource/property "
903 927 "specification."));
904 928 case CMD_END:
905 929 return (gettext("Ends resource/property "
906 930 "specification."));
907 931 }
908 932 /* NOTREACHED */
909 933 return (NULL);
910 934 }
911 935
912 936 /*
913 937 * Return the input filename appended to each component of the path
914 938 * or the filename itself if it is absolute.
915 939 * Parameters: path string, file name, output string.
916 940 */
917 941 /* Copied almost verbatim from libtnfctl/prb_findexec.c */
918 942 static const char *
919 943 exec_cat(const char *s1, const char *s2, char *si)
920 944 {
921 945 char *s;
922 946 /* Number of remaining characters in s */
923 947 int cnt = PATH_MAX + 1;
924 948
925 949 s = si;
926 950 while (*s1 && *s1 != ':') { /* Copy first component of path to si */
927 951 if (cnt > 0) {
928 952 *s++ = *s1++;
929 953 cnt--;
930 954 } else {
931 955 s1++;
932 956 }
933 957 }
934 958 if (si != s && cnt > 0) { /* Add slash if s2 is not absolute */
935 959 *s++ = '/';
936 960 cnt--;
937 961 }
938 962 while (*s2 && cnt > 0) { /* Copy s2 to si */
939 963 *s++ = *s2++;
940 964 cnt--;
941 965 }
942 966 *s = '\0'; /* Terminate the output string */
943 967 return (*s1 ? ++s1 : NULL); /* Return next path component or NULL */
944 968 }
945 969
946 970 /* Determine that a name exists in PATH */
947 971 /* Copied with changes from libtnfctl/prb_findexec.c */
948 972 static int
949 973 path_find(const char *name)
950 974 {
951 975 const char *pathstr;
952 976 char fname[PATH_MAX + 2];
953 977 const char *cp;
954 978 struct stat stat_buf;
955 979
956 980 if ((pathstr = getenv("PATH")) == NULL) {
957 981 if (geteuid() == 0 || getuid() == 0)
958 982 pathstr = "/usr/sbin:/usr/bin";
959 983 else
960 984 pathstr = "/usr/bin:";
961 985 }
962 986 cp = strchr(name, '/') ? (const char *) "" : pathstr;
963 987
964 988 do {
965 989 cp = exec_cat(cp, name, fname);
↓ open down ↓ |
295 lines elided |
↑ open up ↑ |
966 990 if (stat(fname, &stat_buf) != -1) {
967 991 /* successful find of the file */
968 992 return (0);
969 993 }
970 994 } while (cp != NULL);
971 995
972 996 return (-1);
973 997 }
974 998
975 999 static FILE *
976 -pager_open(void) {
1000 +pager_open(void)
1001 +{
977 1002 FILE *newfp;
978 1003 char *pager, *space;
979 1004
980 1005 pager = getenv("PAGER");
981 1006 if (pager == NULL || *pager == '\0')
982 1007 pager = PAGER;
983 1008
984 1009 space = strchr(pager, ' ');
985 1010 if (space)
986 1011 *space = '\0';
987 1012 if (path_find(pager) == 0) {
988 1013 if (space)
989 1014 *space = ' ';
990 1015 if ((newfp = popen(pager, "w")) == NULL)
991 1016 zerr(gettext("PAGER open failed (%s)."),
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
992 1017 strerror(errno));
993 1018 return (newfp);
994 1019 } else {
995 1020 zerr(gettext("PAGER %s does not exist (%s)."),
996 1021 pager, strerror(errno));
997 1022 }
998 1023 return (NULL);
999 1024 }
1000 1025
1001 1026 static void
1002 -pager_close(FILE *fp) {
1027 +pager_close(FILE *fp)
1028 +{
1003 1029 int status;
1004 1030
1005 1031 status = pclose(fp);
1006 1032 if (status == -1)
1007 1033 zerr(gettext("PAGER close failed (%s)."),
1008 1034 strerror(errno));
1009 1035 }
1010 1036
1011 1037 /*
1012 1038 * Called with verbose TRUE when help is explicitly requested, FALSE for
1013 1039 * unexpected errors.
1014 1040 */
1015 1041
1016 1042 void
1017 1043 usage(boolean_t verbose, uint_t flags)
1018 1044 {
1019 1045 FILE *fp = verbose ? stdout : stderr;
1020 1046 FILE *newfp;
1021 1047 boolean_t need_to_close = B_FALSE;
1022 1048 int i;
1023 1049
1024 1050 /* don't page error output */
1025 1051 if (verbose && interactive_mode) {
1026 1052 if ((newfp = pager_open()) != NULL) {
1027 1053 need_to_close = B_TRUE;
1028 1054 fp = newfp;
1029 1055 }
1030 1056 }
1031 1057
1032 1058 if (flags & HELP_META) {
1033 1059 (void) fprintf(fp, gettext("More help is available for the "
1034 1060 "following:\n"));
1035 1061 (void) fprintf(fp, "\n\tcommands ('%s commands')\n",
1036 1062 cmd_to_str(CMD_HELP));
1037 1063 (void) fprintf(fp, "\tsyntax ('%s syntax')\n",
1038 1064 cmd_to_str(CMD_HELP));
1039 1065 (void) fprintf(fp, "\tusage ('%s usage')\n\n",
1040 1066 cmd_to_str(CMD_HELP));
1041 1067 (void) fprintf(fp, gettext("You may also obtain help on any "
1042 1068 "command by typing '%s <command-name>.'\n"),
1043 1069 cmd_to_str(CMD_HELP));
1044 1070 }
1045 1071 if (flags & HELP_RES_SCOPE) {
1046 1072 switch (resource_scope) {
1047 1073 case RT_FS:
1048 1074 (void) fprintf(fp, gettext("The '%s' resource scope is "
1049 1075 "used to configure a file-system.\n"),
1050 1076 rt_to_str(resource_scope));
1051 1077 (void) fprintf(fp, gettext("Valid commands:\n"));
1052 1078 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1053 1079 pt_to_str(PT_DIR), gettext("<path>"));
1054 1080 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1055 1081 pt_to_str(PT_SPECIAL), gettext("<path>"));
1056 1082 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1057 1083 pt_to_str(PT_RAW), gettext("<raw-device>"));
1058 1084 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1059 1085 pt_to_str(PT_TYPE), gettext("<file-system type>"));
1060 1086 (void) fprintf(fp, "\t%s %s %s\n", cmd_to_str(CMD_ADD),
1061 1087 pt_to_str(PT_OPTIONS),
1062 1088 gettext("<file-system options>"));
1063 1089 (void) fprintf(fp, "\t%s %s %s\n",
1064 1090 cmd_to_str(CMD_REMOVE), pt_to_str(PT_OPTIONS),
1065 1091 gettext("<file-system options>"));
1066 1092 (void) fprintf(fp, gettext("Consult the file-system "
1067 1093 "specific manual page, such as mount_ufs(1M), "
1068 1094 "for\ndetails about file-system options. Note "
1069 1095 "that any file-system options with an\nembedded "
1070 1096 "'=' character must be enclosed in double quotes, "
1071 1097 /*CSTYLED*/
1072 1098 "such as \"%s=5\".\n"), MNTOPT_RETRY);
1073 1099 break;
1074 1100 case RT_NET:
1075 1101 (void) fprintf(fp, gettext("The '%s' resource scope is "
1076 1102 "used to configure a network interface.\n"),
1077 1103 rt_to_str(resource_scope));
1078 1104 (void) fprintf(fp, gettext("Valid commands:\n"));
1079 1105 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1080 1106 pt_to_str(PT_ADDRESS), gettext("<IP-address>"));
1081 1107 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1082 1108 pt_to_str(PT_ALLOWED_ADDRESS),
1083 1109 gettext("<IP-address>"));
1084 1110 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1085 1111 pt_to_str(PT_PHYSICAL), gettext("<interface>"));
1086 1112 (void) fprintf(fp, gettext("See ifconfig(1M) for "
1087 1113 "details of the <interface> string.\n"));
1088 1114 (void) fprintf(fp, gettext("%s %s is valid "
1089 1115 "if the %s property is set to %s, otherwise it "
1090 1116 "must not be set.\n"),
1091 1117 cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS),
1092 1118 pt_to_str(PT_IPTYPE), gettext("shared"));
1093 1119 (void) fprintf(fp, gettext("%s %s is valid "
1094 1120 "if the %s property is set to %s, otherwise it "
1095 1121 "must not be set.\n"),
1096 1122 cmd_to_str(CMD_SET), pt_to_str(PT_ALLOWED_ADDRESS),
1097 1123 pt_to_str(PT_IPTYPE), gettext("exclusive"));
1098 1124 (void) fprintf(fp, gettext("\t%s %s=%s\n%s %s "
1099 1125 "is valid if the %s or %s property is set, "
1100 1126 "otherwise it must not be set\n"),
1101 1127 cmd_to_str(CMD_SET),
1102 1128 pt_to_str(PT_DEFROUTER), gettext("<IP-address>"),
1103 1129 cmd_to_str(CMD_SET), pt_to_str(PT_DEFROUTER),
1104 1130 gettext(pt_to_str(PT_ADDRESS)),
1105 1131 gettext(pt_to_str(PT_ALLOWED_ADDRESS)));
1106 1132 break;
1107 1133 case RT_DEVICE:
1108 1134 (void) fprintf(fp, gettext("The '%s' resource scope is "
1109 1135 "used to configure a device node.\n"),
1110 1136 rt_to_str(resource_scope));
1111 1137 (void) fprintf(fp, gettext("Valid commands:\n"));
1112 1138 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1113 1139 pt_to_str(PT_MATCH), gettext("<device-path>"));
1114 1140 break;
1115 1141 case RT_RCTL:
1116 1142 (void) fprintf(fp, gettext("The '%s' resource scope is "
1117 1143 "used to configure a resource control.\n"),
1118 1144 rt_to_str(resource_scope));
1119 1145 (void) fprintf(fp, gettext("Valid commands:\n"));
1120 1146 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1121 1147 pt_to_str(PT_NAME), gettext("<string>"));
1122 1148 (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n",
1123 1149 cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE),
1124 1150 pt_to_str(PT_PRIV), gettext("<priv-value>"),
1125 1151 pt_to_str(PT_LIMIT), gettext("<number>"),
1126 1152 pt_to_str(PT_ACTION), gettext("<action-value>"));
1127 1153 (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n",
1128 1154 cmd_to_str(CMD_REMOVE), pt_to_str(PT_VALUE),
1129 1155 pt_to_str(PT_PRIV), gettext("<priv-value>"),
1130 1156 pt_to_str(PT_LIMIT), gettext("<number>"),
1131 1157 pt_to_str(PT_ACTION), gettext("<action-value>"));
1132 1158 (void) fprintf(fp, "%s\n\t%s := privileged\n"
1133 1159 "\t%s := none | deny\n", gettext("Where"),
1134 1160 gettext("<priv-value>"), gettext("<action-value>"));
1135 1161 break;
1136 1162 case RT_ATTR:
1137 1163 (void) fprintf(fp, gettext("The '%s' resource scope is "
1138 1164 "used to configure a generic attribute.\n"),
1139 1165 rt_to_str(resource_scope));
1140 1166 (void) fprintf(fp, gettext("Valid commands:\n"));
1141 1167 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1142 1168 pt_to_str(PT_NAME), gettext("<name>"));
1143 1169 (void) fprintf(fp, "\t%s %s=boolean\n",
1144 1170 cmd_to_str(CMD_SET), pt_to_str(PT_TYPE));
1145 1171 (void) fprintf(fp, "\t%s %s=true | false\n",
1146 1172 cmd_to_str(CMD_SET), pt_to_str(PT_VALUE));
1147 1173 (void) fprintf(fp, gettext("or\n"));
1148 1174 (void) fprintf(fp, "\t%s %s=int\n", cmd_to_str(CMD_SET),
1149 1175 pt_to_str(PT_TYPE));
1150 1176 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1151 1177 pt_to_str(PT_VALUE), gettext("<integer>"));
1152 1178 (void) fprintf(fp, gettext("or\n"));
1153 1179 (void) fprintf(fp, "\t%s %s=string\n",
1154 1180 cmd_to_str(CMD_SET), pt_to_str(PT_TYPE));
1155 1181 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1156 1182 pt_to_str(PT_VALUE), gettext("<string>"));
1157 1183 (void) fprintf(fp, gettext("or\n"));
1158 1184 (void) fprintf(fp, "\t%s %s=uint\n",
1159 1185 cmd_to_str(CMD_SET), pt_to_str(PT_TYPE));
1160 1186 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1161 1187 pt_to_str(PT_VALUE), gettext("<unsigned integer>"));
1162 1188 break;
1163 1189 case RT_DATASET:
1164 1190 (void) fprintf(fp, gettext("The '%s' resource scope is "
1165 1191 "used to export ZFS datasets.\n"),
1166 1192 rt_to_str(resource_scope));
1167 1193 (void) fprintf(fp, gettext("Valid commands:\n"));
1168 1194 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1169 1195 pt_to_str(PT_NAME), gettext("<name>"));
1170 1196 break;
1171 1197 case RT_DCPU:
1172 1198 (void) fprintf(fp, gettext("The '%s' resource scope "
1173 1199 "configures the 'pools' facility to dedicate\na "
1174 1200 "subset of the system's processors to this zone "
1175 1201 "while it is running.\n"),
1176 1202 rt_to_str(resource_scope));
1177 1203 (void) fprintf(fp, gettext("Valid commands:\n"));
1178 1204 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1179 1205 pt_to_str(PT_NCPUS),
1180 1206 gettext("<unsigned integer | range>"));
1181 1207 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1182 1208 pt_to_str(PT_IMPORTANCE),
1183 1209 gettext("<unsigned integer>"));
1184 1210 break;
1185 1211 case RT_PCAP:
1186 1212 (void) fprintf(fp, gettext("The '%s' resource scope is "
1187 1213 "used to set an upper limit (a cap) on the\n"
1188 1214 "percentage of CPU that can be used by this zone. "
1189 1215 "A '%s' value of 1\ncorresponds to one cpu. The "
1190 1216 "value can be set higher than 1, up to the total\n"
1191 1217 "number of CPUs on the system. The value can "
1192 1218 "also be less than 1,\nrepresenting a fraction of "
1193 1219 "a cpu.\n"),
1194 1220 rt_to_str(resource_scope), pt_to_str(PT_NCPUS));
1195 1221 (void) fprintf(fp, gettext("Valid commands:\n"));
1196 1222 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1197 1223 pt_to_str(PT_NCPUS), gettext("<unsigned decimal>"));
1198 1224 break;
1199 1225 case RT_MCAP:
1200 1226 (void) fprintf(fp, gettext("The '%s' resource scope is "
1201 1227 "used to set an upper limit (a cap) on the\n"
1202 1228 "amount of physical memory, swap space and locked "
1203 1229 "memory that can be used by\nthis zone.\n"),
1204 1230 rt_to_str(resource_scope));
1205 1231 (void) fprintf(fp, gettext("Valid commands:\n"));
1206 1232 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1207 1233 pt_to_str(PT_PHYSICAL),
1208 1234 gettext("<qualified unsigned decimal>"));
1209 1235 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1210 1236 pt_to_str(PT_SWAP),
1211 1237 gettext("<qualified unsigned decimal>"));
1212 1238 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1213 1239 pt_to_str(PT_LOCKED),
1214 1240 gettext("<qualified unsigned decimal>"));
1215 1241 break;
1216 1242 case RT_ADMIN:
1217 1243 (void) fprintf(fp, gettext("The '%s' resource scope is "
1218 1244 "used to delegate specific zone management\n"
1219 1245 "rights to users and roles. These rights are "
↓ open down ↓ |
207 lines elided |
↑ open up ↑ |
1220 1246 "only applicable to this zone.\n"),
1221 1247 rt_to_str(resource_scope));
1222 1248 (void) fprintf(fp, gettext("Valid commands:\n"));
1223 1249 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1224 1250 pt_to_str(PT_USER),
1225 1251 gettext("<single user or role name>"));
1226 1252 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1227 1253 pt_to_str(PT_AUTHS),
1228 1254 gettext("<comma separated list>"));
1229 1255 break;
1256 + case RT_SECFLAGS:
1257 + (void) fprintf(fp, gettext("The '%s' resource scope is "
1258 + "used to specify the default security-flags\n"
1259 + "of this zone, and their upper and lower bound.\n"),
1260 + rt_to_str(resource_scope));
1261 + (void) fprintf(fp, "\t%s %s=%s\n",
1262 + cmd_to_str(CMD_SET), pt_to_str(PT_DEFAULT),
1263 + gettext("<security flags>"));
1264 + (void) fprintf(fp, "\t%s %s=%s\n",
1265 + cmd_to_str(CMD_SET), pt_to_str(PT_LOWER),
1266 + gettext("<security flags>"));
1267 + (void) fprintf(fp, "\t%s %s=%s\n",
1268 + cmd_to_str(CMD_SET), pt_to_str(PT_UPPER),
1269 + gettext("<security flags>"));
1270 + break;
1230 1271 }
1231 1272 (void) fprintf(fp, gettext("And from any resource scope, you "
1232 1273 "can:\n"));
1233 1274 (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_END),
1234 1275 gettext("(to conclude this operation)"));
1235 1276 (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_CANCEL),
1236 1277 gettext("(to cancel this operation)"));
1237 1278 (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_EXIT),
1238 1279 gettext("(to exit the zonecfg utility)"));
1239 1280 }
1240 1281 if (flags & HELP_USAGE) {
1241 1282 (void) fprintf(fp, "%s:\t%s %s\n", gettext("usage"),
1242 1283 execname, cmd_to_str(CMD_HELP));
1243 1284 (void) fprintf(fp, "\t%s -z <zone>\t\t\t(%s)\n",
1244 1285 execname, gettext("interactive"));
1245 1286 (void) fprintf(fp, "\t%s -z <zone> <command>\n", execname);
1246 1287 (void) fprintf(fp, "\t%s -z <zone> -f <command-file>\n",
1247 1288 execname);
1248 1289 }
1249 1290 if (flags & HELP_SUBCMDS) {
1250 1291 (void) fprintf(fp, "%s:\n\n", gettext("Commands"));
1251 1292 for (i = 0; i <= CMD_MAX; i++) {
1252 1293 (void) fprintf(fp, "%s\n", helptab[i].short_usage);
1253 1294 if (verbose)
1254 1295 (void) fprintf(fp, "\t%s\n\n", long_help(i));
1255 1296 }
1256 1297 }
1257 1298 if (flags & HELP_SYNTAX) {
1258 1299 if (!verbose)
1259 1300 (void) fprintf(fp, "\n");
1260 1301 (void) fprintf(fp, "<zone> := [A-Za-z0-9][A-Za-z0-9_.-]*\n");
1261 1302 (void) fprintf(fp, gettext("\t(except the reserved words "
1262 1303 "'%s' and anything starting with '%s')\n"), "global",
1263 1304 "SUNW");
1264 1305 (void) fprintf(fp,
1265 1306 gettext("\tName must be less than %d characters.\n"),
1266 1307 ZONENAME_MAX);
1267 1308 if (verbose)
1268 1309 (void) fprintf(fp, "\n");
1269 1310 }
1270 1311 if (flags & HELP_NETADDR) {
1271 1312 (void) fprintf(fp, gettext("\n<net-addr> :="));
1272 1313 (void) fprintf(fp,
1273 1314 gettext("\t<IPv4-address>[/<IPv4-prefix-length>] |\n"));
1274 1315 (void) fprintf(fp,
1275 1316 gettext("\t\t<IPv6-address>/<IPv6-prefix-length> |\n"));
1276 1317 (void) fprintf(fp,
1277 1318 gettext("\t\t<hostname>[/<IPv4-prefix-length>]\n"));
1278 1319 (void) fprintf(fp, gettext("See inet(3SOCKET) for IPv4 and "
1279 1320 "IPv6 address syntax.\n"));
1280 1321 (void) fprintf(fp, gettext("<IPv4-prefix-length> := [0-32]\n"));
1281 1322 (void) fprintf(fp,
1282 1323 gettext("<IPv6-prefix-length> := [0-128]\n"));
1283 1324 (void) fprintf(fp,
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
1284 1325 gettext("<hostname> := [A-Za-z0-9][A-Za-z0-9-.]*\n"));
1285 1326 }
1286 1327 if (flags & HELP_RESOURCES) {
1287 1328 (void) fprintf(fp, "<%s> := %s | %s | %s | %s | %s |\n\t"
1288 1329 "%s | %s | %s | %s | %s\n\n",
1289 1330 gettext("resource type"), rt_to_str(RT_FS),
1290 1331 rt_to_str(RT_NET), rt_to_str(RT_DEVICE),
1291 1332 rt_to_str(RT_RCTL), rt_to_str(RT_ATTR),
1292 1333 rt_to_str(RT_DATASET), rt_to_str(RT_DCPU),
1293 1334 rt_to_str(RT_PCAP), rt_to_str(RT_MCAP),
1294 - rt_to_str(RT_ADMIN));
1335 + rt_to_str(RT_ADMIN), rt_to_str(RT_SECFLAGS));
1295 1336 }
1296 1337 if (flags & HELP_PROPS) {
1297 1338 (void) fprintf(fp, gettext("For resource type ... there are "
1298 1339 "property types ...:\n"));
1299 1340 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1300 1341 pt_to_str(PT_ZONENAME));
1301 1342 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1302 1343 pt_to_str(PT_ZONEPATH));
1303 1344 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1304 1345 pt_to_str(PT_BRAND));
1305 1346 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1306 1347 pt_to_str(PT_AUTOBOOT));
1307 1348 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1308 1349 pt_to_str(PT_BOOTARGS));
1309 1350 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1310 1351 pt_to_str(PT_POOL));
1311 1352 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1312 1353 pt_to_str(PT_LIMITPRIV));
1313 1354 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1314 1355 pt_to_str(PT_SCHED));
1315 1356 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1316 1357 pt_to_str(PT_IPTYPE));
1317 1358 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1318 1359 pt_to_str(PT_HOSTID));
1319 1360 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1320 1361 pt_to_str(PT_FS_ALLOWED));
1321 1362 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1322 1363 pt_to_str(PT_MAXLWPS));
1323 1364 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1324 1365 pt_to_str(PT_MAXPROCS));
1325 1366 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1326 1367 pt_to_str(PT_MAXSHMMEM));
1327 1368 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1328 1369 pt_to_str(PT_MAXSHMIDS));
1329 1370 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1330 1371 pt_to_str(PT_MAXMSGIDS));
1331 1372 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1332 1373 pt_to_str(PT_MAXSEMIDS));
1333 1374 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1334 1375 pt_to_str(PT_SHARES));
1335 1376 (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s\n",
1336 1377 rt_to_str(RT_FS), pt_to_str(PT_DIR),
1337 1378 pt_to_str(PT_SPECIAL), pt_to_str(PT_RAW),
1338 1379 pt_to_str(PT_TYPE), pt_to_str(PT_OPTIONS));
1339 1380 (void) fprintf(fp, "\t%s\t\t%s, %s, %s|%s\n", rt_to_str(RT_NET),
1340 1381 pt_to_str(PT_ADDRESS), pt_to_str(PT_ALLOWED_ADDRESS),
1341 1382 pt_to_str(PT_PHYSICAL), pt_to_str(PT_DEFROUTER));
1342 1383 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE),
1343 1384 pt_to_str(PT_MATCH));
1344 1385 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL),
1345 1386 pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
1346 1387 (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR),
1347 1388 pt_to_str(PT_NAME), pt_to_str(PT_TYPE),
1348 1389 pt_to_str(PT_VALUE));
1349 1390 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DATASET),
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
1350 1391 pt_to_str(PT_NAME));
1351 1392 (void) fprintf(fp, "\t%s\t%s, %s\n", rt_to_str(RT_DCPU),
1352 1393 pt_to_str(PT_NCPUS), pt_to_str(PT_IMPORTANCE));
1353 1394 (void) fprintf(fp, "\t%s\t%s\n", rt_to_str(RT_PCAP),
1354 1395 pt_to_str(PT_NCPUS));
1355 1396 (void) fprintf(fp, "\t%s\t%s, %s, %s\n", rt_to_str(RT_MCAP),
1356 1397 pt_to_str(PT_PHYSICAL), pt_to_str(PT_SWAP),
1357 1398 pt_to_str(PT_LOCKED));
1358 1399 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_ADMIN),
1359 1400 pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
1401 + (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n",
1402 + rt_to_str(RT_SECFLAGS), pt_to_str(PT_DEFAULT),
1403 + pt_to_str(PT_LOWER), pt_to_str(PT_UPPER));
1360 1404 }
1361 1405 if (need_to_close)
1362 1406 (void) pager_close(fp);
1363 1407 }
1364 1408
1365 1409 static void
1366 1410 zone_perror(char *prefix, int err, boolean_t set_saw)
1367 1411 {
1368 1412 zerr("%s: %s", prefix, zonecfg_strerror(err));
1369 1413 if (set_saw)
1370 1414 saw_error = B_TRUE;
1371 1415 }
1372 1416
1373 1417 /*
1374 1418 * zone_perror() expects a single string, but for remove and select
1375 1419 * we have both the command and the resource type, so this wrapper
1376 1420 * function serves the same purpose in a slightly different way.
1377 1421 */
1378 1422
1379 1423 static void
1380 1424 z_cmd_rt_perror(int cmd_num, int res_num, int err, boolean_t set_saw)
1381 1425 {
1382 1426 zerr("%s %s: %s", cmd_to_str(cmd_num), rt_to_str(res_num),
1383 1427 zonecfg_strerror(err));
1384 1428 if (set_saw)
1385 1429 saw_error = B_TRUE;
1386 1430 }
1387 1431
1388 1432 /* returns Z_OK if successful, Z_foo from <libzonecfg.h> otherwise */
1389 1433 static int
1390 1434 initialize(boolean_t handle_expected)
1391 1435 {
1392 1436 int err;
1393 1437 char brandname[MAXNAMELEN];
1394 1438
1395 1439 if (zonecfg_check_handle(handle) != Z_OK) {
1396 1440 if ((err = zonecfg_get_handle(zone, handle)) == Z_OK) {
1397 1441 got_handle = B_TRUE;
1398 1442 if (zonecfg_get_brand(handle, brandname,
1399 1443 sizeof (brandname)) != Z_OK) {
1400 1444 zerr("Zone %s is inconsistent: missing "
1401 1445 "brand attribute", zone);
1402 1446 exit(Z_ERR);
1403 1447 }
1404 1448 if ((brand = brand_open(brandname)) == NULL) {
1405 1449 zerr("Zone %s uses non-existent brand \"%s\"."
1406 1450 " Unable to continue", zone, brandname);
1407 1451 exit(Z_ERR);
1408 1452 }
1409 1453 /*
1410 1454 * If the user_attr file is newer than
1411 1455 * the zone config file, the admins
1412 1456 * may need to be updated since the
1413 1457 * RBAC files are authoritative for
1414 1458 * authorization checks.
1415 1459 */
1416 1460 err = zonecfg_update_userauths(handle, zone);
1417 1461 if (err == Z_OK) {
1418 1462 zerr(gettext("The administrative rights "
1419 1463 "were updated to match "
1420 1464 "the current RBAC configuration.\n"
1421 1465 "Use \"info admin\" and \"revert\" to "
1422 1466 "compare with the previous settings."));
1423 1467 need_to_commit = B_TRUE;
1424 1468 } else if (err != Z_NO_ENTRY) {
1425 1469 zerr(gettext("failed to update "
1426 1470 "admin rights."));
1427 1471 exit(Z_ERR);
1428 1472 } else if (need_to_commit) {
1429 1473 zerr(gettext("admin rights were updated "
1430 1474 "to match RBAC configuration."));
1431 1475 }
1432 1476
1433 1477 } else if (global_zone && err == Z_NO_ZONE && !got_handle &&
1434 1478 !read_only_mode) {
1435 1479 /*
1436 1480 * We implicitly create the global zone config if it
1437 1481 * doesn't exist.
1438 1482 */
1439 1483 zone_dochandle_t tmphandle;
1440 1484
1441 1485 if ((tmphandle = zonecfg_init_handle()) == NULL) {
1442 1486 zone_perror(execname, Z_NOMEM, B_TRUE);
1443 1487 exit(Z_ERR);
1444 1488 }
1445 1489
1446 1490 err = zonecfg_get_template_handle("SUNWblank", zone,
1447 1491 tmphandle);
1448 1492
1449 1493 if (err != Z_OK) {
1450 1494 zonecfg_fini_handle(tmphandle);
1451 1495 zone_perror("SUNWblank", err, B_TRUE);
1452 1496 return (err);
1453 1497 }
1454 1498
1455 1499 need_to_commit = B_TRUE;
1456 1500 zonecfg_fini_handle(handle);
1457 1501 handle = tmphandle;
1458 1502 got_handle = B_TRUE;
1459 1503
1460 1504 } else {
1461 1505 zone_perror(zone, err, handle_expected || got_handle);
1462 1506 if (err == Z_NO_ZONE && !got_handle &&
1463 1507 interactive_mode && !read_only_mode)
1464 1508 (void) printf(gettext("Use '%s' to begin "
1465 1509 "configuring a new zone.\n"),
1466 1510 cmd_to_str(CMD_CREATE));
1467 1511 return (err);
1468 1512 }
1469 1513 }
1470 1514 return (Z_OK);
1471 1515 }
1472 1516
1473 1517 static boolean_t
1474 1518 state_atleast(zone_state_t state)
1475 1519 {
1476 1520 zone_state_t state_num;
1477 1521 int err;
1478 1522
1479 1523 if ((err = zone_get_state(zone, &state_num)) != Z_OK) {
1480 1524 /* all states are greater than "non-existent" */
1481 1525 if (err == Z_NO_ZONE)
1482 1526 return (B_FALSE);
1483 1527 zerr(gettext("Unexpectedly failed to determine state "
1484 1528 "of zone %s: %s"), zone, zonecfg_strerror(err));
1485 1529 exit(Z_ERR);
1486 1530 }
1487 1531 return (state_num >= state);
1488 1532 }
1489 1533
1490 1534 /*
1491 1535 * short_usage() is for bad syntax: getopt() issues, too many arguments, etc.
1492 1536 */
1493 1537
1494 1538 void
1495 1539 short_usage(int command)
1496 1540 {
1497 1541 /* lex_lineno has already been incremented in the lexer; compensate */
1498 1542 if (cmd_file_mode) {
1499 1543 if (strcmp(cmd_file_name, "-") == 0)
1500 1544 (void) fprintf(stderr,
1501 1545 gettext("syntax error on line %d\n"),
1502 1546 lex_lineno - 1);
1503 1547 else
1504 1548 (void) fprintf(stderr,
1505 1549 gettext("syntax error on line %d of %s\n"),
1506 1550 lex_lineno - 1, cmd_file_name);
1507 1551 }
1508 1552 (void) fprintf(stderr, "%s:\n%s\n", gettext("usage"),
1509 1553 helptab[command].short_usage);
1510 1554 saw_error = B_TRUE;
1511 1555 }
1512 1556
1513 1557 /*
1514 1558 * long_usage() is for bad semantics: e.g., wrong property type for a given
1515 1559 * resource type. It is also used by longer_usage() below.
1516 1560 */
1517 1561
1518 1562 void
1519 1563 long_usage(uint_t cmd_num, boolean_t set_saw)
1520 1564 {
1521 1565 (void) fprintf(set_saw ? stderr : stdout, "%s:\n%s\n", gettext("usage"),
1522 1566 helptab[cmd_num].short_usage);
1523 1567 (void) fprintf(set_saw ? stderr : stdout, "\t%s\n", long_help(cmd_num));
1524 1568 if (set_saw)
1525 1569 saw_error = B_TRUE;
1526 1570 }
1527 1571
1528 1572 /*
1529 1573 * longer_usage() is for 'help foo' and 'foo -?': call long_usage() and also
1530 1574 * any extra usage() flags as appropriate for whatever command.
1531 1575 */
1532 1576
1533 1577 void
1534 1578 longer_usage(uint_t cmd_num)
1535 1579 {
1536 1580 long_usage(cmd_num, B_FALSE);
1537 1581 if (helptab[cmd_num].flags != 0) {
1538 1582 (void) printf("\n");
1539 1583 usage(B_TRUE, helptab[cmd_num].flags);
1540 1584 }
1541 1585 }
1542 1586
1543 1587 /*
1544 1588 * scope_usage() is simply used when a command is called from the wrong scope.
1545 1589 */
1546 1590
1547 1591 static void
1548 1592 scope_usage(uint_t cmd_num)
1549 1593 {
1550 1594 zerr(gettext("The %s command only makes sense in the %s scope."),
1551 1595 cmd_to_str(cmd_num),
1552 1596 global_scope ? gettext("resource") : gettext("global"));
1553 1597 saw_error = B_TRUE;
1554 1598 }
1555 1599
1556 1600 /*
1557 1601 * On input, B_TRUE => yes, B_FALSE => no.
1558 1602 * On return, B_TRUE => 1, B_FALSE => no, could not ask => -1.
1559 1603 */
1560 1604
1561 1605 static int
1562 1606 ask_yesno(boolean_t default_answer, const char *question)
1563 1607 {
1564 1608 char line[64]; /* should be enough to answer yes or no */
1565 1609
1566 1610 if (!ok_to_prompt) {
1567 1611 saw_error = B_TRUE;
1568 1612 return (-1);
1569 1613 }
1570 1614 for (;;) {
1571 1615 if (printf("%s (%s)? ", question,
1572 1616 default_answer ? "[y]/n" : "y/[n]") < 0)
1573 1617 return (-1);
1574 1618 if (fgets(line, sizeof (line), stdin) == NULL)
1575 1619 return (-1);
1576 1620
1577 1621 if (line[0] == '\n')
1578 1622 return (default_answer ? 1 : 0);
1579 1623 if (tolower(line[0]) == 'y')
1580 1624 return (1);
1581 1625 if (tolower(line[0]) == 'n')
1582 1626 return (0);
1583 1627 }
1584 1628 }
1585 1629
1586 1630 /*
1587 1631 * Prints warning if zone already exists.
1588 1632 * In interactive mode, prompts if we should continue anyway and returns Z_OK
1589 1633 * if so, Z_ERR if not. In non-interactive mode, exits with Z_ERR.
1590 1634 *
1591 1635 * Note that if a zone exists and its state is >= INSTALLED, an error message
1592 1636 * will be printed and this function will return Z_ERR regardless of mode.
1593 1637 */
1594 1638
1595 1639 static int
1596 1640 check_if_zone_already_exists(boolean_t force)
1597 1641 {
1598 1642 char line[ZONENAME_MAX + 128]; /* enough to ask a question */
1599 1643 zone_dochandle_t tmphandle;
1600 1644 int res, answer;
1601 1645
1602 1646 if ((tmphandle = zonecfg_init_handle()) == NULL) {
1603 1647 zone_perror(execname, Z_NOMEM, B_TRUE);
1604 1648 exit(Z_ERR);
1605 1649 }
1606 1650 res = zonecfg_get_handle(zone, tmphandle);
1607 1651 zonecfg_fini_handle(tmphandle);
1608 1652 if (res != Z_OK)
1609 1653 return (Z_OK);
1610 1654
1611 1655 if (state_atleast(ZONE_STATE_INSTALLED)) {
1612 1656 zerr(gettext("Zone %s already installed; %s not allowed."),
1613 1657 zone, cmd_to_str(CMD_CREATE));
1614 1658 return (Z_ERR);
1615 1659 }
1616 1660
1617 1661 if (force) {
1618 1662 (void) printf(gettext("Zone %s already exists; overwriting.\n"),
1619 1663 zone);
1620 1664 return (Z_OK);
1621 1665 }
1622 1666 (void) snprintf(line, sizeof (line),
1623 1667 gettext("Zone %s already exists; %s anyway"), zone,
1624 1668 cmd_to_str(CMD_CREATE));
1625 1669 if ((answer = ask_yesno(B_FALSE, line)) == -1) {
1626 1670 zerr(gettext("Zone exists, input not from terminal and -F not "
1627 1671 "specified:\n%s command ignored, exiting."),
1628 1672 cmd_to_str(CMD_CREATE));
1629 1673 exit(Z_ERR);
1630 1674 }
1631 1675 return (answer == 1 ? Z_OK : Z_ERR);
1632 1676 }
1633 1677
1634 1678 static boolean_t
1635 1679 zone_is_read_only(int cmd_num)
1636 1680 {
1637 1681 if (strncmp(zone, "SUNW", 4) == 0) {
1638 1682 zerr(gettext("%s: zones beginning with SUNW are read-only."),
1639 1683 zone);
1640 1684 saw_error = B_TRUE;
1641 1685 return (B_TRUE);
1642 1686 }
1643 1687 if (read_only_mode) {
1644 1688 zerr(gettext("%s: cannot %s in read-only mode."), zone,
1645 1689 cmd_to_str(cmd_num));
1646 1690 saw_error = B_TRUE;
1647 1691 return (B_TRUE);
1648 1692 }
1649 1693 return (B_FALSE);
1650 1694 }
1651 1695
1652 1696 /*
1653 1697 * Create a new configuration.
1654 1698 */
1655 1699 void
1656 1700 create_func(cmd_t *cmd)
1657 1701 {
1658 1702 int err, arg;
1659 1703 char zone_template[ZONENAME_MAX];
1660 1704 char attach_path[MAXPATHLEN];
1661 1705 zone_dochandle_t tmphandle;
1662 1706 boolean_t force = B_FALSE;
1663 1707 boolean_t attach = B_FALSE;
1664 1708 boolean_t arg_err = B_FALSE;
1665 1709
1666 1710 assert(cmd != NULL);
1667 1711
1668 1712 /* This is the default if no arguments are given. */
1669 1713 (void) strlcpy(zone_template, "SUNWdefault", sizeof (zone_template));
1670 1714
1671 1715 optind = 0;
1672 1716 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?a:bFt:"))
1673 1717 != EOF) {
1674 1718 switch (arg) {
1675 1719 case '?':
1676 1720 if (optopt == '?')
1677 1721 longer_usage(CMD_CREATE);
1678 1722 else
1679 1723 short_usage(CMD_CREATE);
1680 1724 arg_err = B_TRUE;
1681 1725 break;
1682 1726 case 'a':
1683 1727 (void) strlcpy(attach_path, optarg,
1684 1728 sizeof (attach_path));
1685 1729 attach = B_TRUE;
1686 1730 break;
1687 1731 case 'b':
1688 1732 (void) strlcpy(zone_template, "SUNWblank",
1689 1733 sizeof (zone_template));
1690 1734 break;
1691 1735 case 'F':
1692 1736 force = B_TRUE;
1693 1737 break;
1694 1738 case 't':
1695 1739 (void) strlcpy(zone_template, optarg,
1696 1740 sizeof (zone_template));
1697 1741 break;
1698 1742 default:
1699 1743 short_usage(CMD_CREATE);
1700 1744 arg_err = B_TRUE;
1701 1745 break;
1702 1746 }
1703 1747 }
1704 1748 if (arg_err)
1705 1749 return;
1706 1750
1707 1751 if (optind != cmd->cmd_argc) {
1708 1752 short_usage(CMD_CREATE);
1709 1753 return;
1710 1754 }
1711 1755
1712 1756 if (zone_is_read_only(CMD_CREATE))
1713 1757 return;
1714 1758
1715 1759 if (check_if_zone_already_exists(force) != Z_OK)
1716 1760 return;
1717 1761
1718 1762 /*
1719 1763 * Get a temporary handle first. If that fails, the old handle
1720 1764 * will not be lost. Then finish whichever one we don't need,
1721 1765 * to avoid leaks. Then get the handle for zone_template, and
1722 1766 * set the name to zone: this "copy, rename" method is how
1723 1767 * create -[b|t] works.
1724 1768 */
1725 1769 if ((tmphandle = zonecfg_init_handle()) == NULL) {
1726 1770 zone_perror(execname, Z_NOMEM, B_TRUE);
1727 1771 exit(Z_ERR);
1728 1772 }
1729 1773
1730 1774 if (attach)
1731 1775 err = zonecfg_get_attach_handle(attach_path, ZONE_DETACHED,
1732 1776 zone, B_FALSE, tmphandle);
1733 1777 else
1734 1778 err = zonecfg_get_template_handle(zone_template, zone,
1735 1779 tmphandle);
1736 1780
1737 1781 if (err != Z_OK) {
1738 1782 zonecfg_fini_handle(tmphandle);
1739 1783 if (attach && err == Z_NO_ZONE)
1740 1784 (void) fprintf(stderr, gettext("invalid path to "
1741 1785 "detached zone\n"));
1742 1786 else if (attach && err == Z_INVALID_DOCUMENT)
1743 1787 (void) fprintf(stderr, gettext("Cannot attach to an "
1744 1788 "earlier release of the operating system\n"));
1745 1789 else
1746 1790 zone_perror(zone_template, err, B_TRUE);
1747 1791 return;
1748 1792 }
1749 1793
1750 1794 need_to_commit = B_TRUE;
1751 1795 zonecfg_fini_handle(handle);
1752 1796 handle = tmphandle;
1753 1797 got_handle = B_TRUE;
1754 1798 }
1755 1799
1756 1800 /*
1757 1801 * This malloc()'s memory, which must be freed by the caller.
1758 1802 */
1759 1803 static char *
1760 1804 quoteit(char *instr)
1761 1805 {
1762 1806 char *outstr;
1763 1807 size_t outstrsize = strlen(instr) + 3; /* 2 quotes + '\0' */
1764 1808
1765 1809 if ((outstr = malloc(outstrsize)) == NULL) {
1766 1810 zone_perror(zone, Z_NOMEM, B_FALSE);
1767 1811 exit(Z_ERR);
1768 1812 }
1769 1813 if (strchr(instr, ' ') == NULL) {
1770 1814 (void) strlcpy(outstr, instr, outstrsize);
1771 1815 return (outstr);
1772 1816 }
1773 1817 (void) snprintf(outstr, outstrsize, "\"%s\"", instr);
1774 1818 return (outstr);
1775 1819 }
1776 1820
1777 1821 static void
1778 1822 export_prop(FILE *of, int prop_num, char *prop_id)
1779 1823 {
1780 1824 char *quote_str;
1781 1825
1782 1826 if (strlen(prop_id) == 0)
1783 1827 return;
1784 1828 quote_str = quoteit(prop_id);
1785 1829 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1786 1830 pt_to_str(prop_num), quote_str);
1787 1831 free(quote_str);
1788 1832 }
1789 1833
1790 1834 void
1791 1835 export_func(cmd_t *cmd)
1792 1836 {
↓ open down ↓ |
423 lines elided |
↑ open up ↑ |
1793 1837 struct zone_nwiftab nwiftab;
1794 1838 struct zone_fstab fstab;
1795 1839 struct zone_devtab devtab;
1796 1840 struct zone_attrtab attrtab;
1797 1841 struct zone_rctltab rctltab;
1798 1842 struct zone_dstab dstab;
1799 1843 struct zone_psettab psettab;
1800 1844 struct zone_mcaptab mcaptab;
1801 1845 struct zone_rctlvaltab *valptr;
1802 1846 struct zone_admintab admintab;
1847 + struct zone_secflagstab secflagstab;
1803 1848 int err, arg;
1804 1849 char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN];
1805 1850 char bootargs[BOOTARGS_MAX];
1806 1851 char sched[MAXNAMELEN];
1807 1852 char brand[MAXNAMELEN];
1808 1853 char hostidp[HW_HOSTID_LEN];
1809 1854 char fsallowedp[ZONE_FS_ALLOWED_MAX];
1810 1855 char *limitpriv;
1811 1856 FILE *of;
1812 1857 boolean_t autoboot;
1813 1858 zone_iptype_t iptype;
1814 1859 boolean_t need_to_close = B_FALSE;
1815 1860 boolean_t arg_err = B_FALSE;
1816 1861
1817 1862 assert(cmd != NULL);
1818 1863
1819 1864 outfile[0] = '\0';
1820 1865 optind = 0;
1821 1866 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?f:")) != EOF) {
1822 1867 switch (arg) {
1823 1868 case '?':
1824 1869 if (optopt == '?')
1825 1870 longer_usage(CMD_EXPORT);
1826 1871 else
1827 1872 short_usage(CMD_EXPORT);
1828 1873 arg_err = B_TRUE;
1829 1874 break;
1830 1875 case 'f':
1831 1876 (void) strlcpy(outfile, optarg, sizeof (outfile));
1832 1877 break;
1833 1878 default:
1834 1879 short_usage(CMD_EXPORT);
1835 1880 arg_err = B_TRUE;
1836 1881 break;
1837 1882 }
1838 1883 }
1839 1884 if (arg_err)
1840 1885 return;
1841 1886
1842 1887 if (optind != cmd->cmd_argc) {
1843 1888 short_usage(CMD_EXPORT);
1844 1889 return;
1845 1890 }
1846 1891 if (strlen(outfile) == 0) {
1847 1892 of = stdout;
1848 1893 } else {
1849 1894 if ((of = fopen(outfile, "w")) == NULL) {
1850 1895 zerr(gettext("opening file %s: %s"),
1851 1896 outfile, strerror(errno));
1852 1897 goto done;
1853 1898 }
1854 1899 setbuf(of, NULL);
1855 1900 need_to_close = B_TRUE;
1856 1901 }
1857 1902
1858 1903 if ((err = initialize(B_TRUE)) != Z_OK)
1859 1904 goto done;
1860 1905
1861 1906 (void) fprintf(of, "%s -b\n", cmd_to_str(CMD_CREATE));
1862 1907
1863 1908 if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) == Z_OK &&
1864 1909 strlen(zonepath) > 0)
1865 1910 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1866 1911 pt_to_str(PT_ZONEPATH), zonepath);
1867 1912
1868 1913 if ((zone_get_brand(zone, brand, sizeof (brand)) == Z_OK) &&
1869 1914 (strcmp(brand, NATIVE_BRAND_NAME) != 0))
1870 1915 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1871 1916 pt_to_str(PT_BRAND), brand);
1872 1917
1873 1918 if (zonecfg_get_autoboot(handle, &autoboot) == Z_OK)
1874 1919 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1875 1920 pt_to_str(PT_AUTOBOOT), autoboot ? "true" : "false");
1876 1921
1877 1922 if (zonecfg_get_bootargs(handle, bootargs, sizeof (bootargs)) == Z_OK &&
1878 1923 strlen(bootargs) > 0) {
1879 1924 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1880 1925 pt_to_str(PT_BOOTARGS), bootargs);
1881 1926 }
1882 1927
1883 1928 if (zonecfg_get_pool(handle, pool, sizeof (pool)) == Z_OK &&
1884 1929 strlen(pool) > 0)
1885 1930 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1886 1931 pt_to_str(PT_POOL), pool);
1887 1932
1888 1933 if (zonecfg_get_limitpriv(handle, &limitpriv) == Z_OK &&
1889 1934 strlen(limitpriv) > 0) {
1890 1935 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1891 1936 pt_to_str(PT_LIMITPRIV), limitpriv);
1892 1937 free(limitpriv);
1893 1938 }
1894 1939
1895 1940 if (zonecfg_get_sched_class(handle, sched, sizeof (sched)) == Z_OK &&
1896 1941 strlen(sched) > 0)
1897 1942 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1898 1943 pt_to_str(PT_SCHED), sched);
1899 1944
1900 1945 if (zonecfg_get_iptype(handle, &iptype) == Z_OK) {
1901 1946 switch (iptype) {
1902 1947 case ZS_SHARED:
1903 1948 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1904 1949 pt_to_str(PT_IPTYPE), "shared");
1905 1950 break;
1906 1951 case ZS_EXCLUSIVE:
1907 1952 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1908 1953 pt_to_str(PT_IPTYPE), "exclusive");
1909 1954 break;
1910 1955 }
1911 1956 }
1912 1957
1913 1958 if (zonecfg_get_hostid(handle, hostidp, sizeof (hostidp)) == Z_OK) {
1914 1959 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1915 1960 pt_to_str(PT_HOSTID), hostidp);
1916 1961 }
1917 1962
1918 1963 if (zonecfg_get_fs_allowed(handle, fsallowedp,
1919 1964 sizeof (fsallowedp)) == Z_OK) {
1920 1965 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1921 1966 pt_to_str(PT_FS_ALLOWED), fsallowedp);
1922 1967 }
1923 1968
1924 1969 if ((err = zonecfg_setfsent(handle)) != Z_OK) {
1925 1970 zone_perror(zone, err, B_FALSE);
1926 1971 goto done;
1927 1972 }
1928 1973 while (zonecfg_getfsent(handle, &fstab) == Z_OK) {
1929 1974 zone_fsopt_t *optptr;
1930 1975
1931 1976 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
1932 1977 rt_to_str(RT_FS));
1933 1978 export_prop(of, PT_DIR, fstab.zone_fs_dir);
1934 1979 export_prop(of, PT_SPECIAL, fstab.zone_fs_special);
1935 1980 export_prop(of, PT_RAW, fstab.zone_fs_raw);
1936 1981 export_prop(of, PT_TYPE, fstab.zone_fs_type);
1937 1982 for (optptr = fstab.zone_fs_options; optptr != NULL;
1938 1983 optptr = optptr->zone_fsopt_next) {
1939 1984 /*
1940 1985 * Simple property values with embedded equal signs
1941 1986 * need to be quoted to prevent the lexer from
1942 1987 * mis-parsing them as complex name=value pairs.
1943 1988 */
1944 1989 if (strchr(optptr->zone_fsopt_opt, '='))
1945 1990 (void) fprintf(of, "%s %s \"%s\"\n",
1946 1991 cmd_to_str(CMD_ADD),
1947 1992 pt_to_str(PT_OPTIONS),
1948 1993 optptr->zone_fsopt_opt);
1949 1994 else
1950 1995 (void) fprintf(of, "%s %s %s\n",
1951 1996 cmd_to_str(CMD_ADD),
1952 1997 pt_to_str(PT_OPTIONS),
1953 1998 optptr->zone_fsopt_opt);
1954 1999 }
1955 2000 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
1956 2001 zonecfg_free_fs_option_list(fstab.zone_fs_options);
1957 2002 }
1958 2003 (void) zonecfg_endfsent(handle);
1959 2004
1960 2005 if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
1961 2006 zone_perror(zone, err, B_FALSE);
1962 2007 goto done;
1963 2008 }
1964 2009 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
1965 2010 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
1966 2011 rt_to_str(RT_NET));
1967 2012 export_prop(of, PT_ADDRESS, nwiftab.zone_nwif_address);
1968 2013 export_prop(of, PT_ALLOWED_ADDRESS,
1969 2014 nwiftab.zone_nwif_allowed_address);
1970 2015 export_prop(of, PT_PHYSICAL, nwiftab.zone_nwif_physical);
1971 2016 export_prop(of, PT_DEFROUTER, nwiftab.zone_nwif_defrouter);
1972 2017 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
1973 2018 }
1974 2019 (void) zonecfg_endnwifent(handle);
1975 2020
1976 2021 if ((err = zonecfg_setdevent(handle)) != Z_OK) {
1977 2022 zone_perror(zone, err, B_FALSE);
1978 2023 goto done;
1979 2024 }
1980 2025 while (zonecfg_getdevent(handle, &devtab) == Z_OK) {
1981 2026 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
1982 2027 rt_to_str(RT_DEVICE));
1983 2028 export_prop(of, PT_MATCH, devtab.zone_dev_match);
1984 2029 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
1985 2030 }
1986 2031 (void) zonecfg_enddevent(handle);
1987 2032
1988 2033 if (zonecfg_getmcapent(handle, &mcaptab) == Z_OK) {
1989 2034 char buf[128];
1990 2035
1991 2036 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
1992 2037 rt_to_str(RT_MCAP));
1993 2038 bytes_to_units(mcaptab.zone_physmem_cap, buf, sizeof (buf));
1994 2039 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1995 2040 pt_to_str(PT_PHYSICAL), buf);
1996 2041 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
1997 2042 }
1998 2043
1999 2044 if ((err = zonecfg_setrctlent(handle)) != Z_OK) {
2000 2045 zone_perror(zone, err, B_FALSE);
2001 2046 goto done;
2002 2047 }
2003 2048 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
2004 2049 (void) fprintf(of, "%s rctl\n", cmd_to_str(CMD_ADD));
2005 2050 export_prop(of, PT_NAME, rctltab.zone_rctl_name);
2006 2051 for (valptr = rctltab.zone_rctl_valptr; valptr != NULL;
2007 2052 valptr = valptr->zone_rctlval_next) {
2008 2053 fprintf(of, "%s %s (%s=%s,%s=%s,%s=%s)\n",
2009 2054 cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE),
2010 2055 pt_to_str(PT_PRIV), valptr->zone_rctlval_priv,
2011 2056 pt_to_str(PT_LIMIT), valptr->zone_rctlval_limit,
2012 2057 pt_to_str(PT_ACTION), valptr->zone_rctlval_action);
2013 2058 }
2014 2059 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2015 2060 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
2016 2061 }
2017 2062 (void) zonecfg_endrctlent(handle);
2018 2063
2019 2064 if ((err = zonecfg_setattrent(handle)) != Z_OK) {
2020 2065 zone_perror(zone, err, B_FALSE);
2021 2066 goto done;
2022 2067 }
2023 2068 while (zonecfg_getattrent(handle, &attrtab) == Z_OK) {
2024 2069 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2025 2070 rt_to_str(RT_ATTR));
2026 2071 export_prop(of, PT_NAME, attrtab.zone_attr_name);
2027 2072 export_prop(of, PT_TYPE, attrtab.zone_attr_type);
2028 2073 export_prop(of, PT_VALUE, attrtab.zone_attr_value);
2029 2074 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2030 2075 }
2031 2076 (void) zonecfg_endattrent(handle);
2032 2077
2033 2078 if ((err = zonecfg_setdsent(handle)) != Z_OK) {
2034 2079 zone_perror(zone, err, B_FALSE);
2035 2080 goto done;
2036 2081 }
2037 2082 while (zonecfg_getdsent(handle, &dstab) == Z_OK) {
2038 2083 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2039 2084 rt_to_str(RT_DATASET));
2040 2085 export_prop(of, PT_NAME, dstab.zone_dataset_name);
2041 2086 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2042 2087 }
2043 2088 (void) zonecfg_enddsent(handle);
2044 2089
2045 2090 if (zonecfg_getpsetent(handle, &psettab) == Z_OK) {
2046 2091 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2047 2092 rt_to_str(RT_DCPU));
2048 2093 if (strcmp(psettab.zone_ncpu_min, psettab.zone_ncpu_max) == 0)
2049 2094 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
2050 2095 pt_to_str(PT_NCPUS), psettab.zone_ncpu_max);
2051 2096 else
2052 2097 (void) fprintf(of, "%s %s=%s-%s\n", cmd_to_str(CMD_SET),
2053 2098 pt_to_str(PT_NCPUS), psettab.zone_ncpu_min,
2054 2099 psettab.zone_ncpu_max);
2055 2100 if (psettab.zone_importance[0] != '\0')
2056 2101 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
2057 2102 pt_to_str(PT_IMPORTANCE), psettab.zone_importance);
2058 2103 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2059 2104 }
2060 2105
2061 2106 if ((err = zonecfg_setadminent(handle)) != Z_OK) {
↓ open down ↓ |
249 lines elided |
↑ open up ↑ |
2062 2107 zone_perror(zone, err, B_FALSE);
2063 2108 goto done;
2064 2109 }
2065 2110 while (zonecfg_getadminent(handle, &admintab) == Z_OK) {
2066 2111 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2067 2112 rt_to_str(RT_ADMIN));
2068 2113 export_prop(of, PT_USER, admintab.zone_admin_user);
2069 2114 export_prop(of, PT_AUTHS, admintab.zone_admin_auths);
2070 2115 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2071 2116 }
2117 +
2072 2118 (void) zonecfg_endadminent(handle);
2073 2119
2120 + if (zonecfg_getsecflagsent(handle, &secflagstab) == Z_OK) {
2121 + (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2122 + rt_to_str(RT_SECFLAGS));
2123 + export_prop(of, PT_DEFAULT, secflagstab.zone_secflags_default);
2124 + export_prop(of, PT_LOWER, secflagstab.zone_secflags_lower);
2125 + export_prop(of, PT_UPPER, secflagstab.zone_secflags_upper);
2126 + (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2127 + }
2128 +
2074 2129 /*
2075 2130 * There is nothing to export for pcap since this resource is just
2076 2131 * a container for an rctl alias.
2077 2132 */
2078 2133
2079 2134 done:
2080 2135 if (need_to_close)
2081 2136 (void) fclose(of);
2082 2137 }
2083 2138
2084 2139 void
2085 2140 exit_func(cmd_t *cmd)
2086 2141 {
2087 2142 int arg, answer;
2088 2143 boolean_t arg_err = B_FALSE;
2089 2144
2090 2145 optind = 0;
2091 2146 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
2092 2147 switch (arg) {
2093 2148 case '?':
2094 2149 longer_usage(CMD_EXIT);
2095 2150 arg_err = B_TRUE;
2096 2151 break;
2097 2152 case 'F':
2098 2153 force_exit = B_TRUE;
2099 2154 break;
2100 2155 default:
2101 2156 short_usage(CMD_EXIT);
2102 2157 arg_err = B_TRUE;
2103 2158 break;
2104 2159 }
2105 2160 }
2106 2161 if (arg_err)
2107 2162 return;
2108 2163
2109 2164 if (optind < cmd->cmd_argc) {
2110 2165 short_usage(CMD_EXIT);
2111 2166 return;
2112 2167 }
2113 2168
2114 2169 if (global_scope || force_exit) {
2115 2170 time_to_exit = B_TRUE;
2116 2171 return;
2117 2172 }
2118 2173
2119 2174 answer = ask_yesno(B_FALSE, "Resource incomplete; really quit");
2120 2175 if (answer == -1) {
2121 2176 zerr(gettext("Resource incomplete, input "
2122 2177 "not from terminal and -F not specified:\n%s command "
2123 2178 "ignored, but exiting anyway."), cmd_to_str(CMD_EXIT));
2124 2179 exit(Z_ERR);
2125 2180 } else if (answer == 1) {
2126 2181 time_to_exit = B_TRUE;
2127 2182 }
2128 2183 /* (answer == 0) => just return */
2129 2184 }
2130 2185
2131 2186 static int
2132 2187 validate_zonepath_syntax(char *path)
2133 2188 {
2134 2189 if (path[0] != '/') {
2135 2190 zerr(gettext("%s is not an absolute path."), path);
2136 2191 return (Z_ERR);
2137 2192 }
2138 2193 /* If path is all slashes, then fail */
2139 2194 if (strspn(path, "/") == strlen(path)) {
2140 2195 zerr(gettext("/ is not allowed as a %s."),
2141 2196 pt_to_str(PT_ZONEPATH));
2142 2197 return (Z_ERR);
↓ open down ↓ |
59 lines elided |
↑ open up ↑ |
2143 2198 }
2144 2199 return (Z_OK);
2145 2200 }
2146 2201
2147 2202 static void
2148 2203 add_resource(cmd_t *cmd)
2149 2204 {
2150 2205 int type;
2151 2206 struct zone_psettab tmp_psettab;
2152 2207 struct zone_mcaptab tmp_mcaptab;
2208 + struct zone_secflagstab tmp_secflagstab;
2153 2209 uint64_t tmp;
2154 2210 uint64_t tmp_mcap;
2155 2211 char pool[MAXNAMELEN];
2156 2212
2157 2213 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
2158 2214 long_usage(CMD_ADD, B_TRUE);
2159 2215 goto bad;
2160 2216 }
2161 2217
2162 2218 switch (type) {
2163 2219 case RT_FS:
2164 2220 bzero(&in_progress_fstab, sizeof (in_progress_fstab));
2165 2221 return;
2166 2222 case RT_NET:
2167 2223 bzero(&in_progress_nwiftab, sizeof (in_progress_nwiftab));
2168 2224 return;
2169 2225 case RT_DEVICE:
2170 2226 bzero(&in_progress_devtab, sizeof (in_progress_devtab));
2171 2227 return;
2172 2228 case RT_RCTL:
2173 2229 if (global_zone)
2174 2230 zerr(gettext("WARNING: Setting a global zone resource "
2175 2231 "control too low could deny\nservice "
2176 2232 "to even the root user; "
2177 2233 "this could render the system impossible\n"
2178 2234 "to administer. Please use caution."));
2179 2235 bzero(&in_progress_rctltab, sizeof (in_progress_rctltab));
2180 2236 return;
2181 2237 case RT_ATTR:
2182 2238 bzero(&in_progress_attrtab, sizeof (in_progress_attrtab));
2183 2239 return;
2184 2240 case RT_DATASET:
2185 2241 bzero(&in_progress_dstab, sizeof (in_progress_dstab));
2186 2242 return;
2187 2243 case RT_DCPU:
2188 2244 /* Make sure there isn't already a cpu-set or cpu-cap entry. */
2189 2245 if (zonecfg_lookup_pset(handle, &tmp_psettab) == Z_OK) {
2190 2246 zerr(gettext("The %s resource already exists."),
2191 2247 rt_to_str(RT_DCPU));
2192 2248 goto bad;
2193 2249 }
2194 2250 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp) !=
2195 2251 Z_NO_ENTRY) {
2196 2252 zerr(gettext("The %s resource already exists."),
2197 2253 rt_to_str(RT_PCAP));
2198 2254 goto bad;
2199 2255 }
2200 2256
2201 2257 /* Make sure the pool property isn't set. */
2202 2258 if (zonecfg_get_pool(handle, pool, sizeof (pool)) == Z_OK &&
2203 2259 strlen(pool) > 0) {
2204 2260 zerr(gettext("The %s property is already set. "
2205 2261 "A persistent pool is incompatible with\nthe %s "
2206 2262 "resource."),
2207 2263 pt_to_str(PT_POOL), rt_to_str(RT_DCPU));
2208 2264 goto bad;
2209 2265 }
2210 2266
2211 2267 bzero(&in_progress_psettab, sizeof (in_progress_psettab));
2212 2268 return;
2213 2269 case RT_PCAP:
2214 2270 /*
2215 2271 * Make sure there isn't already a cpu-set or incompatible
2216 2272 * cpu-cap rctls.
2217 2273 */
2218 2274 if (zonecfg_lookup_pset(handle, &tmp_psettab) == Z_OK) {
2219 2275 zerr(gettext("The %s resource already exists."),
2220 2276 rt_to_str(RT_DCPU));
2221 2277 goto bad;
2222 2278 }
2223 2279
2224 2280 switch (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp)) {
2225 2281 case Z_ALIAS_DISALLOW:
2226 2282 zone_perror(rt_to_str(RT_PCAP), Z_ALIAS_DISALLOW,
2227 2283 B_FALSE);
2228 2284 goto bad;
2229 2285
2230 2286 case Z_OK:
2231 2287 zerr(gettext("The %s resource already exists."),
2232 2288 rt_to_str(RT_PCAP));
2233 2289 goto bad;
2234 2290
2235 2291 default:
2236 2292 break;
2237 2293 }
2238 2294 return;
2239 2295 case RT_MCAP:
2240 2296 /*
2241 2297 * Make sure there isn't already a mem-cap entry or max-swap
2242 2298 * or max-locked rctl.
2243 2299 */
2244 2300 if (zonecfg_lookup_mcap(handle, &tmp_mcaptab) == Z_OK ||
2245 2301 zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp_mcap)
2246 2302 == Z_OK ||
2247 2303 zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM,
2248 2304 &tmp_mcap) == Z_OK) {
2249 2305 zerr(gettext("The %s resource or a related resource "
2250 2306 "control already exists."), rt_to_str(RT_MCAP));
2251 2307 goto bad;
2252 2308 }
2253 2309 if (global_zone)
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
2254 2310 zerr(gettext("WARNING: Setting a global zone memory "
2255 2311 "cap too low could deny\nservice "
2256 2312 "to even the root user; "
2257 2313 "this could render the system impossible\n"
2258 2314 "to administer. Please use caution."));
2259 2315 bzero(&in_progress_mcaptab, sizeof (in_progress_mcaptab));
2260 2316 return;
2261 2317 case RT_ADMIN:
2262 2318 bzero(&in_progress_admintab, sizeof (in_progress_admintab));
2263 2319 return;
2320 + case RT_SECFLAGS:
2321 + /* Make sure we haven't already set this */
2322 + if (zonecfg_lookup_secflags(handle, &tmp_secflagstab) == Z_OK)
2323 + zerr(gettext("The %s resource already exists."),
2324 + rt_to_str(RT_SECFLAGS));
2325 + bzero(&in_progress_secflagstab,
2326 + sizeof (in_progress_secflagstab));
2327 + return;
2264 2328 default:
2265 2329 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
2266 2330 long_usage(CMD_ADD, B_TRUE);
2267 2331 usage(B_FALSE, HELP_RESOURCES);
2268 2332 }
2269 2333 bad:
2270 2334 global_scope = B_TRUE;
2271 2335 end_op = -1;
2272 2336 }
2273 2337
2274 2338 static void
2275 2339 do_complex_rctl_val(complex_property_ptr_t cp)
2276 2340 {
2277 2341 struct zone_rctlvaltab *rctlvaltab;
2278 2342 complex_property_ptr_t cx;
2279 2343 boolean_t seen_priv = B_FALSE, seen_limit = B_FALSE,
2280 2344 seen_action = B_FALSE;
2281 2345 rctlblk_t *rctlblk;
2282 2346 int err;
2283 2347
2284 2348 if ((rctlvaltab = alloc_rctlvaltab()) == NULL) {
2285 2349 zone_perror(zone, Z_NOMEM, B_TRUE);
2286 2350 exit(Z_ERR);
2287 2351 }
2288 2352 for (cx = cp; cx != NULL; cx = cx->cp_next) {
2289 2353 switch (cx->cp_type) {
2290 2354 case PT_PRIV:
2291 2355 if (seen_priv) {
2292 2356 zerr(gettext("%s already specified"),
2293 2357 pt_to_str(PT_PRIV));
2294 2358 goto bad;
2295 2359 }
2296 2360 (void) strlcpy(rctlvaltab->zone_rctlval_priv,
2297 2361 cx->cp_value,
2298 2362 sizeof (rctlvaltab->zone_rctlval_priv));
2299 2363 seen_priv = B_TRUE;
2300 2364 break;
2301 2365 case PT_LIMIT:
2302 2366 if (seen_limit) {
2303 2367 zerr(gettext("%s already specified"),
2304 2368 pt_to_str(PT_LIMIT));
2305 2369 goto bad;
2306 2370 }
2307 2371 (void) strlcpy(rctlvaltab->zone_rctlval_limit,
2308 2372 cx->cp_value,
2309 2373 sizeof (rctlvaltab->zone_rctlval_limit));
2310 2374 seen_limit = B_TRUE;
2311 2375 break;
2312 2376 case PT_ACTION:
2313 2377 if (seen_action) {
2314 2378 zerr(gettext("%s already specified"),
2315 2379 pt_to_str(PT_ACTION));
2316 2380 goto bad;
2317 2381 }
2318 2382 (void) strlcpy(rctlvaltab->zone_rctlval_action,
2319 2383 cx->cp_value,
2320 2384 sizeof (rctlvaltab->zone_rctlval_action));
2321 2385 seen_action = B_TRUE;
2322 2386 break;
2323 2387 default:
2324 2388 zone_perror(pt_to_str(PT_VALUE),
2325 2389 Z_NO_PROPERTY_TYPE, B_TRUE);
2326 2390 long_usage(CMD_ADD, B_TRUE);
2327 2391 usage(B_FALSE, HELP_PROPS);
2328 2392 zonecfg_free_rctl_value_list(rctlvaltab);
2329 2393 return;
2330 2394 }
2331 2395 }
2332 2396 if (!seen_priv)
2333 2397 zerr(gettext("%s not specified"), pt_to_str(PT_PRIV));
2334 2398 if (!seen_limit)
2335 2399 zerr(gettext("%s not specified"), pt_to_str(PT_LIMIT));
2336 2400 if (!seen_action)
2337 2401 zerr(gettext("%s not specified"), pt_to_str(PT_ACTION));
2338 2402 if (!seen_priv || !seen_limit || !seen_action)
2339 2403 goto bad;
2340 2404 rctlvaltab->zone_rctlval_next = NULL;
2341 2405 rctlblk = alloca(rctlblk_size());
2342 2406 /*
2343 2407 * Make sure the rctl value looks roughly correct; we won't know if
2344 2408 * it's truly OK until we verify the configuration on the target
2345 2409 * system.
2346 2410 */
2347 2411 if (zonecfg_construct_rctlblk(rctlvaltab, rctlblk) != Z_OK ||
2348 2412 !zonecfg_valid_rctlblk(rctlblk)) {
2349 2413 zerr(gettext("Invalid %s %s specification"), rt_to_str(RT_RCTL),
2350 2414 pt_to_str(PT_VALUE));
2351 2415 goto bad;
2352 2416 }
2353 2417 err = zonecfg_add_rctl_value(&in_progress_rctltab, rctlvaltab);
2354 2418 if (err != Z_OK)
2355 2419 zone_perror(pt_to_str(PT_VALUE), err, B_TRUE);
2356 2420 return;
2357 2421
2358 2422 bad:
2359 2423 zonecfg_free_rctl_value_list(rctlvaltab);
2360 2424 }
2361 2425
2362 2426 static void
2363 2427 add_property(cmd_t *cmd)
2364 2428 {
2365 2429 char *prop_id;
2366 2430 int err, res_type, prop_type;
2367 2431 property_value_ptr_t pp;
2368 2432 list_property_ptr_t l;
2369 2433
2370 2434 res_type = resource_scope;
2371 2435 prop_type = cmd->cmd_prop_name[0];
2372 2436 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
2373 2437 long_usage(CMD_ADD, B_TRUE);
2374 2438 return;
2375 2439 }
2376 2440
2377 2441 if (cmd->cmd_prop_nv_pairs != 1) {
2378 2442 long_usage(CMD_ADD, B_TRUE);
2379 2443 return;
2380 2444 }
2381 2445
2382 2446 if (initialize(B_TRUE) != Z_OK)
2383 2447 return;
2384 2448
2385 2449 switch (res_type) {
2386 2450 case RT_FS:
2387 2451 if (prop_type != PT_OPTIONS) {
2388 2452 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
2389 2453 B_TRUE);
2390 2454 long_usage(CMD_ADD, B_TRUE);
2391 2455 usage(B_FALSE, HELP_PROPS);
2392 2456 return;
2393 2457 }
2394 2458 pp = cmd->cmd_property_ptr[0];
2395 2459 if (pp->pv_type != PROP_VAL_SIMPLE &&
2396 2460 pp->pv_type != PROP_VAL_LIST) {
2397 2461 zerr(gettext("A %s or %s value was expected here."),
2398 2462 pvt_to_str(PROP_VAL_SIMPLE),
2399 2463 pvt_to_str(PROP_VAL_LIST));
2400 2464 saw_error = B_TRUE;
2401 2465 return;
2402 2466 }
2403 2467 if (pp->pv_type == PROP_VAL_SIMPLE) {
2404 2468 if (pp->pv_simple == NULL) {
2405 2469 long_usage(CMD_ADD, B_TRUE);
2406 2470 return;
2407 2471 }
2408 2472 prop_id = pp->pv_simple;
2409 2473 err = zonecfg_add_fs_option(&in_progress_fstab,
2410 2474 prop_id);
2411 2475 if (err != Z_OK)
2412 2476 zone_perror(pt_to_str(prop_type), err, B_TRUE);
2413 2477 } else {
2414 2478 list_property_ptr_t list;
2415 2479
2416 2480 for (list = pp->pv_list; list != NULL;
2417 2481 list = list->lp_next) {
2418 2482 prop_id = list->lp_simple;
2419 2483 if (prop_id == NULL)
2420 2484 break;
2421 2485 err = zonecfg_add_fs_option(
2422 2486 &in_progress_fstab, prop_id);
2423 2487 if (err != Z_OK)
2424 2488 zone_perror(pt_to_str(prop_type), err,
2425 2489 B_TRUE);
2426 2490 }
2427 2491 }
2428 2492 return;
2429 2493 case RT_RCTL:
2430 2494 if (prop_type != PT_VALUE) {
2431 2495 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
2432 2496 B_TRUE);
2433 2497 long_usage(CMD_ADD, B_TRUE);
2434 2498 usage(B_FALSE, HELP_PROPS);
2435 2499 return;
2436 2500 }
2437 2501 pp = cmd->cmd_property_ptr[0];
2438 2502 if (pp->pv_type != PROP_VAL_COMPLEX &&
2439 2503 pp->pv_type != PROP_VAL_LIST) {
2440 2504 zerr(gettext("A %s or %s value was expected here."),
2441 2505 pvt_to_str(PROP_VAL_COMPLEX),
2442 2506 pvt_to_str(PROP_VAL_LIST));
2443 2507 saw_error = B_TRUE;
2444 2508 return;
2445 2509 }
2446 2510 if (pp->pv_type == PROP_VAL_COMPLEX) {
2447 2511 do_complex_rctl_val(pp->pv_complex);
2448 2512 return;
2449 2513 }
2450 2514 for (l = pp->pv_list; l != NULL; l = l->lp_next)
2451 2515 do_complex_rctl_val(l->lp_complex);
2452 2516 return;
2453 2517 default:
2454 2518 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
2455 2519 long_usage(CMD_ADD, B_TRUE);
2456 2520 usage(B_FALSE, HELP_RESOURCES);
2457 2521 return;
2458 2522 }
2459 2523 }
2460 2524
2461 2525 static boolean_t
2462 2526 gz_invalid_resource(int type)
2463 2527 {
2464 2528 return (global_zone && (type == RT_FS ||
2465 2529 type == RT_NET || type == RT_DEVICE || type == RT_ATTR ||
2466 2530 type == RT_DATASET));
2467 2531 }
2468 2532
2469 2533 static boolean_t
2470 2534 gz_invalid_rt_property(int type)
2471 2535 {
2472 2536 return (global_zone && (type == RT_ZONENAME || type == RT_ZONEPATH ||
2473 2537 type == RT_AUTOBOOT || type == RT_LIMITPRIV ||
2474 2538 type == RT_BOOTARGS || type == RT_BRAND || type == RT_SCHED ||
2475 2539 type == RT_IPTYPE || type == RT_HOSTID || type == RT_FS_ALLOWED));
2476 2540 }
2477 2541
2478 2542 static boolean_t
2479 2543 gz_invalid_property(int type)
2480 2544 {
2481 2545 return (global_zone && (type == PT_ZONENAME || type == PT_ZONEPATH ||
2482 2546 type == PT_AUTOBOOT || type == PT_LIMITPRIV ||
2483 2547 type == PT_BOOTARGS || type == PT_BRAND || type == PT_SCHED ||
2484 2548 type == PT_IPTYPE || type == PT_HOSTID || type == PT_FS_ALLOWED));
2485 2549 }
2486 2550
2487 2551 void
2488 2552 add_func(cmd_t *cmd)
2489 2553 {
2490 2554 int arg;
2491 2555 boolean_t arg_err = B_FALSE;
2492 2556
2493 2557 assert(cmd != NULL);
2494 2558
2495 2559 optind = 0;
2496 2560 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
2497 2561 switch (arg) {
2498 2562 case '?':
2499 2563 longer_usage(CMD_ADD);
2500 2564 arg_err = B_TRUE;
2501 2565 break;
2502 2566 default:
2503 2567 short_usage(CMD_ADD);
2504 2568 arg_err = B_TRUE;
2505 2569 break;
2506 2570 }
2507 2571 }
2508 2572 if (arg_err)
2509 2573 return;
2510 2574
2511 2575 if (optind != cmd->cmd_argc) {
2512 2576 short_usage(CMD_ADD);
2513 2577 return;
2514 2578 }
2515 2579
2516 2580 if (zone_is_read_only(CMD_ADD))
2517 2581 return;
2518 2582
2519 2583 if (initialize(B_TRUE) != Z_OK)
2520 2584 return;
2521 2585 if (global_scope) {
2522 2586 if (gz_invalid_resource(cmd->cmd_res_type)) {
2523 2587 zerr(gettext("Cannot add a %s resource to the "
2524 2588 "global zone."), rt_to_str(cmd->cmd_res_type));
2525 2589 saw_error = B_TRUE;
2526 2590 return;
2527 2591 }
2528 2592
2529 2593 global_scope = B_FALSE;
2530 2594 resource_scope = cmd->cmd_res_type;
2531 2595 end_op = CMD_ADD;
2532 2596 add_resource(cmd);
2533 2597 } else
2534 2598 add_property(cmd);
2535 2599 }
2536 2600
2537 2601 /*
2538 2602 * This routine has an unusual implementation, because it tries very
2539 2603 * hard to succeed in the face of a variety of failure modes.
2540 2604 * The most common and most vexing occurs when the index file and
2541 2605 * the /etc/zones/<zonename.xml> file are not both present. In
2542 2606 * this case, delete must eradicate as much of the zone state as is left
2543 2607 * so that the user can later create a new zone with the same name.
2544 2608 */
2545 2609 void
2546 2610 delete_func(cmd_t *cmd)
2547 2611 {
2548 2612 int err, arg, answer;
2549 2613 char line[ZONENAME_MAX + 128]; /* enough to ask a question */
2550 2614 boolean_t force = B_FALSE;
2551 2615 boolean_t arg_err = B_FALSE;
2552 2616
2553 2617 optind = 0;
2554 2618 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
2555 2619 switch (arg) {
2556 2620 case '?':
2557 2621 longer_usage(CMD_DELETE);
2558 2622 arg_err = B_TRUE;
2559 2623 break;
2560 2624 case 'F':
2561 2625 force = B_TRUE;
2562 2626 break;
2563 2627 default:
2564 2628 short_usage(CMD_DELETE);
2565 2629 arg_err = B_TRUE;
2566 2630 break;
2567 2631 }
2568 2632 }
2569 2633 if (arg_err)
2570 2634 return;
2571 2635
2572 2636 if (optind != cmd->cmd_argc) {
2573 2637 short_usage(CMD_DELETE);
2574 2638 return;
2575 2639 }
2576 2640
2577 2641 if (zone_is_read_only(CMD_DELETE))
2578 2642 return;
2579 2643
2580 2644 if (!force) {
2581 2645 /*
2582 2646 * Initialize sets up the global called "handle" and warns the
2583 2647 * user if the zone is not configured. In force mode, we don't
2584 2648 * trust that evaluation, and hence skip it. (We don't need the
2585 2649 * handle to be loaded anyway, since zonecfg_destroy is done by
2586 2650 * zonename). However, we also have to take care to emulate the
2587 2651 * messages spit out by initialize; see below.
2588 2652 */
2589 2653 if (initialize(B_TRUE) != Z_OK)
2590 2654 return;
2591 2655
2592 2656 (void) snprintf(line, sizeof (line),
2593 2657 gettext("Are you sure you want to delete zone %s"), zone);
2594 2658 if ((answer = ask_yesno(B_FALSE, line)) == -1) {
2595 2659 zerr(gettext("Input not from terminal and -F not "
2596 2660 "specified:\n%s command ignored, exiting."),
2597 2661 cmd_to_str(CMD_DELETE));
2598 2662 exit(Z_ERR);
2599 2663 }
2600 2664 if (answer != 1)
2601 2665 return;
2602 2666 }
2603 2667
2604 2668 /*
2605 2669 * This function removes the authorizations from user_attr
2606 2670 * that correspond to those specified in the configuration
2607 2671 */
2608 2672 if (initialize(B_TRUE) == Z_OK) {
2609 2673 (void) zonecfg_deauthorize_users(handle, zone);
2610 2674 }
2611 2675 if ((err = zonecfg_destroy(zone, force)) != Z_OK) {
2612 2676 if ((err == Z_BAD_ZONE_STATE) && !force) {
2613 2677 zerr(gettext("Zone %s not in %s state; %s not "
2614 2678 "allowed. Use -F to force %s."),
2615 2679 zone, zone_state_str(ZONE_STATE_CONFIGURED),
2616 2680 cmd_to_str(CMD_DELETE), cmd_to_str(CMD_DELETE));
2617 2681 } else {
2618 2682 zone_perror(zone, err, B_TRUE);
2619 2683 }
2620 2684 }
2621 2685 need_to_commit = B_FALSE;
2622 2686
2623 2687 /*
2624 2688 * Emulate initialize's messaging; if there wasn't a valid handle to
2625 2689 * begin with, then user had typed delete (or delete -F) multiple
2626 2690 * times. So we emit a message.
2627 2691 *
2628 2692 * We only do this in the 'force' case because normally, initialize()
2629 2693 * takes care of this for us.
2630 2694 */
2631 2695 if (force && zonecfg_check_handle(handle) != Z_OK && interactive_mode)
2632 2696 (void) printf(gettext("Use '%s' to begin "
2633 2697 "configuring a new zone.\n"), cmd_to_str(CMD_CREATE));
2634 2698
2635 2699 /*
2636 2700 * Time for a new handle: finish the old one off first
2637 2701 * then get a new one properly to avoid leaks.
2638 2702 */
2639 2703 if (got_handle) {
2640 2704 zonecfg_fini_handle(handle);
2641 2705 if ((handle = zonecfg_init_handle()) == NULL) {
2642 2706 zone_perror(execname, Z_NOMEM, B_TRUE);
2643 2707 exit(Z_ERR);
2644 2708 }
2645 2709 if ((err = zonecfg_get_handle(zone, handle)) != Z_OK) {
2646 2710 /* If there was no zone before, that's OK */
2647 2711 if (err != Z_NO_ZONE)
2648 2712 zone_perror(zone, err, B_TRUE);
2649 2713 got_handle = B_FALSE;
2650 2714 }
2651 2715 }
2652 2716 }
2653 2717
2654 2718 static int
2655 2719 fill_in_fstab(cmd_t *cmd, struct zone_fstab *fstab, boolean_t fill_in_only)
2656 2720 {
2657 2721 int err, i;
2658 2722 property_value_ptr_t pp;
2659 2723
2660 2724 if ((err = initialize(B_TRUE)) != Z_OK)
2661 2725 return (err);
2662 2726
2663 2727 bzero(fstab, sizeof (*fstab));
2664 2728 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2665 2729 pp = cmd->cmd_property_ptr[i];
2666 2730 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2667 2731 zerr(gettext("A simple value was expected here."));
2668 2732 saw_error = B_TRUE;
2669 2733 return (Z_INSUFFICIENT_SPEC);
2670 2734 }
2671 2735 switch (cmd->cmd_prop_name[i]) {
2672 2736 case PT_DIR:
2673 2737 (void) strlcpy(fstab->zone_fs_dir, pp->pv_simple,
2674 2738 sizeof (fstab->zone_fs_dir));
2675 2739 break;
2676 2740 case PT_SPECIAL:
2677 2741 (void) strlcpy(fstab->zone_fs_special, pp->pv_simple,
2678 2742 sizeof (fstab->zone_fs_special));
2679 2743 break;
2680 2744 case PT_RAW:
2681 2745 (void) strlcpy(fstab->zone_fs_raw, pp->pv_simple,
2682 2746 sizeof (fstab->zone_fs_raw));
2683 2747 break;
2684 2748 case PT_TYPE:
2685 2749 (void) strlcpy(fstab->zone_fs_type, pp->pv_simple,
2686 2750 sizeof (fstab->zone_fs_type));
2687 2751 break;
2688 2752 default:
2689 2753 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2690 2754 Z_NO_PROPERTY_TYPE, B_TRUE);
2691 2755 return (Z_INSUFFICIENT_SPEC);
2692 2756 }
2693 2757 }
2694 2758 if (fill_in_only)
2695 2759 return (Z_OK);
2696 2760 return (zonecfg_lookup_filesystem(handle, fstab));
2697 2761 }
2698 2762
2699 2763 static int
2700 2764 fill_in_nwiftab(cmd_t *cmd, struct zone_nwiftab *nwiftab,
2701 2765 boolean_t fill_in_only)
2702 2766 {
2703 2767 int err, i;
2704 2768 property_value_ptr_t pp;
2705 2769
2706 2770 if ((err = initialize(B_TRUE)) != Z_OK)
2707 2771 return (err);
2708 2772
2709 2773 bzero(nwiftab, sizeof (*nwiftab));
2710 2774 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2711 2775 pp = cmd->cmd_property_ptr[i];
2712 2776 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2713 2777 zerr(gettext("A simple value was expected here."));
2714 2778 saw_error = B_TRUE;
2715 2779 return (Z_INSUFFICIENT_SPEC);
2716 2780 }
2717 2781 switch (cmd->cmd_prop_name[i]) {
2718 2782 case PT_ADDRESS:
2719 2783 (void) strlcpy(nwiftab->zone_nwif_address,
2720 2784 pp->pv_simple, sizeof (nwiftab->zone_nwif_address));
2721 2785 break;
2722 2786 case PT_ALLOWED_ADDRESS:
2723 2787 (void) strlcpy(nwiftab->zone_nwif_allowed_address,
2724 2788 pp->pv_simple,
2725 2789 sizeof (nwiftab->zone_nwif_allowed_address));
2726 2790 break;
2727 2791 case PT_PHYSICAL:
2728 2792 (void) strlcpy(nwiftab->zone_nwif_physical,
2729 2793 pp->pv_simple,
2730 2794 sizeof (nwiftab->zone_nwif_physical));
2731 2795 break;
2732 2796 case PT_DEFROUTER:
2733 2797 (void) strlcpy(nwiftab->zone_nwif_defrouter,
2734 2798 pp->pv_simple,
2735 2799 sizeof (nwiftab->zone_nwif_defrouter));
2736 2800 break;
2737 2801 default:
2738 2802 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2739 2803 Z_NO_PROPERTY_TYPE, B_TRUE);
2740 2804 return (Z_INSUFFICIENT_SPEC);
2741 2805 }
2742 2806 }
2743 2807 if (fill_in_only)
2744 2808 return (Z_OK);
2745 2809 err = zonecfg_lookup_nwif(handle, nwiftab);
2746 2810 return (err);
2747 2811 }
2748 2812
2749 2813 static int
2750 2814 fill_in_devtab(cmd_t *cmd, struct zone_devtab *devtab, boolean_t fill_in_only)
2751 2815 {
2752 2816 int err, i;
2753 2817 property_value_ptr_t pp;
2754 2818
2755 2819 if ((err = initialize(B_TRUE)) != Z_OK)
2756 2820 return (err);
2757 2821
2758 2822 bzero(devtab, sizeof (*devtab));
2759 2823 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2760 2824 pp = cmd->cmd_property_ptr[i];
2761 2825 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2762 2826 zerr(gettext("A simple value was expected here."));
2763 2827 saw_error = B_TRUE;
2764 2828 return (Z_INSUFFICIENT_SPEC);
2765 2829 }
2766 2830 switch (cmd->cmd_prop_name[i]) {
2767 2831 case PT_MATCH:
2768 2832 (void) strlcpy(devtab->zone_dev_match, pp->pv_simple,
2769 2833 sizeof (devtab->zone_dev_match));
2770 2834 break;
2771 2835 default:
2772 2836 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2773 2837 Z_NO_PROPERTY_TYPE, B_TRUE);
2774 2838 return (Z_INSUFFICIENT_SPEC);
2775 2839 }
2776 2840 }
2777 2841 if (fill_in_only)
2778 2842 return (Z_OK);
2779 2843 err = zonecfg_lookup_dev(handle, devtab);
2780 2844 return (err);
2781 2845 }
2782 2846
2783 2847 static int
2784 2848 fill_in_rctltab(cmd_t *cmd, struct zone_rctltab *rctltab,
2785 2849 boolean_t fill_in_only)
2786 2850 {
2787 2851 int err, i;
2788 2852 property_value_ptr_t pp;
2789 2853
2790 2854 if ((err = initialize(B_TRUE)) != Z_OK)
2791 2855 return (err);
2792 2856
2793 2857 bzero(rctltab, sizeof (*rctltab));
2794 2858 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2795 2859 pp = cmd->cmd_property_ptr[i];
2796 2860 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2797 2861 zerr(gettext("A simple value was expected here."));
2798 2862 saw_error = B_TRUE;
2799 2863 return (Z_INSUFFICIENT_SPEC);
2800 2864 }
2801 2865 switch (cmd->cmd_prop_name[i]) {
2802 2866 case PT_NAME:
2803 2867 (void) strlcpy(rctltab->zone_rctl_name, pp->pv_simple,
2804 2868 sizeof (rctltab->zone_rctl_name));
2805 2869 break;
2806 2870 default:
2807 2871 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2808 2872 Z_NO_PROPERTY_TYPE, B_TRUE);
2809 2873 return (Z_INSUFFICIENT_SPEC);
2810 2874 }
2811 2875 }
2812 2876 if (fill_in_only)
2813 2877 return (Z_OK);
2814 2878 err = zonecfg_lookup_rctl(handle, rctltab);
2815 2879 return (err);
2816 2880 }
2817 2881
2818 2882 static int
2819 2883 fill_in_attrtab(cmd_t *cmd, struct zone_attrtab *attrtab,
2820 2884 boolean_t fill_in_only)
2821 2885 {
2822 2886 int err, i;
2823 2887 property_value_ptr_t pp;
2824 2888
2825 2889 if ((err = initialize(B_TRUE)) != Z_OK)
2826 2890 return (err);
2827 2891
2828 2892 bzero(attrtab, sizeof (*attrtab));
2829 2893 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2830 2894 pp = cmd->cmd_property_ptr[i];
2831 2895 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2832 2896 zerr(gettext("A simple value was expected here."));
2833 2897 saw_error = B_TRUE;
2834 2898 return (Z_INSUFFICIENT_SPEC);
2835 2899 }
2836 2900 switch (cmd->cmd_prop_name[i]) {
2837 2901 case PT_NAME:
2838 2902 (void) strlcpy(attrtab->zone_attr_name, pp->pv_simple,
2839 2903 sizeof (attrtab->zone_attr_name));
2840 2904 break;
2841 2905 case PT_TYPE:
2842 2906 (void) strlcpy(attrtab->zone_attr_type, pp->pv_simple,
2843 2907 sizeof (attrtab->zone_attr_type));
2844 2908 break;
2845 2909 case PT_VALUE:
2846 2910 (void) strlcpy(attrtab->zone_attr_value, pp->pv_simple,
2847 2911 sizeof (attrtab->zone_attr_value));
2848 2912 break;
2849 2913 default:
2850 2914 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2851 2915 Z_NO_PROPERTY_TYPE, B_TRUE);
2852 2916 return (Z_INSUFFICIENT_SPEC);
2853 2917 }
2854 2918 }
2855 2919 if (fill_in_only)
2856 2920 return (Z_OK);
2857 2921 err = zonecfg_lookup_attr(handle, attrtab);
2858 2922 return (err);
2859 2923 }
2860 2924
2861 2925 static int
2862 2926 fill_in_dstab(cmd_t *cmd, struct zone_dstab *dstab, boolean_t fill_in_only)
2863 2927 {
2864 2928 int err, i;
2865 2929 property_value_ptr_t pp;
2866 2930
2867 2931 if ((err = initialize(B_TRUE)) != Z_OK)
2868 2932 return (err);
2869 2933
2870 2934 dstab->zone_dataset_name[0] = '\0';
2871 2935 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2872 2936 pp = cmd->cmd_property_ptr[i];
2873 2937 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2874 2938 zerr(gettext("A simple value was expected here."));
2875 2939 saw_error = B_TRUE;
2876 2940 return (Z_INSUFFICIENT_SPEC);
2877 2941 }
2878 2942 switch (cmd->cmd_prop_name[i]) {
2879 2943 case PT_NAME:
2880 2944 (void) strlcpy(dstab->zone_dataset_name, pp->pv_simple,
2881 2945 sizeof (dstab->zone_dataset_name));
2882 2946 break;
2883 2947 default:
2884 2948 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2885 2949 Z_NO_PROPERTY_TYPE, B_TRUE);
2886 2950 return (Z_INSUFFICIENT_SPEC);
2887 2951 }
2888 2952 }
2889 2953 if (fill_in_only)
2890 2954 return (Z_OK);
2891 2955 return (zonecfg_lookup_ds(handle, dstab));
2892 2956 }
2893 2957
2894 2958 static int
2895 2959 fill_in_admintab(cmd_t *cmd, struct zone_admintab *admintab,
2896 2960 boolean_t fill_in_only)
2897 2961 {
2898 2962 int err, i;
2899 2963 property_value_ptr_t pp;
2900 2964
2901 2965 if ((err = initialize(B_TRUE)) != Z_OK)
2902 2966 return (err);
2903 2967
2904 2968 bzero(admintab, sizeof (*admintab));
2905 2969 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2906 2970 pp = cmd->cmd_property_ptr[i];
2907 2971 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2908 2972 zerr(gettext("A simple value was expected here."));
2909 2973 saw_error = B_TRUE;
2910 2974 return (Z_INSUFFICIENT_SPEC);
2911 2975 }
2912 2976 switch (cmd->cmd_prop_name[i]) {
2913 2977 case PT_USER:
2914 2978 (void) strlcpy(admintab->zone_admin_user, pp->pv_simple,
2915 2979 sizeof (admintab->zone_admin_user));
2916 2980 break;
2917 2981 case PT_AUTHS:
2918 2982 (void) strlcpy(admintab->zone_admin_auths,
2919 2983 pp->pv_simple, sizeof (admintab->zone_admin_auths));
2920 2984 break;
2921 2985 default:
2922 2986 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
↓ open down ↓ |
649 lines elided |
↑ open up ↑ |
2923 2987 Z_NO_PROPERTY_TYPE, B_TRUE);
2924 2988 return (Z_INSUFFICIENT_SPEC);
2925 2989 }
2926 2990 }
2927 2991 if (fill_in_only)
2928 2992 return (Z_OK);
2929 2993 err = zonecfg_lookup_admin(handle, admintab);
2930 2994 return (err);
2931 2995 }
2932 2996
2997 +static int
2998 +fill_in_secflagstab(cmd_t *cmd, struct zone_secflagstab *secflagstab,
2999 + boolean_t fill_in_only)
3000 +{
3001 + int err, i;
3002 + property_value_ptr_t pp;
3003 +
3004 + if ((err = initialize(B_TRUE)) != Z_OK)
3005 + return (err);
3006 +
3007 + bzero(secflagstab, sizeof (*secflagstab));
3008 + for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
3009 + pp = cmd->cmd_property_ptr[i];
3010 + if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
3011 + zerr(gettext("A simple value was expected here."));
3012 + saw_error = B_TRUE;
3013 + return (Z_INSUFFICIENT_SPEC);
3014 + }
3015 + switch (cmd->cmd_prop_name[i]) {
3016 + case PT_DEFAULT:
3017 + (void) strlcpy(secflagstab->zone_secflags_default,
3018 + pp->pv_simple,
3019 + sizeof (secflagstab->zone_secflags_default));
3020 + break;
3021 + case PT_LOWER:
3022 + (void) strlcpy(secflagstab->zone_secflags_lower,
3023 + pp->pv_simple,
3024 + sizeof (secflagstab->zone_secflags_lower));
3025 + break;
3026 + case PT_UPPER:
3027 + (void) strlcpy(secflagstab->zone_secflags_upper,
3028 + pp->pv_simple,
3029 + sizeof (secflagstab->zone_secflags_upper));
3030 + break;
3031 + default:
3032 + zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
3033 + Z_NO_PROPERTY_TYPE, B_TRUE);
3034 + return (Z_INSUFFICIENT_SPEC);
3035 + }
3036 + }
3037 + if (fill_in_only)
3038 + return (Z_OK);
3039 +
3040 + err = zonecfg_lookup_secflags(handle, secflagstab);
3041 +
3042 + return (err);
3043 +}
3044 +
2933 3045 static void
2934 3046 remove_aliased_rctl(int type, char *name)
2935 3047 {
2936 3048 int err;
2937 3049 uint64_t tmp;
2938 3050
2939 3051 if ((err = zonecfg_get_aliased_rctl(handle, name, &tmp)) != Z_OK) {
2940 3052 zerr("%s %s: %s", cmd_to_str(CMD_CLEAR), pt_to_str(type),
2941 3053 zonecfg_strerror(err));
2942 3054 saw_error = B_TRUE;
2943 3055 return;
2944 3056 }
2945 3057 if ((err = zonecfg_rm_aliased_rctl(handle, name)) != Z_OK) {
2946 3058 zerr("%s %s: %s", cmd_to_str(CMD_CLEAR), pt_to_str(type),
2947 3059 zonecfg_strerror(err));
2948 3060 saw_error = B_TRUE;
2949 3061 } else {
2950 3062 need_to_commit = B_TRUE;
2951 3063 }
2952 3064 }
2953 3065
2954 3066 static boolean_t
2955 3067 prompt_remove_resource(cmd_t *cmd, char *rsrc)
2956 3068 {
2957 3069 int num;
2958 3070 int answer;
2959 3071 int arg;
2960 3072 boolean_t force = B_FALSE;
2961 3073 char prompt[128];
2962 3074 boolean_t arg_err = B_FALSE;
2963 3075
2964 3076 optind = 0;
2965 3077 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) {
2966 3078 switch (arg) {
2967 3079 case 'F':
2968 3080 force = B_TRUE;
2969 3081 break;
2970 3082 default:
2971 3083 arg_err = B_TRUE;
2972 3084 break;
2973 3085 }
2974 3086 }
2975 3087 if (arg_err)
2976 3088 return (B_FALSE);
2977 3089
2978 3090
2979 3091 num = zonecfg_num_resources(handle, rsrc);
2980 3092
2981 3093 if (num == 0) {
2982 3094 z_cmd_rt_perror(CMD_REMOVE, cmd->cmd_res_type, Z_NO_ENTRY,
2983 3095 B_TRUE);
2984 3096 return (B_FALSE);
2985 3097 }
2986 3098 if (num > 1 && !force) {
2987 3099 if (!interactive_mode) {
2988 3100 zerr(gettext("There are multiple instances of this "
2989 3101 "resource. Either qualify the resource to\n"
2990 3102 "remove a single instance or use the -F option to "
2991 3103 "remove all instances."));
2992 3104 saw_error = B_TRUE;
2993 3105 return (B_FALSE);
2994 3106 }
2995 3107 (void) snprintf(prompt, sizeof (prompt), gettext(
2996 3108 "Are you sure you want to remove ALL '%s' resources"),
2997 3109 rsrc);
2998 3110 answer = ask_yesno(B_FALSE, prompt);
2999 3111 if (answer == -1) {
3000 3112 zerr(gettext("Resource incomplete."));
3001 3113 return (B_FALSE);
3002 3114 }
3003 3115 if (answer != 1)
3004 3116 return (B_FALSE);
3005 3117 }
3006 3118 return (B_TRUE);
3007 3119 }
3008 3120
3009 3121 static void
3010 3122 remove_fs(cmd_t *cmd)
3011 3123 {
3012 3124 int err;
3013 3125
3014 3126 /* traditional, qualified fs removal */
3015 3127 if (cmd->cmd_prop_nv_pairs > 0) {
3016 3128 struct zone_fstab fstab;
3017 3129
3018 3130 if ((err = fill_in_fstab(cmd, &fstab, B_FALSE)) != Z_OK) {
3019 3131 z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE);
3020 3132 return;
3021 3133 }
3022 3134 if ((err = zonecfg_delete_filesystem(handle, &fstab)) != Z_OK)
3023 3135 z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE);
3024 3136 else
3025 3137 need_to_commit = B_TRUE;
3026 3138 zonecfg_free_fs_option_list(fstab.zone_fs_options);
3027 3139 return;
3028 3140 }
3029 3141
3030 3142 /*
3031 3143 * unqualified fs removal. remove all fs's but prompt if more
3032 3144 * than one.
3033 3145 */
3034 3146 if (!prompt_remove_resource(cmd, "fs"))
3035 3147 return;
3036 3148
3037 3149 if ((err = zonecfg_del_all_resources(handle, "fs")) != Z_OK)
3038 3150 z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE);
3039 3151 else
3040 3152 need_to_commit = B_TRUE;
3041 3153 }
3042 3154
3043 3155 static void
3044 3156 remove_net(cmd_t *cmd)
3045 3157 {
3046 3158 int err;
3047 3159
3048 3160 /* traditional, qualified net removal */
3049 3161 if (cmd->cmd_prop_nv_pairs > 0) {
3050 3162 struct zone_nwiftab nwiftab;
3051 3163
3052 3164 if ((err = fill_in_nwiftab(cmd, &nwiftab, B_FALSE)) != Z_OK) {
3053 3165 z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE);
3054 3166 return;
3055 3167 }
3056 3168 if ((err = zonecfg_delete_nwif(handle, &nwiftab)) != Z_OK)
3057 3169 z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE);
3058 3170 else
3059 3171 need_to_commit = B_TRUE;
3060 3172 return;
3061 3173 }
3062 3174
3063 3175 /*
3064 3176 * unqualified net removal. remove all nets but prompt if more
3065 3177 * than one.
3066 3178 */
3067 3179 if (!prompt_remove_resource(cmd, "net"))
3068 3180 return;
3069 3181
3070 3182 if ((err = zonecfg_del_all_resources(handle, "net")) != Z_OK)
3071 3183 z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE);
3072 3184 else
3073 3185 need_to_commit = B_TRUE;
3074 3186 }
3075 3187
3076 3188 static void
3077 3189 remove_device(cmd_t *cmd)
3078 3190 {
3079 3191 int err;
3080 3192
3081 3193 /* traditional, qualified device removal */
3082 3194 if (cmd->cmd_prop_nv_pairs > 0) {
3083 3195 struct zone_devtab devtab;
3084 3196
3085 3197 if ((err = fill_in_devtab(cmd, &devtab, B_FALSE)) != Z_OK) {
3086 3198 z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE);
3087 3199 return;
3088 3200 }
3089 3201 if ((err = zonecfg_delete_dev(handle, &devtab)) != Z_OK)
3090 3202 z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE);
3091 3203 else
3092 3204 need_to_commit = B_TRUE;
3093 3205 return;
3094 3206 }
3095 3207
3096 3208 /*
3097 3209 * unqualified device removal. remove all devices but prompt if more
3098 3210 * than one.
3099 3211 */
3100 3212 if (!prompt_remove_resource(cmd, "device"))
3101 3213 return;
3102 3214
3103 3215 if ((err = zonecfg_del_all_resources(handle, "device")) != Z_OK)
3104 3216 z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE);
3105 3217 else
3106 3218 need_to_commit = B_TRUE;
3107 3219 }
3108 3220
3109 3221 static void
3110 3222 remove_attr(cmd_t *cmd)
3111 3223 {
3112 3224 int err;
3113 3225
3114 3226 /* traditional, qualified attr removal */
3115 3227 if (cmd->cmd_prop_nv_pairs > 0) {
3116 3228 struct zone_attrtab attrtab;
3117 3229
3118 3230 if ((err = fill_in_attrtab(cmd, &attrtab, B_FALSE)) != Z_OK) {
3119 3231 z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE);
3120 3232 return;
3121 3233 }
3122 3234 if ((err = zonecfg_delete_attr(handle, &attrtab)) != Z_OK)
3123 3235 z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE);
3124 3236 else
3125 3237 need_to_commit = B_TRUE;
3126 3238 return;
3127 3239 }
3128 3240
3129 3241 /*
3130 3242 * unqualified attr removal. remove all attrs but prompt if more
3131 3243 * than one.
3132 3244 */
3133 3245 if (!prompt_remove_resource(cmd, "attr"))
3134 3246 return;
3135 3247
3136 3248 if ((err = zonecfg_del_all_resources(handle, "attr")) != Z_OK)
3137 3249 z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE);
3138 3250 else
3139 3251 need_to_commit = B_TRUE;
3140 3252 }
3141 3253
3142 3254 static void
3143 3255 remove_dataset(cmd_t *cmd)
3144 3256 {
3145 3257 int err;
3146 3258
3147 3259 /* traditional, qualified dataset removal */
3148 3260 if (cmd->cmd_prop_nv_pairs > 0) {
3149 3261 struct zone_dstab dstab;
3150 3262
3151 3263 if ((err = fill_in_dstab(cmd, &dstab, B_FALSE)) != Z_OK) {
3152 3264 z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE);
3153 3265 return;
3154 3266 }
3155 3267 if ((err = zonecfg_delete_ds(handle, &dstab)) != Z_OK)
3156 3268 z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE);
3157 3269 else
3158 3270 need_to_commit = B_TRUE;
3159 3271 return;
3160 3272 }
3161 3273
3162 3274 /*
3163 3275 * unqualified dataset removal. remove all datasets but prompt if more
3164 3276 * than one.
3165 3277 */
3166 3278 if (!prompt_remove_resource(cmd, "dataset"))
3167 3279 return;
3168 3280
3169 3281 if ((err = zonecfg_del_all_resources(handle, "dataset")) != Z_OK)
3170 3282 z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE);
3171 3283 else
3172 3284 need_to_commit = B_TRUE;
3173 3285 }
3174 3286
3175 3287 static void
3176 3288 remove_rctl(cmd_t *cmd)
3177 3289 {
3178 3290 int err;
3179 3291
3180 3292 /* traditional, qualified rctl removal */
3181 3293 if (cmd->cmd_prop_nv_pairs > 0) {
3182 3294 struct zone_rctltab rctltab;
3183 3295
3184 3296 if ((err = fill_in_rctltab(cmd, &rctltab, B_FALSE)) != Z_OK) {
3185 3297 z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE);
3186 3298 return;
3187 3299 }
3188 3300 if ((err = zonecfg_delete_rctl(handle, &rctltab)) != Z_OK)
3189 3301 z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE);
3190 3302 else
3191 3303 need_to_commit = B_TRUE;
3192 3304 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
3193 3305 return;
3194 3306 }
3195 3307
3196 3308 /*
3197 3309 * unqualified rctl removal. remove all rctls but prompt if more
3198 3310 * than one.
3199 3311 */
3200 3312 if (!prompt_remove_resource(cmd, "rctl"))
3201 3313 return;
3202 3314
3203 3315 if ((err = zonecfg_del_all_resources(handle, "rctl")) != Z_OK)
3204 3316 z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE);
3205 3317 else
3206 3318 need_to_commit = B_TRUE;
3207 3319 }
3208 3320
3209 3321 static void
3210 3322 remove_pset()
3211 3323 {
3212 3324 int err;
3213 3325 struct zone_psettab psettab;
3214 3326
3215 3327 if ((err = zonecfg_lookup_pset(handle, &psettab)) != Z_OK) {
3216 3328 z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE);
3217 3329 return;
3218 3330 }
3219 3331 if ((err = zonecfg_delete_pset(handle)) != Z_OK)
3220 3332 z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE);
3221 3333 else
3222 3334 need_to_commit = B_TRUE;
3223 3335 }
3224 3336
3225 3337 static void
3226 3338 remove_pcap()
3227 3339 {
3228 3340 int err;
3229 3341 uint64_t tmp;
3230 3342
3231 3343 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp) != Z_OK) {
3232 3344 zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_PCAP),
3233 3345 zonecfg_strerror(Z_NO_RESOURCE_TYPE));
3234 3346 saw_error = B_TRUE;
3235 3347 return;
3236 3348 }
3237 3349
3238 3350 if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_CPUCAP)) != Z_OK)
3239 3351 z_cmd_rt_perror(CMD_REMOVE, RT_PCAP, err, B_TRUE);
3240 3352 else
3241 3353 need_to_commit = B_TRUE;
3242 3354 }
3243 3355
3244 3356 static void
3245 3357 remove_mcap()
3246 3358 {
3247 3359 int err, res1, res2, res3;
3248 3360 uint64_t tmp;
3249 3361 struct zone_mcaptab mcaptab;
3250 3362 boolean_t revert = B_FALSE;
3251 3363
3252 3364 res1 = zonecfg_lookup_mcap(handle, &mcaptab);
3253 3365 res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp);
3254 3366 res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &tmp);
3255 3367
3256 3368 /* if none of these exist, there is no resource to remove */
3257 3369 if (res1 != Z_OK && res2 != Z_OK && res3 != Z_OK) {
3258 3370 zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_MCAP),
3259 3371 zonecfg_strerror(Z_NO_RESOURCE_TYPE));
3260 3372 saw_error = B_TRUE;
3261 3373 return;
3262 3374 }
3263 3375 if (res1 == Z_OK) {
3264 3376 if ((err = zonecfg_delete_mcap(handle)) != Z_OK) {
3265 3377 z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE);
3266 3378 revert = B_TRUE;
3267 3379 } else {
3268 3380 need_to_commit = B_TRUE;
3269 3381 }
3270 3382 }
3271 3383 if (res2 == Z_OK) {
3272 3384 if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXSWAP))
3273 3385 != Z_OK) {
3274 3386 z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE);
3275 3387 revert = B_TRUE;
3276 3388 } else {
3277 3389 need_to_commit = B_TRUE;
3278 3390 }
3279 3391 }
3280 3392 if (res3 == Z_OK) {
3281 3393 if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM))
3282 3394 != Z_OK) {
3283 3395 z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE);
3284 3396 revert = B_TRUE;
3285 3397 } else {
3286 3398 need_to_commit = B_TRUE;
3287 3399 }
3288 3400 }
3289 3401
3290 3402 if (revert)
3291 3403 need_to_commit = B_FALSE;
3292 3404 }
3293 3405
3294 3406 static void
3295 3407 remove_admin(cmd_t *cmd)
3296 3408 {
3297 3409 int err;
3298 3410
3299 3411 /* traditional, qualified attr removal */
3300 3412 if (cmd->cmd_prop_nv_pairs > 0) {
3301 3413 struct zone_admintab admintab;
3302 3414
3303 3415 if ((err = fill_in_admintab(cmd, &admintab, B_FALSE)) != Z_OK) {
3304 3416 z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3305 3417 err, B_TRUE);
3306 3418 return;
3307 3419 }
3308 3420 if ((err = zonecfg_delete_admin(handle, &admintab,
3309 3421 zone))
3310 3422 != Z_OK)
3311 3423 z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3312 3424 err, B_TRUE);
3313 3425 else
3314 3426 need_to_commit = B_TRUE;
3315 3427 return;
3316 3428 } else {
3317 3429 /*
3318 3430 * unqualified admin removal.
3319 3431 * remove all admins but prompt if more
3320 3432 * than one.
3321 3433 */
3322 3434 if (!prompt_remove_resource(cmd, "admin"))
3323 3435 return;
3324 3436
↓ open down ↓ |
382 lines elided |
↑ open up ↑ |
3325 3437 if ((err = zonecfg_delete_admins(handle, zone))
3326 3438 != Z_OK)
3327 3439 z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3328 3440 err, B_TRUE);
3329 3441 else
3330 3442 need_to_commit = B_TRUE;
3331 3443 }
3332 3444 }
3333 3445
3334 3446 static void
3447 +remove_secflags()
3448 +{
3449 + int err;
3450 + struct zone_secflagstab sectab = { 0 };
3451 +
3452 + if (zonecfg_lookup_secflags(handle, §ab) != Z_OK) {
3453 + zerr("%s %s: %s", cmd_to_str(CMD_REMOVE),
3454 + rt_to_str(RT_SECFLAGS),
3455 + zonecfg_strerror(Z_NO_RESOURCE_TYPE));
3456 + return;
3457 + }
3458 +
3459 + if ((err = zonecfg_delete_secflags(handle, §ab)) != Z_OK) {
3460 + z_cmd_rt_perror(CMD_REMOVE, RT_SECFLAGS, err, B_TRUE);
3461 + return;
3462 + }
3463 +
3464 + need_to_commit = B_TRUE;
3465 +}
3466 +
3467 +static void
3335 3468 remove_resource(cmd_t *cmd)
3336 3469 {
3337 3470 int type;
3338 3471 int arg;
3339 3472 boolean_t arg_err = B_FALSE;
3340 3473
3341 3474 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3342 3475 long_usage(CMD_REMOVE, B_TRUE);
3343 3476 return;
3344 3477 }
3345 3478
3346 3479 optind = 0;
3347 3480 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
3348 3481 switch (arg) {
3349 3482 case '?':
3350 3483 longer_usage(CMD_REMOVE);
3351 3484 arg_err = B_TRUE;
3352 3485 break;
3353 3486 case 'F':
3354 3487 break;
3355 3488 default:
3356 3489 short_usage(CMD_REMOVE);
3357 3490 arg_err = B_TRUE;
3358 3491 break;
3359 3492 }
3360 3493 }
3361 3494 if (arg_err)
3362 3495 return;
3363 3496
3364 3497 if (initialize(B_TRUE) != Z_OK)
3365 3498 return;
3366 3499
3367 3500 switch (type) {
3368 3501 case RT_FS:
3369 3502 remove_fs(cmd);
3370 3503 return;
3371 3504 case RT_NET:
3372 3505 remove_net(cmd);
3373 3506 return;
3374 3507 case RT_DEVICE:
3375 3508 remove_device(cmd);
3376 3509 return;
3377 3510 case RT_RCTL:
3378 3511 remove_rctl(cmd);
3379 3512 return;
3380 3513 case RT_ATTR:
3381 3514 remove_attr(cmd);
3382 3515 return;
3383 3516 case RT_DATASET:
3384 3517 remove_dataset(cmd);
3385 3518 return;
3386 3519 case RT_DCPU:
3387 3520 remove_pset();
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
3388 3521 return;
3389 3522 case RT_PCAP:
3390 3523 remove_pcap();
3391 3524 return;
3392 3525 case RT_MCAP:
3393 3526 remove_mcap();
3394 3527 return;
3395 3528 case RT_ADMIN:
3396 3529 remove_admin(cmd);
3397 3530 return;
3531 + case RT_SECFLAGS:
3532 + remove_secflags();
3533 + return;
3398 3534 default:
3399 3535 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3400 3536 long_usage(CMD_REMOVE, B_TRUE);
3401 3537 usage(B_FALSE, HELP_RESOURCES);
3402 3538 return;
3403 3539 }
3404 3540 }
3405 3541
3406 3542 static void
3407 3543 remove_property(cmd_t *cmd)
3408 3544 {
3409 3545 char *prop_id;
3410 3546 int err, res_type, prop_type;
3411 3547 property_value_ptr_t pp;
3412 3548 struct zone_rctlvaltab *rctlvaltab;
3413 3549 complex_property_ptr_t cx;
3414 3550
3415 3551 res_type = resource_scope;
3416 3552 prop_type = cmd->cmd_prop_name[0];
3417 3553 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
3418 3554 long_usage(CMD_REMOVE, B_TRUE);
3419 3555 return;
3420 3556 }
3421 3557
3422 3558 if (cmd->cmd_prop_nv_pairs != 1) {
3423 3559 long_usage(CMD_ADD, B_TRUE);
3424 3560 return;
3425 3561 }
3426 3562
3427 3563 if (initialize(B_TRUE) != Z_OK)
3428 3564 return;
3429 3565
3430 3566 switch (res_type) {
3431 3567 case RT_FS:
3432 3568 if (prop_type != PT_OPTIONS) {
3433 3569 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3434 3570 B_TRUE);
3435 3571 long_usage(CMD_REMOVE, B_TRUE);
3436 3572 usage(B_FALSE, HELP_PROPS);
3437 3573 return;
3438 3574 }
3439 3575 pp = cmd->cmd_property_ptr[0];
3440 3576 if (pp->pv_type == PROP_VAL_COMPLEX) {
3441 3577 zerr(gettext("A %s or %s value was expected here."),
3442 3578 pvt_to_str(PROP_VAL_SIMPLE),
3443 3579 pvt_to_str(PROP_VAL_LIST));
3444 3580 saw_error = B_TRUE;
3445 3581 return;
3446 3582 }
3447 3583 if (pp->pv_type == PROP_VAL_SIMPLE) {
3448 3584 if (pp->pv_simple == NULL) {
3449 3585 long_usage(CMD_ADD, B_TRUE);
3450 3586 return;
3451 3587 }
3452 3588 prop_id = pp->pv_simple;
3453 3589 err = zonecfg_remove_fs_option(&in_progress_fstab,
3454 3590 prop_id);
3455 3591 if (err != Z_OK)
3456 3592 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3457 3593 } else {
3458 3594 list_property_ptr_t list;
3459 3595
3460 3596 for (list = pp->pv_list; list != NULL;
3461 3597 list = list->lp_next) {
3462 3598 prop_id = list->lp_simple;
3463 3599 if (prop_id == NULL)
3464 3600 break;
3465 3601 err = zonecfg_remove_fs_option(
3466 3602 &in_progress_fstab, prop_id);
3467 3603 if (err != Z_OK)
3468 3604 zone_perror(pt_to_str(prop_type), err,
3469 3605 B_TRUE);
3470 3606 }
3471 3607 }
3472 3608 return;
3473 3609 case RT_RCTL:
3474 3610 if (prop_type != PT_VALUE) {
3475 3611 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3476 3612 B_TRUE);
3477 3613 long_usage(CMD_REMOVE, B_TRUE);
3478 3614 usage(B_FALSE, HELP_PROPS);
3479 3615 return;
3480 3616 }
3481 3617 pp = cmd->cmd_property_ptr[0];
3482 3618 if (pp->pv_type != PROP_VAL_COMPLEX) {
3483 3619 zerr(gettext("A %s value was expected here."),
3484 3620 pvt_to_str(PROP_VAL_COMPLEX));
3485 3621 saw_error = B_TRUE;
3486 3622 return;
3487 3623 }
3488 3624 if ((rctlvaltab = alloc_rctlvaltab()) == NULL) {
3489 3625 zone_perror(zone, Z_NOMEM, B_TRUE);
3490 3626 exit(Z_ERR);
3491 3627 }
3492 3628 for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) {
3493 3629 switch (cx->cp_type) {
3494 3630 case PT_PRIV:
3495 3631 (void) strlcpy(rctlvaltab->zone_rctlval_priv,
3496 3632 cx->cp_value,
3497 3633 sizeof (rctlvaltab->zone_rctlval_priv));
3498 3634 break;
3499 3635 case PT_LIMIT:
3500 3636 (void) strlcpy(rctlvaltab->zone_rctlval_limit,
3501 3637 cx->cp_value,
3502 3638 sizeof (rctlvaltab->zone_rctlval_limit));
3503 3639 break;
3504 3640 case PT_ACTION:
3505 3641 (void) strlcpy(rctlvaltab->zone_rctlval_action,
3506 3642 cx->cp_value,
3507 3643 sizeof (rctlvaltab->zone_rctlval_action));
3508 3644 break;
3509 3645 default:
3510 3646 zone_perror(pt_to_str(prop_type),
3511 3647 Z_NO_PROPERTY_TYPE, B_TRUE);
3512 3648 long_usage(CMD_ADD, B_TRUE);
3513 3649 usage(B_FALSE, HELP_PROPS);
3514 3650 zonecfg_free_rctl_value_list(rctlvaltab);
3515 3651 return;
3516 3652 }
3517 3653 }
3518 3654 rctlvaltab->zone_rctlval_next = NULL;
3519 3655 err = zonecfg_remove_rctl_value(&in_progress_rctltab,
3520 3656 rctlvaltab);
3521 3657 if (err != Z_OK)
3522 3658 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3523 3659 zonecfg_free_rctl_value_list(rctlvaltab);
3524 3660 return;
3525 3661 case RT_NET:
3526 3662 if (prop_type != PT_DEFROUTER) {
3527 3663 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3528 3664 B_TRUE);
3529 3665 long_usage(CMD_REMOVE, B_TRUE);
3530 3666 usage(B_FALSE, HELP_PROPS);
3531 3667 return;
3532 3668 } else {
3533 3669 bzero(&in_progress_nwiftab.zone_nwif_defrouter,
3534 3670 sizeof (in_progress_nwiftab.zone_nwif_defrouter));
3535 3671 return;
3536 3672 }
3537 3673 default:
3538 3674 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
3539 3675 long_usage(CMD_REMOVE, B_TRUE);
3540 3676 usage(B_FALSE, HELP_RESOURCES);
3541 3677 return;
3542 3678 }
3543 3679 }
3544 3680
3545 3681 void
3546 3682 remove_func(cmd_t *cmd)
3547 3683 {
3548 3684 if (zone_is_read_only(CMD_REMOVE))
3549 3685 return;
3550 3686
3551 3687 assert(cmd != NULL);
3552 3688
3553 3689 if (global_scope) {
3554 3690 if (gz_invalid_resource(cmd->cmd_res_type)) {
3555 3691 zerr(gettext("%s is not a valid resource for the "
3556 3692 "global zone."), rt_to_str(cmd->cmd_res_type));
3557 3693 saw_error = B_TRUE;
3558 3694 return;
3559 3695 }
3560 3696 remove_resource(cmd);
3561 3697 } else {
3562 3698 remove_property(cmd);
3563 3699 }
3564 3700 }
3565 3701
3566 3702 static void
3567 3703 clear_property(cmd_t *cmd)
3568 3704 {
3569 3705 int res_type, prop_type;
3570 3706
3571 3707 res_type = resource_scope;
3572 3708 prop_type = cmd->cmd_res_type;
3573 3709 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
3574 3710 long_usage(CMD_CLEAR, B_TRUE);
3575 3711 return;
3576 3712 }
3577 3713
3578 3714 if (initialize(B_TRUE) != Z_OK)
3579 3715 return;
3580 3716
3581 3717 switch (res_type) {
3582 3718 case RT_FS:
3583 3719 if (prop_type == PT_RAW) {
3584 3720 in_progress_fstab.zone_fs_raw[0] = '\0';
3585 3721 need_to_commit = B_TRUE;
3586 3722 return;
3587 3723 }
3588 3724 break;
3589 3725 case RT_DCPU:
3590 3726 if (prop_type == PT_IMPORTANCE) {
3591 3727 in_progress_psettab.zone_importance[0] = '\0';
3592 3728 need_to_commit = B_TRUE;
3593 3729 return;
3594 3730 }
3595 3731 break;
3596 3732 case RT_MCAP:
3597 3733 switch (prop_type) {
3598 3734 case PT_PHYSICAL:
3599 3735 in_progress_mcaptab.zone_physmem_cap[0] = '\0';
↓ open down ↓ |
192 lines elided |
↑ open up ↑ |
3600 3736 need_to_commit = B_TRUE;
3601 3737 return;
3602 3738 case PT_SWAP:
3603 3739 remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP);
3604 3740 return;
3605 3741 case PT_LOCKED:
3606 3742 remove_aliased_rctl(PT_LOCKED, ALIAS_MAXLOCKEDMEM);
3607 3743 return;
3608 3744 }
3609 3745 break;
3746 + case RT_SECFLAGS:
3747 + switch (prop_type) {
3748 + case PT_LOWER:
3749 + in_progress_secflagstab.zone_secflags_lower[0] = '\0';
3750 + need_to_commit = B_TRUE;
3751 + return;
3752 + case PT_DEFAULT:
3753 + in_progress_secflagstab.zone_secflags_default[0] = '\0';
3754 + need_to_commit = B_TRUE;
3755 + return;
3756 + case PT_UPPER:
3757 + in_progress_secflagstab.zone_secflags_upper[0] = '\0';
3758 + need_to_commit = B_TRUE;
3759 + return;
3760 + }
3761 + break;
3610 3762 default:
3611 3763 break;
3612 3764 }
3613 3765
3614 3766 zone_perror(pt_to_str(prop_type), Z_CLEAR_DISALLOW, B_TRUE);
3615 3767 }
3616 3768
3617 3769 static void
3618 3770 clear_global(cmd_t *cmd)
3619 3771 {
3620 3772 int err, type;
3621 3773
3622 3774 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3623 3775 long_usage(CMD_CLEAR, B_TRUE);
3624 3776 return;
3625 3777 }
3626 3778
3627 3779 if (initialize(B_TRUE) != Z_OK)
3628 3780 return;
3629 3781
3630 3782 switch (type) {
3631 3783 case PT_ZONENAME:
3632 3784 /* FALLTHRU */
3633 3785 case PT_ZONEPATH:
3634 3786 /* FALLTHRU */
3635 3787 case PT_BRAND:
3636 3788 zone_perror(pt_to_str(type), Z_CLEAR_DISALLOW, B_TRUE);
3637 3789 return;
3638 3790 case PT_AUTOBOOT:
3639 3791 /* false is default; we'll treat as equivalent to clearing */
3640 3792 if ((err = zonecfg_set_autoboot(handle, B_FALSE)) != Z_OK)
3641 3793 z_cmd_rt_perror(CMD_CLEAR, RT_AUTOBOOT, err, B_TRUE);
3642 3794 else
3643 3795 need_to_commit = B_TRUE;
3644 3796 return;
3645 3797 case PT_POOL:
3646 3798 if ((err = zonecfg_set_pool(handle, NULL)) != Z_OK)
3647 3799 z_cmd_rt_perror(CMD_CLEAR, RT_POOL, err, B_TRUE);
3648 3800 else
3649 3801 need_to_commit = B_TRUE;
3650 3802 return;
3651 3803 case PT_LIMITPRIV:
3652 3804 if ((err = zonecfg_set_limitpriv(handle, NULL)) != Z_OK)
3653 3805 z_cmd_rt_perror(CMD_CLEAR, RT_LIMITPRIV, err, B_TRUE);
3654 3806 else
3655 3807 need_to_commit = B_TRUE;
3656 3808 return;
3657 3809 case PT_BOOTARGS:
3658 3810 if ((err = zonecfg_set_bootargs(handle, NULL)) != Z_OK)
3659 3811 z_cmd_rt_perror(CMD_CLEAR, RT_BOOTARGS, err, B_TRUE);
3660 3812 else
3661 3813 need_to_commit = B_TRUE;
3662 3814 return;
3663 3815 case PT_SCHED:
3664 3816 if ((err = zonecfg_set_sched(handle, NULL)) != Z_OK)
3665 3817 z_cmd_rt_perror(CMD_CLEAR, RT_SCHED, err, B_TRUE);
3666 3818 else
3667 3819 need_to_commit = B_TRUE;
3668 3820 return;
3669 3821 case PT_IPTYPE:
3670 3822 /* shared is default; we'll treat as equivalent to clearing */
3671 3823 if ((err = zonecfg_set_iptype(handle, ZS_SHARED)) != Z_OK)
3672 3824 z_cmd_rt_perror(CMD_CLEAR, RT_IPTYPE, err, B_TRUE);
3673 3825 else
3674 3826 need_to_commit = B_TRUE;
3675 3827 return;
3676 3828 case PT_MAXLWPS:
3677 3829 remove_aliased_rctl(PT_MAXLWPS, ALIAS_MAXLWPS);
3678 3830 return;
3679 3831 case PT_MAXPROCS:
3680 3832 remove_aliased_rctl(PT_MAXPROCS, ALIAS_MAXPROCS);
3681 3833 return;
3682 3834 case PT_MAXSHMMEM:
3683 3835 remove_aliased_rctl(PT_MAXSHMMEM, ALIAS_MAXSHMMEM);
3684 3836 return;
3685 3837 case PT_MAXSHMIDS:
3686 3838 remove_aliased_rctl(PT_MAXSHMIDS, ALIAS_MAXSHMIDS);
3687 3839 return;
3688 3840 case PT_MAXMSGIDS:
3689 3841 remove_aliased_rctl(PT_MAXMSGIDS, ALIAS_MAXMSGIDS);
3690 3842 return;
3691 3843 case PT_MAXSEMIDS:
3692 3844 remove_aliased_rctl(PT_MAXSEMIDS, ALIAS_MAXSEMIDS);
3693 3845 return;
3694 3846 case PT_SHARES:
3695 3847 remove_aliased_rctl(PT_SHARES, ALIAS_SHARES);
3696 3848 return;
3697 3849 case PT_HOSTID:
3698 3850 if ((err = zonecfg_set_hostid(handle, NULL)) != Z_OK)
3699 3851 z_cmd_rt_perror(CMD_CLEAR, RT_HOSTID, err, B_TRUE);
3700 3852 else
3701 3853 need_to_commit = B_TRUE;
3702 3854 return;
3703 3855 case PT_FS_ALLOWED:
3704 3856 if ((err = zonecfg_set_fs_allowed(handle, NULL)) != Z_OK)
3705 3857 z_cmd_rt_perror(CMD_CLEAR, RT_FS_ALLOWED, err, B_TRUE);
3706 3858 else
3707 3859 need_to_commit = B_TRUE;
3708 3860 return;
3709 3861 default:
3710 3862 zone_perror(pt_to_str(type), Z_NO_PROPERTY_TYPE, B_TRUE);
3711 3863 long_usage(CMD_CLEAR, B_TRUE);
3712 3864 usage(B_FALSE, HELP_PROPS);
3713 3865 return;
3714 3866 }
3715 3867 }
3716 3868
3717 3869 void
3718 3870 clear_func(cmd_t *cmd)
3719 3871 {
3720 3872 if (zone_is_read_only(CMD_CLEAR))
3721 3873 return;
3722 3874
3723 3875 assert(cmd != NULL);
3724 3876
3725 3877 if (global_scope) {
3726 3878 if (gz_invalid_property(cmd->cmd_res_type)) {
3727 3879 zerr(gettext("%s is not a valid property for the "
3728 3880 "global zone."), pt_to_str(cmd->cmd_res_type));
3729 3881 saw_error = B_TRUE;
3730 3882 return;
3731 3883 }
3732 3884
3733 3885 clear_global(cmd);
3734 3886 } else {
3735 3887 clear_property(cmd);
3736 3888 }
3737 3889 }
3738 3890
3739 3891 void
3740 3892 select_func(cmd_t *cmd)
3741 3893 {
3742 3894 int type, err, res;
3743 3895 uint64_t limit;
3744 3896 uint64_t tmp;
3745 3897
3746 3898 if (zone_is_read_only(CMD_SELECT))
3747 3899 return;
3748 3900
3749 3901 assert(cmd != NULL);
3750 3902
3751 3903 if (global_scope) {
3752 3904 global_scope = B_FALSE;
3753 3905 resource_scope = cmd->cmd_res_type;
3754 3906 end_op = CMD_SELECT;
3755 3907 } else {
3756 3908 scope_usage(CMD_SELECT);
3757 3909 return;
3758 3910 }
3759 3911
3760 3912 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3761 3913 long_usage(CMD_SELECT, B_TRUE);
3762 3914 return;
3763 3915 }
3764 3916
3765 3917 if (initialize(B_TRUE) != Z_OK)
3766 3918 return;
3767 3919
3768 3920 switch (type) {
3769 3921 case RT_FS:
3770 3922 if ((err = fill_in_fstab(cmd, &old_fstab, B_FALSE)) != Z_OK) {
3771 3923 z_cmd_rt_perror(CMD_SELECT, RT_FS, err, B_TRUE);
3772 3924 global_scope = B_TRUE;
3773 3925 }
3774 3926 bcopy(&old_fstab, &in_progress_fstab,
3775 3927 sizeof (struct zone_fstab));
3776 3928 return;
3777 3929 case RT_NET:
3778 3930 if ((err = fill_in_nwiftab(cmd, &old_nwiftab, B_FALSE))
3779 3931 != Z_OK) {
3780 3932 z_cmd_rt_perror(CMD_SELECT, RT_NET, err, B_TRUE);
3781 3933 global_scope = B_TRUE;
3782 3934 }
3783 3935 bcopy(&old_nwiftab, &in_progress_nwiftab,
3784 3936 sizeof (struct zone_nwiftab));
3785 3937 return;
3786 3938 case RT_DEVICE:
3787 3939 if ((err = fill_in_devtab(cmd, &old_devtab, B_FALSE)) != Z_OK) {
3788 3940 z_cmd_rt_perror(CMD_SELECT, RT_DEVICE, err, B_TRUE);
3789 3941 global_scope = B_TRUE;
3790 3942 }
3791 3943 bcopy(&old_devtab, &in_progress_devtab,
3792 3944 sizeof (struct zone_devtab));
3793 3945 return;
3794 3946 case RT_RCTL:
3795 3947 if ((err = fill_in_rctltab(cmd, &old_rctltab, B_FALSE))
3796 3948 != Z_OK) {
3797 3949 z_cmd_rt_perror(CMD_SELECT, RT_RCTL, err, B_TRUE);
3798 3950 global_scope = B_TRUE;
3799 3951 }
3800 3952 bcopy(&old_rctltab, &in_progress_rctltab,
3801 3953 sizeof (struct zone_rctltab));
3802 3954 return;
3803 3955 case RT_ATTR:
3804 3956 if ((err = fill_in_attrtab(cmd, &old_attrtab, B_FALSE))
3805 3957 != Z_OK) {
3806 3958 z_cmd_rt_perror(CMD_SELECT, RT_ATTR, err, B_TRUE);
3807 3959 global_scope = B_TRUE;
3808 3960 }
3809 3961 bcopy(&old_attrtab, &in_progress_attrtab,
3810 3962 sizeof (struct zone_attrtab));
3811 3963 return;
3812 3964 case RT_DATASET:
3813 3965 if ((err = fill_in_dstab(cmd, &old_dstab, B_FALSE)) != Z_OK) {
3814 3966 z_cmd_rt_perror(CMD_SELECT, RT_DATASET, err, B_TRUE);
3815 3967 global_scope = B_TRUE;
3816 3968 }
3817 3969 bcopy(&old_dstab, &in_progress_dstab,
3818 3970 sizeof (struct zone_dstab));
3819 3971 return;
3820 3972 case RT_DCPU:
3821 3973 if ((err = zonecfg_lookup_pset(handle, &old_psettab)) != Z_OK) {
3822 3974 z_cmd_rt_perror(CMD_SELECT, RT_DCPU, err, B_TRUE);
3823 3975 global_scope = B_TRUE;
3824 3976 }
3825 3977 bcopy(&old_psettab, &in_progress_psettab,
3826 3978 sizeof (struct zone_psettab));
3827 3979 return;
3828 3980 case RT_PCAP:
3829 3981 if ((err = zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp))
3830 3982 != Z_OK) {
3831 3983 z_cmd_rt_perror(CMD_SELECT, RT_PCAP, err, B_TRUE);
3832 3984 global_scope = B_TRUE;
3833 3985 }
3834 3986 return;
3835 3987 case RT_MCAP:
3836 3988 /* if none of these exist, there is no resource to select */
3837 3989 if ((res = zonecfg_lookup_mcap(handle, &old_mcaptab)) != Z_OK &&
3838 3990 zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &limit)
3839 3991 != Z_OK &&
3840 3992 zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &limit)
3841 3993 != Z_OK) {
3842 3994 z_cmd_rt_perror(CMD_SELECT, RT_MCAP, Z_NO_RESOURCE_TYPE,
3843 3995 B_TRUE);
3844 3996 global_scope = B_TRUE;
3845 3997 }
3846 3998 if (res == Z_OK)
3847 3999 bcopy(&old_mcaptab, &in_progress_mcaptab,
3848 4000 sizeof (struct zone_mcaptab));
3849 4001 else
3850 4002 bzero(&in_progress_mcaptab,
3851 4003 sizeof (in_progress_mcaptab));
3852 4004 return;
↓ open down ↓ |
233 lines elided |
↑ open up ↑ |
3853 4005 case RT_ADMIN:
3854 4006 if ((err = fill_in_admintab(cmd, &old_admintab, B_FALSE))
3855 4007 != Z_OK) {
3856 4008 z_cmd_rt_perror(CMD_SELECT, RT_ADMIN, err,
3857 4009 B_TRUE);
3858 4010 global_scope = B_TRUE;
3859 4011 }
3860 4012 bcopy(&old_admintab, &in_progress_admintab,
3861 4013 sizeof (struct zone_admintab));
3862 4014 return;
4015 + case RT_SECFLAGS:
4016 + if ((err = fill_in_secflagstab(cmd, &old_secflagstab, B_FALSE))
4017 + != Z_OK) {
4018 + z_cmd_rt_perror(CMD_SELECT, RT_SECFLAGS, err,
4019 + B_TRUE);
4020 + global_scope = B_TRUE;
4021 + }
4022 + bcopy(&old_secflagstab, &in_progress_secflagstab,
4023 + sizeof (struct zone_secflagstab));
4024 + return;
3863 4025 default:
3864 4026 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3865 4027 long_usage(CMD_SELECT, B_TRUE);
3866 4028 usage(B_FALSE, HELP_RESOURCES);
3867 4029 return;
3868 4030 }
3869 4031 }
3870 4032
3871 4033 /*
3872 4034 * Network "addresses" can be one of the following forms:
3873 4035 * <IPv4 address>
3874 4036 * <IPv4 address>/<prefix length>
3875 4037 * <IPv6 address>/<prefix length>
3876 4038 * <host name>
3877 4039 * <host name>/<prefix length>
3878 4040 * In other words, the "/" followed by a prefix length is allowed but not
3879 4041 * required for IPv4 addresses and host names, and required for IPv6 addresses.
3880 4042 * If a prefix length is given, it must be in the allowable range: 0 to 32 for
3881 4043 * IPv4 addresses and host names, 0 to 128 for IPv6 addresses.
3882 4044 * Host names must start with an alpha-numeric character, and all subsequent
3883 4045 * characters must be either alpha-numeric or "-".
3884 4046 *
3885 4047 * In some cases, e.g., the nexthop for the defrouter, the context indicates
3886 4048 * that this is the IPV4_ABITS or IPV6_ABITS netmask, in which case we don't
3887 4049 * require the /<prefix length> (and should ignore it if provided).
3888 4050 */
3889 4051
3890 4052 static int
3891 4053 validate_net_address_syntax(char *address, boolean_t ishost)
3892 4054 {
3893 4055 char *slashp, part1[MAXHOSTNAMELEN];
3894 4056 struct in6_addr in6;
3895 4057 struct in_addr in4;
3896 4058 int prefixlen, i;
3897 4059
3898 4060 /*
3899 4061 * Copy the part before any '/' into part1 or copy the whole
3900 4062 * thing if there is no '/'.
3901 4063 */
3902 4064 if ((slashp = strchr(address, '/')) != NULL) {
3903 4065 *slashp = '\0';
3904 4066 (void) strlcpy(part1, address, sizeof (part1));
3905 4067 *slashp = '/';
3906 4068 prefixlen = atoi(++slashp);
3907 4069 } else {
3908 4070 (void) strlcpy(part1, address, sizeof (part1));
3909 4071 }
3910 4072
3911 4073 if (ishost && slashp != NULL) {
3912 4074 zerr(gettext("Warning: prefix length in %s is not required and "
3913 4075 "will be ignored. The default host-prefix length "
3914 4076 "will be used"), address);
3915 4077 }
3916 4078
3917 4079
3918 4080 if (inet_pton(AF_INET6, part1, &in6) == 1) {
3919 4081 if (ishost) {
3920 4082 prefixlen = IPV6_ABITS;
3921 4083 } else if (slashp == NULL) {
3922 4084 zerr(gettext("%s: IPv6 addresses "
3923 4085 "require /prefix-length suffix."), address);
3924 4086 return (Z_ERR);
3925 4087 }
3926 4088 if (prefixlen < 0 || prefixlen > 128) {
3927 4089 zerr(gettext("%s: IPv6 address "
3928 4090 "prefix lengths must be 0 - 128."), address);
3929 4091 return (Z_ERR);
3930 4092 }
3931 4093 return (Z_OK);
3932 4094 }
3933 4095
3934 4096 /* At this point, any /prefix must be for IPv4. */
3935 4097 if (ishost)
3936 4098 prefixlen = IPV4_ABITS;
3937 4099 else if (slashp != NULL) {
3938 4100 if (prefixlen < 0 || prefixlen > 32) {
3939 4101 zerr(gettext("%s: IPv4 address "
3940 4102 "prefix lengths must be 0 - 32."), address);
3941 4103 return (Z_ERR);
3942 4104 }
3943 4105 }
3944 4106
3945 4107 if (inet_pton(AF_INET, part1, &in4) == 1)
3946 4108 return (Z_OK);
3947 4109
3948 4110 /* address may also be a host name */
3949 4111 if (!isalnum(part1[0])) {
3950 4112 zerr(gettext("%s: bogus host name or network address syntax"),
3951 4113 part1);
3952 4114 saw_error = B_TRUE;
3953 4115 usage(B_FALSE, HELP_NETADDR);
3954 4116 return (Z_ERR);
3955 4117 }
3956 4118 for (i = 1; part1[i]; i++)
3957 4119 if (!isalnum(part1[i]) && part1[i] != '-' && part1[i] != '.') {
3958 4120 zerr(gettext("%s: bogus host name or "
3959 4121 "network address syntax"), part1);
3960 4122 saw_error = B_TRUE;
3961 4123 usage(B_FALSE, HELP_NETADDR);
3962 4124 return (Z_ERR);
3963 4125 }
3964 4126 return (Z_OK);
3965 4127 }
3966 4128
3967 4129 static int
3968 4130 validate_net_physical_syntax(const char *ifname)
3969 4131 {
3970 4132 ifspec_t ifnameprop;
3971 4133 zone_iptype_t iptype;
3972 4134
3973 4135 if (zonecfg_get_iptype(handle, &iptype) != Z_OK) {
3974 4136 zerr(gettext("zone configuration has an invalid or nonexistent "
3975 4137 "ip-type property"));
3976 4138 return (Z_ERR);
3977 4139 }
3978 4140 switch (iptype) {
3979 4141 case ZS_SHARED:
3980 4142 if (ifparse_ifspec(ifname, &ifnameprop) == B_FALSE) {
3981 4143 zerr(gettext("%s: invalid physical interface name"),
3982 4144 ifname);
3983 4145 return (Z_ERR);
3984 4146 }
3985 4147 if (ifnameprop.ifsp_lunvalid) {
3986 4148 zerr(gettext("%s: LUNs not allowed in physical "
3987 4149 "interface names"), ifname);
3988 4150 return (Z_ERR);
3989 4151 }
3990 4152 break;
3991 4153 case ZS_EXCLUSIVE:
3992 4154 if (dladm_valid_linkname(ifname) == B_FALSE) {
3993 4155 if (strchr(ifname, ':') != NULL)
3994 4156 zerr(gettext("%s: physical interface name "
3995 4157 "required; logical interface name not "
3996 4158 "allowed"), ifname);
3997 4159 else
3998 4160 zerr(gettext("%s: invalid physical interface "
3999 4161 "name"), ifname);
4000 4162 return (Z_ERR);
4001 4163 }
4002 4164 break;
4003 4165 }
4004 4166 return (Z_OK);
4005 4167 }
4006 4168
4007 4169 static boolean_t
4008 4170 valid_fs_type(const char *type)
4009 4171 {
4010 4172 /*
4011 4173 * Is this a valid path component?
4012 4174 */
4013 4175 if (strlen(type) + 1 > MAXNAMELEN)
4014 4176 return (B_FALSE);
4015 4177 /*
4016 4178 * Make sure a bad value for "type" doesn't make
4017 4179 * /usr/lib/fs/<type>/mount turn into something else.
4018 4180 */
4019 4181 if (strchr(type, '/') != NULL || type[0] == '\0' ||
4020 4182 strcmp(type, ".") == 0 || strcmp(type, "..") == 0)
4021 4183 return (B_FALSE);
4022 4184 /*
4023 4185 * More detailed verification happens later by zoneadm(1m).
4024 4186 */
4025 4187 return (B_TRUE);
4026 4188 }
4027 4189
4028 4190 static boolean_t
4029 4191 allow_exclusive()
4030 4192 {
4031 4193 brand_handle_t bh;
4032 4194 char brand[MAXNAMELEN];
4033 4195 boolean_t ret;
4034 4196
4035 4197 if (zonecfg_get_brand(handle, brand, sizeof (brand)) != Z_OK) {
4036 4198 zerr("%s: %s\n", zone, gettext("could not get zone brand"));
4037 4199 return (B_FALSE);
4038 4200 }
4039 4201 if ((bh = brand_open(brand)) == NULL) {
4040 4202 zerr("%s: %s\n", zone, gettext("unknown brand."));
4041 4203 return (B_FALSE);
4042 4204 }
4043 4205 ret = brand_allow_exclusive_ip(bh);
4044 4206 brand_close(bh);
4045 4207 if (!ret)
4046 4208 zerr(gettext("%s cannot be '%s' when %s is '%s'."),
4047 4209 pt_to_str(PT_IPTYPE), "exclusive",
4048 4210 pt_to_str(PT_BRAND), brand);
4049 4211 return (ret);
4050 4212 }
4051 4213
4052 4214 static void
4053 4215 set_aliased_rctl(char *alias, int prop_type, char *s)
4054 4216 {
4055 4217 uint64_t limit;
4056 4218 int err;
4057 4219 char tmp[128];
4058 4220
4059 4221 if (global_zone && strcmp(alias, ALIAS_SHARES) != 0)
4060 4222 zerr(gettext("WARNING: Setting a global zone resource "
4061 4223 "control too low could deny\nservice "
4062 4224 "to even the root user; "
4063 4225 "this could render the system impossible\n"
4064 4226 "to administer. Please use caution."));
4065 4227
4066 4228 /* convert memory based properties */
4067 4229 if (prop_type == PT_MAXSHMMEM) {
4068 4230 if (!zonecfg_valid_memlimit(s, &limit)) {
4069 4231 zerr(gettext("A non-negative number with a required "
4070 4232 "scale suffix (K, M, G or T) was expected\nhere."));
4071 4233 saw_error = B_TRUE;
4072 4234 return;
4073 4235 }
4074 4236
4075 4237 (void) snprintf(tmp, sizeof (tmp), "%llu", limit);
4076 4238 s = tmp;
4077 4239 }
4078 4240
4079 4241 if (!zonecfg_aliased_rctl_ok(handle, alias)) {
4080 4242 zone_perror(pt_to_str(prop_type), Z_ALIAS_DISALLOW, B_FALSE);
4081 4243 saw_error = B_TRUE;
4082 4244 } else if (!zonecfg_valid_alias_limit(alias, s, &limit)) {
4083 4245 zerr(gettext("%s property is out of range."),
4084 4246 pt_to_str(prop_type));
4085 4247 saw_error = B_TRUE;
4086 4248 } else if ((err = zonecfg_set_aliased_rctl(handle, alias, limit))
4087 4249 != Z_OK) {
4088 4250 zone_perror(zone, err, B_TRUE);
4089 4251 saw_error = B_TRUE;
4090 4252 } else {
4091 4253 need_to_commit = B_TRUE;
4092 4254 }
4093 4255 }
4094 4256
4095 4257 static void
4096 4258 set_in_progress_nwiftab_address(char *prop_id, int prop_type)
4097 4259 {
4098 4260 if (prop_type == PT_ADDRESS) {
4099 4261 (void) strlcpy(in_progress_nwiftab.zone_nwif_address, prop_id,
4100 4262 sizeof (in_progress_nwiftab.zone_nwif_address));
4101 4263 } else {
4102 4264 assert(prop_type == PT_ALLOWED_ADDRESS);
4103 4265 (void) strlcpy(in_progress_nwiftab.zone_nwif_allowed_address,
4104 4266 prop_id,
4105 4267 sizeof (in_progress_nwiftab.zone_nwif_allowed_address));
4106 4268 }
4107 4269 }
4108 4270
4109 4271 void
4110 4272 set_func(cmd_t *cmd)
4111 4273 {
4112 4274 char *prop_id;
4113 4275 int arg, err, res_type, prop_type;
4114 4276 property_value_ptr_t pp;
4115 4277 boolean_t autoboot;
4116 4278 zone_iptype_t iptype;
4117 4279 boolean_t force_set = B_FALSE;
4118 4280 size_t physmem_size = sizeof (in_progress_mcaptab.zone_physmem_cap);
4119 4281 uint64_t mem_cap, mem_limit;
4120 4282 float cap;
4121 4283 char *unitp;
4122 4284 struct zone_psettab tmp_psettab;
4123 4285 boolean_t arg_err = B_FALSE;
4124 4286
4125 4287 if (zone_is_read_only(CMD_SET))
4126 4288 return;
4127 4289
4128 4290 assert(cmd != NULL);
4129 4291
4130 4292 optind = opterr = 0;
4131 4293 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) {
4132 4294 switch (arg) {
4133 4295 case 'F':
4134 4296 force_set = B_TRUE;
4135 4297 break;
4136 4298 default:
4137 4299 if (optopt == '?')
4138 4300 longer_usage(CMD_SET);
4139 4301 else
4140 4302 short_usage(CMD_SET);
4141 4303 arg_err = B_TRUE;
4142 4304 break;
4143 4305 }
4144 4306 }
4145 4307 if (arg_err)
4146 4308 return;
4147 4309
4148 4310 prop_type = cmd->cmd_prop_name[0];
4149 4311 if (global_scope) {
4150 4312 if (gz_invalid_property(prop_type)) {
4151 4313 zerr(gettext("%s is not a valid property for the "
4152 4314 "global zone."), pt_to_str(prop_type));
4153 4315 saw_error = B_TRUE;
4154 4316 return;
4155 4317 }
4156 4318
4157 4319 if (prop_type == PT_ZONENAME) {
4158 4320 res_type = RT_ZONENAME;
4159 4321 } else if (prop_type == PT_ZONEPATH) {
4160 4322 res_type = RT_ZONEPATH;
4161 4323 } else if (prop_type == PT_AUTOBOOT) {
4162 4324 res_type = RT_AUTOBOOT;
4163 4325 } else if (prop_type == PT_BRAND) {
4164 4326 res_type = RT_BRAND;
4165 4327 } else if (prop_type == PT_POOL) {
4166 4328 res_type = RT_POOL;
4167 4329 } else if (prop_type == PT_LIMITPRIV) {
4168 4330 res_type = RT_LIMITPRIV;
4169 4331 } else if (prop_type == PT_BOOTARGS) {
4170 4332 res_type = RT_BOOTARGS;
4171 4333 } else if (prop_type == PT_SCHED) {
4172 4334 res_type = RT_SCHED;
4173 4335 } else if (prop_type == PT_IPTYPE) {
4174 4336 res_type = RT_IPTYPE;
4175 4337 } else if (prop_type == PT_MAXLWPS) {
4176 4338 res_type = RT_MAXLWPS;
4177 4339 } else if (prop_type == PT_MAXPROCS) {
4178 4340 res_type = RT_MAXPROCS;
4179 4341 } else if (prop_type == PT_MAXSHMMEM) {
4180 4342 res_type = RT_MAXSHMMEM;
4181 4343 } else if (prop_type == PT_MAXSHMIDS) {
4182 4344 res_type = RT_MAXSHMIDS;
4183 4345 } else if (prop_type == PT_MAXMSGIDS) {
4184 4346 res_type = RT_MAXMSGIDS;
4185 4347 } else if (prop_type == PT_MAXSEMIDS) {
4186 4348 res_type = RT_MAXSEMIDS;
4187 4349 } else if (prop_type == PT_SHARES) {
4188 4350 res_type = RT_SHARES;
4189 4351 } else if (prop_type == PT_HOSTID) {
4190 4352 res_type = RT_HOSTID;
4191 4353 } else if (prop_type == PT_FS_ALLOWED) {
4192 4354 res_type = RT_FS_ALLOWED;
4193 4355 } else {
4194 4356 zerr(gettext("Cannot set a resource-specific property "
4195 4357 "from the global scope."));
4196 4358 saw_error = B_TRUE;
4197 4359 return;
4198 4360 }
4199 4361 } else {
4200 4362 res_type = resource_scope;
4201 4363 }
4202 4364
4203 4365 if (force_set) {
4204 4366 if (res_type != RT_ZONEPATH) {
4205 4367 zerr(gettext("Only zonepath setting can be forced."));
4206 4368 saw_error = B_TRUE;
4207 4369 return;
4208 4370 }
4209 4371 if (!zonecfg_in_alt_root()) {
4210 4372 zerr(gettext("Zonepath is changeable only in an "
4211 4373 "alternate root."));
4212 4374 saw_error = B_TRUE;
4213 4375 return;
4214 4376 }
4215 4377 }
4216 4378
4217 4379 pp = cmd->cmd_property_ptr[0];
4218 4380 /*
4219 4381 * A nasty expression but not that complicated:
4220 4382 * 1. fs options are simple or list (tested below)
4221 4383 * 2. rctl value's are complex or list (tested below)
4222 4384 * Anything else should be simple.
4223 4385 */
4224 4386 if (!(res_type == RT_FS && prop_type == PT_OPTIONS) &&
4225 4387 !(res_type == RT_RCTL && prop_type == PT_VALUE) &&
4226 4388 (pp->pv_type != PROP_VAL_SIMPLE ||
4227 4389 (prop_id = pp->pv_simple) == NULL)) {
4228 4390 zerr(gettext("A %s value was expected here."),
4229 4391 pvt_to_str(PROP_VAL_SIMPLE));
4230 4392 saw_error = B_TRUE;
4231 4393 return;
4232 4394 }
4233 4395 if (prop_type == PT_UNKNOWN) {
4234 4396 long_usage(CMD_SET, B_TRUE);
4235 4397 return;
4236 4398 }
4237 4399
4238 4400 /*
4239 4401 * Special case: the user can change the zone name prior to 'create';
4240 4402 * if the zone already exists, we fall through letting initialize()
4241 4403 * and the rest of the logic run.
4242 4404 */
4243 4405 if (res_type == RT_ZONENAME && got_handle == B_FALSE &&
4244 4406 !state_atleast(ZONE_STATE_CONFIGURED)) {
4245 4407 if ((err = zonecfg_validate_zonename(prop_id)) != Z_OK) {
4246 4408 zone_perror(prop_id, err, B_TRUE);
4247 4409 usage(B_FALSE, HELP_SYNTAX);
4248 4410 return;
4249 4411 }
4250 4412 (void) strlcpy(zone, prop_id, sizeof (zone));
4251 4413 return;
4252 4414 }
4253 4415
4254 4416 if (initialize(B_TRUE) != Z_OK)
4255 4417 return;
4256 4418
4257 4419 switch (res_type) {
4258 4420 case RT_ZONENAME:
4259 4421 if ((err = zonecfg_set_name(handle, prop_id)) != Z_OK) {
4260 4422 /*
4261 4423 * Use prop_id instead of 'zone' here, since we're
4262 4424 * reporting a problem about the *new* zonename.
4263 4425 */
4264 4426 zone_perror(prop_id, err, B_TRUE);
4265 4427 usage(B_FALSE, HELP_SYNTAX);
4266 4428 } else {
4267 4429 need_to_commit = B_TRUE;
4268 4430 (void) strlcpy(zone, prop_id, sizeof (zone));
4269 4431 }
4270 4432 return;
4271 4433 case RT_ZONEPATH:
4272 4434 if (!force_set && state_atleast(ZONE_STATE_INSTALLED)) {
4273 4435 zerr(gettext("Zone %s already installed; %s %s not "
4274 4436 "allowed."), zone, cmd_to_str(CMD_SET),
4275 4437 rt_to_str(RT_ZONEPATH));
4276 4438 return;
4277 4439 }
4278 4440 if (validate_zonepath_syntax(prop_id) != Z_OK) {
4279 4441 saw_error = B_TRUE;
4280 4442 return;
4281 4443 }
4282 4444 if ((err = zonecfg_set_zonepath(handle, prop_id)) != Z_OK)
4283 4445 zone_perror(zone, err, B_TRUE);
4284 4446 else
4285 4447 need_to_commit = B_TRUE;
4286 4448 return;
4287 4449 case RT_BRAND:
4288 4450 if (state_atleast(ZONE_STATE_INSTALLED)) {
4289 4451 zerr(gettext("Zone %s already installed; %s %s not "
4290 4452 "allowed."), zone, cmd_to_str(CMD_SET),
4291 4453 rt_to_str(RT_BRAND));
4292 4454 return;
4293 4455 }
4294 4456 if ((err = zonecfg_set_brand(handle, prop_id)) != Z_OK)
4295 4457 zone_perror(zone, err, B_TRUE);
4296 4458 else
4297 4459 need_to_commit = B_TRUE;
4298 4460 return;
4299 4461 case RT_AUTOBOOT:
4300 4462 if (strcmp(prop_id, "true") == 0) {
4301 4463 autoboot = B_TRUE;
4302 4464 } else if (strcmp(prop_id, "false") == 0) {
4303 4465 autoboot = B_FALSE;
4304 4466 } else {
4305 4467 zerr(gettext("%s value must be '%s' or '%s'."),
4306 4468 pt_to_str(PT_AUTOBOOT), "true", "false");
4307 4469 saw_error = B_TRUE;
4308 4470 return;
4309 4471 }
4310 4472 if ((err = zonecfg_set_autoboot(handle, autoboot)) != Z_OK)
4311 4473 zone_perror(zone, err, B_TRUE);
4312 4474 else
4313 4475 need_to_commit = B_TRUE;
4314 4476 return;
4315 4477 case RT_POOL:
4316 4478 /* don't allow use of the reserved temporary pool names */
4317 4479 if (strncmp("SUNW", prop_id, 4) == 0) {
4318 4480 zerr(gettext("pool names starting with SUNW are "
4319 4481 "reserved."));
4320 4482 saw_error = B_TRUE;
4321 4483 return;
4322 4484 }
4323 4485
4324 4486 /* can't set pool if dedicated-cpu exists */
4325 4487 if (zonecfg_lookup_pset(handle, &tmp_psettab) == Z_OK) {
4326 4488 zerr(gettext("The %s resource already exists. "
4327 4489 "A persistent pool is incompatible\nwith the %s "
4328 4490 "resource."), rt_to_str(RT_DCPU),
4329 4491 rt_to_str(RT_DCPU));
4330 4492 saw_error = B_TRUE;
4331 4493 return;
4332 4494 }
4333 4495
4334 4496 if ((err = zonecfg_set_pool(handle, prop_id)) != Z_OK)
4335 4497 zone_perror(zone, err, B_TRUE);
4336 4498 else
4337 4499 need_to_commit = B_TRUE;
4338 4500 return;
4339 4501 case RT_LIMITPRIV:
4340 4502 if ((err = zonecfg_set_limitpriv(handle, prop_id)) != Z_OK)
4341 4503 zone_perror(zone, err, B_TRUE);
4342 4504 else
4343 4505 need_to_commit = B_TRUE;
4344 4506 return;
4345 4507 case RT_BOOTARGS:
4346 4508 if ((err = zonecfg_set_bootargs(handle, prop_id)) != Z_OK)
4347 4509 zone_perror(zone, err, B_TRUE);
4348 4510 else
4349 4511 need_to_commit = B_TRUE;
4350 4512 return;
4351 4513 case RT_SCHED:
4352 4514 if ((err = zonecfg_set_sched(handle, prop_id)) != Z_OK)
4353 4515 zone_perror(zone, err, B_TRUE);
4354 4516 else
4355 4517 need_to_commit = B_TRUE;
4356 4518 return;
4357 4519 case RT_IPTYPE:
4358 4520 if (strcmp(prop_id, "shared") == 0) {
4359 4521 iptype = ZS_SHARED;
4360 4522 } else if (strcmp(prop_id, "exclusive") == 0) {
4361 4523 iptype = ZS_EXCLUSIVE;
4362 4524 } else {
4363 4525 zerr(gettext("%s value must be '%s' or '%s'."),
4364 4526 pt_to_str(PT_IPTYPE), "shared", "exclusive");
4365 4527 saw_error = B_TRUE;
4366 4528 return;
4367 4529 }
4368 4530 if (iptype == ZS_EXCLUSIVE && !allow_exclusive()) {
4369 4531 saw_error = B_TRUE;
4370 4532 return;
4371 4533 }
4372 4534 if ((err = zonecfg_set_iptype(handle, iptype)) != Z_OK)
4373 4535 zone_perror(zone, err, B_TRUE);
4374 4536 else
4375 4537 need_to_commit = B_TRUE;
4376 4538 return;
4377 4539 case RT_MAXLWPS:
4378 4540 set_aliased_rctl(ALIAS_MAXLWPS, prop_type, prop_id);
4379 4541 return;
4380 4542 case RT_MAXPROCS:
4381 4543 set_aliased_rctl(ALIAS_MAXPROCS, prop_type, prop_id);
4382 4544 return;
4383 4545 case RT_MAXSHMMEM:
4384 4546 set_aliased_rctl(ALIAS_MAXSHMMEM, prop_type, prop_id);
4385 4547 return;
4386 4548 case RT_MAXSHMIDS:
4387 4549 set_aliased_rctl(ALIAS_MAXSHMIDS, prop_type, prop_id);
4388 4550 return;
4389 4551 case RT_MAXMSGIDS:
4390 4552 set_aliased_rctl(ALIAS_MAXMSGIDS, prop_type, prop_id);
4391 4553 return;
4392 4554 case RT_MAXSEMIDS:
4393 4555 set_aliased_rctl(ALIAS_MAXSEMIDS, prop_type, prop_id);
4394 4556 return;
4395 4557 case RT_SHARES:
4396 4558 set_aliased_rctl(ALIAS_SHARES, prop_type, prop_id);
4397 4559 return;
4398 4560 case RT_HOSTID:
4399 4561 if ((err = zonecfg_set_hostid(handle, prop_id)) != Z_OK) {
4400 4562 if (err == Z_TOO_BIG) {
4401 4563 zerr(gettext("hostid string is too large: %s"),
4402 4564 prop_id);
4403 4565 saw_error = B_TRUE;
4404 4566 } else {
4405 4567 zone_perror(pt_to_str(prop_type), err, B_TRUE);
4406 4568 }
4407 4569 return;
4408 4570 }
4409 4571 need_to_commit = B_TRUE;
4410 4572 return;
4411 4573 case RT_FS_ALLOWED:
4412 4574 if ((err = zonecfg_set_fs_allowed(handle, prop_id)) != Z_OK)
4413 4575 zone_perror(zone, err, B_TRUE);
4414 4576 else
4415 4577 need_to_commit = B_TRUE;
4416 4578 return;
4417 4579 case RT_FS:
4418 4580 switch (prop_type) {
4419 4581 case PT_DIR:
4420 4582 (void) strlcpy(in_progress_fstab.zone_fs_dir, prop_id,
4421 4583 sizeof (in_progress_fstab.zone_fs_dir));
4422 4584 return;
4423 4585 case PT_SPECIAL:
4424 4586 (void) strlcpy(in_progress_fstab.zone_fs_special,
4425 4587 prop_id,
4426 4588 sizeof (in_progress_fstab.zone_fs_special));
4427 4589 return;
4428 4590 case PT_RAW:
4429 4591 (void) strlcpy(in_progress_fstab.zone_fs_raw,
4430 4592 prop_id, sizeof (in_progress_fstab.zone_fs_raw));
4431 4593 return;
4432 4594 case PT_TYPE:
4433 4595 if (!valid_fs_type(prop_id)) {
4434 4596 zerr(gettext("\"%s\" is not a valid %s."),
4435 4597 prop_id, pt_to_str(PT_TYPE));
4436 4598 saw_error = B_TRUE;
4437 4599 return;
4438 4600 }
4439 4601 (void) strlcpy(in_progress_fstab.zone_fs_type, prop_id,
4440 4602 sizeof (in_progress_fstab.zone_fs_type));
4441 4603 return;
4442 4604 case PT_OPTIONS:
4443 4605 if (pp->pv_type != PROP_VAL_SIMPLE &&
4444 4606 pp->pv_type != PROP_VAL_LIST) {
4445 4607 zerr(gettext("A %s or %s value was expected "
4446 4608 "here."), pvt_to_str(PROP_VAL_SIMPLE),
4447 4609 pvt_to_str(PROP_VAL_LIST));
4448 4610 saw_error = B_TRUE;
4449 4611 return;
4450 4612 }
4451 4613 zonecfg_free_fs_option_list(
4452 4614 in_progress_fstab.zone_fs_options);
4453 4615 in_progress_fstab.zone_fs_options = NULL;
4454 4616 if (!(pp->pv_type == PROP_VAL_LIST &&
4455 4617 pp->pv_list == NULL))
4456 4618 add_property(cmd);
4457 4619 return;
4458 4620 default:
4459 4621 break;
4460 4622 }
4461 4623 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE);
4462 4624 long_usage(CMD_SET, B_TRUE);
4463 4625 usage(B_FALSE, HELP_PROPS);
4464 4626 return;
4465 4627 case RT_NET:
4466 4628 switch (prop_type) {
4467 4629 case PT_ADDRESS:
4468 4630 case PT_ALLOWED_ADDRESS:
4469 4631 if (validate_net_address_syntax(prop_id, B_FALSE)
4470 4632 != Z_OK) {
4471 4633 saw_error = B_TRUE;
4472 4634 return;
4473 4635 }
4474 4636 set_in_progress_nwiftab_address(prop_id, prop_type);
4475 4637 break;
4476 4638 case PT_PHYSICAL:
4477 4639 if (validate_net_physical_syntax(prop_id) != Z_OK) {
4478 4640 saw_error = B_TRUE;
4479 4641 return;
4480 4642 }
4481 4643 (void) strlcpy(in_progress_nwiftab.zone_nwif_physical,
4482 4644 prop_id,
4483 4645 sizeof (in_progress_nwiftab.zone_nwif_physical));
4484 4646 break;
4485 4647 case PT_DEFROUTER:
4486 4648 if (validate_net_address_syntax(prop_id, B_TRUE)
4487 4649 != Z_OK) {
4488 4650 saw_error = B_TRUE;
4489 4651 return;
4490 4652 }
4491 4653 (void) strlcpy(in_progress_nwiftab.zone_nwif_defrouter,
4492 4654 prop_id,
4493 4655 sizeof (in_progress_nwiftab.zone_nwif_defrouter));
4494 4656 break;
4495 4657 default:
4496 4658 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4497 4659 B_TRUE);
4498 4660 long_usage(CMD_SET, B_TRUE);
4499 4661 usage(B_FALSE, HELP_PROPS);
4500 4662 return;
4501 4663 }
4502 4664 return;
4503 4665 case RT_DEVICE:
4504 4666 switch (prop_type) {
4505 4667 case PT_MATCH:
4506 4668 (void) strlcpy(in_progress_devtab.zone_dev_match,
4507 4669 prop_id,
4508 4670 sizeof (in_progress_devtab.zone_dev_match));
4509 4671 break;
4510 4672 default:
4511 4673 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4512 4674 B_TRUE);
4513 4675 long_usage(CMD_SET, B_TRUE);
4514 4676 usage(B_FALSE, HELP_PROPS);
4515 4677 return;
4516 4678 }
4517 4679 return;
4518 4680 case RT_RCTL:
4519 4681 switch (prop_type) {
4520 4682 case PT_NAME:
4521 4683 if (!zonecfg_valid_rctlname(prop_id)) {
4522 4684 zerr(gettext("'%s' is not a valid zone %s "
4523 4685 "name."), prop_id, rt_to_str(RT_RCTL));
4524 4686 return;
4525 4687 }
4526 4688 (void) strlcpy(in_progress_rctltab.zone_rctl_name,
4527 4689 prop_id,
4528 4690 sizeof (in_progress_rctltab.zone_rctl_name));
4529 4691 break;
4530 4692 case PT_VALUE:
4531 4693 if (pp->pv_type != PROP_VAL_COMPLEX &&
4532 4694 pp->pv_type != PROP_VAL_LIST) {
4533 4695 zerr(gettext("A %s or %s value was expected "
4534 4696 "here."), pvt_to_str(PROP_VAL_COMPLEX),
4535 4697 pvt_to_str(PROP_VAL_LIST));
4536 4698 saw_error = B_TRUE;
4537 4699 return;
4538 4700 }
4539 4701 zonecfg_free_rctl_value_list(
4540 4702 in_progress_rctltab.zone_rctl_valptr);
4541 4703 in_progress_rctltab.zone_rctl_valptr = NULL;
4542 4704 if (!(pp->pv_type == PROP_VAL_LIST &&
4543 4705 pp->pv_list == NULL))
4544 4706 add_property(cmd);
4545 4707 break;
4546 4708 default:
4547 4709 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4548 4710 B_TRUE);
4549 4711 long_usage(CMD_SET, B_TRUE);
4550 4712 usage(B_FALSE, HELP_PROPS);
4551 4713 return;
4552 4714 }
4553 4715 return;
4554 4716 case RT_ATTR:
4555 4717 switch (prop_type) {
4556 4718 case PT_NAME:
4557 4719 (void) strlcpy(in_progress_attrtab.zone_attr_name,
4558 4720 prop_id,
4559 4721 sizeof (in_progress_attrtab.zone_attr_name));
4560 4722 break;
4561 4723 case PT_TYPE:
4562 4724 (void) strlcpy(in_progress_attrtab.zone_attr_type,
4563 4725 prop_id,
4564 4726 sizeof (in_progress_attrtab.zone_attr_type));
4565 4727 break;
4566 4728 case PT_VALUE:
4567 4729 (void) strlcpy(in_progress_attrtab.zone_attr_value,
4568 4730 prop_id,
4569 4731 sizeof (in_progress_attrtab.zone_attr_value));
4570 4732 break;
4571 4733 default:
4572 4734 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4573 4735 B_TRUE);
4574 4736 long_usage(CMD_SET, B_TRUE);
4575 4737 usage(B_FALSE, HELP_PROPS);
4576 4738 return;
4577 4739 }
4578 4740 return;
4579 4741 case RT_DATASET:
4580 4742 switch (prop_type) {
4581 4743 case PT_NAME:
4582 4744 (void) strlcpy(in_progress_dstab.zone_dataset_name,
4583 4745 prop_id,
4584 4746 sizeof (in_progress_dstab.zone_dataset_name));
4585 4747 return;
4586 4748 default:
4587 4749 break;
4588 4750 }
4589 4751 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE);
4590 4752 long_usage(CMD_SET, B_TRUE);
4591 4753 usage(B_FALSE, HELP_PROPS);
4592 4754 return;
4593 4755 case RT_DCPU:
4594 4756 switch (prop_type) {
4595 4757 char *lowp, *highp;
4596 4758
4597 4759 case PT_NCPUS:
4598 4760 lowp = prop_id;
4599 4761 if ((highp = strchr(prop_id, '-')) != NULL)
4600 4762 *highp++ = '\0';
4601 4763 else
4602 4764 highp = lowp;
4603 4765
4604 4766 /* Make sure the input makes sense. */
4605 4767 if (!zonecfg_valid_ncpus(lowp, highp)) {
4606 4768 zerr(gettext("%s property is out of range."),
4607 4769 pt_to_str(PT_NCPUS));
4608 4770 saw_error = B_TRUE;
4609 4771 return;
4610 4772 }
4611 4773
4612 4774 (void) strlcpy(
4613 4775 in_progress_psettab.zone_ncpu_min, lowp,
4614 4776 sizeof (in_progress_psettab.zone_ncpu_min));
4615 4777 (void) strlcpy(
4616 4778 in_progress_psettab.zone_ncpu_max, highp,
4617 4779 sizeof (in_progress_psettab.zone_ncpu_max));
4618 4780 return;
4619 4781 case PT_IMPORTANCE:
4620 4782 /* Make sure the value makes sense. */
4621 4783 if (!zonecfg_valid_importance(prop_id)) {
4622 4784 zerr(gettext("%s property is out of range."),
4623 4785 pt_to_str(PT_IMPORTANCE));
4624 4786 saw_error = B_TRUE;
4625 4787 return;
4626 4788 }
4627 4789
4628 4790 (void) strlcpy(in_progress_psettab.zone_importance,
4629 4791 prop_id,
4630 4792 sizeof (in_progress_psettab.zone_importance));
4631 4793 return;
4632 4794 default:
4633 4795 break;
4634 4796 }
4635 4797 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE);
4636 4798 long_usage(CMD_SET, B_TRUE);
4637 4799 usage(B_FALSE, HELP_PROPS);
4638 4800 return;
4639 4801 case RT_PCAP:
4640 4802 if (prop_type != PT_NCPUS) {
4641 4803 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4642 4804 B_TRUE);
4643 4805 long_usage(CMD_SET, B_TRUE);
4644 4806 usage(B_FALSE, HELP_PROPS);
4645 4807 return;
4646 4808 }
4647 4809
4648 4810 /*
4649 4811 * We already checked that an rctl alias is allowed in
4650 4812 * the add_resource() function.
4651 4813 */
4652 4814
4653 4815 if ((cap = strtof(prop_id, &unitp)) <= 0 || *unitp != '\0' ||
4654 4816 (int)(cap * 100) < 1) {
4655 4817 zerr(gettext("%s property is out of range."),
4656 4818 pt_to_str(PT_NCPUS));
4657 4819 saw_error = B_TRUE;
4658 4820 return;
4659 4821 }
4660 4822
4661 4823 if ((err = zonecfg_set_aliased_rctl(handle, ALIAS_CPUCAP,
4662 4824 (int)(cap * 100))) != Z_OK)
4663 4825 zone_perror(zone, err, B_TRUE);
4664 4826 else
4665 4827 need_to_commit = B_TRUE;
4666 4828 return;
4667 4829 case RT_MCAP:
4668 4830 switch (prop_type) {
4669 4831 case PT_PHYSICAL:
4670 4832 if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) {
4671 4833 zerr(gettext("A positive number with a "
4672 4834 "required scale suffix (K, M, G or T) was "
4673 4835 "expected here."));
4674 4836 saw_error = B_TRUE;
4675 4837 } else if (mem_cap < ONE_MB) {
4676 4838 zerr(gettext("%s value is too small. It must "
4677 4839 "be at least 1M."), pt_to_str(PT_PHYSICAL));
4678 4840 saw_error = B_TRUE;
4679 4841 } else {
4680 4842 snprintf(in_progress_mcaptab.zone_physmem_cap,
4681 4843 physmem_size, "%llu", mem_cap);
4682 4844 }
4683 4845 break;
4684 4846 case PT_SWAP:
4685 4847 /*
4686 4848 * We have to check if an rctl is allowed here since
4687 4849 * there might already be a rctl defined that blocks
4688 4850 * the alias.
4689 4851 */
4690 4852 if (!zonecfg_aliased_rctl_ok(handle, ALIAS_MAXSWAP)) {
4691 4853 zone_perror(pt_to_str(PT_MAXSWAP),
4692 4854 Z_ALIAS_DISALLOW, B_FALSE);
4693 4855 saw_error = B_TRUE;
4694 4856 return;
4695 4857 }
4696 4858
4697 4859 if (global_zone)
4698 4860 mem_limit = ONE_MB * 100;
4699 4861 else
4700 4862 mem_limit = ONE_MB * 50;
4701 4863
4702 4864 if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) {
4703 4865 zerr(gettext("A positive number with a "
4704 4866 "required scale suffix (K, M, G or T) was "
4705 4867 "expected here."));
4706 4868 saw_error = B_TRUE;
4707 4869 } else if (mem_cap < mem_limit) {
4708 4870 char buf[128];
4709 4871
4710 4872 (void) snprintf(buf, sizeof (buf), "%llu",
4711 4873 mem_limit);
4712 4874 bytes_to_units(buf, buf, sizeof (buf));
4713 4875 zerr(gettext("%s value is too small. It must "
4714 4876 "be at least %s."), pt_to_str(PT_SWAP),
4715 4877 buf);
4716 4878 saw_error = B_TRUE;
4717 4879 } else {
4718 4880 if ((err = zonecfg_set_aliased_rctl(handle,
4719 4881 ALIAS_MAXSWAP, mem_cap)) != Z_OK)
4720 4882 zone_perror(zone, err, B_TRUE);
4721 4883 else
4722 4884 need_to_commit = B_TRUE;
4723 4885 }
4724 4886 break;
4725 4887 case PT_LOCKED:
4726 4888 /*
4727 4889 * We have to check if an rctl is allowed here since
4728 4890 * there might already be a rctl defined that blocks
4729 4891 * the alias.
4730 4892 */
4731 4893 if (!zonecfg_aliased_rctl_ok(handle,
4732 4894 ALIAS_MAXLOCKEDMEM)) {
4733 4895 zone_perror(pt_to_str(PT_LOCKED),
4734 4896 Z_ALIAS_DISALLOW, B_FALSE);
4735 4897 saw_error = B_TRUE;
4736 4898 return;
4737 4899 }
4738 4900
4739 4901 if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) {
4740 4902 zerr(gettext("A non-negative number with a "
4741 4903 "required scale suffix (K, M, G or T) was "
4742 4904 "expected\nhere."));
4743 4905 saw_error = B_TRUE;
4744 4906 } else {
4745 4907 if ((err = zonecfg_set_aliased_rctl(handle,
4746 4908 ALIAS_MAXLOCKEDMEM, mem_cap)) != Z_OK)
4747 4909 zone_perror(zone, err, B_TRUE);
4748 4910 else
4749 4911 need_to_commit = B_TRUE;
4750 4912 }
4751 4913 break;
4752 4914 default:
4753 4915 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4754 4916 B_TRUE);
4755 4917 long_usage(CMD_SET, B_TRUE);
4756 4918 usage(B_FALSE, HELP_PROPS);
4757 4919 return;
4758 4920 }
4759 4921 return;
4760 4922 case RT_ADMIN:
4761 4923 switch (prop_type) {
4762 4924 case PT_USER:
4763 4925 (void) strlcpy(in_progress_admintab.zone_admin_user,
4764 4926 prop_id,
4765 4927 sizeof (in_progress_admintab.zone_admin_user));
4766 4928 return;
4767 4929 case PT_AUTHS:
4768 4930 (void) strlcpy(in_progress_admintab.zone_admin_auths,
↓ open down ↓ |
896 lines elided |
↑ open up ↑ |
4769 4931 prop_id,
4770 4932 sizeof (in_progress_admintab.zone_admin_auths));
4771 4933 return;
4772 4934 default:
4773 4935 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4774 4936 B_TRUE);
4775 4937 long_usage(CMD_SET, B_TRUE);
4776 4938 usage(B_FALSE, HELP_PROPS);
4777 4939 return;
4778 4940 }
4941 + case RT_SECFLAGS: {
4942 + char *propstr;
4943 +
4944 + switch (prop_type) {
4945 + case PT_DEFAULT:
4946 + propstr = in_progress_secflagstab.zone_secflags_default;
4947 + break;
4948 + case PT_UPPER:
4949 + propstr = in_progress_secflagstab.zone_secflags_upper;
4950 + break;
4951 + case PT_LOWER:
4952 + propstr = in_progress_secflagstab.zone_secflags_lower;
4953 + break;
4954 + default:
4955 + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4956 + B_TRUE);
4957 + long_usage(CMD_SET, B_TRUE);
4958 + usage(B_FALSE, HELP_PROPS);
4959 + return;
4960 + }
4961 + (void) strlcpy(propstr, prop_id, ZONECFG_SECFLAGS_MAX);
4962 + return;
4963 + }
4779 4964 default:
4780 4965 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
4781 4966 long_usage(CMD_SET, B_TRUE);
4782 4967 usage(B_FALSE, HELP_RESOURCES);
4783 4968 return;
4784 4969 }
4785 4970 }
4786 4971
4787 4972 static void
4788 4973 output_prop(FILE *fp, int pnum, char *pval, boolean_t print_notspec)
4789 4974 {
4790 4975 char *qstr;
4791 4976
4792 4977 if (*pval != '\0') {
4793 4978 qstr = quoteit(pval);
4794 4979 if (pnum == PT_SWAP || pnum == PT_LOCKED)
4795 4980 (void) fprintf(fp, "\t[%s: %s]\n", pt_to_str(pnum),
4796 4981 qstr);
4797 4982 else
4798 4983 (void) fprintf(fp, "\t%s: %s\n", pt_to_str(pnum), qstr);
4799 4984 free(qstr);
4800 4985 } else if (print_notspec)
4801 4986 (void) fprintf(fp, gettext("\t%s not specified\n"),
4802 4987 pt_to_str(pnum));
4803 4988 }
4804 4989
4805 4990 static void
4806 4991 info_zonename(zone_dochandle_t handle, FILE *fp)
4807 4992 {
4808 4993 char zonename[ZONENAME_MAX];
4809 4994
4810 4995 if (zonecfg_get_name(handle, zonename, sizeof (zonename)) == Z_OK)
4811 4996 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_ZONENAME),
4812 4997 zonename);
4813 4998 else
4814 4999 (void) fprintf(fp, gettext("%s not specified\n"),
4815 5000 pt_to_str(PT_ZONENAME));
4816 5001 }
4817 5002
4818 5003 static void
4819 5004 info_zonepath(zone_dochandle_t handle, FILE *fp)
4820 5005 {
4821 5006 char zonepath[MAXPATHLEN];
4822 5007
4823 5008 if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) == Z_OK)
4824 5009 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_ZONEPATH),
4825 5010 zonepath);
4826 5011 else {
4827 5012 (void) fprintf(fp, gettext("%s not specified\n"),
4828 5013 pt_to_str(PT_ZONEPATH));
4829 5014 }
4830 5015 }
4831 5016
4832 5017 static void
4833 5018 info_brand(zone_dochandle_t handle, FILE *fp)
4834 5019 {
4835 5020 char brand[MAXNAMELEN];
4836 5021
4837 5022 if (zonecfg_get_brand(handle, brand, sizeof (brand)) == Z_OK)
4838 5023 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_BRAND),
4839 5024 brand);
4840 5025 else
4841 5026 (void) fprintf(fp, "%s %s\n", pt_to_str(PT_BRAND),
4842 5027 gettext("not specified"));
4843 5028 }
4844 5029
4845 5030 static void
4846 5031 info_autoboot(zone_dochandle_t handle, FILE *fp)
4847 5032 {
4848 5033 boolean_t autoboot;
4849 5034 int err;
4850 5035
4851 5036 if ((err = zonecfg_get_autoboot(handle, &autoboot)) == Z_OK)
4852 5037 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_AUTOBOOT),
4853 5038 autoboot ? "true" : "false");
4854 5039 else
4855 5040 zone_perror(zone, err, B_TRUE);
4856 5041 }
4857 5042
4858 5043 static void
4859 5044 info_pool(zone_dochandle_t handle, FILE *fp)
4860 5045 {
4861 5046 char pool[MAXNAMELEN];
4862 5047 int err;
4863 5048
4864 5049 if ((err = zonecfg_get_pool(handle, pool, sizeof (pool))) == Z_OK)
4865 5050 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_POOL), pool);
4866 5051 else
4867 5052 zone_perror(zone, err, B_TRUE);
4868 5053 }
4869 5054
4870 5055 static void
4871 5056 info_limitpriv(zone_dochandle_t handle, FILE *fp)
4872 5057 {
4873 5058 char *limitpriv;
4874 5059 int err;
4875 5060
4876 5061 if ((err = zonecfg_get_limitpriv(handle, &limitpriv)) == Z_OK) {
4877 5062 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_LIMITPRIV),
4878 5063 limitpriv);
4879 5064 free(limitpriv);
4880 5065 } else {
4881 5066 zone_perror(zone, err, B_TRUE);
4882 5067 }
4883 5068 }
4884 5069
4885 5070 static void
4886 5071 info_bootargs(zone_dochandle_t handle, FILE *fp)
4887 5072 {
4888 5073 char bootargs[BOOTARGS_MAX];
4889 5074 int err;
4890 5075
4891 5076 if ((err = zonecfg_get_bootargs(handle, bootargs,
4892 5077 sizeof (bootargs))) == Z_OK) {
4893 5078 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_BOOTARGS),
4894 5079 bootargs);
4895 5080 } else {
4896 5081 zone_perror(zone, err, B_TRUE);
4897 5082 }
4898 5083 }
4899 5084
4900 5085 static void
4901 5086 info_sched(zone_dochandle_t handle, FILE *fp)
4902 5087 {
4903 5088 char sched[MAXNAMELEN];
4904 5089 int err;
4905 5090
4906 5091 if ((err = zonecfg_get_sched_class(handle, sched, sizeof (sched)))
4907 5092 == Z_OK) {
4908 5093 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_SCHED), sched);
4909 5094 } else {
4910 5095 zone_perror(zone, err, B_TRUE);
4911 5096 }
4912 5097 }
4913 5098
4914 5099 static void
4915 5100 info_iptype(zone_dochandle_t handle, FILE *fp)
4916 5101 {
4917 5102 zone_iptype_t iptype;
4918 5103 int err;
4919 5104
4920 5105 if ((err = zonecfg_get_iptype(handle, &iptype)) == Z_OK) {
4921 5106 switch (iptype) {
4922 5107 case ZS_SHARED:
4923 5108 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_IPTYPE),
4924 5109 "shared");
4925 5110 break;
4926 5111 case ZS_EXCLUSIVE:
4927 5112 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_IPTYPE),
4928 5113 "exclusive");
4929 5114 break;
4930 5115 }
4931 5116 } else {
4932 5117 zone_perror(zone, err, B_TRUE);
4933 5118 }
4934 5119 }
4935 5120
4936 5121 static void
4937 5122 info_hostid(zone_dochandle_t handle, FILE *fp)
4938 5123 {
4939 5124 char hostidp[HW_HOSTID_LEN];
4940 5125 int err;
4941 5126
4942 5127 if ((err = zonecfg_get_hostid(handle, hostidp,
4943 5128 sizeof (hostidp))) == Z_OK) {
4944 5129 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_HOSTID), hostidp);
4945 5130 } else if (err == Z_BAD_PROPERTY) {
4946 5131 (void) fprintf(fp, "%s: \n", pt_to_str(PT_HOSTID));
4947 5132 } else {
4948 5133 zone_perror(zone, err, B_TRUE);
4949 5134 }
4950 5135 }
4951 5136
4952 5137 static void
4953 5138 info_fs_allowed(zone_dochandle_t handle, FILE *fp)
4954 5139 {
4955 5140 char fsallowedp[ZONE_FS_ALLOWED_MAX];
4956 5141 int err;
4957 5142
4958 5143 if ((err = zonecfg_get_fs_allowed(handle, fsallowedp,
4959 5144 sizeof (fsallowedp))) == Z_OK) {
4960 5145 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_FS_ALLOWED),
4961 5146 fsallowedp);
4962 5147 } else if (err == Z_BAD_PROPERTY) {
4963 5148 (void) fprintf(fp, "%s: \n", pt_to_str(PT_FS_ALLOWED));
4964 5149 } else {
4965 5150 zone_perror(zone, err, B_TRUE);
4966 5151 }
4967 5152 }
4968 5153
4969 5154 static void
4970 5155 output_fs(FILE *fp, struct zone_fstab *fstab)
4971 5156 {
4972 5157 zone_fsopt_t *this;
4973 5158
4974 5159 (void) fprintf(fp, "%s:\n", rt_to_str(RT_FS));
4975 5160 output_prop(fp, PT_DIR, fstab->zone_fs_dir, B_TRUE);
4976 5161 output_prop(fp, PT_SPECIAL, fstab->zone_fs_special, B_TRUE);
4977 5162 output_prop(fp, PT_RAW, fstab->zone_fs_raw, B_TRUE);
4978 5163 output_prop(fp, PT_TYPE, fstab->zone_fs_type, B_TRUE);
4979 5164 (void) fprintf(fp, "\t%s: [", pt_to_str(PT_OPTIONS));
4980 5165 for (this = fstab->zone_fs_options; this != NULL;
4981 5166 this = this->zone_fsopt_next) {
4982 5167 if (strchr(this->zone_fsopt_opt, '='))
4983 5168 (void) fprintf(fp, "\"%s\"", this->zone_fsopt_opt);
4984 5169 else
4985 5170 (void) fprintf(fp, "%s", this->zone_fsopt_opt);
4986 5171 if (this->zone_fsopt_next != NULL)
4987 5172 (void) fprintf(fp, ",");
4988 5173 }
4989 5174 (void) fprintf(fp, "]\n");
4990 5175 }
4991 5176
4992 5177 static void
4993 5178 info_fs(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
4994 5179 {
4995 5180 struct zone_fstab lookup, user;
4996 5181 boolean_t output = B_FALSE;
4997 5182
4998 5183 if (zonecfg_setfsent(handle) != Z_OK)
4999 5184 return;
5000 5185 while (zonecfg_getfsent(handle, &lookup) == Z_OK) {
5001 5186 if (cmd->cmd_prop_nv_pairs == 0) {
5002 5187 output_fs(fp, &lookup);
5003 5188 goto loopend;
5004 5189 }
5005 5190 if (fill_in_fstab(cmd, &user, B_TRUE) != Z_OK)
5006 5191 goto loopend;
5007 5192 if (strlen(user.zone_fs_dir) > 0 &&
5008 5193 strcmp(user.zone_fs_dir, lookup.zone_fs_dir) != 0)
5009 5194 goto loopend; /* no match */
5010 5195 if (strlen(user.zone_fs_special) > 0 &&
5011 5196 strcmp(user.zone_fs_special, lookup.zone_fs_special) != 0)
5012 5197 goto loopend; /* no match */
5013 5198 if (strlen(user.zone_fs_type) > 0 &&
5014 5199 strcmp(user.zone_fs_type, lookup.zone_fs_type) != 0)
5015 5200 goto loopend; /* no match */
5016 5201 output_fs(fp, &lookup);
5017 5202 output = B_TRUE;
5018 5203 loopend:
5019 5204 zonecfg_free_fs_option_list(lookup.zone_fs_options);
5020 5205 }
5021 5206 (void) zonecfg_endfsent(handle);
5022 5207 /*
5023 5208 * If a property n/v pair was specified, warn the user if there was
5024 5209 * nothing to output.
5025 5210 */
5026 5211 if (!output && cmd->cmd_prop_nv_pairs > 0)
5027 5212 (void) printf(gettext("No such %s resource.\n"),
5028 5213 rt_to_str(RT_FS));
5029 5214 }
5030 5215
5031 5216 static void
5032 5217 output_net(FILE *fp, struct zone_nwiftab *nwiftab)
5033 5218 {
5034 5219 (void) fprintf(fp, "%s:\n", rt_to_str(RT_NET));
5035 5220 output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE);
5036 5221 output_prop(fp, PT_ALLOWED_ADDRESS,
5037 5222 nwiftab->zone_nwif_allowed_address, B_TRUE);
5038 5223 output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE);
5039 5224 output_prop(fp, PT_DEFROUTER, nwiftab->zone_nwif_defrouter, B_TRUE);
5040 5225 }
5041 5226
5042 5227 static void
5043 5228 info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5044 5229 {
5045 5230 struct zone_nwiftab lookup, user;
5046 5231 boolean_t output = B_FALSE;
5047 5232
5048 5233 if (zonecfg_setnwifent(handle) != Z_OK)
5049 5234 return;
5050 5235 while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
5051 5236 if (cmd->cmd_prop_nv_pairs == 0) {
5052 5237 output_net(fp, &lookup);
5053 5238 continue;
5054 5239 }
5055 5240 if (fill_in_nwiftab(cmd, &user, B_TRUE) != Z_OK)
5056 5241 continue;
5057 5242 if (strlen(user.zone_nwif_physical) > 0 &&
5058 5243 strcmp(user.zone_nwif_physical,
5059 5244 lookup.zone_nwif_physical) != 0)
5060 5245 continue; /* no match */
5061 5246 /* If present make sure it matches */
5062 5247 if (strlen(user.zone_nwif_address) > 0 &&
5063 5248 !zonecfg_same_net_address(user.zone_nwif_address,
5064 5249 lookup.zone_nwif_address))
5065 5250 continue; /* no match */
5066 5251 output_net(fp, &lookup);
5067 5252 output = B_TRUE;
5068 5253 }
5069 5254 (void) zonecfg_endnwifent(handle);
5070 5255 /*
5071 5256 * If a property n/v pair was specified, warn the user if there was
5072 5257 * nothing to output.
5073 5258 */
5074 5259 if (!output && cmd->cmd_prop_nv_pairs > 0)
5075 5260 (void) printf(gettext("No such %s resource.\n"),
5076 5261 rt_to_str(RT_NET));
5077 5262 }
5078 5263
5079 5264 static void
5080 5265 output_dev(FILE *fp, struct zone_devtab *devtab)
5081 5266 {
5082 5267 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DEVICE));
5083 5268 output_prop(fp, PT_MATCH, devtab->zone_dev_match, B_TRUE);
5084 5269 }
5085 5270
5086 5271 static void
5087 5272 info_dev(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5088 5273 {
5089 5274 struct zone_devtab lookup, user;
5090 5275 boolean_t output = B_FALSE;
5091 5276
5092 5277 if (zonecfg_setdevent(handle) != Z_OK)
5093 5278 return;
5094 5279 while (zonecfg_getdevent(handle, &lookup) == Z_OK) {
5095 5280 if (cmd->cmd_prop_nv_pairs == 0) {
5096 5281 output_dev(fp, &lookup);
5097 5282 continue;
5098 5283 }
5099 5284 if (fill_in_devtab(cmd, &user, B_TRUE) != Z_OK)
5100 5285 continue;
5101 5286 if (strlen(user.zone_dev_match) > 0 &&
5102 5287 strcmp(user.zone_dev_match, lookup.zone_dev_match) != 0)
5103 5288 continue; /* no match */
5104 5289 output_dev(fp, &lookup);
5105 5290 output = B_TRUE;
5106 5291 }
5107 5292 (void) zonecfg_enddevent(handle);
5108 5293 /*
5109 5294 * If a property n/v pair was specified, warn the user if there was
5110 5295 * nothing to output.
5111 5296 */
5112 5297 if (!output && cmd->cmd_prop_nv_pairs > 0)
5113 5298 (void) printf(gettext("No such %s resource.\n"),
5114 5299 rt_to_str(RT_DEVICE));
5115 5300 }
5116 5301
5117 5302 static void
5118 5303 output_rctl(FILE *fp, struct zone_rctltab *rctltab)
5119 5304 {
5120 5305 struct zone_rctlvaltab *valptr;
5121 5306
5122 5307 (void) fprintf(fp, "%s:\n", rt_to_str(RT_RCTL));
5123 5308 output_prop(fp, PT_NAME, rctltab->zone_rctl_name, B_TRUE);
5124 5309 for (valptr = rctltab->zone_rctl_valptr; valptr != NULL;
5125 5310 valptr = valptr->zone_rctlval_next) {
5126 5311 fprintf(fp, "\t%s: (%s=%s,%s=%s,%s=%s)\n",
5127 5312 pt_to_str(PT_VALUE),
5128 5313 pt_to_str(PT_PRIV), valptr->zone_rctlval_priv,
5129 5314 pt_to_str(PT_LIMIT), valptr->zone_rctlval_limit,
5130 5315 pt_to_str(PT_ACTION), valptr->zone_rctlval_action);
5131 5316 }
5132 5317 }
5133 5318
5134 5319 static void
5135 5320 info_rctl(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5136 5321 {
5137 5322 struct zone_rctltab lookup, user;
5138 5323 boolean_t output = B_FALSE;
5139 5324
5140 5325 if (zonecfg_setrctlent(handle) != Z_OK)
5141 5326 return;
5142 5327 while (zonecfg_getrctlent(handle, &lookup) == Z_OK) {
5143 5328 if (cmd->cmd_prop_nv_pairs == 0) {
5144 5329 output_rctl(fp, &lookup);
5145 5330 } else if (fill_in_rctltab(cmd, &user, B_TRUE) == Z_OK &&
5146 5331 (strlen(user.zone_rctl_name) == 0 ||
5147 5332 strcmp(user.zone_rctl_name, lookup.zone_rctl_name) == 0)) {
5148 5333 output_rctl(fp, &lookup);
5149 5334 output = B_TRUE;
5150 5335 }
5151 5336 zonecfg_free_rctl_value_list(lookup.zone_rctl_valptr);
5152 5337 }
5153 5338 (void) zonecfg_endrctlent(handle);
5154 5339 /*
5155 5340 * If a property n/v pair was specified, warn the user if there was
5156 5341 * nothing to output.
5157 5342 */
5158 5343 if (!output && cmd->cmd_prop_nv_pairs > 0)
5159 5344 (void) printf(gettext("No such %s resource.\n"),
5160 5345 rt_to_str(RT_RCTL));
5161 5346 }
5162 5347
5163 5348 static void
5164 5349 output_attr(FILE *fp, struct zone_attrtab *attrtab)
5165 5350 {
5166 5351 (void) fprintf(fp, "%s:\n", rt_to_str(RT_ATTR));
5167 5352 output_prop(fp, PT_NAME, attrtab->zone_attr_name, B_TRUE);
5168 5353 output_prop(fp, PT_TYPE, attrtab->zone_attr_type, B_TRUE);
5169 5354 output_prop(fp, PT_VALUE, attrtab->zone_attr_value, B_TRUE);
5170 5355 }
5171 5356
5172 5357 static void
5173 5358 info_attr(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5174 5359 {
5175 5360 struct zone_attrtab lookup, user;
5176 5361 boolean_t output = B_FALSE;
5177 5362
5178 5363 if (zonecfg_setattrent(handle) != Z_OK)
5179 5364 return;
5180 5365 while (zonecfg_getattrent(handle, &lookup) == Z_OK) {
5181 5366 if (cmd->cmd_prop_nv_pairs == 0) {
5182 5367 output_attr(fp, &lookup);
5183 5368 continue;
5184 5369 }
5185 5370 if (fill_in_attrtab(cmd, &user, B_TRUE) != Z_OK)
5186 5371 continue;
5187 5372 if (strlen(user.zone_attr_name) > 0 &&
5188 5373 strcmp(user.zone_attr_name, lookup.zone_attr_name) != 0)
5189 5374 continue; /* no match */
5190 5375 if (strlen(user.zone_attr_type) > 0 &&
5191 5376 strcmp(user.zone_attr_type, lookup.zone_attr_type) != 0)
5192 5377 continue; /* no match */
5193 5378 if (strlen(user.zone_attr_value) > 0 &&
5194 5379 strcmp(user.zone_attr_value, lookup.zone_attr_value) != 0)
5195 5380 continue; /* no match */
5196 5381 output_attr(fp, &lookup);
5197 5382 output = B_TRUE;
5198 5383 }
5199 5384 (void) zonecfg_endattrent(handle);
5200 5385 /*
5201 5386 * If a property n/v pair was specified, warn the user if there was
5202 5387 * nothing to output.
5203 5388 */
5204 5389 if (!output && cmd->cmd_prop_nv_pairs > 0)
5205 5390 (void) printf(gettext("No such %s resource.\n"),
5206 5391 rt_to_str(RT_ATTR));
5207 5392 }
5208 5393
5209 5394 static void
5210 5395 output_ds(FILE *fp, struct zone_dstab *dstab)
5211 5396 {
5212 5397 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DATASET));
5213 5398 output_prop(fp, PT_NAME, dstab->zone_dataset_name, B_TRUE);
5214 5399 }
5215 5400
5216 5401 static void
5217 5402 info_ds(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5218 5403 {
5219 5404 struct zone_dstab lookup, user;
5220 5405 boolean_t output = B_FALSE;
5221 5406
5222 5407 if (zonecfg_setdsent(handle) != Z_OK)
5223 5408 return;
5224 5409 while (zonecfg_getdsent(handle, &lookup) == Z_OK) {
5225 5410 if (cmd->cmd_prop_nv_pairs == 0) {
5226 5411 output_ds(fp, &lookup);
5227 5412 continue;
5228 5413 }
5229 5414 if (fill_in_dstab(cmd, &user, B_TRUE) != Z_OK)
5230 5415 continue;
5231 5416 if (strlen(user.zone_dataset_name) > 0 &&
5232 5417 strcmp(user.zone_dataset_name,
5233 5418 lookup.zone_dataset_name) != 0)
5234 5419 continue; /* no match */
5235 5420 output_ds(fp, &lookup);
5236 5421 output = B_TRUE;
5237 5422 }
5238 5423 (void) zonecfg_enddsent(handle);
5239 5424 /*
5240 5425 * If a property n/v pair was specified, warn the user if there was
5241 5426 * nothing to output.
5242 5427 */
5243 5428 if (!output && cmd->cmd_prop_nv_pairs > 0)
5244 5429 (void) printf(gettext("No such %s resource.\n"),
5245 5430 rt_to_str(RT_DATASET));
5246 5431 }
5247 5432
5248 5433 static void
5249 5434 output_pset(FILE *fp, struct zone_psettab *psettab)
5250 5435 {
5251 5436 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DCPU));
5252 5437 if (strcmp(psettab->zone_ncpu_min, psettab->zone_ncpu_max) == 0)
5253 5438 (void) fprintf(fp, "\t%s: %s\n", pt_to_str(PT_NCPUS),
5254 5439 psettab->zone_ncpu_max);
5255 5440 else
5256 5441 (void) fprintf(fp, "\t%s: %s-%s\n", pt_to_str(PT_NCPUS),
5257 5442 psettab->zone_ncpu_min, psettab->zone_ncpu_max);
5258 5443 if (psettab->zone_importance[0] != '\0')
5259 5444 (void) fprintf(fp, "\t%s: %s\n", pt_to_str(PT_IMPORTANCE),
5260 5445 psettab->zone_importance);
5261 5446 }
5262 5447
5263 5448 static void
5264 5449 info_pset(zone_dochandle_t handle, FILE *fp)
5265 5450 {
5266 5451 struct zone_psettab lookup;
5267 5452
5268 5453 if (zonecfg_getpsetent(handle, &lookup) == Z_OK)
5269 5454 output_pset(fp, &lookup);
5270 5455 }
5271 5456
5272 5457 static void
5273 5458 output_pcap(FILE *fp)
5274 5459 {
5275 5460 uint64_t cap;
5276 5461
5277 5462 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &cap) == Z_OK) {
5278 5463 float scaled = (float)cap / 100;
5279 5464 (void) fprintf(fp, "%s:\n", rt_to_str(RT_PCAP));
5280 5465 (void) fprintf(fp, "\t[%s: %.2f]\n", pt_to_str(PT_NCPUS),
5281 5466 scaled);
5282 5467 }
5283 5468 }
5284 5469
5285 5470 static void
5286 5471 info_pcap(FILE *fp)
5287 5472 {
5288 5473 output_pcap(fp);
5289 5474 }
5290 5475
5291 5476
5292 5477 static void
5293 5478 info_aliased_rctl(zone_dochandle_t handle, FILE *fp, char *alias)
5294 5479 {
5295 5480 uint64_t limit;
5296 5481
5297 5482 if (zonecfg_get_aliased_rctl(handle, alias, &limit) == Z_OK) {
5298 5483 /* convert memory based properties */
5299 5484 if (strcmp(alias, ALIAS_MAXSHMMEM) == 0) {
5300 5485 char buf[128];
5301 5486
5302 5487 (void) snprintf(buf, sizeof (buf), "%llu", limit);
5303 5488 bytes_to_units(buf, buf, sizeof (buf));
5304 5489 (void) fprintf(fp, "[%s: %s]\n", alias, buf);
5305 5490 return;
5306 5491 }
5307 5492
5308 5493 (void) fprintf(fp, "[%s: %llu]\n", alias, limit);
5309 5494 }
5310 5495 }
5311 5496
5312 5497 static void
5313 5498 bytes_to_units(char *str, char *buf, int bufsize)
5314 5499 {
5315 5500 unsigned long long num;
5316 5501 unsigned long long save = 0;
5317 5502 char *units = "BKMGT";
5318 5503 char *up = units;
5319 5504
5320 5505 num = strtoll(str, NULL, 10);
5321 5506
5322 5507 if (num < 1024) {
5323 5508 (void) snprintf(buf, bufsize, "%llu", num);
5324 5509 return;
5325 5510 }
5326 5511
5327 5512 while ((num >= 1024) && (*up != 'T')) {
5328 5513 up++; /* next unit of measurement */
5329 5514 save = num;
5330 5515 num = (num + 512) >> 10;
5331 5516 }
5332 5517
5333 5518 /* check if we should output a fraction. snprintf will round for us */
5334 5519 if (save % 1024 != 0 && ((save >> 10) < 10))
5335 5520 (void) snprintf(buf, bufsize, "%2.1f%c", ((float)save / 1024),
5336 5521 *up);
5337 5522 else
5338 5523 (void) snprintf(buf, bufsize, "%llu%c", num, *up);
5339 5524 }
5340 5525
5341 5526 static void
5342 5527 output_mcap(FILE *fp, struct zone_mcaptab *mcaptab, int showswap,
5343 5528 uint64_t maxswap, int showlocked, uint64_t maxlocked)
5344 5529 {
5345 5530 char buf[128];
5346 5531
5347 5532 (void) fprintf(fp, "%s:\n", rt_to_str(RT_MCAP));
5348 5533 if (mcaptab->zone_physmem_cap[0] != '\0') {
5349 5534 bytes_to_units(mcaptab->zone_physmem_cap, buf, sizeof (buf));
5350 5535 output_prop(fp, PT_PHYSICAL, buf, B_TRUE);
5351 5536 }
5352 5537
5353 5538 if (showswap == Z_OK) {
5354 5539 (void) snprintf(buf, sizeof (buf), "%llu", maxswap);
5355 5540 bytes_to_units(buf, buf, sizeof (buf));
5356 5541 output_prop(fp, PT_SWAP, buf, B_TRUE);
5357 5542 }
5358 5543
5359 5544 if (showlocked == Z_OK) {
5360 5545 (void) snprintf(buf, sizeof (buf), "%llu", maxlocked);
5361 5546 bytes_to_units(buf, buf, sizeof (buf));
5362 5547 output_prop(fp, PT_LOCKED, buf, B_TRUE);
5363 5548 }
5364 5549 }
5365 5550
5366 5551 static void
5367 5552 info_mcap(zone_dochandle_t handle, FILE *fp)
5368 5553 {
5369 5554 int res1, res2, res3;
5370 5555 uint64_t swap_limit;
5371 5556 uint64_t locked_limit;
5372 5557 struct zone_mcaptab lookup;
5373 5558
5374 5559 bzero(&lookup, sizeof (lookup));
5375 5560 res1 = zonecfg_getmcapent(handle, &lookup);
5376 5561 res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &swap_limit);
5377 5562 res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM,
5378 5563 &locked_limit);
5379 5564
5380 5565 if (res1 == Z_OK || res2 == Z_OK || res3 == Z_OK)
5381 5566 output_mcap(fp, &lookup, res2, swap_limit, res3, locked_limit);
5382 5567 }
↓ open down ↓ |
594 lines elided |
↑ open up ↑ |
5383 5568
5384 5569 static void
5385 5570 output_auth(FILE *fp, struct zone_admintab *admintab)
5386 5571 {
5387 5572 (void) fprintf(fp, "%s:\n", rt_to_str(RT_ADMIN));
5388 5573 output_prop(fp, PT_USER, admintab->zone_admin_user, B_TRUE);
5389 5574 output_prop(fp, PT_AUTHS, admintab->zone_admin_auths, B_TRUE);
5390 5575 }
5391 5576
5392 5577 static void
5578 +output_secflags(FILE *fp, struct zone_secflagstab *sftab)
5579 +{
5580 + (void) fprintf(fp, "%s:\n", rt_to_str(RT_SECFLAGS));
5581 + output_prop(fp, PT_DEFAULT, sftab->zone_secflags_default, B_TRUE);
5582 + output_prop(fp, PT_LOWER, sftab->zone_secflags_lower, B_TRUE);
5583 + output_prop(fp, PT_UPPER, sftab->zone_secflags_upper, B_TRUE);
5584 +}
5585 +
5586 +static void
5393 5587 info_auth(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5394 5588 {
5395 5589 struct zone_admintab lookup, user;
5396 5590 boolean_t output = B_FALSE;
5397 5591 int err;
5398 5592
5399 5593 if ((err = zonecfg_setadminent(handle)) != Z_OK) {
5400 5594 zone_perror(zone, err, B_TRUE);
5401 5595 return;
5402 5596 }
5403 5597 while (zonecfg_getadminent(handle, &lookup) == Z_OK) {
5404 5598 if (cmd->cmd_prop_nv_pairs == 0) {
5405 5599 output_auth(fp, &lookup);
5406 5600 continue;
5407 5601 }
5408 5602 if (fill_in_admintab(cmd, &user, B_TRUE) != Z_OK)
5409 5603 continue;
5410 5604 if (strlen(user.zone_admin_user) > 0 &&
5411 5605 strcmp(user.zone_admin_user, lookup.zone_admin_user) != 0)
5412 5606 continue; /* no match */
5413 5607 output_auth(fp, &lookup);
5414 5608 output = B_TRUE;
5415 5609 }
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
5416 5610 (void) zonecfg_endadminent(handle);
5417 5611 /*
5418 5612 * If a property n/v pair was specified, warn the user if there was
5419 5613 * nothing to output.
5420 5614 */
5421 5615 if (!output && cmd->cmd_prop_nv_pairs > 0)
5422 5616 (void) printf(gettext("No such %s resource.\n"),
5423 5617 rt_to_str(RT_ADMIN));
5424 5618 }
5425 5619
5620 +static void
5621 +info_secflags(zone_dochandle_t handle, FILE *fp)
5622 +{
5623 + struct zone_secflagstab sftab;
5624 +
5625 + if (zonecfg_lookup_secflags(handle, &sftab) == Z_OK) {
5626 + output_secflags(fp, &sftab);
5627 + }
5628 +}
5629 +
5426 5630 void
5427 5631 info_func(cmd_t *cmd)
5428 5632 {
5429 5633 FILE *fp = stdout;
5430 5634 boolean_t need_to_close = B_FALSE;
5431 5635 int type;
5432 5636 int res1, res2;
5433 5637 uint64_t swap_limit;
5434 5638 uint64_t locked_limit;
5435 5639
5436 5640 assert(cmd != NULL);
5437 5641
5438 5642 if (initialize(B_TRUE) != Z_OK)
5439 5643 return;
5440 5644
5441 5645 /* don't page error output */
5442 5646 if (interactive_mode) {
5443 5647 if ((fp = pager_open()) != NULL)
5444 5648 need_to_close = B_TRUE;
5445 5649 else
5446 5650 fp = stdout;
5447 5651
5448 5652 setbuf(fp, NULL);
5449 5653 }
5450 5654
5451 5655 if (!global_scope) {
5452 5656 switch (resource_scope) {
5453 5657 case RT_FS:
5454 5658 output_fs(fp, &in_progress_fstab);
5455 5659 break;
5456 5660 case RT_NET:
5457 5661 output_net(fp, &in_progress_nwiftab);
5458 5662 break;
5459 5663 case RT_DEVICE:
5460 5664 output_dev(fp, &in_progress_devtab);
5461 5665 break;
5462 5666 case RT_RCTL:
5463 5667 output_rctl(fp, &in_progress_rctltab);
5464 5668 break;
5465 5669 case RT_ATTR:
5466 5670 output_attr(fp, &in_progress_attrtab);
5467 5671 break;
5468 5672 case RT_DATASET:
5469 5673 output_ds(fp, &in_progress_dstab);
5470 5674 break;
5471 5675 case RT_DCPU:
5472 5676 output_pset(fp, &in_progress_psettab);
5473 5677 break;
5474 5678 case RT_PCAP:
5475 5679 output_pcap(fp);
5476 5680 break;
5477 5681 case RT_MCAP:
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
5478 5682 res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP,
5479 5683 &swap_limit);
5480 5684 res2 = zonecfg_get_aliased_rctl(handle,
5481 5685 ALIAS_MAXLOCKEDMEM, &locked_limit);
5482 5686 output_mcap(fp, &in_progress_mcaptab, res1, swap_limit,
5483 5687 res2, locked_limit);
5484 5688 break;
5485 5689 case RT_ADMIN:
5486 5690 output_auth(fp, &in_progress_admintab);
5487 5691 break;
5692 + case RT_SECFLAGS:
5693 + output_secflags(fp, &in_progress_secflagstab);
5694 + break;
5488 5695 }
5489 5696 goto cleanup;
5490 5697 }
5491 5698
5492 5699 type = cmd->cmd_res_type;
5493 5700
5494 5701 if (gz_invalid_rt_property(type)) {
5495 5702 zerr(gettext("%s is not a valid property for the global zone."),
5496 5703 rt_to_str(type));
5497 5704 goto cleanup;
5498 5705 }
5499 5706
5500 5707 if (gz_invalid_resource(type)) {
5501 5708 zerr(gettext("%s is not a valid resource for the global zone."),
5502 5709 rt_to_str(type));
5503 5710 goto cleanup;
5504 5711 }
5505 5712
5506 5713 switch (cmd->cmd_res_type) {
5507 5714 case RT_UNKNOWN:
5508 5715 info_zonename(handle, fp);
5509 5716 if (!global_zone) {
5510 5717 info_zonepath(handle, fp);
5511 5718 info_brand(handle, fp);
5512 5719 info_autoboot(handle, fp);
5513 5720 info_bootargs(handle, fp);
5514 5721 }
5515 5722 info_pool(handle, fp);
5516 5723 if (!global_zone) {
5517 5724 info_limitpriv(handle, fp);
5518 5725 info_sched(handle, fp);
5519 5726 info_iptype(handle, fp);
5520 5727 info_hostid(handle, fp);
5521 5728 info_fs_allowed(handle, fp);
5522 5729 }
5523 5730 info_aliased_rctl(handle, fp, ALIAS_MAXLWPS);
5524 5731 info_aliased_rctl(handle, fp, ALIAS_MAXPROCS);
5525 5732 info_aliased_rctl(handle, fp, ALIAS_MAXSHMMEM);
5526 5733 info_aliased_rctl(handle, fp, ALIAS_MAXSHMIDS);
5527 5734 info_aliased_rctl(handle, fp, ALIAS_MAXMSGIDS);
5528 5735 info_aliased_rctl(handle, fp, ALIAS_MAXSEMIDS);
5529 5736 info_aliased_rctl(handle, fp, ALIAS_SHARES);
5530 5737 if (!global_zone) {
5531 5738 info_fs(handle, fp, cmd);
5532 5739 info_net(handle, fp, cmd);
5533 5740 info_dev(handle, fp, cmd);
↓ open down ↓ |
36 lines elided |
↑ open up ↑ |
5534 5741 }
5535 5742 info_pset(handle, fp);
5536 5743 info_pcap(fp);
5537 5744 info_mcap(handle, fp);
5538 5745 if (!global_zone) {
5539 5746 info_attr(handle, fp, cmd);
5540 5747 info_ds(handle, fp, cmd);
5541 5748 info_auth(handle, fp, cmd);
5542 5749 }
5543 5750 info_rctl(handle, fp, cmd);
5751 + info_secflags(handle, fp);
5544 5752 break;
5545 5753 case RT_ZONENAME:
5546 5754 info_zonename(handle, fp);
5547 5755 break;
5548 5756 case RT_ZONEPATH:
5549 5757 info_zonepath(handle, fp);
5550 5758 break;
5551 5759 case RT_BRAND:
5552 5760 info_brand(handle, fp);
5553 5761 break;
5554 5762 case RT_AUTOBOOT:
5555 5763 info_autoboot(handle, fp);
5556 5764 break;
5557 5765 case RT_POOL:
5558 5766 info_pool(handle, fp);
5559 5767 break;
5560 5768 case RT_LIMITPRIV:
5561 5769 info_limitpriv(handle, fp);
5562 5770 break;
5563 5771 case RT_BOOTARGS:
5564 5772 info_bootargs(handle, fp);
5565 5773 break;
5566 5774 case RT_SCHED:
5567 5775 info_sched(handle, fp);
5568 5776 break;
5569 5777 case RT_IPTYPE:
5570 5778 info_iptype(handle, fp);
5571 5779 break;
5572 5780 case RT_MAXLWPS:
5573 5781 info_aliased_rctl(handle, fp, ALIAS_MAXLWPS);
5574 5782 break;
5575 5783 case RT_MAXPROCS:
5576 5784 info_aliased_rctl(handle, fp, ALIAS_MAXPROCS);
5577 5785 break;
5578 5786 case RT_MAXSHMMEM:
5579 5787 info_aliased_rctl(handle, fp, ALIAS_MAXSHMMEM);
5580 5788 break;
5581 5789 case RT_MAXSHMIDS:
5582 5790 info_aliased_rctl(handle, fp, ALIAS_MAXSHMIDS);
5583 5791 break;
5584 5792 case RT_MAXMSGIDS:
5585 5793 info_aliased_rctl(handle, fp, ALIAS_MAXMSGIDS);
5586 5794 break;
5587 5795 case RT_MAXSEMIDS:
5588 5796 info_aliased_rctl(handle, fp, ALIAS_MAXSEMIDS);
5589 5797 break;
5590 5798 case RT_SHARES:
5591 5799 info_aliased_rctl(handle, fp, ALIAS_SHARES);
5592 5800 break;
5593 5801 case RT_FS:
5594 5802 info_fs(handle, fp, cmd);
5595 5803 break;
5596 5804 case RT_NET:
5597 5805 info_net(handle, fp, cmd);
5598 5806 break;
5599 5807 case RT_DEVICE:
5600 5808 info_dev(handle, fp, cmd);
5601 5809 break;
5602 5810 case RT_RCTL:
5603 5811 info_rctl(handle, fp, cmd);
5604 5812 break;
5605 5813 case RT_ATTR:
5606 5814 info_attr(handle, fp, cmd);
5607 5815 break;
5608 5816 case RT_DATASET:
5609 5817 info_ds(handle, fp, cmd);
5610 5818 break;
5611 5819 case RT_DCPU:
5612 5820 info_pset(handle, fp);
5613 5821 break;
5614 5822 case RT_PCAP:
5615 5823 info_pcap(fp);
5616 5824 break;
5617 5825 case RT_MCAP:
5618 5826 info_mcap(handle, fp);
↓ open down ↓ |
65 lines elided |
↑ open up ↑ |
5619 5827 break;
5620 5828 case RT_HOSTID:
5621 5829 info_hostid(handle, fp);
5622 5830 break;
5623 5831 case RT_ADMIN:
5624 5832 info_auth(handle, fp, cmd);
5625 5833 break;
5626 5834 case RT_FS_ALLOWED:
5627 5835 info_fs_allowed(handle, fp);
5628 5836 break;
5837 + case RT_SECFLAGS:
5838 + info_secflags(handle, fp);
5839 + break;
5629 5840 default:
5630 5841 zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
5631 5842 B_TRUE);
5632 5843 }
5633 5844
5634 5845 cleanup:
5635 5846 if (need_to_close)
5636 5847 (void) pager_close(fp);
5637 5848 }
5638 5849
5639 5850 /*
5640 5851 * Helper function for verify-- checks that a required string property
5641 5852 * exists.
5642 5853 */
5643 5854 static void
5644 5855 check_reqd_prop(char *attr, int rt, int pt, int *ret_val)
5645 5856 {
5646 5857 if (strlen(attr) == 0) {
5647 5858 zerr(gettext("%s: %s not specified"), rt_to_str(rt),
5648 5859 pt_to_str(pt));
5649 5860 saw_error = B_TRUE;
5650 5861 if (*ret_val == Z_OK)
5651 5862 *ret_val = Z_REQD_PROPERTY_MISSING;
5652 5863 }
5653 5864 }
5654 5865
5655 5866 static int
5656 5867 do_subproc(char *cmdbuf)
5657 5868 {
5658 5869 char inbuf[MAX_CMD_LEN];
5659 5870 FILE *file;
5660 5871 int status;
5661 5872
5662 5873 file = popen(cmdbuf, "r");
5663 5874 if (file == NULL) {
5664 5875 zerr(gettext("Could not launch: %s"), cmdbuf);
5665 5876 return (-1);
5666 5877 }
5667 5878
5668 5879 while (fgets(inbuf, sizeof (inbuf), file) != NULL)
5669 5880 fprintf(stderr, "%s", inbuf);
5670 5881 status = pclose(file);
5671 5882
5672 5883 if (WIFSIGNALED(status)) {
5673 5884 zerr(gettext("%s unexpectedly terminated due to signal %d"),
5674 5885 cmdbuf, WTERMSIG(status));
5675 5886 return (-1);
5676 5887 }
5677 5888 assert(WIFEXITED(status));
5678 5889 return (WEXITSTATUS(status));
5679 5890 }
5680 5891
5681 5892 static int
5682 5893 brand_verify(zone_dochandle_t handle)
5683 5894 {
5684 5895 char xml_file[32];
5685 5896 char cmdbuf[MAX_CMD_LEN];
5686 5897 brand_handle_t bh;
5687 5898 char brand[MAXNAMELEN];
5688 5899 int err;
5689 5900
5690 5901 if (zonecfg_get_brand(handle, brand, sizeof (brand)) != Z_OK) {
5691 5902 zerr("%s: %s\n", zone, gettext("could not get zone brand"));
5692 5903 return (Z_INVALID_DOCUMENT);
5693 5904 }
5694 5905 if ((bh = brand_open(brand)) == NULL) {
5695 5906 zerr("%s: %s\n", zone, gettext("unknown brand."));
5696 5907 return (Z_INVALID_DOCUMENT);
5697 5908 }
5698 5909
5699 5910 /*
5700 5911 * Fetch the verify command, if any, from the brand configuration
5701 5912 * and build the command line to execute it.
5702 5913 */
5703 5914 strcpy(cmdbuf, EXEC_PREFIX);
5704 5915 err = brand_get_verify_cfg(bh, cmdbuf + EXEC_LEN,
5705 5916 sizeof (cmdbuf) - (EXEC_LEN + (strlen(xml_file) + 1)));
5706 5917 brand_close(bh);
5707 5918 if (err != Z_OK) {
5708 5919 zerr("%s: %s\n", zone,
5709 5920 gettext("could not get brand verification command"));
5710 5921 return (Z_INVALID_DOCUMENT);
5711 5922 }
5712 5923
5713 5924 /*
5714 5925 * If the brand doesn't provide a verification routine, we just
5715 5926 * return success.
5716 5927 */
5717 5928 if (strlen(cmdbuf) == EXEC_LEN)
5718 5929 return (Z_OK);
5719 5930
5720 5931 /*
5721 5932 * Dump the current config information for this zone to a file.
5722 5933 */
5723 5934 strcpy(xml_file, "/tmp/zonecfg_verify.XXXXXX");
5724 5935 if (mkstemp(xml_file) == NULL)
5725 5936 return (Z_TEMP_FILE);
5726 5937 if ((err = zonecfg_verify_save(handle, xml_file)) != Z_OK) {
5727 5938 (void) unlink(xml_file);
5728 5939 return (err);
5729 5940 }
5730 5941
5731 5942 /*
5732 5943 * Execute the verification command.
5733 5944 */
5734 5945 if ((strlcat(cmdbuf, " ", MAX_CMD_LEN) >= MAX_CMD_LEN) ||
5735 5946 (strlcat(cmdbuf, xml_file, MAX_CMD_LEN) >= MAX_CMD_LEN)) {
5736 5947 err = Z_BRAND_ERROR;
5737 5948 } else {
5738 5949 err = do_subproc(cmdbuf);
5739 5950 }
5740 5951
5741 5952 (void) unlink(xml_file);
5742 5953 return ((err == Z_OK) ? Z_OK : Z_BRAND_ERROR);
5743 5954 }
5744 5955
5745 5956 /*
5746 5957 * Track the network interfaces listed in zonecfg(1m) in a linked list
5747 5958 * so that we can later check that defrouter is specified for an exclusive IP
5748 5959 * zone if and only if at least one allowed-address has been specified.
5749 5960 */
5750 5961 static boolean_t
5751 5962 add_nwif(struct zone_nwiftab *nwif)
5752 5963 {
5753 5964 struct xif *tmp;
5754 5965
5755 5966 for (tmp = xif; tmp != NULL; tmp = tmp->xif_next) {
5756 5967 if (strcmp(tmp->xif_name, nwif->zone_nwif_physical) == 0) {
5757 5968 if (strlen(nwif->zone_nwif_allowed_address) > 0)
5758 5969 tmp->xif_has_address = B_TRUE;
5759 5970 if (strlen(nwif->zone_nwif_defrouter) > 0)
5760 5971 tmp->xif_has_defrouter = B_TRUE;
5761 5972 return (B_TRUE);
5762 5973 }
5763 5974 }
5764 5975
5765 5976 tmp = malloc(sizeof (*tmp));
5766 5977 if (tmp == NULL) {
5767 5978 zerr(gettext("memory allocation failed for %s"),
5768 5979 nwif->zone_nwif_physical);
5769 5980 return (B_FALSE);
↓ open down ↓ |
131 lines elided |
↑ open up ↑ |
5770 5981 }
5771 5982 strlcpy(tmp->xif_name, nwif->zone_nwif_physical,
5772 5983 sizeof (tmp->xif_name));
5773 5984 tmp->xif_has_defrouter = (strlen(nwif->zone_nwif_defrouter) > 0);
5774 5985 tmp->xif_has_address = (strlen(nwif->zone_nwif_allowed_address) > 0);
5775 5986 tmp->xif_next = xif;
5776 5987 xif = tmp;
5777 5988 return (B_TRUE);
5778 5989 }
5779 5990
5991 +boolean_t
5992 +verify_secflags(struct zone_secflagstab *tab)
5993 +{
5994 + secflagdelta_t def = {0};
5995 + secflagdelta_t upper = {0};
5996 + secflagdelta_t lower = {0};
5997 + boolean_t def_set = B_FALSE;
5998 + boolean_t upper_set = B_FALSE;
5999 + boolean_t lower_set = B_FALSE;
6000 + boolean_t ret = B_TRUE;
6001 +
6002 + if (strlen(tab->zone_secflags_default) > 0) {
6003 + def_set = B_TRUE;
6004 + if (secflags_parse(NULL, tab->zone_secflags_default,
6005 + &def) == -1) {
6006 + zerr(gettext("default security flags '%s' are invalid"),
6007 + tab->zone_secflags_default);
6008 + ret = B_FALSE;
6009 + }
6010 + } else {
6011 + secflags_zero(&def.psd_assign);
6012 + def.psd_ass_active = B_TRUE;
6013 + }
6014 +
6015 + if (strlen(tab->zone_secflags_upper) > 0) {
6016 + upper_set = B_TRUE;
6017 + if (secflags_parse(NULL, tab->zone_secflags_upper,
6018 + &upper) == -1) {
6019 + zerr(gettext("upper security flags '%s' are invalid"),
6020 + tab->zone_secflags_upper);
6021 + ret = B_FALSE;
6022 + }
6023 + } else {
6024 + secflags_fullset(&upper.psd_assign);
6025 + upper.psd_ass_active = B_TRUE;
6026 + }
6027 +
6028 + if (strlen(tab->zone_secflags_lower) > 0) {
6029 + lower_set = B_TRUE;
6030 + if (secflags_parse(NULL, tab->zone_secflags_lower,
6031 + &lower) == -1) {
6032 + zerr(gettext("lower security flags '%s' are invalid"),
6033 + tab->zone_secflags_lower);
6034 + ret = B_FALSE;
6035 + }
6036 + } else {
6037 + secflags_zero(&lower.psd_assign);
6038 + lower.psd_ass_active = B_TRUE;
6039 + }
6040 +
6041 + if (def_set && !def.psd_ass_active) {
6042 + zerr(gettext("only assignment of security flags is "
6043 + "allowed (default: %s)"), tab->zone_secflags_default);
6044 + }
6045 +
6046 + if (lower_set && !lower.psd_ass_active) {
6047 + zerr(gettext("only assignment of security flags is "
6048 + "allowed (lower: %s)"), tab->zone_secflags_lower);
6049 + }
6050 +
6051 + if (upper_set && !upper.psd_ass_active) {
6052 + zerr(gettext("only assignment of security flags is "
6053 + "allowed (upper: %s)"), tab->zone_secflags_upper);
6054 + }
6055 +
6056 + if (def.psd_assign & ~upper.psd_assign) { /* In default but not upper */
6057 + zerr(gettext("default secflags must be within the "
6058 + "upper limit"));
6059 + ret = B_FALSE;
6060 + }
6061 + if (lower.psd_assign & ~def.psd_assign) { /* In lower but not default */
6062 + zerr(gettext("default secflags must be above the lower limit"));
6063 + ret = B_FALSE;
6064 + }
6065 + if (lower.psd_assign & ~upper.psd_assign) { /* In lower but not upper */
6066 + zerr(gettext("lower secflags must be within the upper limit"));
6067 + ret = B_FALSE;
6068 + }
6069 +
6070 + return (ret);
6071 +}
6072 +
5780 6073 /*
5781 6074 * See the DTD for which attributes are required for which resources.
5782 6075 *
5783 6076 * This function can be called by commit_func(), which needs to save things,
5784 6077 * in addition to the general call from parse_and_run(), which doesn't need
5785 6078 * things saved. Since the parameters are standardized, we distinguish by
5786 6079 * having commit_func() call here with cmd->cmd_arg set to "save" to indicate
5787 6080 * that a save is needed.
5788 6081 */
5789 6082 void
5790 6083 verify_func(cmd_t *cmd)
5791 6084 {
5792 6085 struct zone_nwiftab nwiftab;
5793 6086 struct zone_fstab fstab;
5794 6087 struct zone_attrtab attrtab;
5795 6088 struct zone_rctltab rctltab;
5796 6089 struct zone_dstab dstab;
5797 6090 struct zone_psettab psettab;
5798 6091 struct zone_admintab admintab;
6092 + struct zone_secflagstab secflagstab;
5799 6093 char zonepath[MAXPATHLEN];
5800 6094 char sched[MAXNAMELEN];
5801 6095 char brand[MAXNAMELEN];
5802 6096 char hostidp[HW_HOSTID_LEN];
5803 6097 char fsallowedp[ZONE_FS_ALLOWED_MAX];
5804 6098 priv_set_t *privs;
5805 6099 char *privname = NULL;
5806 6100 int err, ret_val = Z_OK, arg;
5807 6101 int pset_res;
5808 6102 boolean_t save = B_FALSE;
5809 6103 boolean_t arg_err = B_FALSE;
5810 6104 zone_iptype_t iptype;
5811 6105 boolean_t has_cpu_shares = B_FALSE;
5812 6106 boolean_t has_cpu_cap = B_FALSE;
5813 6107 struct xif *tmp;
5814 6108
5815 6109 optind = 0;
5816 6110 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
5817 6111 switch (arg) {
5818 6112 case '?':
5819 6113 longer_usage(CMD_VERIFY);
5820 6114 arg_err = B_TRUE;
5821 6115 break;
5822 6116 default:
5823 6117 short_usage(CMD_VERIFY);
5824 6118 arg_err = B_TRUE;
5825 6119 break;
5826 6120 }
5827 6121 }
5828 6122 if (arg_err)
5829 6123 return;
5830 6124
5831 6125 if (optind > cmd->cmd_argc) {
5832 6126 short_usage(CMD_VERIFY);
5833 6127 return;
5834 6128 }
5835 6129
5836 6130 if (zone_is_read_only(CMD_VERIFY))
5837 6131 return;
5838 6132
5839 6133 assert(cmd != NULL);
5840 6134
5841 6135 if (cmd->cmd_argc > 0 && (strcmp(cmd->cmd_argv[0], "save") == 0))
5842 6136 save = B_TRUE;
5843 6137 if (initialize(B_TRUE) != Z_OK)
5844 6138 return;
5845 6139
5846 6140 if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) != Z_OK &&
5847 6141 !global_zone) {
5848 6142 zerr(gettext("%s not specified"), pt_to_str(PT_ZONEPATH));
5849 6143 ret_val = Z_REQD_RESOURCE_MISSING;
5850 6144 saw_error = B_TRUE;
5851 6145 }
5852 6146 if (strlen(zonepath) == 0 && !global_zone) {
5853 6147 zerr(gettext("%s cannot be empty."), pt_to_str(PT_ZONEPATH));
5854 6148 ret_val = Z_REQD_RESOURCE_MISSING;
5855 6149 saw_error = B_TRUE;
5856 6150 }
5857 6151
5858 6152 if ((err = zonecfg_get_brand(handle, brand, sizeof (brand))) != Z_OK) {
5859 6153 zone_perror(zone, err, B_TRUE);
5860 6154 return;
5861 6155 }
5862 6156 if ((err = brand_verify(handle)) != Z_OK) {
5863 6157 zone_perror(zone, err, B_TRUE);
5864 6158 return;
5865 6159 }
5866 6160
5867 6161 if (zonecfg_get_iptype(handle, &iptype) != Z_OK) {
5868 6162 zerr("%s %s", gettext("cannot get"), pt_to_str(PT_IPTYPE));
5869 6163 ret_val = Z_REQD_RESOURCE_MISSING;
5870 6164 saw_error = B_TRUE;
5871 6165 }
5872 6166
5873 6167 if ((privs = priv_allocset()) == NULL) {
5874 6168 zerr(gettext("%s: priv_allocset failed"), zone);
5875 6169 return;
5876 6170 }
5877 6171 if (zonecfg_get_privset(handle, privs, &privname) != Z_OK) {
5878 6172 zerr(gettext("%s: invalid privilege: %s"), zone, privname);
5879 6173 priv_freeset(privs);
5880 6174 free(privname);
5881 6175 return;
5882 6176 }
5883 6177 priv_freeset(privs);
5884 6178
5885 6179 if (zonecfg_get_hostid(handle, hostidp,
5886 6180 sizeof (hostidp)) == Z_INVALID_PROPERTY) {
5887 6181 zerr(gettext("%s: invalid hostid: %s"),
5888 6182 zone, hostidp);
5889 6183 return;
5890 6184 }
5891 6185
5892 6186 if (zonecfg_get_fs_allowed(handle, fsallowedp,
5893 6187 sizeof (fsallowedp)) == Z_INVALID_PROPERTY) {
5894 6188 zerr(gettext("%s: invalid fs-allowed: %s"),
5895 6189 zone, fsallowedp);
5896 6190 return;
5897 6191 }
5898 6192
5899 6193 if ((err = zonecfg_setfsent(handle)) != Z_OK) {
5900 6194 zone_perror(zone, err, B_TRUE);
5901 6195 return;
5902 6196 }
5903 6197 while (zonecfg_getfsent(handle, &fstab) == Z_OK) {
5904 6198 check_reqd_prop(fstab.zone_fs_dir, RT_FS, PT_DIR, &ret_val);
5905 6199 check_reqd_prop(fstab.zone_fs_special, RT_FS, PT_SPECIAL,
5906 6200 &ret_val);
5907 6201 check_reqd_prop(fstab.zone_fs_type, RT_FS, PT_TYPE, &ret_val);
5908 6202
5909 6203 zonecfg_free_fs_option_list(fstab.zone_fs_options);
5910 6204 }
5911 6205 (void) zonecfg_endfsent(handle);
5912 6206
5913 6207 if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
5914 6208 zone_perror(zone, err, B_TRUE);
5915 6209 return;
5916 6210 }
5917 6211 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
5918 6212 /*
5919 6213 * physical is required in all cases.
5920 6214 * A shared IP requires an address,
5921 6215 * and may include a default router, while
5922 6216 * an exclusive IP must have neither an address
5923 6217 * nor a default router.
5924 6218 * The physical interface name must be valid in all cases.
5925 6219 */
5926 6220 check_reqd_prop(nwiftab.zone_nwif_physical, RT_NET,
5927 6221 PT_PHYSICAL, &ret_val);
5928 6222 if (validate_net_physical_syntax(nwiftab.zone_nwif_physical) !=
5929 6223 Z_OK) {
5930 6224 saw_error = B_TRUE;
5931 6225 if (ret_val == Z_OK)
5932 6226 ret_val = Z_INVAL;
5933 6227 }
5934 6228
5935 6229 switch (iptype) {
5936 6230 case ZS_SHARED:
5937 6231 check_reqd_prop(nwiftab.zone_nwif_address, RT_NET,
5938 6232 PT_ADDRESS, &ret_val);
5939 6233 if (strlen(nwiftab.zone_nwif_allowed_address) > 0) {
5940 6234 zerr(gettext("%s: %s cannot be specified "
5941 6235 "for a shared IP type"),
5942 6236 rt_to_str(RT_NET),
5943 6237 pt_to_str(PT_ALLOWED_ADDRESS));
5944 6238 saw_error = B_TRUE;
5945 6239 if (ret_val == Z_OK)
5946 6240 ret_val = Z_INVAL;
5947 6241 }
5948 6242 break;
5949 6243 case ZS_EXCLUSIVE:
5950 6244 if (strlen(nwiftab.zone_nwif_address) > 0) {
5951 6245 zerr(gettext("%s: %s cannot be specified "
5952 6246 "for an exclusive IP type"),
5953 6247 rt_to_str(RT_NET), pt_to_str(PT_ADDRESS));
5954 6248 saw_error = B_TRUE;
5955 6249 if (ret_val == Z_OK)
5956 6250 ret_val = Z_INVAL;
5957 6251 } else {
5958 6252 if (!add_nwif(&nwiftab)) {
5959 6253 saw_error = B_TRUE;
5960 6254 if (ret_val == Z_OK)
5961 6255 ret_val = Z_INVAL;
5962 6256 }
5963 6257 }
5964 6258 break;
5965 6259 }
5966 6260 }
5967 6261 for (tmp = xif; tmp != NULL; tmp = tmp->xif_next) {
5968 6262 if (!tmp->xif_has_address && tmp->xif_has_defrouter) {
5969 6263 zerr(gettext("%s: %s for %s cannot be specified "
5970 6264 "without %s for an exclusive IP type"),
5971 6265 rt_to_str(RT_NET), pt_to_str(PT_DEFROUTER),
5972 6266 tmp->xif_name, pt_to_str(PT_ALLOWED_ADDRESS));
5973 6267 saw_error = B_TRUE;
5974 6268 ret_val = Z_INVAL;
5975 6269 }
5976 6270 }
5977 6271 free(xif);
5978 6272 xif = NULL;
5979 6273 (void) zonecfg_endnwifent(handle);
5980 6274
5981 6275 if ((err = zonecfg_setrctlent(handle)) != Z_OK) {
5982 6276 zone_perror(zone, err, B_TRUE);
5983 6277 return;
5984 6278 }
5985 6279 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
5986 6280 check_reqd_prop(rctltab.zone_rctl_name, RT_RCTL, PT_NAME,
5987 6281 &ret_val);
5988 6282
5989 6283 if (strcmp(rctltab.zone_rctl_name, "zone.cpu-shares") == 0)
5990 6284 has_cpu_shares = B_TRUE;
5991 6285
5992 6286 if (strcmp(rctltab.zone_rctl_name, "zone.cpu-cap") == 0)
5993 6287 has_cpu_cap = B_TRUE;
5994 6288
5995 6289 if (rctltab.zone_rctl_valptr == NULL) {
5996 6290 zerr(gettext("%s: no %s specified"),
5997 6291 rt_to_str(RT_RCTL), pt_to_str(PT_VALUE));
5998 6292 saw_error = B_TRUE;
5999 6293 if (ret_val == Z_OK)
6000 6294 ret_val = Z_REQD_PROPERTY_MISSING;
6001 6295 } else {
6002 6296 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
6003 6297 }
6004 6298 }
6005 6299 (void) zonecfg_endrctlent(handle);
6006 6300
6007 6301 if ((pset_res = zonecfg_lookup_pset(handle, &psettab)) == Z_OK &&
6008 6302 has_cpu_shares) {
6009 6303 zerr(gettext("%s zone.cpu-shares and %s are incompatible."),
6010 6304 rt_to_str(RT_RCTL), rt_to_str(RT_DCPU));
6011 6305 saw_error = B_TRUE;
6012 6306 if (ret_val == Z_OK)
6013 6307 ret_val = Z_INCOMPATIBLE;
6014 6308 }
6015 6309
6016 6310 if (has_cpu_shares && zonecfg_get_sched_class(handle, sched,
6017 6311 sizeof (sched)) == Z_OK && strlen(sched) > 0 &&
6018 6312 strcmp(sched, "FSS") != 0) {
6019 6313 zerr(gettext("WARNING: %s zone.cpu-shares and %s=%s are "
6020 6314 "incompatible"),
6021 6315 rt_to_str(RT_RCTL), rt_to_str(RT_SCHED), sched);
6022 6316 saw_error = B_TRUE;
6023 6317 if (ret_val == Z_OK)
6024 6318 ret_val = Z_INCOMPATIBLE;
6025 6319 }
6026 6320
6027 6321 if (pset_res == Z_OK && has_cpu_cap) {
6028 6322 zerr(gettext("%s zone.cpu-cap and the %s are incompatible."),
6029 6323 rt_to_str(RT_RCTL), rt_to_str(RT_DCPU));
6030 6324 saw_error = B_TRUE;
6031 6325 if (ret_val == Z_OK)
6032 6326 ret_val = Z_INCOMPATIBLE;
6033 6327 }
6034 6328
6035 6329 if ((err = zonecfg_setattrent(handle)) != Z_OK) {
6036 6330 zone_perror(zone, err, B_TRUE);
6037 6331 return;
6038 6332 }
6039 6333 while (zonecfg_getattrent(handle, &attrtab) == Z_OK) {
6040 6334 check_reqd_prop(attrtab.zone_attr_name, RT_ATTR, PT_NAME,
6041 6335 &ret_val);
6042 6336 check_reqd_prop(attrtab.zone_attr_type, RT_ATTR, PT_TYPE,
6043 6337 &ret_val);
6044 6338 check_reqd_prop(attrtab.zone_attr_value, RT_ATTR, PT_VALUE,
6045 6339 &ret_val);
6046 6340 }
6047 6341 (void) zonecfg_endattrent(handle);
6048 6342
6049 6343 if ((err = zonecfg_setdsent(handle)) != Z_OK) {
6050 6344 zone_perror(zone, err, B_TRUE);
6051 6345 return;
6052 6346 }
6053 6347 while (zonecfg_getdsent(handle, &dstab) == Z_OK) {
6054 6348 if (strlen(dstab.zone_dataset_name) == 0) {
6055 6349 zerr("%s: %s %s", rt_to_str(RT_DATASET),
6056 6350 pt_to_str(PT_NAME), gettext("not specified"));
6057 6351 saw_error = B_TRUE;
6058 6352 if (ret_val == Z_OK)
6059 6353 ret_val = Z_REQD_PROPERTY_MISSING;
6060 6354 } else if (!zfs_name_valid(dstab.zone_dataset_name,
6061 6355 ZFS_TYPE_FILESYSTEM)) {
6062 6356 zerr("%s: %s %s", rt_to_str(RT_DATASET),
6063 6357 pt_to_str(PT_NAME), gettext("invalid"));
6064 6358 saw_error = B_TRUE;
6065 6359 if (ret_val == Z_OK)
6066 6360 ret_val = Z_BAD_PROPERTY;
6067 6361 }
6068 6362
6069 6363 }
6070 6364 (void) zonecfg_enddsent(handle);
6071 6365
6072 6366 if ((err = zonecfg_setadminent(handle)) != Z_OK) {
6073 6367 zone_perror(zone, err, B_TRUE);
6074 6368 return;
6075 6369 }
6076 6370 while (zonecfg_getadminent(handle, &admintab) == Z_OK) {
6077 6371 check_reqd_prop(admintab.zone_admin_user, RT_ADMIN,
6078 6372 PT_USER, &ret_val);
6079 6373 check_reqd_prop(admintab.zone_admin_auths, RT_ADMIN,
6080 6374 PT_AUTHS, &ret_val);
6081 6375 if ((ret_val == Z_OK) && (getpwnam(admintab.zone_admin_user)
6082 6376 == NULL)) {
6083 6377 zerr(gettext("%s %s is not a valid username"),
6084 6378 pt_to_str(PT_USER),
↓ open down ↓ |
276 lines elided |
↑ open up ↑ |
6085 6379 admintab.zone_admin_user);
6086 6380 ret_val = Z_BAD_PROPERTY;
6087 6381 }
6088 6382 if ((ret_val == Z_OK) && (!zonecfg_valid_auths(
6089 6383 admintab.zone_admin_auths, zone))) {
6090 6384 ret_val = Z_BAD_PROPERTY;
6091 6385 }
6092 6386 }
6093 6387 (void) zonecfg_endadminent(handle);
6094 6388
6389 + if (zonecfg_getsecflagsent(handle, &secflagstab) == Z_OK) {
6390 + /*
6391 + * No properties are required, but any specified should be
6392 + * valid
6393 + */
6394 + if (verify_secflags(&secflagstab) != B_TRUE) {
6395 + /* Error is reported from verify_secflags */
6396 + ret_val = Z_BAD_PROPERTY;
6397 + }
6398 + }
6399 +
6095 6400 if (!global_scope) {
6096 6401 zerr(gettext("resource specification incomplete"));
6097 6402 saw_error = B_TRUE;
6098 6403 if (ret_val == Z_OK)
6099 6404 ret_val = Z_INSUFFICIENT_SPEC;
6100 6405 }
6101 6406
6102 6407 if (save) {
6103 6408 if (ret_val == Z_OK) {
6104 6409 if ((ret_val = zonecfg_save(handle)) == Z_OK) {
6105 6410 need_to_commit = B_FALSE;
6106 6411 (void) strlcpy(revert_zone, zone,
6107 6412 sizeof (revert_zone));
6108 6413 }
6109 6414 } else {
6110 6415 zerr(gettext("Zone %s failed to verify"), zone);
6111 6416 }
6112 6417 }
6113 6418 if (ret_val != Z_OK)
6114 6419 zone_perror(zone, ret_val, B_TRUE);
6115 6420 }
6116 6421
6117 6422 void
6118 6423 cancel_func(cmd_t *cmd)
6119 6424 {
6120 6425 int arg;
6121 6426 boolean_t arg_err = B_FALSE;
6122 6427
6123 6428 assert(cmd != NULL);
6124 6429
6125 6430 optind = 0;
6126 6431 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
6127 6432 switch (arg) {
6128 6433 case '?':
6129 6434 longer_usage(CMD_CANCEL);
6130 6435 arg_err = B_TRUE;
6131 6436 break;
6132 6437 default:
6133 6438 short_usage(CMD_CANCEL);
6134 6439 arg_err = B_TRUE;
6135 6440 break;
6136 6441 }
6137 6442 }
6138 6443 if (arg_err)
6139 6444 return;
6140 6445
6141 6446 if (optind != cmd->cmd_argc) {
6142 6447 short_usage(CMD_CANCEL);
6143 6448 return;
6144 6449 }
6145 6450
6146 6451 if (global_scope)
6147 6452 scope_usage(CMD_CANCEL);
6148 6453 global_scope = B_TRUE;
6149 6454 zonecfg_free_fs_option_list(in_progress_fstab.zone_fs_options);
6150 6455 bzero(&in_progress_fstab, sizeof (in_progress_fstab));
6151 6456 bzero(&in_progress_nwiftab, sizeof (in_progress_nwiftab));
6152 6457 bzero(&in_progress_devtab, sizeof (in_progress_devtab));
6153 6458 zonecfg_free_rctl_value_list(in_progress_rctltab.zone_rctl_valptr);
6154 6459 bzero(&in_progress_rctltab, sizeof (in_progress_rctltab));
6155 6460 bzero(&in_progress_attrtab, sizeof (in_progress_attrtab));
6156 6461 bzero(&in_progress_dstab, sizeof (in_progress_dstab));
6157 6462 }
6158 6463
6159 6464 static int
6160 6465 validate_attr_name(char *name)
6161 6466 {
6162 6467 int i;
6163 6468
6164 6469 if (!isalnum(name[0])) {
6165 6470 zerr(gettext("Invalid %s %s %s: must start with an alpha-"
6166 6471 "numeric character."), rt_to_str(RT_ATTR),
6167 6472 pt_to_str(PT_NAME), name);
6168 6473 return (Z_INVAL);
6169 6474 }
6170 6475 for (i = 1; name[i]; i++)
6171 6476 if (!isalnum(name[i]) && name[i] != '-' && name[i] != '.') {
6172 6477 zerr(gettext("Invalid %s %s %s: can only contain "
6173 6478 "alpha-numeric characters, plus '-' and '.'."),
6174 6479 rt_to_str(RT_ATTR), pt_to_str(PT_NAME), name);
6175 6480 return (Z_INVAL);
6176 6481 }
6177 6482 return (Z_OK);
6178 6483 }
6179 6484
6180 6485 static int
6181 6486 validate_attr_type_val(struct zone_attrtab *attrtab)
6182 6487 {
6183 6488 boolean_t boolval;
6184 6489 int64_t intval;
6185 6490 char strval[MAXNAMELEN];
6186 6491 uint64_t uintval;
6187 6492
6188 6493 if (strcmp(attrtab->zone_attr_type, "boolean") == 0) {
6189 6494 if (zonecfg_get_attr_boolean(attrtab, &boolval) == Z_OK)
6190 6495 return (Z_OK);
6191 6496 zerr(gettext("invalid %s value for %s=%s"),
6192 6497 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "boolean");
6193 6498 return (Z_ERR);
6194 6499 }
6195 6500
6196 6501 if (strcmp(attrtab->zone_attr_type, "int") == 0) {
6197 6502 if (zonecfg_get_attr_int(attrtab, &intval) == Z_OK)
6198 6503 return (Z_OK);
6199 6504 zerr(gettext("invalid %s value for %s=%s"),
6200 6505 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "int");
6201 6506 return (Z_ERR);
6202 6507 }
6203 6508
6204 6509 if (strcmp(attrtab->zone_attr_type, "string") == 0) {
6205 6510 if (zonecfg_get_attr_string(attrtab, strval,
6206 6511 sizeof (strval)) == Z_OK)
6207 6512 return (Z_OK);
6208 6513 zerr(gettext("invalid %s value for %s=%s"),
6209 6514 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "string");
6210 6515 return (Z_ERR);
6211 6516 }
6212 6517
6213 6518 if (strcmp(attrtab->zone_attr_type, "uint") == 0) {
6214 6519 if (zonecfg_get_attr_uint(attrtab, &uintval) == Z_OK)
6215 6520 return (Z_OK);
6216 6521 zerr(gettext("invalid %s value for %s=%s"),
6217 6522 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "uint");
6218 6523 return (Z_ERR);
6219 6524 }
6220 6525
6221 6526 zerr(gettext("invalid %s %s '%s'"), rt_to_str(RT_ATTR),
6222 6527 pt_to_str(PT_TYPE), attrtab->zone_attr_type);
6223 6528 return (Z_ERR);
6224 6529 }
6225 6530
6226 6531 /*
6227 6532 * Helper function for end_func-- checks the existence of a given property
6228 6533 * and emits a message if not specified.
6229 6534 */
6230 6535 static int
6231 6536 end_check_reqd(char *attr, int pt, boolean_t *validation_failed)
6232 6537 {
6233 6538 if (strlen(attr) == 0) {
6234 6539 *validation_failed = B_TRUE;
6235 6540 zerr(gettext("%s not specified"), pt_to_str(pt));
6236 6541 return (Z_ERR);
6237 6542 }
6238 6543 return (Z_OK);
6239 6544 }
6240 6545
6241 6546 static void
6242 6547 net_exists_error(struct zone_nwiftab nwif)
6243 6548 {
6244 6549 if (strlen(nwif.zone_nwif_address) > 0) {
6245 6550 zerr(gettext("A %s resource with the %s '%s', "
6246 6551 "and %s '%s' already exists."),
6247 6552 rt_to_str(RT_NET),
6248 6553 pt_to_str(PT_PHYSICAL),
6249 6554 nwif.zone_nwif_physical,
6250 6555 pt_to_str(PT_ADDRESS),
6251 6556 in_progress_nwiftab.zone_nwif_address);
6252 6557 } else {
6253 6558 zerr(gettext("A %s resource with the %s '%s', "
6254 6559 "and %s '%s' already exists."),
6255 6560 rt_to_str(RT_NET),
6256 6561 pt_to_str(PT_PHYSICAL),
6257 6562 nwif.zone_nwif_physical,
6258 6563 pt_to_str(PT_ALLOWED_ADDRESS),
6259 6564 nwif.zone_nwif_allowed_address);
6260 6565 }
6261 6566 }
6262 6567
6263 6568 void
6264 6569 end_func(cmd_t *cmd)
6265 6570 {
6266 6571 boolean_t validation_failed = B_FALSE;
6267 6572 boolean_t arg_err = B_FALSE;
6268 6573 struct zone_fstab tmp_fstab;
6269 6574 struct zone_nwiftab tmp_nwiftab;
6270 6575 struct zone_devtab tmp_devtab;
6271 6576 struct zone_rctltab tmp_rctltab;
6272 6577 struct zone_attrtab tmp_attrtab;
6273 6578 struct zone_dstab tmp_dstab;
6274 6579 struct zone_admintab tmp_admintab;
6275 6580 int err, arg, res1, res2, res3;
6276 6581 uint64_t swap_limit;
6277 6582 uint64_t locked_limit;
6278 6583 uint64_t proc_cap;
6279 6584
6280 6585 assert(cmd != NULL);
6281 6586
6282 6587 optind = 0;
6283 6588 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
6284 6589 switch (arg) {
6285 6590 case '?':
6286 6591 longer_usage(CMD_END);
6287 6592 arg_err = B_TRUE;
6288 6593 break;
6289 6594 default:
6290 6595 short_usage(CMD_END);
6291 6596 arg_err = B_TRUE;
6292 6597 break;
6293 6598 }
6294 6599 }
6295 6600 if (arg_err)
6296 6601 return;
6297 6602
6298 6603 if (optind != cmd->cmd_argc) {
6299 6604 short_usage(CMD_END);
6300 6605 return;
6301 6606 }
6302 6607
6303 6608 if (global_scope) {
6304 6609 scope_usage(CMD_END);
6305 6610 return;
6306 6611 }
6307 6612
6308 6613 assert(end_op == CMD_ADD || end_op == CMD_SELECT);
6309 6614
6310 6615 switch (resource_scope) {
6311 6616 case RT_FS:
6312 6617 /* First make sure everything was filled in. */
6313 6618 if (end_check_reqd(in_progress_fstab.zone_fs_dir,
6314 6619 PT_DIR, &validation_failed) == Z_OK) {
6315 6620 if (in_progress_fstab.zone_fs_dir[0] != '/') {
6316 6621 zerr(gettext("%s %s is not an absolute path."),
6317 6622 pt_to_str(PT_DIR),
6318 6623 in_progress_fstab.zone_fs_dir);
6319 6624 validation_failed = B_TRUE;
6320 6625 }
6321 6626 }
6322 6627
6323 6628 (void) end_check_reqd(in_progress_fstab.zone_fs_special,
6324 6629 PT_SPECIAL, &validation_failed);
6325 6630
6326 6631 if (in_progress_fstab.zone_fs_raw[0] != '\0' &&
6327 6632 in_progress_fstab.zone_fs_raw[0] != '/') {
6328 6633 zerr(gettext("%s %s is not an absolute path."),
6329 6634 pt_to_str(PT_RAW),
6330 6635 in_progress_fstab.zone_fs_raw);
6331 6636 validation_failed = B_TRUE;
6332 6637 }
6333 6638
6334 6639 (void) end_check_reqd(in_progress_fstab.zone_fs_type, PT_TYPE,
6335 6640 &validation_failed);
6336 6641
6337 6642 if (validation_failed) {
6338 6643 saw_error = B_TRUE;
6339 6644 return;
6340 6645 }
6341 6646
6342 6647 if (end_op == CMD_ADD) {
6343 6648 /* Make sure there isn't already one like this. */
6344 6649 bzero(&tmp_fstab, sizeof (tmp_fstab));
6345 6650 (void) strlcpy(tmp_fstab.zone_fs_dir,
6346 6651 in_progress_fstab.zone_fs_dir,
6347 6652 sizeof (tmp_fstab.zone_fs_dir));
6348 6653 err = zonecfg_lookup_filesystem(handle, &tmp_fstab);
6349 6654 zonecfg_free_fs_option_list(tmp_fstab.zone_fs_options);
6350 6655 if (err == Z_OK) {
6351 6656 zerr(gettext("A %s resource "
6352 6657 "with the %s '%s' already exists."),
6353 6658 rt_to_str(RT_FS), pt_to_str(PT_DIR),
6354 6659 in_progress_fstab.zone_fs_dir);
6355 6660 saw_error = B_TRUE;
6356 6661 return;
6357 6662 }
6358 6663 err = zonecfg_add_filesystem(handle,
6359 6664 &in_progress_fstab);
6360 6665 } else {
6361 6666 err = zonecfg_modify_filesystem(handle, &old_fstab,
6362 6667 &in_progress_fstab);
6363 6668 }
6364 6669 zonecfg_free_fs_option_list(in_progress_fstab.zone_fs_options);
6365 6670 in_progress_fstab.zone_fs_options = NULL;
6366 6671 break;
6367 6672
6368 6673 case RT_NET:
6369 6674 /*
6370 6675 * First make sure everything was filled in.
6371 6676 * Since we don't know whether IP will be shared
6372 6677 * or exclusive here, some checks are deferred until
6373 6678 * the verify command.
6374 6679 */
6375 6680 (void) end_check_reqd(in_progress_nwiftab.zone_nwif_physical,
6376 6681 PT_PHYSICAL, &validation_failed);
6377 6682
6378 6683 if (validation_failed) {
6379 6684 saw_error = B_TRUE;
6380 6685 return;
6381 6686 }
6382 6687 if (end_op == CMD_ADD) {
6383 6688 /* Make sure there isn't already one like this. */
6384 6689 bzero(&tmp_nwiftab, sizeof (tmp_nwiftab));
6385 6690 (void) strlcpy(tmp_nwiftab.zone_nwif_physical,
6386 6691 in_progress_nwiftab.zone_nwif_physical,
6387 6692 sizeof (tmp_nwiftab.zone_nwif_physical));
6388 6693 (void) strlcpy(tmp_nwiftab.zone_nwif_address,
6389 6694 in_progress_nwiftab.zone_nwif_address,
6390 6695 sizeof (tmp_nwiftab.zone_nwif_address));
6391 6696 (void) strlcpy(tmp_nwiftab.zone_nwif_allowed_address,
6392 6697 in_progress_nwiftab.zone_nwif_allowed_address,
6393 6698 sizeof (tmp_nwiftab.zone_nwif_allowed_address));
6394 6699 (void) strlcpy(tmp_nwiftab.zone_nwif_defrouter,
6395 6700 in_progress_nwiftab.zone_nwif_defrouter,
6396 6701 sizeof (tmp_nwiftab.zone_nwif_defrouter));
6397 6702 if (zonecfg_lookup_nwif(handle, &tmp_nwiftab) == Z_OK) {
6398 6703 net_exists_error(in_progress_nwiftab);
6399 6704 saw_error = B_TRUE;
6400 6705 return;
6401 6706 }
6402 6707 err = zonecfg_add_nwif(handle, &in_progress_nwiftab);
6403 6708 } else {
6404 6709 err = zonecfg_modify_nwif(handle, &old_nwiftab,
6405 6710 &in_progress_nwiftab);
6406 6711 }
6407 6712 break;
6408 6713
6409 6714 case RT_DEVICE:
6410 6715 /* First make sure everything was filled in. */
6411 6716 (void) end_check_reqd(in_progress_devtab.zone_dev_match,
6412 6717 PT_MATCH, &validation_failed);
6413 6718
6414 6719 if (validation_failed) {
6415 6720 saw_error = B_TRUE;
6416 6721 return;
6417 6722 }
6418 6723
6419 6724 if (end_op == CMD_ADD) {
6420 6725 /* Make sure there isn't already one like this. */
6421 6726 (void) strlcpy(tmp_devtab.zone_dev_match,
6422 6727 in_progress_devtab.zone_dev_match,
6423 6728 sizeof (tmp_devtab.zone_dev_match));
6424 6729 if (zonecfg_lookup_dev(handle, &tmp_devtab) == Z_OK) {
6425 6730 zerr(gettext("A %s resource with the %s '%s' "
6426 6731 "already exists."), rt_to_str(RT_DEVICE),
6427 6732 pt_to_str(PT_MATCH),
6428 6733 in_progress_devtab.zone_dev_match);
6429 6734 saw_error = B_TRUE;
6430 6735 return;
6431 6736 }
6432 6737 err = zonecfg_add_dev(handle, &in_progress_devtab);
6433 6738 } else {
6434 6739 err = zonecfg_modify_dev(handle, &old_devtab,
6435 6740 &in_progress_devtab);
6436 6741 }
6437 6742 break;
6438 6743
6439 6744 case RT_RCTL:
6440 6745 /* First make sure everything was filled in. */
6441 6746 (void) end_check_reqd(in_progress_rctltab.zone_rctl_name,
6442 6747 PT_NAME, &validation_failed);
6443 6748
6444 6749 if (in_progress_rctltab.zone_rctl_valptr == NULL) {
6445 6750 zerr(gettext("no %s specified"), pt_to_str(PT_VALUE));
6446 6751 validation_failed = B_TRUE;
6447 6752 }
6448 6753
6449 6754 if (validation_failed) {
6450 6755 saw_error = B_TRUE;
6451 6756 return;
6452 6757 }
6453 6758
6454 6759 if (end_op == CMD_ADD) {
6455 6760 /* Make sure there isn't already one like this. */
6456 6761 (void) strlcpy(tmp_rctltab.zone_rctl_name,
6457 6762 in_progress_rctltab.zone_rctl_name,
6458 6763 sizeof (tmp_rctltab.zone_rctl_name));
6459 6764 tmp_rctltab.zone_rctl_valptr = NULL;
6460 6765 err = zonecfg_lookup_rctl(handle, &tmp_rctltab);
6461 6766 zonecfg_free_rctl_value_list(
6462 6767 tmp_rctltab.zone_rctl_valptr);
6463 6768 if (err == Z_OK) {
6464 6769 zerr(gettext("A %s resource "
6465 6770 "with the %s '%s' already exists."),
6466 6771 rt_to_str(RT_RCTL), pt_to_str(PT_NAME),
6467 6772 in_progress_rctltab.zone_rctl_name);
6468 6773 saw_error = B_TRUE;
6469 6774 return;
6470 6775 }
6471 6776 err = zonecfg_add_rctl(handle, &in_progress_rctltab);
6472 6777 } else {
6473 6778 err = zonecfg_modify_rctl(handle, &old_rctltab,
6474 6779 &in_progress_rctltab);
6475 6780 }
6476 6781 if (err == Z_OK) {
6477 6782 zonecfg_free_rctl_value_list(
6478 6783 in_progress_rctltab.zone_rctl_valptr);
6479 6784 in_progress_rctltab.zone_rctl_valptr = NULL;
6480 6785 }
6481 6786 break;
6482 6787
6483 6788 case RT_ATTR:
6484 6789 /* First make sure everything was filled in. */
6485 6790 (void) end_check_reqd(in_progress_attrtab.zone_attr_name,
6486 6791 PT_NAME, &validation_failed);
6487 6792 (void) end_check_reqd(in_progress_attrtab.zone_attr_type,
6488 6793 PT_TYPE, &validation_failed);
6489 6794 (void) end_check_reqd(in_progress_attrtab.zone_attr_value,
6490 6795 PT_VALUE, &validation_failed);
6491 6796
6492 6797 if (validate_attr_name(in_progress_attrtab.zone_attr_name) !=
6493 6798 Z_OK)
6494 6799 validation_failed = B_TRUE;
6495 6800
6496 6801 if (validate_attr_type_val(&in_progress_attrtab) != Z_OK)
6497 6802 validation_failed = B_TRUE;
6498 6803
6499 6804 if (validation_failed) {
6500 6805 saw_error = B_TRUE;
6501 6806 return;
6502 6807 }
6503 6808 if (end_op == CMD_ADD) {
6504 6809 /* Make sure there isn't already one like this. */
6505 6810 bzero(&tmp_attrtab, sizeof (tmp_attrtab));
6506 6811 (void) strlcpy(tmp_attrtab.zone_attr_name,
6507 6812 in_progress_attrtab.zone_attr_name,
6508 6813 sizeof (tmp_attrtab.zone_attr_name));
6509 6814 if (zonecfg_lookup_attr(handle, &tmp_attrtab) == Z_OK) {
6510 6815 zerr(gettext("An %s resource "
6511 6816 "with the %s '%s' already exists."),
6512 6817 rt_to_str(RT_ATTR), pt_to_str(PT_NAME),
6513 6818 in_progress_attrtab.zone_attr_name);
6514 6819 saw_error = B_TRUE;
6515 6820 return;
6516 6821 }
6517 6822 err = zonecfg_add_attr(handle, &in_progress_attrtab);
6518 6823 } else {
6519 6824 err = zonecfg_modify_attr(handle, &old_attrtab,
6520 6825 &in_progress_attrtab);
6521 6826 }
6522 6827 break;
6523 6828 case RT_DATASET:
6524 6829 /* First make sure everything was filled in. */
6525 6830 if (strlen(in_progress_dstab.zone_dataset_name) == 0) {
6526 6831 zerr("%s %s", pt_to_str(PT_NAME),
6527 6832 gettext("not specified"));
6528 6833 saw_error = B_TRUE;
6529 6834 validation_failed = B_TRUE;
6530 6835 }
6531 6836 if (validation_failed)
6532 6837 return;
6533 6838 if (end_op == CMD_ADD) {
6534 6839 /* Make sure there isn't already one like this. */
6535 6840 bzero(&tmp_dstab, sizeof (tmp_dstab));
6536 6841 (void) strlcpy(tmp_dstab.zone_dataset_name,
6537 6842 in_progress_dstab.zone_dataset_name,
6538 6843 sizeof (tmp_dstab.zone_dataset_name));
6539 6844 err = zonecfg_lookup_ds(handle, &tmp_dstab);
6540 6845 if (err == Z_OK) {
6541 6846 zerr(gettext("A %s resource "
6542 6847 "with the %s '%s' already exists."),
6543 6848 rt_to_str(RT_DATASET), pt_to_str(PT_NAME),
6544 6849 in_progress_dstab.zone_dataset_name);
6545 6850 saw_error = B_TRUE;
6546 6851 return;
6547 6852 }
6548 6853 err = zonecfg_add_ds(handle, &in_progress_dstab);
6549 6854 } else {
6550 6855 err = zonecfg_modify_ds(handle, &old_dstab,
6551 6856 &in_progress_dstab);
6552 6857 }
6553 6858 break;
6554 6859 case RT_DCPU:
6555 6860 /* Make sure everything was filled in. */
6556 6861 if (end_check_reqd(in_progress_psettab.zone_ncpu_min,
6557 6862 PT_NCPUS, &validation_failed) != Z_OK) {
6558 6863 saw_error = B_TRUE;
6559 6864 return;
6560 6865 }
6561 6866
6562 6867 if (end_op == CMD_ADD) {
6563 6868 err = zonecfg_add_pset(handle, &in_progress_psettab);
6564 6869 } else {
6565 6870 err = zonecfg_modify_pset(handle, &in_progress_psettab);
6566 6871 }
6567 6872 break;
6568 6873 case RT_PCAP:
6569 6874 /* Make sure everything was filled in. */
6570 6875 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &proc_cap)
6571 6876 != Z_OK) {
6572 6877 zerr(gettext("%s not specified"), pt_to_str(PT_NCPUS));
6573 6878 saw_error = B_TRUE;
6574 6879 validation_failed = B_TRUE;
6575 6880 return;
6576 6881 }
6577 6882 err = Z_OK;
6578 6883 break;
6579 6884 case RT_MCAP:
6580 6885 /* Make sure everything was filled in. */
6581 6886 res1 = strlen(in_progress_mcaptab.zone_physmem_cap) == 0 ?
6582 6887 Z_ERR : Z_OK;
6583 6888 res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP,
6584 6889 &swap_limit);
6585 6890 res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM,
6586 6891 &locked_limit);
6587 6892
6588 6893 if (res1 != Z_OK && res2 != Z_OK && res3 != Z_OK) {
6589 6894 zerr(gettext("No property was specified. One of %s, "
6590 6895 "%s or %s is required."), pt_to_str(PT_PHYSICAL),
6591 6896 pt_to_str(PT_SWAP), pt_to_str(PT_LOCKED));
6592 6897 saw_error = B_TRUE;
6593 6898 return;
6594 6899 }
6595 6900
6596 6901 /* if phys & locked are both set, verify locked <= phys */
6597 6902 if (res1 == Z_OK && res3 == Z_OK) {
6598 6903 uint64_t phys_limit;
6599 6904 char *endp;
6600 6905
6601 6906 phys_limit = strtoull(
6602 6907 in_progress_mcaptab.zone_physmem_cap, &endp, 10);
6603 6908 if (phys_limit < locked_limit) {
6604 6909 zerr(gettext("The %s cap must be less than or "
6605 6910 "equal to the %s cap."),
6606 6911 pt_to_str(PT_LOCKED),
6607 6912 pt_to_str(PT_PHYSICAL));
6608 6913 saw_error = B_TRUE;
6609 6914 return;
6610 6915 }
6611 6916 }
6612 6917
6613 6918 err = Z_OK;
6614 6919 if (res1 == Z_OK) {
6615 6920 /*
6616 6921 * We could be ending from either an add operation
6617 6922 * or a select operation. Since all of the properties
6618 6923 * within this resource are optional, we always use
6619 6924 * modify on the mcap entry. zonecfg_modify_mcap()
6620 6925 * will handle both adding and modifying a memory cap.
6621 6926 */
6622 6927 err = zonecfg_modify_mcap(handle, &in_progress_mcaptab);
6623 6928 } else if (end_op == CMD_SELECT) {
6624 6929 /*
6625 6930 * If we're ending from a select and the physical
6626 6931 * memory cap is empty then the user could have cleared
6627 6932 * the physical cap value, so try to delete the entry.
6628 6933 */
6629 6934 (void) zonecfg_delete_mcap(handle);
6630 6935 }
6631 6936 break;
6632 6937 case RT_ADMIN:
6633 6938 /* First make sure everything was filled in. */
6634 6939 if (end_check_reqd(in_progress_admintab.zone_admin_user,
6635 6940 PT_USER, &validation_failed) == Z_OK) {
6636 6941 if (getpwnam(in_progress_admintab.zone_admin_user)
6637 6942 == NULL) {
6638 6943 zerr(gettext("%s %s is not a valid username"),
6639 6944 pt_to_str(PT_USER),
6640 6945 in_progress_admintab.zone_admin_user);
6641 6946 validation_failed = B_TRUE;
6642 6947 }
6643 6948 }
6644 6949
6645 6950 if (end_check_reqd(in_progress_admintab.zone_admin_auths,
6646 6951 PT_AUTHS, &validation_failed) == Z_OK) {
6647 6952 if (!zonecfg_valid_auths(
6648 6953 in_progress_admintab.zone_admin_auths,
6649 6954 zone)) {
6650 6955 validation_failed = B_TRUE;
6651 6956 }
6652 6957 }
6653 6958
6654 6959 if (validation_failed) {
6655 6960 saw_error = B_TRUE;
6656 6961 return;
6657 6962 }
6658 6963
6659 6964 if (end_op == CMD_ADD) {
6660 6965 /* Make sure there isn't already one like this. */
6661 6966 bzero(&tmp_admintab, sizeof (tmp_admintab));
6662 6967 (void) strlcpy(tmp_admintab.zone_admin_user,
6663 6968 in_progress_admintab.zone_admin_user,
6664 6969 sizeof (tmp_admintab.zone_admin_user));
6665 6970 err = zonecfg_lookup_admin(
6666 6971 handle, &tmp_admintab);
6667 6972 if (err == Z_OK) {
6668 6973 zerr(gettext("A %s resource "
6669 6974 "with the %s '%s' already exists."),
6670 6975 rt_to_str(RT_ADMIN),
6671 6976 pt_to_str(PT_USER),
6672 6977 in_progress_admintab.zone_admin_user);
6673 6978 saw_error = B_TRUE;
↓ open down ↓ |
569 lines elided |
↑ open up ↑ |
6674 6979 return;
6675 6980 }
6676 6981 err = zonecfg_add_admin(handle,
6677 6982 &in_progress_admintab, zone);
6678 6983 } else {
6679 6984 err = zonecfg_modify_admin(handle,
6680 6985 &old_admintab, &in_progress_admintab,
6681 6986 zone);
6682 6987 }
6683 6988 break;
6989 + case RT_SECFLAGS:
6990 + if (verify_secflags(&in_progress_secflagstab) != B_TRUE) {
6991 + saw_error = B_TRUE;
6992 + return;
6993 + }
6994 +
6995 + if (end_op == CMD_ADD) {
6996 + err = zonecfg_add_secflags(handle,
6997 + &in_progress_secflagstab);
6998 + } else {
6999 + err = zonecfg_modify_secflags(handle,
7000 + &old_secflagstab, &in_progress_secflagstab);
7001 + }
7002 + break;
6684 7003 default:
6685 7004 zone_perror(rt_to_str(resource_scope), Z_NO_RESOURCE_TYPE,
6686 7005 B_TRUE);
6687 7006 saw_error = B_TRUE;
6688 7007 return;
6689 7008 }
6690 7009
6691 7010 if (err != Z_OK) {
6692 7011 zone_perror(zone, err, B_TRUE);
6693 7012 } else {
6694 7013 need_to_commit = B_TRUE;
6695 7014 global_scope = B_TRUE;
6696 7015 end_op = -1;
6697 7016 }
6698 7017 }
6699 7018
6700 7019 void
6701 7020 commit_func(cmd_t *cmd)
6702 7021 {
6703 7022 int arg;
6704 7023 boolean_t arg_err = B_FALSE;
6705 7024
6706 7025 optind = 0;
6707 7026 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
6708 7027 switch (arg) {
6709 7028 case '?':
6710 7029 longer_usage(CMD_COMMIT);
6711 7030 arg_err = B_TRUE;
6712 7031 break;
6713 7032 default:
6714 7033 short_usage(CMD_COMMIT);
6715 7034 arg_err = B_TRUE;
6716 7035 break;
6717 7036 }
6718 7037 }
6719 7038 if (arg_err)
6720 7039 return;
6721 7040
6722 7041 if (optind != cmd->cmd_argc) {
6723 7042 short_usage(CMD_COMMIT);
6724 7043 return;
6725 7044 }
6726 7045
6727 7046 if (zone_is_read_only(CMD_COMMIT))
6728 7047 return;
6729 7048
6730 7049 assert(cmd != NULL);
6731 7050
6732 7051 cmd->cmd_argc = 1;
6733 7052 /*
6734 7053 * cmd_arg normally comes from a strdup() in the lexer, and the
6735 7054 * whole cmd structure and its (char *) attributes are freed at
6736 7055 * the completion of each command, so the strdup() below is needed
6737 7056 * to match this and prevent a core dump from trying to free()
6738 7057 * something that can't be.
6739 7058 */
6740 7059 if ((cmd->cmd_argv[0] = strdup("save")) == NULL) {
6741 7060 zone_perror(zone, Z_NOMEM, B_TRUE);
6742 7061 exit(Z_ERR);
6743 7062 }
6744 7063 cmd->cmd_argv[1] = NULL;
6745 7064 verify_func(cmd);
6746 7065 }
6747 7066
6748 7067 void
6749 7068 revert_func(cmd_t *cmd)
6750 7069 {
6751 7070 char line[128]; /* enough to ask a question */
6752 7071 boolean_t force = B_FALSE;
6753 7072 boolean_t arg_err = B_FALSE;
6754 7073 int err, arg, answer;
6755 7074
6756 7075 optind = 0;
6757 7076 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
6758 7077 switch (arg) {
6759 7078 case '?':
6760 7079 longer_usage(CMD_REVERT);
6761 7080 arg_err = B_TRUE;
6762 7081 break;
6763 7082 case 'F':
6764 7083 force = B_TRUE;
6765 7084 break;
6766 7085 default:
6767 7086 short_usage(CMD_REVERT);
6768 7087 arg_err = B_TRUE;
6769 7088 break;
6770 7089 }
6771 7090 }
6772 7091 if (arg_err)
6773 7092 return;
6774 7093
6775 7094 if (optind != cmd->cmd_argc) {
6776 7095 short_usage(CMD_REVERT);
6777 7096 return;
6778 7097 }
6779 7098
6780 7099 if (zone_is_read_only(CMD_REVERT))
6781 7100 return;
6782 7101
6783 7102 if (!global_scope) {
6784 7103 zerr(gettext("You can only use %s in the global scope.\nUse"
6785 7104 " '%s' to cancel changes to a resource specification."),
6786 7105 cmd_to_str(CMD_REVERT), cmd_to_str(CMD_CANCEL));
6787 7106 saw_error = B_TRUE;
6788 7107 return;
6789 7108 }
6790 7109
6791 7110 if (zonecfg_check_handle(handle) != Z_OK) {
6792 7111 zerr(gettext("No changes to revert."));
6793 7112 saw_error = B_TRUE;
6794 7113 return;
6795 7114 }
6796 7115
6797 7116 if (!force) {
6798 7117 (void) snprintf(line, sizeof (line),
6799 7118 gettext("Are you sure you want to revert"));
6800 7119 if ((answer = ask_yesno(B_FALSE, line)) == -1) {
6801 7120 zerr(gettext("Input not from terminal and -F not "
6802 7121 "specified:\n%s command ignored, exiting."),
6803 7122 cmd_to_str(CMD_REVERT));
6804 7123 exit(Z_ERR);
6805 7124 }
6806 7125 if (answer != 1)
6807 7126 return;
6808 7127 }
6809 7128
6810 7129 /*
6811 7130 * Reset any pending admins that were
6812 7131 * removed from the previous zone
6813 7132 */
6814 7133 zonecfg_remove_userauths(handle, "", zone, B_FALSE);
6815 7134
6816 7135 /*
6817 7136 * Time for a new handle: finish the old one off first
6818 7137 * then get a new one properly to avoid leaks.
6819 7138 */
6820 7139 zonecfg_fini_handle(handle);
6821 7140 if ((handle = zonecfg_init_handle()) == NULL) {
6822 7141 zone_perror(execname, Z_NOMEM, B_TRUE);
6823 7142 exit(Z_ERR);
6824 7143 }
6825 7144
6826 7145 if ((err = zonecfg_get_handle(revert_zone, handle)) != Z_OK) {
6827 7146 saw_error = B_TRUE;
6828 7147 got_handle = B_FALSE;
6829 7148 if (err == Z_NO_ZONE)
6830 7149 zerr(gettext("%s: no such saved zone to revert to."),
6831 7150 revert_zone);
6832 7151 else
6833 7152 zone_perror(zone, err, B_TRUE);
6834 7153 }
6835 7154 (void) strlcpy(zone, revert_zone, sizeof (zone));
6836 7155 }
6837 7156
6838 7157 void
6839 7158 help_func(cmd_t *cmd)
6840 7159 {
6841 7160 int i;
6842 7161
6843 7162 assert(cmd != NULL);
6844 7163
6845 7164 if (cmd->cmd_argc == 0) {
6846 7165 usage(B_TRUE, global_scope ? HELP_SUBCMDS : HELP_RES_SCOPE);
6847 7166 return;
6848 7167 }
6849 7168 if (strcmp(cmd->cmd_argv[0], "usage") == 0) {
6850 7169 usage(B_TRUE, HELP_USAGE);
6851 7170 return;
6852 7171 }
6853 7172 if (strcmp(cmd->cmd_argv[0], "commands") == 0) {
6854 7173 usage(B_TRUE, HELP_SUBCMDS);
6855 7174 return;
6856 7175 }
6857 7176 if (strcmp(cmd->cmd_argv[0], "syntax") == 0) {
6858 7177 usage(B_TRUE, HELP_SYNTAX | HELP_RES_PROPS);
6859 7178 return;
6860 7179 }
6861 7180 if (strcmp(cmd->cmd_argv[0], "-?") == 0) {
6862 7181 longer_usage(CMD_HELP);
6863 7182 return;
6864 7183 }
6865 7184
6866 7185 for (i = 0; i <= CMD_MAX; i++) {
6867 7186 if (strcmp(cmd->cmd_argv[0], cmd_to_str(i)) == 0) {
6868 7187 longer_usage(i);
6869 7188 return;
6870 7189 }
6871 7190 }
6872 7191 /* We do not use zerr() here because we do not want its extra \n. */
6873 7192 (void) fprintf(stderr, gettext("Unknown help subject %s. "),
6874 7193 cmd->cmd_argv[0]);
6875 7194 usage(B_FALSE, HELP_META);
6876 7195 }
6877 7196
6878 7197 static int
6879 7198 string_to_yyin(char *string)
6880 7199 {
6881 7200 if ((yyin = tmpfile()) == NULL) {
6882 7201 zone_perror(execname, Z_TEMP_FILE, B_TRUE);
6883 7202 return (Z_ERR);
6884 7203 }
6885 7204 if (fwrite(string, strlen(string), 1, yyin) != 1) {
6886 7205 zone_perror(execname, Z_TEMP_FILE, B_TRUE);
6887 7206 return (Z_ERR);
6888 7207 }
6889 7208 if (fseek(yyin, 0, SEEK_SET) != 0) {
6890 7209 zone_perror(execname, Z_TEMP_FILE, B_TRUE);
6891 7210 return (Z_ERR);
6892 7211 }
6893 7212 return (Z_OK);
6894 7213 }
6895 7214
6896 7215 /* This is the back-end helper function for read_input() below. */
6897 7216
6898 7217 static int
6899 7218 cleanup()
6900 7219 {
6901 7220 int answer;
6902 7221 cmd_t *cmd;
6903 7222
6904 7223 if (!interactive_mode && !cmd_file_mode) {
6905 7224 /*
6906 7225 * If we're not in interactive mode, and we're not in command
6907 7226 * file mode, then we must be in commands-from-the-command-line
6908 7227 * mode. As such, we can't loop back and ask for more input.
6909 7228 * It was OK to prompt for such things as whether or not to
6910 7229 * really delete a zone in the command handler called from
6911 7230 * yyparse() above, but "really quit?" makes no sense in this
6912 7231 * context. So disable prompting.
6913 7232 */
6914 7233 ok_to_prompt = B_FALSE;
6915 7234 }
6916 7235 if (!global_scope) {
6917 7236 if (!time_to_exit) {
6918 7237 /*
6919 7238 * Just print a simple error message in the -1 case,
6920 7239 * since exit_func() already handles that case, and
6921 7240 * EOF means we are finished anyway.
6922 7241 */
6923 7242 answer = ask_yesno(B_FALSE,
6924 7243 gettext("Resource incomplete; really quit"));
6925 7244 if (answer == -1) {
6926 7245 zerr(gettext("Resource incomplete."));
6927 7246 return (Z_ERR);
6928 7247 }
6929 7248 if (answer != 1) {
6930 7249 yyin = stdin;
6931 7250 return (Z_REPEAT);
6932 7251 }
6933 7252 } else {
6934 7253 saw_error = B_TRUE;
6935 7254 }
6936 7255 }
6937 7256 /*
6938 7257 * Make sure we tried something and that the handle checks
6939 7258 * out, or we would get a false error trying to commit.
6940 7259 */
6941 7260 if (need_to_commit && zonecfg_check_handle(handle) == Z_OK) {
6942 7261 if ((cmd = alloc_cmd()) == NULL) {
6943 7262 zone_perror(zone, Z_NOMEM, B_TRUE);
6944 7263 return (Z_ERR);
6945 7264 }
6946 7265 cmd->cmd_argc = 0;
6947 7266 cmd->cmd_argv[0] = NULL;
6948 7267 commit_func(cmd);
6949 7268 free_cmd(cmd);
6950 7269 /*
6951 7270 * need_to_commit will get set back to FALSE if the
6952 7271 * configuration is saved successfully.
6953 7272 */
6954 7273 if (need_to_commit) {
6955 7274 if (force_exit) {
6956 7275 zerr(gettext("Configuration not saved."));
6957 7276 return (Z_ERR);
6958 7277 }
6959 7278 answer = ask_yesno(B_FALSE,
6960 7279 gettext("Configuration not saved; really quit"));
6961 7280 if (answer == -1) {
6962 7281 zerr(gettext("Configuration not saved."));
6963 7282 return (Z_ERR);
6964 7283 }
6965 7284 if (answer != 1) {
6966 7285 time_to_exit = B_FALSE;
6967 7286 yyin = stdin;
6968 7287 return (Z_REPEAT);
6969 7288 }
6970 7289 }
6971 7290 }
6972 7291 return ((need_to_commit || saw_error) ? Z_ERR : Z_OK);
6973 7292 }
6974 7293
6975 7294 /*
6976 7295 * read_input() is the driver of this program. It is a wrapper around
6977 7296 * yyparse(), printing appropriate prompts when needed, checking for
6978 7297 * exit conditions and reacting appropriately [the latter in its cleanup()
6979 7298 * helper function].
6980 7299 *
6981 7300 * Like most zonecfg functions, it returns Z_OK or Z_ERR, *or* Z_REPEAT
6982 7301 * so do_interactive() knows that we are not really done (i.e, we asked
6983 7302 * the user if we should really quit and the user said no).
6984 7303 */
6985 7304 static int
6986 7305 read_input()
6987 7306 {
6988 7307 boolean_t yyin_is_a_tty = isatty(fileno(yyin));
6989 7308 /*
6990 7309 * The prompt is "e:z> " or "e:z:r> " where e is execname, z is zone
6991 7310 * and r is resource_scope: 5 is for the two ":"s + "> " + terminator.
6992 7311 */
6993 7312 char prompt[MAXPATHLEN + ZONENAME_MAX + MAX_RT_STRLEN + 5], *line;
6994 7313
6995 7314 /* yyin should have been set to the appropriate (FILE *) if not stdin */
6996 7315 newline_terminated = B_TRUE;
6997 7316 for (;;) {
6998 7317 if (yyin_is_a_tty) {
6999 7318 if (newline_terminated) {
7000 7319 if (global_scope)
7001 7320 (void) snprintf(prompt, sizeof (prompt),
7002 7321 "%s:%s> ", execname, zone);
7003 7322 else
7004 7323 (void) snprintf(prompt, sizeof (prompt),
7005 7324 "%s:%s:%s> ", execname, zone,
7006 7325 rt_to_str(resource_scope));
7007 7326 }
7008 7327 /*
7009 7328 * If the user hits ^C then we want to catch it and
7010 7329 * start over. If the user hits EOF then we want to
7011 7330 * bail out.
7012 7331 */
7013 7332 line = gl_get_line(gl, prompt, NULL, -1);
7014 7333 if (gl_return_status(gl) == GLR_SIGNAL) {
7015 7334 gl_abandon_line(gl);
7016 7335 continue;
7017 7336 }
7018 7337 if (line == NULL)
7019 7338 break;
7020 7339 (void) string_to_yyin(line);
7021 7340 while (!feof(yyin))
7022 7341 yyparse();
7023 7342 } else {
7024 7343 yyparse();
7025 7344 }
7026 7345 /* Bail out on an error in command file mode. */
7027 7346 if (saw_error && cmd_file_mode && !interactive_mode)
7028 7347 time_to_exit = B_TRUE;
7029 7348 if (time_to_exit || (!yyin_is_a_tty && feof(yyin)))
7030 7349 break;
7031 7350 }
7032 7351 return (cleanup());
7033 7352 }
7034 7353
7035 7354 /*
7036 7355 * This function is used in the zonecfg-interactive-mode scenario: it just
7037 7356 * calls read_input() until we are done.
7038 7357 */
7039 7358
7040 7359 static int
7041 7360 do_interactive(void)
7042 7361 {
7043 7362 int err;
7044 7363
7045 7364 interactive_mode = B_TRUE;
7046 7365 if (!read_only_mode) {
7047 7366 /*
7048 7367 * Try to set things up proactively in interactive mode, so
7049 7368 * that if the zone in question does not exist yet, we can
7050 7369 * provide the user with a clue.
7051 7370 */
7052 7371 (void) initialize(B_FALSE);
7053 7372 }
7054 7373 do {
7055 7374 err = read_input();
7056 7375 } while (err == Z_REPEAT);
7057 7376 return (err);
7058 7377 }
7059 7378
7060 7379 /*
7061 7380 * cmd_file is slightly more complicated, as it has to open the command file
7062 7381 * and set yyin appropriately. Once that is done, though, it just calls
7063 7382 * read_input(), and only once, since prompting is not possible.
7064 7383 */
7065 7384
7066 7385 static int
7067 7386 cmd_file(char *file)
7068 7387 {
7069 7388 FILE *infile;
7070 7389 int err;
7071 7390 struct stat statbuf;
7072 7391 boolean_t using_real_file = (strcmp(file, "-") != 0);
7073 7392
7074 7393 if (using_real_file) {
7075 7394 /*
7076 7395 * zerr() prints a line number in cmd_file_mode, which we do
7077 7396 * not want here, so temporarily unset it.
7078 7397 */
7079 7398 cmd_file_mode = B_FALSE;
7080 7399 if ((infile = fopen(file, "r")) == NULL) {
7081 7400 zerr(gettext("could not open file %s: %s"),
7082 7401 file, strerror(errno));
7083 7402 return (Z_ERR);
7084 7403 }
7085 7404 if ((err = fstat(fileno(infile), &statbuf)) != 0) {
7086 7405 zerr(gettext("could not stat file %s: %s"),
7087 7406 file, strerror(errno));
7088 7407 err = Z_ERR;
7089 7408 goto done;
7090 7409 }
7091 7410 if (!S_ISREG(statbuf.st_mode)) {
7092 7411 zerr(gettext("%s is not a regular file."), file);
7093 7412 err = Z_ERR;
7094 7413 goto done;
7095 7414 }
7096 7415 yyin = infile;
7097 7416 cmd_file_mode = B_TRUE;
7098 7417 ok_to_prompt = B_FALSE;
7099 7418 } else {
7100 7419 /*
7101 7420 * "-f -" is essentially the same as interactive mode,
7102 7421 * so treat it that way.
7103 7422 */
7104 7423 interactive_mode = B_TRUE;
7105 7424 }
7106 7425 /* Z_REPEAT is for interactive mode; treat it like Z_ERR here. */
7107 7426 if ((err = read_input()) == Z_REPEAT)
7108 7427 err = Z_ERR;
7109 7428 done:
7110 7429 if (using_real_file)
7111 7430 (void) fclose(infile);
7112 7431 return (err);
7113 7432 }
7114 7433
7115 7434 /*
7116 7435 * Since yacc is based on reading from a (FILE *) whereas what we get from
7117 7436 * the command line is in argv format, we need to convert when the user
7118 7437 * gives us commands directly from the command line. That is done here by
7119 7438 * concatenating the argv list into a space-separated string, writing it
7120 7439 * to a temp file, and rewinding the file so yyin can be set to it. Then
7121 7440 * we call read_input(), and only once, since prompting about whether to
7122 7441 * continue or quit would make no sense in this context.
7123 7442 */
7124 7443
7125 7444 static int
7126 7445 one_command_at_a_time(int argc, char *argv[])
7127 7446 {
7128 7447 char *command;
7129 7448 size_t len = 2; /* terminal \n\0 */
7130 7449 int i, err;
7131 7450
7132 7451 for (i = 0; i < argc; i++)
7133 7452 len += strlen(argv[i]) + 1;
7134 7453 if ((command = malloc(len)) == NULL) {
7135 7454 zone_perror(execname, Z_NOMEM, B_TRUE);
7136 7455 return (Z_ERR);
7137 7456 }
7138 7457 (void) strlcpy(command, argv[0], len);
7139 7458 for (i = 1; i < argc; i++) {
7140 7459 (void) strlcat(command, " ", len);
7141 7460 (void) strlcat(command, argv[i], len);
7142 7461 }
7143 7462 (void) strlcat(command, "\n", len);
7144 7463 err = string_to_yyin(command);
7145 7464 free(command);
7146 7465 if (err != Z_OK)
7147 7466 return (err);
7148 7467 while (!feof(yyin))
7149 7468 yyparse();
7150 7469 return (cleanup());
7151 7470 }
7152 7471
7153 7472 static char *
7154 7473 get_execbasename(char *execfullname)
7155 7474 {
7156 7475 char *last_slash, *execbasename;
7157 7476
7158 7477 /* guard against '/' at end of command invocation */
7159 7478 for (;;) {
7160 7479 last_slash = strrchr(execfullname, '/');
7161 7480 if (last_slash == NULL) {
7162 7481 execbasename = execfullname;
7163 7482 break;
7164 7483 } else {
7165 7484 execbasename = last_slash + 1;
7166 7485 if (*execbasename == '\0') {
7167 7486 *last_slash = '\0';
7168 7487 continue;
7169 7488 }
7170 7489 break;
7171 7490 }
7172 7491 }
7173 7492 return (execbasename);
7174 7493 }
7175 7494
7176 7495 int
7177 7496 main(int argc, char *argv[])
7178 7497 {
7179 7498 int err, arg;
7180 7499 struct stat st;
7181 7500
7182 7501 /* This must be before anything goes to stdout. */
7183 7502 setbuf(stdout, NULL);
7184 7503
7185 7504 saw_error = B_FALSE;
7186 7505 cmd_file_mode = B_FALSE;
7187 7506 execname = get_execbasename(argv[0]);
7188 7507
7189 7508 (void) setlocale(LC_ALL, "");
7190 7509 (void) textdomain(TEXT_DOMAIN);
7191 7510
7192 7511 if (getzoneid() != GLOBAL_ZONEID) {
7193 7512 zerr(gettext("%s can only be run from the global zone."),
7194 7513 execname);
7195 7514 exit(Z_ERR);
7196 7515 }
7197 7516
7198 7517 if (argc < 2) {
7199 7518 usage(B_FALSE, HELP_USAGE | HELP_SUBCMDS);
7200 7519 exit(Z_USAGE);
7201 7520 }
7202 7521 if (strcmp(argv[1], cmd_to_str(CMD_HELP)) == 0) {
7203 7522 (void) one_command_at_a_time(argc - 1, &(argv[1]));
7204 7523 exit(Z_OK);
7205 7524 }
7206 7525
7207 7526 while ((arg = getopt(argc, argv, "?f:R:z:")) != EOF) {
7208 7527 switch (arg) {
7209 7528 case '?':
7210 7529 if (optopt == '?')
7211 7530 usage(B_TRUE, HELP_USAGE | HELP_SUBCMDS);
7212 7531 else
7213 7532 usage(B_FALSE, HELP_USAGE);
7214 7533 exit(Z_USAGE);
7215 7534 /* NOTREACHED */
7216 7535 case 'f':
7217 7536 cmd_file_name = optarg;
7218 7537 cmd_file_mode = B_TRUE;
7219 7538 break;
7220 7539 case 'R':
7221 7540 if (*optarg != '/') {
7222 7541 zerr(gettext("root path must be absolute: %s"),
7223 7542 optarg);
7224 7543 exit(Z_USAGE);
7225 7544 }
7226 7545 if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) {
7227 7546 zerr(gettext(
7228 7547 "root path must be a directory: %s"),
7229 7548 optarg);
7230 7549 exit(Z_USAGE);
7231 7550 }
7232 7551 zonecfg_set_root(optarg);
7233 7552 break;
7234 7553 case 'z':
7235 7554 if (strcmp(optarg, GLOBAL_ZONENAME) == 0) {
7236 7555 global_zone = B_TRUE;
7237 7556 } else if (zonecfg_validate_zonename(optarg) != Z_OK) {
7238 7557 zone_perror(optarg, Z_BOGUS_ZONE_NAME, B_TRUE);
7239 7558 usage(B_FALSE, HELP_SYNTAX);
7240 7559 exit(Z_USAGE);
7241 7560 }
7242 7561 (void) strlcpy(zone, optarg, sizeof (zone));
7243 7562 (void) strlcpy(revert_zone, optarg, sizeof (zone));
7244 7563 break;
7245 7564 default:
7246 7565 usage(B_FALSE, HELP_USAGE);
7247 7566 exit(Z_USAGE);
7248 7567 }
7249 7568 }
7250 7569
7251 7570 if (optind > argc || strcmp(zone, "") == 0) {
7252 7571 usage(B_FALSE, HELP_USAGE);
7253 7572 exit(Z_USAGE);
7254 7573 }
7255 7574
7256 7575 if ((err = zonecfg_access(zone, W_OK)) == Z_OK) {
7257 7576 read_only_mode = B_FALSE;
7258 7577 } else if (err == Z_ACCES) {
7259 7578 read_only_mode = B_TRUE;
7260 7579 /* skip this message in one-off from command line mode */
7261 7580 if (optind == argc)
7262 7581 (void) fprintf(stderr, gettext("WARNING: you do not "
7263 7582 "have write access to this zone's configuration "
7264 7583 "file;\ngoing into read-only mode.\n"));
7265 7584 } else {
7266 7585 fprintf(stderr, "%s: Could not access zone configuration "
7267 7586 "store: %s\n", execname, zonecfg_strerror(err));
7268 7587 exit(Z_ERR);
7269 7588 }
7270 7589
7271 7590 if ((handle = zonecfg_init_handle()) == NULL) {
7272 7591 zone_perror(execname, Z_NOMEM, B_TRUE);
7273 7592 exit(Z_ERR);
7274 7593 }
7275 7594
7276 7595 /*
7277 7596 * This may get set back to FALSE again in cmd_file() if cmd_file_name
7278 7597 * is a "real" file as opposed to "-" (i.e. meaning use stdin).
7279 7598 */
7280 7599 if (isatty(STDIN_FILENO))
7281 7600 ok_to_prompt = B_TRUE;
7282 7601 if ((gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL)
7283 7602 exit(Z_ERR);
7284 7603 if (gl_customize_completion(gl, NULL, cmd_cpl_fn) != 0)
7285 7604 exit(Z_ERR);
7286 7605 (void) sigset(SIGINT, SIG_IGN);
7287 7606 if (optind == argc) {
7288 7607 if (!cmd_file_mode)
7289 7608 err = do_interactive();
7290 7609 else
7291 7610 err = cmd_file(cmd_file_name);
7292 7611 } else {
7293 7612 err = one_command_at_a_time(argc - optind, &(argv[optind]));
7294 7613 }
7295 7614 zonecfg_fini_handle(handle);
7296 7615 if (brand != NULL)
7297 7616 brand_close(brand);
7298 7617 (void) del_GetLine(gl);
7299 7618 return (err);
7300 7619 }
↓ open down ↓ |
607 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX