Print this page
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 ((err = zonecfg_getsecflagsent(handle, &secflagstab)) != Z_OK) {
2121 + zone_perror(zone, err, B_FALSE);
2122 + goto done;
2123 + }
2124 +
2125 + (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2126 + rt_to_str(RT_SECFLAGS));
2127 + export_prop(of, PT_DEFAULT, secflagstab.zone_secflags_default);
2128 + export_prop(of, PT_LOWER, secflagstab.zone_secflags_lower);
2129 + export_prop(of, PT_UPPER, secflagstab.zone_secflags_upper);
2130 + (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2131 +
2074 2132 /*
2075 2133 * There is nothing to export for pcap since this resource is just
2076 2134 * a container for an rctl alias.
2077 2135 */
2078 2136
2079 2137 done:
2080 2138 if (need_to_close)
2081 2139 (void) fclose(of);
2082 2140 }
2083 2141
2084 2142 void
2085 2143 exit_func(cmd_t *cmd)
2086 2144 {
2087 2145 int arg, answer;
2088 2146 boolean_t arg_err = B_FALSE;
2089 2147
2090 2148 optind = 0;
2091 2149 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
2092 2150 switch (arg) {
2093 2151 case '?':
2094 2152 longer_usage(CMD_EXIT);
2095 2153 arg_err = B_TRUE;
2096 2154 break;
2097 2155 case 'F':
2098 2156 force_exit = B_TRUE;
2099 2157 break;
2100 2158 default:
2101 2159 short_usage(CMD_EXIT);
2102 2160 arg_err = B_TRUE;
2103 2161 break;
2104 2162 }
2105 2163 }
2106 2164 if (arg_err)
2107 2165 return;
2108 2166
2109 2167 if (optind < cmd->cmd_argc) {
2110 2168 short_usage(CMD_EXIT);
2111 2169 return;
2112 2170 }
2113 2171
2114 2172 if (global_scope || force_exit) {
2115 2173 time_to_exit = B_TRUE;
2116 2174 return;
2117 2175 }
2118 2176
2119 2177 answer = ask_yesno(B_FALSE, "Resource incomplete; really quit");
2120 2178 if (answer == -1) {
2121 2179 zerr(gettext("Resource incomplete, input "
2122 2180 "not from terminal and -F not specified:\n%s command "
2123 2181 "ignored, but exiting anyway."), cmd_to_str(CMD_EXIT));
2124 2182 exit(Z_ERR);
2125 2183 } else if (answer == 1) {
2126 2184 time_to_exit = B_TRUE;
2127 2185 }
2128 2186 /* (answer == 0) => just return */
2129 2187 }
2130 2188
2131 2189 static int
2132 2190 validate_zonepath_syntax(char *path)
2133 2191 {
2134 2192 if (path[0] != '/') {
2135 2193 zerr(gettext("%s is not an absolute path."), path);
2136 2194 return (Z_ERR);
2137 2195 }
2138 2196 /* If path is all slashes, then fail */
2139 2197 if (strspn(path, "/") == strlen(path)) {
2140 2198 zerr(gettext("/ is not allowed as a %s."),
2141 2199 pt_to_str(PT_ZONEPATH));
2142 2200 return (Z_ERR);
↓ open down ↓ |
59 lines elided |
↑ open up ↑ |
2143 2201 }
2144 2202 return (Z_OK);
2145 2203 }
2146 2204
2147 2205 static void
2148 2206 add_resource(cmd_t *cmd)
2149 2207 {
2150 2208 int type;
2151 2209 struct zone_psettab tmp_psettab;
2152 2210 struct zone_mcaptab tmp_mcaptab;
2211 + struct zone_secflagstab tmp_secflagstab;
2153 2212 uint64_t tmp;
2154 2213 uint64_t tmp_mcap;
2155 2214 char pool[MAXNAMELEN];
2156 2215
2157 2216 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
2158 2217 long_usage(CMD_ADD, B_TRUE);
2159 2218 goto bad;
2160 2219 }
2161 2220
2162 2221 switch (type) {
2163 2222 case RT_FS:
2164 2223 bzero(&in_progress_fstab, sizeof (in_progress_fstab));
2165 2224 return;
2166 2225 case RT_NET:
2167 2226 bzero(&in_progress_nwiftab, sizeof (in_progress_nwiftab));
2168 2227 return;
2169 2228 case RT_DEVICE:
2170 2229 bzero(&in_progress_devtab, sizeof (in_progress_devtab));
2171 2230 return;
2172 2231 case RT_RCTL:
2173 2232 if (global_zone)
2174 2233 zerr(gettext("WARNING: Setting a global zone resource "
2175 2234 "control too low could deny\nservice "
2176 2235 "to even the root user; "
2177 2236 "this could render the system impossible\n"
2178 2237 "to administer. Please use caution."));
2179 2238 bzero(&in_progress_rctltab, sizeof (in_progress_rctltab));
2180 2239 return;
2181 2240 case RT_ATTR:
2182 2241 bzero(&in_progress_attrtab, sizeof (in_progress_attrtab));
2183 2242 return;
2184 2243 case RT_DATASET:
2185 2244 bzero(&in_progress_dstab, sizeof (in_progress_dstab));
2186 2245 return;
2187 2246 case RT_DCPU:
2188 2247 /* Make sure there isn't already a cpu-set or cpu-cap entry. */
2189 2248 if (zonecfg_lookup_pset(handle, &tmp_psettab) == Z_OK) {
2190 2249 zerr(gettext("The %s resource already exists."),
2191 2250 rt_to_str(RT_DCPU));
2192 2251 goto bad;
2193 2252 }
2194 2253 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp) !=
2195 2254 Z_NO_ENTRY) {
2196 2255 zerr(gettext("The %s resource already exists."),
2197 2256 rt_to_str(RT_PCAP));
2198 2257 goto bad;
2199 2258 }
2200 2259
2201 2260 /* Make sure the pool property isn't set. */
2202 2261 if (zonecfg_get_pool(handle, pool, sizeof (pool)) == Z_OK &&
2203 2262 strlen(pool) > 0) {
2204 2263 zerr(gettext("The %s property is already set. "
2205 2264 "A persistent pool is incompatible with\nthe %s "
2206 2265 "resource."),
2207 2266 pt_to_str(PT_POOL), rt_to_str(RT_DCPU));
2208 2267 goto bad;
2209 2268 }
2210 2269
2211 2270 bzero(&in_progress_psettab, sizeof (in_progress_psettab));
2212 2271 return;
2213 2272 case RT_PCAP:
2214 2273 /*
2215 2274 * Make sure there isn't already a cpu-set or incompatible
2216 2275 * cpu-cap rctls.
2217 2276 */
2218 2277 if (zonecfg_lookup_pset(handle, &tmp_psettab) == Z_OK) {
2219 2278 zerr(gettext("The %s resource already exists."),
2220 2279 rt_to_str(RT_DCPU));
2221 2280 goto bad;
2222 2281 }
2223 2282
2224 2283 switch (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp)) {
2225 2284 case Z_ALIAS_DISALLOW:
2226 2285 zone_perror(rt_to_str(RT_PCAP), Z_ALIAS_DISALLOW,
2227 2286 B_FALSE);
2228 2287 goto bad;
2229 2288
2230 2289 case Z_OK:
2231 2290 zerr(gettext("The %s resource already exists."),
2232 2291 rt_to_str(RT_PCAP));
2233 2292 goto bad;
2234 2293
2235 2294 default:
2236 2295 break;
2237 2296 }
2238 2297 return;
2239 2298 case RT_MCAP:
2240 2299 /*
2241 2300 * Make sure there isn't already a mem-cap entry or max-swap
2242 2301 * or max-locked rctl.
2243 2302 */
2244 2303 if (zonecfg_lookup_mcap(handle, &tmp_mcaptab) == Z_OK ||
2245 2304 zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp_mcap)
2246 2305 == Z_OK ||
2247 2306 zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM,
2248 2307 &tmp_mcap) == Z_OK) {
2249 2308 zerr(gettext("The %s resource or a related resource "
2250 2309 "control already exists."), rt_to_str(RT_MCAP));
2251 2310 goto bad;
2252 2311 }
2253 2312 if (global_zone)
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
2254 2313 zerr(gettext("WARNING: Setting a global zone memory "
2255 2314 "cap too low could deny\nservice "
2256 2315 "to even the root user; "
2257 2316 "this could render the system impossible\n"
2258 2317 "to administer. Please use caution."));
2259 2318 bzero(&in_progress_mcaptab, sizeof (in_progress_mcaptab));
2260 2319 return;
2261 2320 case RT_ADMIN:
2262 2321 bzero(&in_progress_admintab, sizeof (in_progress_admintab));
2263 2322 return;
2323 + case RT_SECFLAGS:
2324 + /* Make sure we haven't already set this */
2325 + if (zonecfg_lookup_secflags(handle, &tmp_secflagstab) == Z_OK)
2326 + zerr(gettext("The %s resource already exists."),
2327 + rt_to_str(RT_SECFLAGS));
2328 + bzero(&in_progress_secflagstab,
2329 + sizeof (in_progress_secflagstab));
2330 + return;
2264 2331 default:
2265 2332 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
2266 2333 long_usage(CMD_ADD, B_TRUE);
2267 2334 usage(B_FALSE, HELP_RESOURCES);
2268 2335 }
2269 2336 bad:
2270 2337 global_scope = B_TRUE;
2271 2338 end_op = -1;
2272 2339 }
2273 2340
2274 2341 static void
2275 2342 do_complex_rctl_val(complex_property_ptr_t cp)
2276 2343 {
2277 2344 struct zone_rctlvaltab *rctlvaltab;
2278 2345 complex_property_ptr_t cx;
2279 2346 boolean_t seen_priv = B_FALSE, seen_limit = B_FALSE,
2280 2347 seen_action = B_FALSE;
2281 2348 rctlblk_t *rctlblk;
2282 2349 int err;
2283 2350
2284 2351 if ((rctlvaltab = alloc_rctlvaltab()) == NULL) {
2285 2352 zone_perror(zone, Z_NOMEM, B_TRUE);
2286 2353 exit(Z_ERR);
2287 2354 }
2288 2355 for (cx = cp; cx != NULL; cx = cx->cp_next) {
2289 2356 switch (cx->cp_type) {
2290 2357 case PT_PRIV:
2291 2358 if (seen_priv) {
2292 2359 zerr(gettext("%s already specified"),
2293 2360 pt_to_str(PT_PRIV));
2294 2361 goto bad;
2295 2362 }
2296 2363 (void) strlcpy(rctlvaltab->zone_rctlval_priv,
2297 2364 cx->cp_value,
2298 2365 sizeof (rctlvaltab->zone_rctlval_priv));
2299 2366 seen_priv = B_TRUE;
2300 2367 break;
2301 2368 case PT_LIMIT:
2302 2369 if (seen_limit) {
2303 2370 zerr(gettext("%s already specified"),
2304 2371 pt_to_str(PT_LIMIT));
2305 2372 goto bad;
2306 2373 }
2307 2374 (void) strlcpy(rctlvaltab->zone_rctlval_limit,
2308 2375 cx->cp_value,
2309 2376 sizeof (rctlvaltab->zone_rctlval_limit));
2310 2377 seen_limit = B_TRUE;
2311 2378 break;
2312 2379 case PT_ACTION:
2313 2380 if (seen_action) {
2314 2381 zerr(gettext("%s already specified"),
2315 2382 pt_to_str(PT_ACTION));
2316 2383 goto bad;
2317 2384 }
2318 2385 (void) strlcpy(rctlvaltab->zone_rctlval_action,
2319 2386 cx->cp_value,
2320 2387 sizeof (rctlvaltab->zone_rctlval_action));
2321 2388 seen_action = B_TRUE;
2322 2389 break;
2323 2390 default:
2324 2391 zone_perror(pt_to_str(PT_VALUE),
2325 2392 Z_NO_PROPERTY_TYPE, B_TRUE);
2326 2393 long_usage(CMD_ADD, B_TRUE);
2327 2394 usage(B_FALSE, HELP_PROPS);
2328 2395 zonecfg_free_rctl_value_list(rctlvaltab);
2329 2396 return;
2330 2397 }
2331 2398 }
2332 2399 if (!seen_priv)
2333 2400 zerr(gettext("%s not specified"), pt_to_str(PT_PRIV));
2334 2401 if (!seen_limit)
2335 2402 zerr(gettext("%s not specified"), pt_to_str(PT_LIMIT));
2336 2403 if (!seen_action)
2337 2404 zerr(gettext("%s not specified"), pt_to_str(PT_ACTION));
2338 2405 if (!seen_priv || !seen_limit || !seen_action)
2339 2406 goto bad;
2340 2407 rctlvaltab->zone_rctlval_next = NULL;
2341 2408 rctlblk = alloca(rctlblk_size());
2342 2409 /*
2343 2410 * Make sure the rctl value looks roughly correct; we won't know if
2344 2411 * it's truly OK until we verify the configuration on the target
2345 2412 * system.
2346 2413 */
2347 2414 if (zonecfg_construct_rctlblk(rctlvaltab, rctlblk) != Z_OK ||
2348 2415 !zonecfg_valid_rctlblk(rctlblk)) {
2349 2416 zerr(gettext("Invalid %s %s specification"), rt_to_str(RT_RCTL),
2350 2417 pt_to_str(PT_VALUE));
2351 2418 goto bad;
2352 2419 }
2353 2420 err = zonecfg_add_rctl_value(&in_progress_rctltab, rctlvaltab);
2354 2421 if (err != Z_OK)
2355 2422 zone_perror(pt_to_str(PT_VALUE), err, B_TRUE);
2356 2423 return;
2357 2424
2358 2425 bad:
2359 2426 zonecfg_free_rctl_value_list(rctlvaltab);
2360 2427 }
2361 2428
2362 2429 static void
2363 2430 add_property(cmd_t *cmd)
2364 2431 {
2365 2432 char *prop_id;
2366 2433 int err, res_type, prop_type;
2367 2434 property_value_ptr_t pp;
2368 2435 list_property_ptr_t l;
2369 2436
2370 2437 res_type = resource_scope;
2371 2438 prop_type = cmd->cmd_prop_name[0];
2372 2439 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
2373 2440 long_usage(CMD_ADD, B_TRUE);
2374 2441 return;
2375 2442 }
2376 2443
2377 2444 if (cmd->cmd_prop_nv_pairs != 1) {
2378 2445 long_usage(CMD_ADD, B_TRUE);
2379 2446 return;
2380 2447 }
2381 2448
2382 2449 if (initialize(B_TRUE) != Z_OK)
2383 2450 return;
2384 2451
2385 2452 switch (res_type) {
2386 2453 case RT_FS:
2387 2454 if (prop_type != PT_OPTIONS) {
2388 2455 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
2389 2456 B_TRUE);
2390 2457 long_usage(CMD_ADD, B_TRUE);
2391 2458 usage(B_FALSE, HELP_PROPS);
2392 2459 return;
2393 2460 }
2394 2461 pp = cmd->cmd_property_ptr[0];
2395 2462 if (pp->pv_type != PROP_VAL_SIMPLE &&
2396 2463 pp->pv_type != PROP_VAL_LIST) {
2397 2464 zerr(gettext("A %s or %s value was expected here."),
2398 2465 pvt_to_str(PROP_VAL_SIMPLE),
2399 2466 pvt_to_str(PROP_VAL_LIST));
2400 2467 saw_error = B_TRUE;
2401 2468 return;
2402 2469 }
2403 2470 if (pp->pv_type == PROP_VAL_SIMPLE) {
2404 2471 if (pp->pv_simple == NULL) {
2405 2472 long_usage(CMD_ADD, B_TRUE);
2406 2473 return;
2407 2474 }
2408 2475 prop_id = pp->pv_simple;
2409 2476 err = zonecfg_add_fs_option(&in_progress_fstab,
2410 2477 prop_id);
2411 2478 if (err != Z_OK)
2412 2479 zone_perror(pt_to_str(prop_type), err, B_TRUE);
2413 2480 } else {
2414 2481 list_property_ptr_t list;
2415 2482
2416 2483 for (list = pp->pv_list; list != NULL;
2417 2484 list = list->lp_next) {
2418 2485 prop_id = list->lp_simple;
2419 2486 if (prop_id == NULL)
2420 2487 break;
2421 2488 err = zonecfg_add_fs_option(
2422 2489 &in_progress_fstab, prop_id);
2423 2490 if (err != Z_OK)
2424 2491 zone_perror(pt_to_str(prop_type), err,
2425 2492 B_TRUE);
2426 2493 }
2427 2494 }
2428 2495 return;
2429 2496 case RT_RCTL:
2430 2497 if (prop_type != PT_VALUE) {
2431 2498 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
2432 2499 B_TRUE);
2433 2500 long_usage(CMD_ADD, B_TRUE);
2434 2501 usage(B_FALSE, HELP_PROPS);
2435 2502 return;
2436 2503 }
2437 2504 pp = cmd->cmd_property_ptr[0];
2438 2505 if (pp->pv_type != PROP_VAL_COMPLEX &&
2439 2506 pp->pv_type != PROP_VAL_LIST) {
2440 2507 zerr(gettext("A %s or %s value was expected here."),
2441 2508 pvt_to_str(PROP_VAL_COMPLEX),
2442 2509 pvt_to_str(PROP_VAL_LIST));
2443 2510 saw_error = B_TRUE;
2444 2511 return;
2445 2512 }
2446 2513 if (pp->pv_type == PROP_VAL_COMPLEX) {
2447 2514 do_complex_rctl_val(pp->pv_complex);
2448 2515 return;
2449 2516 }
2450 2517 for (l = pp->pv_list; l != NULL; l = l->lp_next)
2451 2518 do_complex_rctl_val(l->lp_complex);
2452 2519 return;
2453 2520 default:
2454 2521 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
2455 2522 long_usage(CMD_ADD, B_TRUE);
2456 2523 usage(B_FALSE, HELP_RESOURCES);
2457 2524 return;
2458 2525 }
2459 2526 }
2460 2527
2461 2528 static boolean_t
2462 2529 gz_invalid_resource(int type)
2463 2530 {
2464 2531 return (global_zone && (type == RT_FS ||
2465 2532 type == RT_NET || type == RT_DEVICE || type == RT_ATTR ||
2466 2533 type == RT_DATASET));
2467 2534 }
2468 2535
2469 2536 static boolean_t
2470 2537 gz_invalid_rt_property(int type)
2471 2538 {
2472 2539 return (global_zone && (type == RT_ZONENAME || type == RT_ZONEPATH ||
2473 2540 type == RT_AUTOBOOT || type == RT_LIMITPRIV ||
2474 2541 type == RT_BOOTARGS || type == RT_BRAND || type == RT_SCHED ||
2475 2542 type == RT_IPTYPE || type == RT_HOSTID || type == RT_FS_ALLOWED));
2476 2543 }
2477 2544
2478 2545 static boolean_t
2479 2546 gz_invalid_property(int type)
2480 2547 {
2481 2548 return (global_zone && (type == PT_ZONENAME || type == PT_ZONEPATH ||
2482 2549 type == PT_AUTOBOOT || type == PT_LIMITPRIV ||
2483 2550 type == PT_BOOTARGS || type == PT_BRAND || type == PT_SCHED ||
2484 2551 type == PT_IPTYPE || type == PT_HOSTID || type == PT_FS_ALLOWED));
2485 2552 }
2486 2553
2487 2554 void
2488 2555 add_func(cmd_t *cmd)
2489 2556 {
2490 2557 int arg;
2491 2558 boolean_t arg_err = B_FALSE;
2492 2559
2493 2560 assert(cmd != NULL);
2494 2561
2495 2562 optind = 0;
2496 2563 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
2497 2564 switch (arg) {
2498 2565 case '?':
2499 2566 longer_usage(CMD_ADD);
2500 2567 arg_err = B_TRUE;
2501 2568 break;
2502 2569 default:
2503 2570 short_usage(CMD_ADD);
2504 2571 arg_err = B_TRUE;
2505 2572 break;
2506 2573 }
2507 2574 }
2508 2575 if (arg_err)
2509 2576 return;
2510 2577
2511 2578 if (optind != cmd->cmd_argc) {
2512 2579 short_usage(CMD_ADD);
2513 2580 return;
2514 2581 }
2515 2582
2516 2583 if (zone_is_read_only(CMD_ADD))
2517 2584 return;
2518 2585
2519 2586 if (initialize(B_TRUE) != Z_OK)
2520 2587 return;
2521 2588 if (global_scope) {
2522 2589 if (gz_invalid_resource(cmd->cmd_res_type)) {
2523 2590 zerr(gettext("Cannot add a %s resource to the "
2524 2591 "global zone."), rt_to_str(cmd->cmd_res_type));
2525 2592 saw_error = B_TRUE;
2526 2593 return;
2527 2594 }
2528 2595
2529 2596 global_scope = B_FALSE;
2530 2597 resource_scope = cmd->cmd_res_type;
2531 2598 end_op = CMD_ADD;
2532 2599 add_resource(cmd);
2533 2600 } else
2534 2601 add_property(cmd);
2535 2602 }
2536 2603
2537 2604 /*
2538 2605 * This routine has an unusual implementation, because it tries very
2539 2606 * hard to succeed in the face of a variety of failure modes.
2540 2607 * The most common and most vexing occurs when the index file and
2541 2608 * the /etc/zones/<zonename.xml> file are not both present. In
2542 2609 * this case, delete must eradicate as much of the zone state as is left
2543 2610 * so that the user can later create a new zone with the same name.
2544 2611 */
2545 2612 void
2546 2613 delete_func(cmd_t *cmd)
2547 2614 {
2548 2615 int err, arg, answer;
2549 2616 char line[ZONENAME_MAX + 128]; /* enough to ask a question */
2550 2617 boolean_t force = B_FALSE;
2551 2618 boolean_t arg_err = B_FALSE;
2552 2619
2553 2620 optind = 0;
2554 2621 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
2555 2622 switch (arg) {
2556 2623 case '?':
2557 2624 longer_usage(CMD_DELETE);
2558 2625 arg_err = B_TRUE;
2559 2626 break;
2560 2627 case 'F':
2561 2628 force = B_TRUE;
2562 2629 break;
2563 2630 default:
2564 2631 short_usage(CMD_DELETE);
2565 2632 arg_err = B_TRUE;
2566 2633 break;
2567 2634 }
2568 2635 }
2569 2636 if (arg_err)
2570 2637 return;
2571 2638
2572 2639 if (optind != cmd->cmd_argc) {
2573 2640 short_usage(CMD_DELETE);
2574 2641 return;
2575 2642 }
2576 2643
2577 2644 if (zone_is_read_only(CMD_DELETE))
2578 2645 return;
2579 2646
2580 2647 if (!force) {
2581 2648 /*
2582 2649 * Initialize sets up the global called "handle" and warns the
2583 2650 * user if the zone is not configured. In force mode, we don't
2584 2651 * trust that evaluation, and hence skip it. (We don't need the
2585 2652 * handle to be loaded anyway, since zonecfg_destroy is done by
2586 2653 * zonename). However, we also have to take care to emulate the
2587 2654 * messages spit out by initialize; see below.
2588 2655 */
2589 2656 if (initialize(B_TRUE) != Z_OK)
2590 2657 return;
2591 2658
2592 2659 (void) snprintf(line, sizeof (line),
2593 2660 gettext("Are you sure you want to delete zone %s"), zone);
2594 2661 if ((answer = ask_yesno(B_FALSE, line)) == -1) {
2595 2662 zerr(gettext("Input not from terminal and -F not "
2596 2663 "specified:\n%s command ignored, exiting."),
2597 2664 cmd_to_str(CMD_DELETE));
2598 2665 exit(Z_ERR);
2599 2666 }
2600 2667 if (answer != 1)
2601 2668 return;
2602 2669 }
2603 2670
2604 2671 /*
2605 2672 * This function removes the authorizations from user_attr
2606 2673 * that correspond to those specified in the configuration
2607 2674 */
2608 2675 if (initialize(B_TRUE) == Z_OK) {
2609 2676 (void) zonecfg_deauthorize_users(handle, zone);
2610 2677 }
2611 2678 if ((err = zonecfg_destroy(zone, force)) != Z_OK) {
2612 2679 if ((err == Z_BAD_ZONE_STATE) && !force) {
2613 2680 zerr(gettext("Zone %s not in %s state; %s not "
2614 2681 "allowed. Use -F to force %s."),
2615 2682 zone, zone_state_str(ZONE_STATE_CONFIGURED),
2616 2683 cmd_to_str(CMD_DELETE), cmd_to_str(CMD_DELETE));
2617 2684 } else {
2618 2685 zone_perror(zone, err, B_TRUE);
2619 2686 }
2620 2687 }
2621 2688 need_to_commit = B_FALSE;
2622 2689
2623 2690 /*
2624 2691 * Emulate initialize's messaging; if there wasn't a valid handle to
2625 2692 * begin with, then user had typed delete (or delete -F) multiple
2626 2693 * times. So we emit a message.
2627 2694 *
2628 2695 * We only do this in the 'force' case because normally, initialize()
2629 2696 * takes care of this for us.
2630 2697 */
2631 2698 if (force && zonecfg_check_handle(handle) != Z_OK && interactive_mode)
2632 2699 (void) printf(gettext("Use '%s' to begin "
2633 2700 "configuring a new zone.\n"), cmd_to_str(CMD_CREATE));
2634 2701
2635 2702 /*
2636 2703 * Time for a new handle: finish the old one off first
2637 2704 * then get a new one properly to avoid leaks.
2638 2705 */
2639 2706 if (got_handle) {
2640 2707 zonecfg_fini_handle(handle);
2641 2708 if ((handle = zonecfg_init_handle()) == NULL) {
2642 2709 zone_perror(execname, Z_NOMEM, B_TRUE);
2643 2710 exit(Z_ERR);
2644 2711 }
2645 2712 if ((err = zonecfg_get_handle(zone, handle)) != Z_OK) {
2646 2713 /* If there was no zone before, that's OK */
2647 2714 if (err != Z_NO_ZONE)
2648 2715 zone_perror(zone, err, B_TRUE);
2649 2716 got_handle = B_FALSE;
2650 2717 }
2651 2718 }
2652 2719 }
2653 2720
2654 2721 static int
2655 2722 fill_in_fstab(cmd_t *cmd, struct zone_fstab *fstab, boolean_t fill_in_only)
2656 2723 {
2657 2724 int err, i;
2658 2725 property_value_ptr_t pp;
2659 2726
2660 2727 if ((err = initialize(B_TRUE)) != Z_OK)
2661 2728 return (err);
2662 2729
2663 2730 bzero(fstab, sizeof (*fstab));
2664 2731 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2665 2732 pp = cmd->cmd_property_ptr[i];
2666 2733 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2667 2734 zerr(gettext("A simple value was expected here."));
2668 2735 saw_error = B_TRUE;
2669 2736 return (Z_INSUFFICIENT_SPEC);
2670 2737 }
2671 2738 switch (cmd->cmd_prop_name[i]) {
2672 2739 case PT_DIR:
2673 2740 (void) strlcpy(fstab->zone_fs_dir, pp->pv_simple,
2674 2741 sizeof (fstab->zone_fs_dir));
2675 2742 break;
2676 2743 case PT_SPECIAL:
2677 2744 (void) strlcpy(fstab->zone_fs_special, pp->pv_simple,
2678 2745 sizeof (fstab->zone_fs_special));
2679 2746 break;
2680 2747 case PT_RAW:
2681 2748 (void) strlcpy(fstab->zone_fs_raw, pp->pv_simple,
2682 2749 sizeof (fstab->zone_fs_raw));
2683 2750 break;
2684 2751 case PT_TYPE:
2685 2752 (void) strlcpy(fstab->zone_fs_type, pp->pv_simple,
2686 2753 sizeof (fstab->zone_fs_type));
2687 2754 break;
2688 2755 default:
2689 2756 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2690 2757 Z_NO_PROPERTY_TYPE, B_TRUE);
2691 2758 return (Z_INSUFFICIENT_SPEC);
2692 2759 }
2693 2760 }
2694 2761 if (fill_in_only)
2695 2762 return (Z_OK);
2696 2763 return (zonecfg_lookup_filesystem(handle, fstab));
2697 2764 }
2698 2765
2699 2766 static int
2700 2767 fill_in_nwiftab(cmd_t *cmd, struct zone_nwiftab *nwiftab,
2701 2768 boolean_t fill_in_only)
2702 2769 {
2703 2770 int err, i;
2704 2771 property_value_ptr_t pp;
2705 2772
2706 2773 if ((err = initialize(B_TRUE)) != Z_OK)
2707 2774 return (err);
2708 2775
2709 2776 bzero(nwiftab, sizeof (*nwiftab));
2710 2777 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2711 2778 pp = cmd->cmd_property_ptr[i];
2712 2779 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2713 2780 zerr(gettext("A simple value was expected here."));
2714 2781 saw_error = B_TRUE;
2715 2782 return (Z_INSUFFICIENT_SPEC);
2716 2783 }
2717 2784 switch (cmd->cmd_prop_name[i]) {
2718 2785 case PT_ADDRESS:
2719 2786 (void) strlcpy(nwiftab->zone_nwif_address,
2720 2787 pp->pv_simple, sizeof (nwiftab->zone_nwif_address));
2721 2788 break;
2722 2789 case PT_ALLOWED_ADDRESS:
2723 2790 (void) strlcpy(nwiftab->zone_nwif_allowed_address,
2724 2791 pp->pv_simple,
2725 2792 sizeof (nwiftab->zone_nwif_allowed_address));
2726 2793 break;
2727 2794 case PT_PHYSICAL:
2728 2795 (void) strlcpy(nwiftab->zone_nwif_physical,
2729 2796 pp->pv_simple,
2730 2797 sizeof (nwiftab->zone_nwif_physical));
2731 2798 break;
2732 2799 case PT_DEFROUTER:
2733 2800 (void) strlcpy(nwiftab->zone_nwif_defrouter,
2734 2801 pp->pv_simple,
2735 2802 sizeof (nwiftab->zone_nwif_defrouter));
2736 2803 break;
2737 2804 default:
2738 2805 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2739 2806 Z_NO_PROPERTY_TYPE, B_TRUE);
2740 2807 return (Z_INSUFFICIENT_SPEC);
2741 2808 }
2742 2809 }
2743 2810 if (fill_in_only)
2744 2811 return (Z_OK);
2745 2812 err = zonecfg_lookup_nwif(handle, nwiftab);
2746 2813 return (err);
2747 2814 }
2748 2815
2749 2816 static int
2750 2817 fill_in_devtab(cmd_t *cmd, struct zone_devtab *devtab, boolean_t fill_in_only)
2751 2818 {
2752 2819 int err, i;
2753 2820 property_value_ptr_t pp;
2754 2821
2755 2822 if ((err = initialize(B_TRUE)) != Z_OK)
2756 2823 return (err);
2757 2824
2758 2825 bzero(devtab, sizeof (*devtab));
2759 2826 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2760 2827 pp = cmd->cmd_property_ptr[i];
2761 2828 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2762 2829 zerr(gettext("A simple value was expected here."));
2763 2830 saw_error = B_TRUE;
2764 2831 return (Z_INSUFFICIENT_SPEC);
2765 2832 }
2766 2833 switch (cmd->cmd_prop_name[i]) {
2767 2834 case PT_MATCH:
2768 2835 (void) strlcpy(devtab->zone_dev_match, pp->pv_simple,
2769 2836 sizeof (devtab->zone_dev_match));
2770 2837 break;
2771 2838 default:
2772 2839 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2773 2840 Z_NO_PROPERTY_TYPE, B_TRUE);
2774 2841 return (Z_INSUFFICIENT_SPEC);
2775 2842 }
2776 2843 }
2777 2844 if (fill_in_only)
2778 2845 return (Z_OK);
2779 2846 err = zonecfg_lookup_dev(handle, devtab);
2780 2847 return (err);
2781 2848 }
2782 2849
2783 2850 static int
2784 2851 fill_in_rctltab(cmd_t *cmd, struct zone_rctltab *rctltab,
2785 2852 boolean_t fill_in_only)
2786 2853 {
2787 2854 int err, i;
2788 2855 property_value_ptr_t pp;
2789 2856
2790 2857 if ((err = initialize(B_TRUE)) != Z_OK)
2791 2858 return (err);
2792 2859
2793 2860 bzero(rctltab, sizeof (*rctltab));
2794 2861 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2795 2862 pp = cmd->cmd_property_ptr[i];
2796 2863 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2797 2864 zerr(gettext("A simple value was expected here."));
2798 2865 saw_error = B_TRUE;
2799 2866 return (Z_INSUFFICIENT_SPEC);
2800 2867 }
2801 2868 switch (cmd->cmd_prop_name[i]) {
2802 2869 case PT_NAME:
2803 2870 (void) strlcpy(rctltab->zone_rctl_name, pp->pv_simple,
2804 2871 sizeof (rctltab->zone_rctl_name));
2805 2872 break;
2806 2873 default:
2807 2874 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2808 2875 Z_NO_PROPERTY_TYPE, B_TRUE);
2809 2876 return (Z_INSUFFICIENT_SPEC);
2810 2877 }
2811 2878 }
2812 2879 if (fill_in_only)
2813 2880 return (Z_OK);
2814 2881 err = zonecfg_lookup_rctl(handle, rctltab);
2815 2882 return (err);
2816 2883 }
2817 2884
2818 2885 static int
2819 2886 fill_in_attrtab(cmd_t *cmd, struct zone_attrtab *attrtab,
2820 2887 boolean_t fill_in_only)
2821 2888 {
2822 2889 int err, i;
2823 2890 property_value_ptr_t pp;
2824 2891
2825 2892 if ((err = initialize(B_TRUE)) != Z_OK)
2826 2893 return (err);
2827 2894
2828 2895 bzero(attrtab, sizeof (*attrtab));
2829 2896 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2830 2897 pp = cmd->cmd_property_ptr[i];
2831 2898 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2832 2899 zerr(gettext("A simple value was expected here."));
2833 2900 saw_error = B_TRUE;
2834 2901 return (Z_INSUFFICIENT_SPEC);
2835 2902 }
2836 2903 switch (cmd->cmd_prop_name[i]) {
2837 2904 case PT_NAME:
2838 2905 (void) strlcpy(attrtab->zone_attr_name, pp->pv_simple,
2839 2906 sizeof (attrtab->zone_attr_name));
2840 2907 break;
2841 2908 case PT_TYPE:
2842 2909 (void) strlcpy(attrtab->zone_attr_type, pp->pv_simple,
2843 2910 sizeof (attrtab->zone_attr_type));
2844 2911 break;
2845 2912 case PT_VALUE:
2846 2913 (void) strlcpy(attrtab->zone_attr_value, pp->pv_simple,
2847 2914 sizeof (attrtab->zone_attr_value));
2848 2915 break;
2849 2916 default:
2850 2917 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2851 2918 Z_NO_PROPERTY_TYPE, B_TRUE);
2852 2919 return (Z_INSUFFICIENT_SPEC);
2853 2920 }
2854 2921 }
2855 2922 if (fill_in_only)
2856 2923 return (Z_OK);
2857 2924 err = zonecfg_lookup_attr(handle, attrtab);
2858 2925 return (err);
2859 2926 }
2860 2927
2861 2928 static int
2862 2929 fill_in_dstab(cmd_t *cmd, struct zone_dstab *dstab, boolean_t fill_in_only)
2863 2930 {
2864 2931 int err, i;
2865 2932 property_value_ptr_t pp;
2866 2933
2867 2934 if ((err = initialize(B_TRUE)) != Z_OK)
2868 2935 return (err);
2869 2936
2870 2937 dstab->zone_dataset_name[0] = '\0';
2871 2938 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2872 2939 pp = cmd->cmd_property_ptr[i];
2873 2940 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2874 2941 zerr(gettext("A simple value was expected here."));
2875 2942 saw_error = B_TRUE;
2876 2943 return (Z_INSUFFICIENT_SPEC);
2877 2944 }
2878 2945 switch (cmd->cmd_prop_name[i]) {
2879 2946 case PT_NAME:
2880 2947 (void) strlcpy(dstab->zone_dataset_name, pp->pv_simple,
2881 2948 sizeof (dstab->zone_dataset_name));
2882 2949 break;
2883 2950 default:
2884 2951 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2885 2952 Z_NO_PROPERTY_TYPE, B_TRUE);
2886 2953 return (Z_INSUFFICIENT_SPEC);
2887 2954 }
2888 2955 }
2889 2956 if (fill_in_only)
2890 2957 return (Z_OK);
2891 2958 return (zonecfg_lookup_ds(handle, dstab));
2892 2959 }
2893 2960
2894 2961 static int
2895 2962 fill_in_admintab(cmd_t *cmd, struct zone_admintab *admintab,
2896 2963 boolean_t fill_in_only)
2897 2964 {
2898 2965 int err, i;
2899 2966 property_value_ptr_t pp;
2900 2967
2901 2968 if ((err = initialize(B_TRUE)) != Z_OK)
2902 2969 return (err);
2903 2970
2904 2971 bzero(admintab, sizeof (*admintab));
2905 2972 for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
2906 2973 pp = cmd->cmd_property_ptr[i];
2907 2974 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2908 2975 zerr(gettext("A simple value was expected here."));
2909 2976 saw_error = B_TRUE;
2910 2977 return (Z_INSUFFICIENT_SPEC);
2911 2978 }
2912 2979 switch (cmd->cmd_prop_name[i]) {
2913 2980 case PT_USER:
2914 2981 (void) strlcpy(admintab->zone_admin_user, pp->pv_simple,
2915 2982 sizeof (admintab->zone_admin_user));
2916 2983 break;
2917 2984 case PT_AUTHS:
2918 2985 (void) strlcpy(admintab->zone_admin_auths,
2919 2986 pp->pv_simple, sizeof (admintab->zone_admin_auths));
2920 2987 break;
2921 2988 default:
2922 2989 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
↓ open down ↓ |
649 lines elided |
↑ open up ↑ |
2923 2990 Z_NO_PROPERTY_TYPE, B_TRUE);
2924 2991 return (Z_INSUFFICIENT_SPEC);
2925 2992 }
2926 2993 }
2927 2994 if (fill_in_only)
2928 2995 return (Z_OK);
2929 2996 err = zonecfg_lookup_admin(handle, admintab);
2930 2997 return (err);
2931 2998 }
2932 2999
3000 +static int
3001 +fill_in_secflagstab(cmd_t *cmd, struct zone_secflagstab *secflagstab,
3002 + boolean_t fill_in_only)
3003 +{
3004 + int err, i;
3005 + property_value_ptr_t pp;
3006 +
3007 + if ((err = initialize(B_TRUE)) != Z_OK)
3008 + return (err);
3009 +
3010 + bzero(secflagstab, sizeof (*secflagstab));
3011 + for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
3012 + pp = cmd->cmd_property_ptr[i];
3013 + if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
3014 + zerr(gettext("A simple value was expected here."));
3015 + saw_error = B_TRUE;
3016 + return (Z_INSUFFICIENT_SPEC);
3017 + }
3018 + switch (cmd->cmd_prop_name[i]) {
3019 + case PT_DEFAULT:
3020 + (void) strlcpy(secflagstab->zone_secflags_default,
3021 + pp->pv_simple,
3022 + sizeof (secflagstab->zone_secflags_default));
3023 + break;
3024 + case PT_LOWER:
3025 + (void) strlcpy(secflagstab->zone_secflags_lower,
3026 + pp->pv_simple,
3027 + sizeof (secflagstab->zone_secflags_lower));
3028 + break;
3029 + case PT_UPPER:
3030 + (void) strlcpy(secflagstab->zone_secflags_upper,
3031 + pp->pv_simple,
3032 + sizeof (secflagstab->zone_secflags_upper));
3033 + break;
3034 + default:
3035 + zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
3036 + Z_NO_PROPERTY_TYPE, B_TRUE);
3037 + return (Z_INSUFFICIENT_SPEC);
3038 + }
3039 + }
3040 + if (fill_in_only)
3041 + return (Z_OK);
3042 +
3043 + err = zonecfg_lookup_secflags(handle, secflagstab);
3044 +
3045 + return (err);
3046 +}
3047 +
2933 3048 static void
2934 3049 remove_aliased_rctl(int type, char *name)
2935 3050 {
2936 3051 int err;
2937 3052 uint64_t tmp;
2938 3053
2939 3054 if ((err = zonecfg_get_aliased_rctl(handle, name, &tmp)) != Z_OK) {
2940 3055 zerr("%s %s: %s", cmd_to_str(CMD_CLEAR), pt_to_str(type),
2941 3056 zonecfg_strerror(err));
2942 3057 saw_error = B_TRUE;
2943 3058 return;
2944 3059 }
2945 3060 if ((err = zonecfg_rm_aliased_rctl(handle, name)) != Z_OK) {
2946 3061 zerr("%s %s: %s", cmd_to_str(CMD_CLEAR), pt_to_str(type),
2947 3062 zonecfg_strerror(err));
2948 3063 saw_error = B_TRUE;
2949 3064 } else {
2950 3065 need_to_commit = B_TRUE;
2951 3066 }
2952 3067 }
2953 3068
2954 3069 static boolean_t
2955 3070 prompt_remove_resource(cmd_t *cmd, char *rsrc)
2956 3071 {
2957 3072 int num;
2958 3073 int answer;
2959 3074 int arg;
2960 3075 boolean_t force = B_FALSE;
2961 3076 char prompt[128];
2962 3077 boolean_t arg_err = B_FALSE;
2963 3078
2964 3079 optind = 0;
2965 3080 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) {
2966 3081 switch (arg) {
2967 3082 case 'F':
2968 3083 force = B_TRUE;
2969 3084 break;
2970 3085 default:
2971 3086 arg_err = B_TRUE;
2972 3087 break;
2973 3088 }
2974 3089 }
2975 3090 if (arg_err)
2976 3091 return (B_FALSE);
2977 3092
2978 3093
2979 3094 num = zonecfg_num_resources(handle, rsrc);
2980 3095
2981 3096 if (num == 0) {
2982 3097 z_cmd_rt_perror(CMD_REMOVE, cmd->cmd_res_type, Z_NO_ENTRY,
2983 3098 B_TRUE);
2984 3099 return (B_FALSE);
2985 3100 }
2986 3101 if (num > 1 && !force) {
2987 3102 if (!interactive_mode) {
2988 3103 zerr(gettext("There are multiple instances of this "
2989 3104 "resource. Either qualify the resource to\n"
2990 3105 "remove a single instance or use the -F option to "
2991 3106 "remove all instances."));
2992 3107 saw_error = B_TRUE;
2993 3108 return (B_FALSE);
2994 3109 }
2995 3110 (void) snprintf(prompt, sizeof (prompt), gettext(
2996 3111 "Are you sure you want to remove ALL '%s' resources"),
2997 3112 rsrc);
2998 3113 answer = ask_yesno(B_FALSE, prompt);
2999 3114 if (answer == -1) {
3000 3115 zerr(gettext("Resource incomplete."));
3001 3116 return (B_FALSE);
3002 3117 }
3003 3118 if (answer != 1)
3004 3119 return (B_FALSE);
3005 3120 }
3006 3121 return (B_TRUE);
3007 3122 }
3008 3123
3009 3124 static void
3010 3125 remove_fs(cmd_t *cmd)
3011 3126 {
3012 3127 int err;
3013 3128
3014 3129 /* traditional, qualified fs removal */
3015 3130 if (cmd->cmd_prop_nv_pairs > 0) {
3016 3131 struct zone_fstab fstab;
3017 3132
3018 3133 if ((err = fill_in_fstab(cmd, &fstab, B_FALSE)) != Z_OK) {
3019 3134 z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE);
3020 3135 return;
3021 3136 }
3022 3137 if ((err = zonecfg_delete_filesystem(handle, &fstab)) != Z_OK)
3023 3138 z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE);
3024 3139 else
3025 3140 need_to_commit = B_TRUE;
3026 3141 zonecfg_free_fs_option_list(fstab.zone_fs_options);
3027 3142 return;
3028 3143 }
3029 3144
3030 3145 /*
3031 3146 * unqualified fs removal. remove all fs's but prompt if more
3032 3147 * than one.
3033 3148 */
3034 3149 if (!prompt_remove_resource(cmd, "fs"))
3035 3150 return;
3036 3151
3037 3152 if ((err = zonecfg_del_all_resources(handle, "fs")) != Z_OK)
3038 3153 z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE);
3039 3154 else
3040 3155 need_to_commit = B_TRUE;
3041 3156 }
3042 3157
3043 3158 static void
3044 3159 remove_net(cmd_t *cmd)
3045 3160 {
3046 3161 int err;
3047 3162
3048 3163 /* traditional, qualified net removal */
3049 3164 if (cmd->cmd_prop_nv_pairs > 0) {
3050 3165 struct zone_nwiftab nwiftab;
3051 3166
3052 3167 if ((err = fill_in_nwiftab(cmd, &nwiftab, B_FALSE)) != Z_OK) {
3053 3168 z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE);
3054 3169 return;
3055 3170 }
3056 3171 if ((err = zonecfg_delete_nwif(handle, &nwiftab)) != Z_OK)
3057 3172 z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE);
3058 3173 else
3059 3174 need_to_commit = B_TRUE;
3060 3175 return;
3061 3176 }
3062 3177
3063 3178 /*
3064 3179 * unqualified net removal. remove all nets but prompt if more
3065 3180 * than one.
3066 3181 */
3067 3182 if (!prompt_remove_resource(cmd, "net"))
3068 3183 return;
3069 3184
3070 3185 if ((err = zonecfg_del_all_resources(handle, "net")) != Z_OK)
3071 3186 z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE);
3072 3187 else
3073 3188 need_to_commit = B_TRUE;
3074 3189 }
3075 3190
3076 3191 static void
3077 3192 remove_device(cmd_t *cmd)
3078 3193 {
3079 3194 int err;
3080 3195
3081 3196 /* traditional, qualified device removal */
3082 3197 if (cmd->cmd_prop_nv_pairs > 0) {
3083 3198 struct zone_devtab devtab;
3084 3199
3085 3200 if ((err = fill_in_devtab(cmd, &devtab, B_FALSE)) != Z_OK) {
3086 3201 z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE);
3087 3202 return;
3088 3203 }
3089 3204 if ((err = zonecfg_delete_dev(handle, &devtab)) != Z_OK)
3090 3205 z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE);
3091 3206 else
3092 3207 need_to_commit = B_TRUE;
3093 3208 return;
3094 3209 }
3095 3210
3096 3211 /*
3097 3212 * unqualified device removal. remove all devices but prompt if more
3098 3213 * than one.
3099 3214 */
3100 3215 if (!prompt_remove_resource(cmd, "device"))
3101 3216 return;
3102 3217
3103 3218 if ((err = zonecfg_del_all_resources(handle, "device")) != Z_OK)
3104 3219 z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE);
3105 3220 else
3106 3221 need_to_commit = B_TRUE;
3107 3222 }
3108 3223
3109 3224 static void
3110 3225 remove_attr(cmd_t *cmd)
3111 3226 {
3112 3227 int err;
3113 3228
3114 3229 /* traditional, qualified attr removal */
3115 3230 if (cmd->cmd_prop_nv_pairs > 0) {
3116 3231 struct zone_attrtab attrtab;
3117 3232
3118 3233 if ((err = fill_in_attrtab(cmd, &attrtab, B_FALSE)) != Z_OK) {
3119 3234 z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE);
3120 3235 return;
3121 3236 }
3122 3237 if ((err = zonecfg_delete_attr(handle, &attrtab)) != Z_OK)
3123 3238 z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE);
3124 3239 else
3125 3240 need_to_commit = B_TRUE;
3126 3241 return;
3127 3242 }
3128 3243
3129 3244 /*
3130 3245 * unqualified attr removal. remove all attrs but prompt if more
3131 3246 * than one.
3132 3247 */
3133 3248 if (!prompt_remove_resource(cmd, "attr"))
3134 3249 return;
3135 3250
3136 3251 if ((err = zonecfg_del_all_resources(handle, "attr")) != Z_OK)
3137 3252 z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE);
3138 3253 else
3139 3254 need_to_commit = B_TRUE;
3140 3255 }
3141 3256
3142 3257 static void
3143 3258 remove_dataset(cmd_t *cmd)
3144 3259 {
3145 3260 int err;
3146 3261
3147 3262 /* traditional, qualified dataset removal */
3148 3263 if (cmd->cmd_prop_nv_pairs > 0) {
3149 3264 struct zone_dstab dstab;
3150 3265
3151 3266 if ((err = fill_in_dstab(cmd, &dstab, B_FALSE)) != Z_OK) {
3152 3267 z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE);
3153 3268 return;
3154 3269 }
3155 3270 if ((err = zonecfg_delete_ds(handle, &dstab)) != Z_OK)
3156 3271 z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE);
3157 3272 else
3158 3273 need_to_commit = B_TRUE;
3159 3274 return;
3160 3275 }
3161 3276
3162 3277 /*
3163 3278 * unqualified dataset removal. remove all datasets but prompt if more
3164 3279 * than one.
3165 3280 */
3166 3281 if (!prompt_remove_resource(cmd, "dataset"))
3167 3282 return;
3168 3283
3169 3284 if ((err = zonecfg_del_all_resources(handle, "dataset")) != Z_OK)
3170 3285 z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE);
3171 3286 else
3172 3287 need_to_commit = B_TRUE;
3173 3288 }
3174 3289
3175 3290 static void
3176 3291 remove_rctl(cmd_t *cmd)
3177 3292 {
3178 3293 int err;
3179 3294
3180 3295 /* traditional, qualified rctl removal */
3181 3296 if (cmd->cmd_prop_nv_pairs > 0) {
3182 3297 struct zone_rctltab rctltab;
3183 3298
3184 3299 if ((err = fill_in_rctltab(cmd, &rctltab, B_FALSE)) != Z_OK) {
3185 3300 z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE);
3186 3301 return;
3187 3302 }
3188 3303 if ((err = zonecfg_delete_rctl(handle, &rctltab)) != Z_OK)
3189 3304 z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE);
3190 3305 else
3191 3306 need_to_commit = B_TRUE;
3192 3307 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
3193 3308 return;
3194 3309 }
3195 3310
3196 3311 /*
3197 3312 * unqualified rctl removal. remove all rctls but prompt if more
3198 3313 * than one.
3199 3314 */
3200 3315 if (!prompt_remove_resource(cmd, "rctl"))
3201 3316 return;
3202 3317
3203 3318 if ((err = zonecfg_del_all_resources(handle, "rctl")) != Z_OK)
3204 3319 z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE);
3205 3320 else
3206 3321 need_to_commit = B_TRUE;
3207 3322 }
3208 3323
3209 3324 static void
3210 3325 remove_pset()
3211 3326 {
3212 3327 int err;
3213 3328 struct zone_psettab psettab;
3214 3329
3215 3330 if ((err = zonecfg_lookup_pset(handle, &psettab)) != Z_OK) {
3216 3331 z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE);
3217 3332 return;
3218 3333 }
3219 3334 if ((err = zonecfg_delete_pset(handle)) != Z_OK)
3220 3335 z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE);
3221 3336 else
3222 3337 need_to_commit = B_TRUE;
3223 3338 }
3224 3339
3225 3340 static void
3226 3341 remove_pcap()
3227 3342 {
3228 3343 int err;
3229 3344 uint64_t tmp;
3230 3345
3231 3346 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp) != Z_OK) {
3232 3347 zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_PCAP),
3233 3348 zonecfg_strerror(Z_NO_RESOURCE_TYPE));
3234 3349 saw_error = B_TRUE;
3235 3350 return;
3236 3351 }
3237 3352
3238 3353 if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_CPUCAP)) != Z_OK)
3239 3354 z_cmd_rt_perror(CMD_REMOVE, RT_PCAP, err, B_TRUE);
3240 3355 else
3241 3356 need_to_commit = B_TRUE;
3242 3357 }
3243 3358
3244 3359 static void
3245 3360 remove_mcap()
3246 3361 {
3247 3362 int err, res1, res2, res3;
3248 3363 uint64_t tmp;
3249 3364 struct zone_mcaptab mcaptab;
3250 3365 boolean_t revert = B_FALSE;
3251 3366
3252 3367 res1 = zonecfg_lookup_mcap(handle, &mcaptab);
3253 3368 res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp);
3254 3369 res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &tmp);
3255 3370
3256 3371 /* if none of these exist, there is no resource to remove */
3257 3372 if (res1 != Z_OK && res2 != Z_OK && res3 != Z_OK) {
3258 3373 zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_MCAP),
3259 3374 zonecfg_strerror(Z_NO_RESOURCE_TYPE));
3260 3375 saw_error = B_TRUE;
3261 3376 return;
3262 3377 }
3263 3378 if (res1 == Z_OK) {
3264 3379 if ((err = zonecfg_delete_mcap(handle)) != Z_OK) {
3265 3380 z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE);
3266 3381 revert = B_TRUE;
3267 3382 } else {
3268 3383 need_to_commit = B_TRUE;
3269 3384 }
3270 3385 }
3271 3386 if (res2 == Z_OK) {
3272 3387 if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXSWAP))
3273 3388 != Z_OK) {
3274 3389 z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE);
3275 3390 revert = B_TRUE;
3276 3391 } else {
3277 3392 need_to_commit = B_TRUE;
3278 3393 }
3279 3394 }
3280 3395 if (res3 == Z_OK) {
3281 3396 if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM))
3282 3397 != Z_OK) {
3283 3398 z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE);
3284 3399 revert = B_TRUE;
3285 3400 } else {
3286 3401 need_to_commit = B_TRUE;
3287 3402 }
3288 3403 }
3289 3404
3290 3405 if (revert)
3291 3406 need_to_commit = B_FALSE;
3292 3407 }
3293 3408
3294 3409 static void
3295 3410 remove_admin(cmd_t *cmd)
3296 3411 {
3297 3412 int err;
3298 3413
3299 3414 /* traditional, qualified attr removal */
3300 3415 if (cmd->cmd_prop_nv_pairs > 0) {
3301 3416 struct zone_admintab admintab;
3302 3417
3303 3418 if ((err = fill_in_admintab(cmd, &admintab, B_FALSE)) != Z_OK) {
3304 3419 z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3305 3420 err, B_TRUE);
3306 3421 return;
3307 3422 }
3308 3423 if ((err = zonecfg_delete_admin(handle, &admintab,
3309 3424 zone))
3310 3425 != Z_OK)
3311 3426 z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3312 3427 err, B_TRUE);
3313 3428 else
3314 3429 need_to_commit = B_TRUE;
3315 3430 return;
3316 3431 } else {
3317 3432 /*
3318 3433 * unqualified admin removal.
3319 3434 * remove all admins but prompt if more
3320 3435 * than one.
3321 3436 */
3322 3437 if (!prompt_remove_resource(cmd, "admin"))
3323 3438 return;
3324 3439
↓ open down ↓ |
382 lines elided |
↑ open up ↑ |
3325 3440 if ((err = zonecfg_delete_admins(handle, zone))
3326 3441 != Z_OK)
3327 3442 z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN,
3328 3443 err, B_TRUE);
3329 3444 else
3330 3445 need_to_commit = B_TRUE;
3331 3446 }
3332 3447 }
3333 3448
3334 3449 static void
3450 +remove_secflags()
3451 +{
3452 + int err;
3453 + struct zone_secflagstab sectab = { 0 };
3454 +
3455 + if (zonecfg_lookup_secflags(handle, §ab) != Z_OK) {
3456 + zerr("%s %s: %s", cmd_to_str(CMD_REMOVE),
3457 + rt_to_str(RT_SECFLAGS),
3458 + zonecfg_strerror(Z_NO_RESOURCE_TYPE));
3459 + return;
3460 + }
3461 +
3462 + if ((err = zonecfg_delete_secflags(handle, §ab)) != Z_OK) {
3463 + z_cmd_rt_perror(CMD_REMOVE, RT_SECFLAGS, err, B_TRUE);
3464 + return;
3465 + }
3466 +
3467 + need_to_commit = B_TRUE;
3468 +}
3469 +
3470 +static void
3335 3471 remove_resource(cmd_t *cmd)
3336 3472 {
3337 3473 int type;
3338 3474 int arg;
3339 3475 boolean_t arg_err = B_FALSE;
3340 3476
3341 3477 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3342 3478 long_usage(CMD_REMOVE, B_TRUE);
3343 3479 return;
3344 3480 }
3345 3481
3346 3482 optind = 0;
3347 3483 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
3348 3484 switch (arg) {
3349 3485 case '?':
3350 3486 longer_usage(CMD_REMOVE);
3351 3487 arg_err = B_TRUE;
3352 3488 break;
3353 3489 case 'F':
3354 3490 break;
3355 3491 default:
3356 3492 short_usage(CMD_REMOVE);
3357 3493 arg_err = B_TRUE;
3358 3494 break;
3359 3495 }
3360 3496 }
3361 3497 if (arg_err)
3362 3498 return;
3363 3499
3364 3500 if (initialize(B_TRUE) != Z_OK)
3365 3501 return;
3366 3502
3367 3503 switch (type) {
3368 3504 case RT_FS:
3369 3505 remove_fs(cmd);
3370 3506 return;
3371 3507 case RT_NET:
3372 3508 remove_net(cmd);
3373 3509 return;
3374 3510 case RT_DEVICE:
3375 3511 remove_device(cmd);
3376 3512 return;
3377 3513 case RT_RCTL:
3378 3514 remove_rctl(cmd);
3379 3515 return;
3380 3516 case RT_ATTR:
3381 3517 remove_attr(cmd);
3382 3518 return;
3383 3519 case RT_DATASET:
3384 3520 remove_dataset(cmd);
3385 3521 return;
3386 3522 case RT_DCPU:
3387 3523 remove_pset();
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
3388 3524 return;
3389 3525 case RT_PCAP:
3390 3526 remove_pcap();
3391 3527 return;
3392 3528 case RT_MCAP:
3393 3529 remove_mcap();
3394 3530 return;
3395 3531 case RT_ADMIN:
3396 3532 remove_admin(cmd);
3397 3533 return;
3534 + case RT_SECFLAGS:
3535 + remove_secflags();
3536 + return;
3398 3537 default:
3399 3538 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3400 3539 long_usage(CMD_REMOVE, B_TRUE);
3401 3540 usage(B_FALSE, HELP_RESOURCES);
3402 3541 return;
3403 3542 }
3404 3543 }
3405 3544
3406 3545 static void
3407 3546 remove_property(cmd_t *cmd)
3408 3547 {
3409 3548 char *prop_id;
3410 3549 int err, res_type, prop_type;
3411 3550 property_value_ptr_t pp;
3412 3551 struct zone_rctlvaltab *rctlvaltab;
3413 3552 complex_property_ptr_t cx;
3414 3553
3415 3554 res_type = resource_scope;
3416 3555 prop_type = cmd->cmd_prop_name[0];
3417 3556 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
3418 3557 long_usage(CMD_REMOVE, B_TRUE);
3419 3558 return;
3420 3559 }
3421 3560
3422 3561 if (cmd->cmd_prop_nv_pairs != 1) {
3423 3562 long_usage(CMD_ADD, B_TRUE);
3424 3563 return;
3425 3564 }
3426 3565
3427 3566 if (initialize(B_TRUE) != Z_OK)
3428 3567 return;
3429 3568
3430 3569 switch (res_type) {
3431 3570 case RT_FS:
3432 3571 if (prop_type != PT_OPTIONS) {
3433 3572 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3434 3573 B_TRUE);
3435 3574 long_usage(CMD_REMOVE, B_TRUE);
3436 3575 usage(B_FALSE, HELP_PROPS);
3437 3576 return;
3438 3577 }
3439 3578 pp = cmd->cmd_property_ptr[0];
3440 3579 if (pp->pv_type == PROP_VAL_COMPLEX) {
3441 3580 zerr(gettext("A %s or %s value was expected here."),
3442 3581 pvt_to_str(PROP_VAL_SIMPLE),
3443 3582 pvt_to_str(PROP_VAL_LIST));
3444 3583 saw_error = B_TRUE;
3445 3584 return;
3446 3585 }
3447 3586 if (pp->pv_type == PROP_VAL_SIMPLE) {
3448 3587 if (pp->pv_simple == NULL) {
3449 3588 long_usage(CMD_ADD, B_TRUE);
3450 3589 return;
3451 3590 }
3452 3591 prop_id = pp->pv_simple;
3453 3592 err = zonecfg_remove_fs_option(&in_progress_fstab,
3454 3593 prop_id);
3455 3594 if (err != Z_OK)
3456 3595 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3457 3596 } else {
3458 3597 list_property_ptr_t list;
3459 3598
3460 3599 for (list = pp->pv_list; list != NULL;
3461 3600 list = list->lp_next) {
3462 3601 prop_id = list->lp_simple;
3463 3602 if (prop_id == NULL)
3464 3603 break;
3465 3604 err = zonecfg_remove_fs_option(
3466 3605 &in_progress_fstab, prop_id);
3467 3606 if (err != Z_OK)
3468 3607 zone_perror(pt_to_str(prop_type), err,
3469 3608 B_TRUE);
3470 3609 }
3471 3610 }
3472 3611 return;
3473 3612 case RT_RCTL:
3474 3613 if (prop_type != PT_VALUE) {
3475 3614 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3476 3615 B_TRUE);
3477 3616 long_usage(CMD_REMOVE, B_TRUE);
3478 3617 usage(B_FALSE, HELP_PROPS);
3479 3618 return;
3480 3619 }
3481 3620 pp = cmd->cmd_property_ptr[0];
3482 3621 if (pp->pv_type != PROP_VAL_COMPLEX) {
3483 3622 zerr(gettext("A %s value was expected here."),
3484 3623 pvt_to_str(PROP_VAL_COMPLEX));
3485 3624 saw_error = B_TRUE;
3486 3625 return;
3487 3626 }
3488 3627 if ((rctlvaltab = alloc_rctlvaltab()) == NULL) {
3489 3628 zone_perror(zone, Z_NOMEM, B_TRUE);
3490 3629 exit(Z_ERR);
3491 3630 }
3492 3631 for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) {
3493 3632 switch (cx->cp_type) {
3494 3633 case PT_PRIV:
3495 3634 (void) strlcpy(rctlvaltab->zone_rctlval_priv,
3496 3635 cx->cp_value,
3497 3636 sizeof (rctlvaltab->zone_rctlval_priv));
3498 3637 break;
3499 3638 case PT_LIMIT:
3500 3639 (void) strlcpy(rctlvaltab->zone_rctlval_limit,
3501 3640 cx->cp_value,
3502 3641 sizeof (rctlvaltab->zone_rctlval_limit));
3503 3642 break;
3504 3643 case PT_ACTION:
3505 3644 (void) strlcpy(rctlvaltab->zone_rctlval_action,
3506 3645 cx->cp_value,
3507 3646 sizeof (rctlvaltab->zone_rctlval_action));
3508 3647 break;
3509 3648 default:
3510 3649 zone_perror(pt_to_str(prop_type),
3511 3650 Z_NO_PROPERTY_TYPE, B_TRUE);
3512 3651 long_usage(CMD_ADD, B_TRUE);
3513 3652 usage(B_FALSE, HELP_PROPS);
3514 3653 zonecfg_free_rctl_value_list(rctlvaltab);
3515 3654 return;
3516 3655 }
3517 3656 }
3518 3657 rctlvaltab->zone_rctlval_next = NULL;
3519 3658 err = zonecfg_remove_rctl_value(&in_progress_rctltab,
3520 3659 rctlvaltab);
3521 3660 if (err != Z_OK)
3522 3661 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3523 3662 zonecfg_free_rctl_value_list(rctlvaltab);
3524 3663 return;
3525 3664 case RT_NET:
3526 3665 if (prop_type != PT_DEFROUTER) {
3527 3666 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3528 3667 B_TRUE);
3529 3668 long_usage(CMD_REMOVE, B_TRUE);
3530 3669 usage(B_FALSE, HELP_PROPS);
3531 3670 return;
3532 3671 } else {
3533 3672 bzero(&in_progress_nwiftab.zone_nwif_defrouter,
3534 3673 sizeof (in_progress_nwiftab.zone_nwif_defrouter));
3535 3674 return;
3536 3675 }
3537 3676 default:
3538 3677 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
3539 3678 long_usage(CMD_REMOVE, B_TRUE);
3540 3679 usage(B_FALSE, HELP_RESOURCES);
3541 3680 return;
3542 3681 }
3543 3682 }
3544 3683
3545 3684 void
3546 3685 remove_func(cmd_t *cmd)
3547 3686 {
3548 3687 if (zone_is_read_only(CMD_REMOVE))
3549 3688 return;
3550 3689
3551 3690 assert(cmd != NULL);
3552 3691
3553 3692 if (global_scope) {
3554 3693 if (gz_invalid_resource(cmd->cmd_res_type)) {
3555 3694 zerr(gettext("%s is not a valid resource for the "
3556 3695 "global zone."), rt_to_str(cmd->cmd_res_type));
3557 3696 saw_error = B_TRUE;
3558 3697 return;
3559 3698 }
3560 3699 remove_resource(cmd);
3561 3700 } else {
3562 3701 remove_property(cmd);
3563 3702 }
3564 3703 }
3565 3704
3566 3705 static void
3567 3706 clear_property(cmd_t *cmd)
3568 3707 {
3569 3708 int res_type, prop_type;
3570 3709
3571 3710 res_type = resource_scope;
3572 3711 prop_type = cmd->cmd_res_type;
3573 3712 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
3574 3713 long_usage(CMD_CLEAR, B_TRUE);
3575 3714 return;
3576 3715 }
3577 3716
3578 3717 if (initialize(B_TRUE) != Z_OK)
3579 3718 return;
3580 3719
3581 3720 switch (res_type) {
3582 3721 case RT_FS:
3583 3722 if (prop_type == PT_RAW) {
3584 3723 in_progress_fstab.zone_fs_raw[0] = '\0';
3585 3724 need_to_commit = B_TRUE;
3586 3725 return;
3587 3726 }
3588 3727 break;
3589 3728 case RT_DCPU:
3590 3729 if (prop_type == PT_IMPORTANCE) {
3591 3730 in_progress_psettab.zone_importance[0] = '\0';
3592 3731 need_to_commit = B_TRUE;
3593 3732 return;
3594 3733 }
3595 3734 break;
3596 3735 case RT_MCAP:
3597 3736 switch (prop_type) {
3598 3737 case PT_PHYSICAL:
3599 3738 in_progress_mcaptab.zone_physmem_cap[0] = '\0';
↓ open down ↓ |
192 lines elided |
↑ open up ↑ |
3600 3739 need_to_commit = B_TRUE;
3601 3740 return;
3602 3741 case PT_SWAP:
3603 3742 remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP);
3604 3743 return;
3605 3744 case PT_LOCKED:
3606 3745 remove_aliased_rctl(PT_LOCKED, ALIAS_MAXLOCKEDMEM);
3607 3746 return;
3608 3747 }
3609 3748 break;
3749 + case RT_SECFLAGS:
3750 + switch (prop_type) {
3751 + case PT_LOWER:
3752 + in_progress_secflagstab.zone_secflags_lower[0] = '\0';
3753 + need_to_commit = B_TRUE;
3754 + return;
3755 + case PT_DEFAULT:
3756 + in_progress_secflagstab.zone_secflags_default[0] = '\0';
3757 + need_to_commit = B_TRUE;
3758 + return;
3759 + case PT_UPPER:
3760 + in_progress_secflagstab.zone_secflags_upper[0] = '\0';
3761 + need_to_commit = B_TRUE;
3762 + return;
3763 + }
3764 + break;
3610 3765 default:
3611 3766 break;
3612 3767 }
3613 3768
3614 3769 zone_perror(pt_to_str(prop_type), Z_CLEAR_DISALLOW, B_TRUE);
3615 3770 }
3616 3771
3617 3772 static void
3618 3773 clear_global(cmd_t *cmd)
3619 3774 {
3620 3775 int err, type;
3621 3776
3622 3777 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3623 3778 long_usage(CMD_CLEAR, B_TRUE);
3624 3779 return;
3625 3780 }
3626 3781
3627 3782 if (initialize(B_TRUE) != Z_OK)
3628 3783 return;
3629 3784
3630 3785 switch (type) {
3631 3786 case PT_ZONENAME:
3632 3787 /* FALLTHRU */
3633 3788 case PT_ZONEPATH:
3634 3789 /* FALLTHRU */
3635 3790 case PT_BRAND:
3636 3791 zone_perror(pt_to_str(type), Z_CLEAR_DISALLOW, B_TRUE);
3637 3792 return;
3638 3793 case PT_AUTOBOOT:
3639 3794 /* false is default; we'll treat as equivalent to clearing */
3640 3795 if ((err = zonecfg_set_autoboot(handle, B_FALSE)) != Z_OK)
3641 3796 z_cmd_rt_perror(CMD_CLEAR, RT_AUTOBOOT, err, B_TRUE);
3642 3797 else
3643 3798 need_to_commit = B_TRUE;
3644 3799 return;
3645 3800 case PT_POOL:
3646 3801 if ((err = zonecfg_set_pool(handle, NULL)) != Z_OK)
3647 3802 z_cmd_rt_perror(CMD_CLEAR, RT_POOL, err, B_TRUE);
3648 3803 else
3649 3804 need_to_commit = B_TRUE;
3650 3805 return;
3651 3806 case PT_LIMITPRIV:
3652 3807 if ((err = zonecfg_set_limitpriv(handle, NULL)) != Z_OK)
3653 3808 z_cmd_rt_perror(CMD_CLEAR, RT_LIMITPRIV, err, B_TRUE);
3654 3809 else
3655 3810 need_to_commit = B_TRUE;
3656 3811 return;
3657 3812 case PT_BOOTARGS:
3658 3813 if ((err = zonecfg_set_bootargs(handle, NULL)) != Z_OK)
3659 3814 z_cmd_rt_perror(CMD_CLEAR, RT_BOOTARGS, err, B_TRUE);
3660 3815 else
3661 3816 need_to_commit = B_TRUE;
3662 3817 return;
3663 3818 case PT_SCHED:
3664 3819 if ((err = zonecfg_set_sched(handle, NULL)) != Z_OK)
3665 3820 z_cmd_rt_perror(CMD_CLEAR, RT_SCHED, err, B_TRUE);
3666 3821 else
3667 3822 need_to_commit = B_TRUE;
3668 3823 return;
3669 3824 case PT_IPTYPE:
3670 3825 /* shared is default; we'll treat as equivalent to clearing */
3671 3826 if ((err = zonecfg_set_iptype(handle, ZS_SHARED)) != Z_OK)
3672 3827 z_cmd_rt_perror(CMD_CLEAR, RT_IPTYPE, err, B_TRUE);
3673 3828 else
3674 3829 need_to_commit = B_TRUE;
3675 3830 return;
3676 3831 case PT_MAXLWPS:
3677 3832 remove_aliased_rctl(PT_MAXLWPS, ALIAS_MAXLWPS);
3678 3833 return;
3679 3834 case PT_MAXPROCS:
3680 3835 remove_aliased_rctl(PT_MAXPROCS, ALIAS_MAXPROCS);
3681 3836 return;
3682 3837 case PT_MAXSHMMEM:
3683 3838 remove_aliased_rctl(PT_MAXSHMMEM, ALIAS_MAXSHMMEM);
3684 3839 return;
3685 3840 case PT_MAXSHMIDS:
3686 3841 remove_aliased_rctl(PT_MAXSHMIDS, ALIAS_MAXSHMIDS);
3687 3842 return;
3688 3843 case PT_MAXMSGIDS:
3689 3844 remove_aliased_rctl(PT_MAXMSGIDS, ALIAS_MAXMSGIDS);
3690 3845 return;
3691 3846 case PT_MAXSEMIDS:
3692 3847 remove_aliased_rctl(PT_MAXSEMIDS, ALIAS_MAXSEMIDS);
3693 3848 return;
3694 3849 case PT_SHARES:
3695 3850 remove_aliased_rctl(PT_SHARES, ALIAS_SHARES);
3696 3851 return;
3697 3852 case PT_HOSTID:
3698 3853 if ((err = zonecfg_set_hostid(handle, NULL)) != Z_OK)
3699 3854 z_cmd_rt_perror(CMD_CLEAR, RT_HOSTID, err, B_TRUE);
3700 3855 else
3701 3856 need_to_commit = B_TRUE;
3702 3857 return;
3703 3858 case PT_FS_ALLOWED:
3704 3859 if ((err = zonecfg_set_fs_allowed(handle, NULL)) != Z_OK)
3705 3860 z_cmd_rt_perror(CMD_CLEAR, RT_FS_ALLOWED, err, B_TRUE);
3706 3861 else
3707 3862 need_to_commit = B_TRUE;
3708 3863 return;
3709 3864 default:
3710 3865 zone_perror(pt_to_str(type), Z_NO_PROPERTY_TYPE, B_TRUE);
3711 3866 long_usage(CMD_CLEAR, B_TRUE);
3712 3867 usage(B_FALSE, HELP_PROPS);
3713 3868 return;
3714 3869 }
3715 3870 }
3716 3871
3717 3872 void
3718 3873 clear_func(cmd_t *cmd)
3719 3874 {
3720 3875 if (zone_is_read_only(CMD_CLEAR))
3721 3876 return;
3722 3877
3723 3878 assert(cmd != NULL);
3724 3879
3725 3880 if (global_scope) {
3726 3881 if (gz_invalid_property(cmd->cmd_res_type)) {
3727 3882 zerr(gettext("%s is not a valid property for the "
3728 3883 "global zone."), pt_to_str(cmd->cmd_res_type));
3729 3884 saw_error = B_TRUE;
3730 3885 return;
3731 3886 }
3732 3887
3733 3888 clear_global(cmd);
3734 3889 } else {
3735 3890 clear_property(cmd);
3736 3891 }
3737 3892 }
3738 3893
3739 3894 void
3740 3895 select_func(cmd_t *cmd)
3741 3896 {
3742 3897 int type, err, res;
3743 3898 uint64_t limit;
3744 3899 uint64_t tmp;
3745 3900
3746 3901 if (zone_is_read_only(CMD_SELECT))
3747 3902 return;
3748 3903
3749 3904 assert(cmd != NULL);
3750 3905
3751 3906 if (global_scope) {
3752 3907 global_scope = B_FALSE;
3753 3908 resource_scope = cmd->cmd_res_type;
3754 3909 end_op = CMD_SELECT;
3755 3910 } else {
3756 3911 scope_usage(CMD_SELECT);
3757 3912 return;
3758 3913 }
3759 3914
3760 3915 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3761 3916 long_usage(CMD_SELECT, B_TRUE);
3762 3917 return;
3763 3918 }
3764 3919
3765 3920 if (initialize(B_TRUE) != Z_OK)
3766 3921 return;
3767 3922
3768 3923 switch (type) {
3769 3924 case RT_FS:
3770 3925 if ((err = fill_in_fstab(cmd, &old_fstab, B_FALSE)) != Z_OK) {
3771 3926 z_cmd_rt_perror(CMD_SELECT, RT_FS, err, B_TRUE);
3772 3927 global_scope = B_TRUE;
3773 3928 }
3774 3929 bcopy(&old_fstab, &in_progress_fstab,
3775 3930 sizeof (struct zone_fstab));
3776 3931 return;
3777 3932 case RT_NET:
3778 3933 if ((err = fill_in_nwiftab(cmd, &old_nwiftab, B_FALSE))
3779 3934 != Z_OK) {
3780 3935 z_cmd_rt_perror(CMD_SELECT, RT_NET, err, B_TRUE);
3781 3936 global_scope = B_TRUE;
3782 3937 }
3783 3938 bcopy(&old_nwiftab, &in_progress_nwiftab,
3784 3939 sizeof (struct zone_nwiftab));
3785 3940 return;
3786 3941 case RT_DEVICE:
3787 3942 if ((err = fill_in_devtab(cmd, &old_devtab, B_FALSE)) != Z_OK) {
3788 3943 z_cmd_rt_perror(CMD_SELECT, RT_DEVICE, err, B_TRUE);
3789 3944 global_scope = B_TRUE;
3790 3945 }
3791 3946 bcopy(&old_devtab, &in_progress_devtab,
3792 3947 sizeof (struct zone_devtab));
3793 3948 return;
3794 3949 case RT_RCTL:
3795 3950 if ((err = fill_in_rctltab(cmd, &old_rctltab, B_FALSE))
3796 3951 != Z_OK) {
3797 3952 z_cmd_rt_perror(CMD_SELECT, RT_RCTL, err, B_TRUE);
3798 3953 global_scope = B_TRUE;
3799 3954 }
3800 3955 bcopy(&old_rctltab, &in_progress_rctltab,
3801 3956 sizeof (struct zone_rctltab));
3802 3957 return;
3803 3958 case RT_ATTR:
3804 3959 if ((err = fill_in_attrtab(cmd, &old_attrtab, B_FALSE))
3805 3960 != Z_OK) {
3806 3961 z_cmd_rt_perror(CMD_SELECT, RT_ATTR, err, B_TRUE);
3807 3962 global_scope = B_TRUE;
3808 3963 }
3809 3964 bcopy(&old_attrtab, &in_progress_attrtab,
3810 3965 sizeof (struct zone_attrtab));
3811 3966 return;
3812 3967 case RT_DATASET:
3813 3968 if ((err = fill_in_dstab(cmd, &old_dstab, B_FALSE)) != Z_OK) {
3814 3969 z_cmd_rt_perror(CMD_SELECT, RT_DATASET, err, B_TRUE);
3815 3970 global_scope = B_TRUE;
3816 3971 }
3817 3972 bcopy(&old_dstab, &in_progress_dstab,
3818 3973 sizeof (struct zone_dstab));
3819 3974 return;
3820 3975 case RT_DCPU:
3821 3976 if ((err = zonecfg_lookup_pset(handle, &old_psettab)) != Z_OK) {
3822 3977 z_cmd_rt_perror(CMD_SELECT, RT_DCPU, err, B_TRUE);
3823 3978 global_scope = B_TRUE;
3824 3979 }
3825 3980 bcopy(&old_psettab, &in_progress_psettab,
3826 3981 sizeof (struct zone_psettab));
3827 3982 return;
3828 3983 case RT_PCAP:
3829 3984 if ((err = zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp))
3830 3985 != Z_OK) {
3831 3986 z_cmd_rt_perror(CMD_SELECT, RT_PCAP, err, B_TRUE);
3832 3987 global_scope = B_TRUE;
3833 3988 }
3834 3989 return;
3835 3990 case RT_MCAP:
3836 3991 /* if none of these exist, there is no resource to select */
3837 3992 if ((res = zonecfg_lookup_mcap(handle, &old_mcaptab)) != Z_OK &&
3838 3993 zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &limit)
3839 3994 != Z_OK &&
3840 3995 zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &limit)
3841 3996 != Z_OK) {
3842 3997 z_cmd_rt_perror(CMD_SELECT, RT_MCAP, Z_NO_RESOURCE_TYPE,
3843 3998 B_TRUE);
3844 3999 global_scope = B_TRUE;
3845 4000 }
3846 4001 if (res == Z_OK)
3847 4002 bcopy(&old_mcaptab, &in_progress_mcaptab,
3848 4003 sizeof (struct zone_mcaptab));
3849 4004 else
3850 4005 bzero(&in_progress_mcaptab,
3851 4006 sizeof (in_progress_mcaptab));
3852 4007 return;
↓ open down ↓ |
233 lines elided |
↑ open up ↑ |
3853 4008 case RT_ADMIN:
3854 4009 if ((err = fill_in_admintab(cmd, &old_admintab, B_FALSE))
3855 4010 != Z_OK) {
3856 4011 z_cmd_rt_perror(CMD_SELECT, RT_ADMIN, err,
3857 4012 B_TRUE);
3858 4013 global_scope = B_TRUE;
3859 4014 }
3860 4015 bcopy(&old_admintab, &in_progress_admintab,
3861 4016 sizeof (struct zone_admintab));
3862 4017 return;
4018 + case RT_SECFLAGS:
4019 + if ((err = fill_in_secflagstab(cmd, &old_secflagstab, B_FALSE))
4020 + != Z_OK) {
4021 + z_cmd_rt_perror(CMD_SELECT, RT_SECFLAGS, err,
4022 + B_TRUE);
4023 + global_scope = B_TRUE;
4024 + }
4025 + bcopy(&old_secflagstab, &in_progress_secflagstab,
4026 + sizeof (struct zone_secflagstab));
4027 + return;
3863 4028 default:
3864 4029 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3865 4030 long_usage(CMD_SELECT, B_TRUE);
3866 4031 usage(B_FALSE, HELP_RESOURCES);
3867 4032 return;
3868 4033 }
3869 4034 }
3870 4035
3871 4036 /*
3872 4037 * Network "addresses" can be one of the following forms:
3873 4038 * <IPv4 address>
3874 4039 * <IPv4 address>/<prefix length>
3875 4040 * <IPv6 address>/<prefix length>
3876 4041 * <host name>
3877 4042 * <host name>/<prefix length>
3878 4043 * In other words, the "/" followed by a prefix length is allowed but not
3879 4044 * required for IPv4 addresses and host names, and required for IPv6 addresses.
3880 4045 * If a prefix length is given, it must be in the allowable range: 0 to 32 for
3881 4046 * IPv4 addresses and host names, 0 to 128 for IPv6 addresses.
3882 4047 * Host names must start with an alpha-numeric character, and all subsequent
3883 4048 * characters must be either alpha-numeric or "-".
3884 4049 *
3885 4050 * In some cases, e.g., the nexthop for the defrouter, the context indicates
3886 4051 * that this is the IPV4_ABITS or IPV6_ABITS netmask, in which case we don't
3887 4052 * require the /<prefix length> (and should ignore it if provided).
3888 4053 */
3889 4054
3890 4055 static int
3891 4056 validate_net_address_syntax(char *address, boolean_t ishost)
3892 4057 {
3893 4058 char *slashp, part1[MAXHOSTNAMELEN];
3894 4059 struct in6_addr in6;
3895 4060 struct in_addr in4;
3896 4061 int prefixlen, i;
3897 4062
3898 4063 /*
3899 4064 * Copy the part before any '/' into part1 or copy the whole
3900 4065 * thing if there is no '/'.
3901 4066 */
3902 4067 if ((slashp = strchr(address, '/')) != NULL) {
3903 4068 *slashp = '\0';
3904 4069 (void) strlcpy(part1, address, sizeof (part1));
3905 4070 *slashp = '/';
3906 4071 prefixlen = atoi(++slashp);
3907 4072 } else {
3908 4073 (void) strlcpy(part1, address, sizeof (part1));
3909 4074 }
3910 4075
3911 4076 if (ishost && slashp != NULL) {
3912 4077 zerr(gettext("Warning: prefix length in %s is not required and "
3913 4078 "will be ignored. The default host-prefix length "
3914 4079 "will be used"), address);
3915 4080 }
3916 4081
3917 4082
3918 4083 if (inet_pton(AF_INET6, part1, &in6) == 1) {
3919 4084 if (ishost) {
3920 4085 prefixlen = IPV6_ABITS;
3921 4086 } else if (slashp == NULL) {
3922 4087 zerr(gettext("%s: IPv6 addresses "
3923 4088 "require /prefix-length suffix."), address);
3924 4089 return (Z_ERR);
3925 4090 }
3926 4091 if (prefixlen < 0 || prefixlen > 128) {
3927 4092 zerr(gettext("%s: IPv6 address "
3928 4093 "prefix lengths must be 0 - 128."), address);
3929 4094 return (Z_ERR);
3930 4095 }
3931 4096 return (Z_OK);
3932 4097 }
3933 4098
3934 4099 /* At this point, any /prefix must be for IPv4. */
3935 4100 if (ishost)
3936 4101 prefixlen = IPV4_ABITS;
3937 4102 else if (slashp != NULL) {
3938 4103 if (prefixlen < 0 || prefixlen > 32) {
3939 4104 zerr(gettext("%s: IPv4 address "
3940 4105 "prefix lengths must be 0 - 32."), address);
3941 4106 return (Z_ERR);
3942 4107 }
3943 4108 }
3944 4109
3945 4110 if (inet_pton(AF_INET, part1, &in4) == 1)
3946 4111 return (Z_OK);
3947 4112
3948 4113 /* address may also be a host name */
3949 4114 if (!isalnum(part1[0])) {
3950 4115 zerr(gettext("%s: bogus host name or network address syntax"),
3951 4116 part1);
3952 4117 saw_error = B_TRUE;
3953 4118 usage(B_FALSE, HELP_NETADDR);
3954 4119 return (Z_ERR);
3955 4120 }
3956 4121 for (i = 1; part1[i]; i++)
3957 4122 if (!isalnum(part1[i]) && part1[i] != '-' && part1[i] != '.') {
3958 4123 zerr(gettext("%s: bogus host name or "
3959 4124 "network address syntax"), part1);
3960 4125 saw_error = B_TRUE;
3961 4126 usage(B_FALSE, HELP_NETADDR);
3962 4127 return (Z_ERR);
3963 4128 }
3964 4129 return (Z_OK);
3965 4130 }
3966 4131
3967 4132 static int
3968 4133 validate_net_physical_syntax(const char *ifname)
3969 4134 {
3970 4135 ifspec_t ifnameprop;
3971 4136 zone_iptype_t iptype;
3972 4137
3973 4138 if (zonecfg_get_iptype(handle, &iptype) != Z_OK) {
3974 4139 zerr(gettext("zone configuration has an invalid or nonexistent "
3975 4140 "ip-type property"));
3976 4141 return (Z_ERR);
3977 4142 }
3978 4143 switch (iptype) {
3979 4144 case ZS_SHARED:
3980 4145 if (ifparse_ifspec(ifname, &ifnameprop) == B_FALSE) {
3981 4146 zerr(gettext("%s: invalid physical interface name"),
3982 4147 ifname);
3983 4148 return (Z_ERR);
3984 4149 }
3985 4150 if (ifnameprop.ifsp_lunvalid) {
3986 4151 zerr(gettext("%s: LUNs not allowed in physical "
3987 4152 "interface names"), ifname);
3988 4153 return (Z_ERR);
3989 4154 }
3990 4155 break;
3991 4156 case ZS_EXCLUSIVE:
3992 4157 if (dladm_valid_linkname(ifname) == B_FALSE) {
3993 4158 if (strchr(ifname, ':') != NULL)
3994 4159 zerr(gettext("%s: physical interface name "
3995 4160 "required; logical interface name not "
3996 4161 "allowed"), ifname);
3997 4162 else
3998 4163 zerr(gettext("%s: invalid physical interface "
3999 4164 "name"), ifname);
4000 4165 return (Z_ERR);
4001 4166 }
4002 4167 break;
4003 4168 }
4004 4169 return (Z_OK);
4005 4170 }
4006 4171
4007 4172 static boolean_t
4008 4173 valid_fs_type(const char *type)
4009 4174 {
4010 4175 /*
4011 4176 * Is this a valid path component?
4012 4177 */
4013 4178 if (strlen(type) + 1 > MAXNAMELEN)
4014 4179 return (B_FALSE);
4015 4180 /*
4016 4181 * Make sure a bad value for "type" doesn't make
4017 4182 * /usr/lib/fs/<type>/mount turn into something else.
4018 4183 */
4019 4184 if (strchr(type, '/') != NULL || type[0] == '\0' ||
4020 4185 strcmp(type, ".") == 0 || strcmp(type, "..") == 0)
4021 4186 return (B_FALSE);
4022 4187 /*
4023 4188 * More detailed verification happens later by zoneadm(1m).
4024 4189 */
4025 4190 return (B_TRUE);
4026 4191 }
4027 4192
4028 4193 static boolean_t
4029 4194 allow_exclusive()
4030 4195 {
4031 4196 brand_handle_t bh;
4032 4197 char brand[MAXNAMELEN];
4033 4198 boolean_t ret;
4034 4199
4035 4200 if (zonecfg_get_brand(handle, brand, sizeof (brand)) != Z_OK) {
4036 4201 zerr("%s: %s\n", zone, gettext("could not get zone brand"));
4037 4202 return (B_FALSE);
4038 4203 }
4039 4204 if ((bh = brand_open(brand)) == NULL) {
4040 4205 zerr("%s: %s\n", zone, gettext("unknown brand."));
4041 4206 return (B_FALSE);
4042 4207 }
4043 4208 ret = brand_allow_exclusive_ip(bh);
4044 4209 brand_close(bh);
4045 4210 if (!ret)
4046 4211 zerr(gettext("%s cannot be '%s' when %s is '%s'."),
4047 4212 pt_to_str(PT_IPTYPE), "exclusive",
4048 4213 pt_to_str(PT_BRAND), brand);
4049 4214 return (ret);
4050 4215 }
4051 4216
4052 4217 static void
4053 4218 set_aliased_rctl(char *alias, int prop_type, char *s)
4054 4219 {
4055 4220 uint64_t limit;
4056 4221 int err;
4057 4222 char tmp[128];
4058 4223
4059 4224 if (global_zone && strcmp(alias, ALIAS_SHARES) != 0)
4060 4225 zerr(gettext("WARNING: Setting a global zone resource "
4061 4226 "control too low could deny\nservice "
4062 4227 "to even the root user; "
4063 4228 "this could render the system impossible\n"
4064 4229 "to administer. Please use caution."));
4065 4230
4066 4231 /* convert memory based properties */
4067 4232 if (prop_type == PT_MAXSHMMEM) {
4068 4233 if (!zonecfg_valid_memlimit(s, &limit)) {
4069 4234 zerr(gettext("A non-negative number with a required "
4070 4235 "scale suffix (K, M, G or T) was expected\nhere."));
4071 4236 saw_error = B_TRUE;
4072 4237 return;
4073 4238 }
4074 4239
4075 4240 (void) snprintf(tmp, sizeof (tmp), "%llu", limit);
4076 4241 s = tmp;
4077 4242 }
4078 4243
4079 4244 if (!zonecfg_aliased_rctl_ok(handle, alias)) {
4080 4245 zone_perror(pt_to_str(prop_type), Z_ALIAS_DISALLOW, B_FALSE);
4081 4246 saw_error = B_TRUE;
4082 4247 } else if (!zonecfg_valid_alias_limit(alias, s, &limit)) {
4083 4248 zerr(gettext("%s property is out of range."),
4084 4249 pt_to_str(prop_type));
4085 4250 saw_error = B_TRUE;
4086 4251 } else if ((err = zonecfg_set_aliased_rctl(handle, alias, limit))
4087 4252 != Z_OK) {
4088 4253 zone_perror(zone, err, B_TRUE);
4089 4254 saw_error = B_TRUE;
4090 4255 } else {
4091 4256 need_to_commit = B_TRUE;
4092 4257 }
4093 4258 }
4094 4259
4095 4260 static void
4096 4261 set_in_progress_nwiftab_address(char *prop_id, int prop_type)
4097 4262 {
4098 4263 if (prop_type == PT_ADDRESS) {
4099 4264 (void) strlcpy(in_progress_nwiftab.zone_nwif_address, prop_id,
4100 4265 sizeof (in_progress_nwiftab.zone_nwif_address));
4101 4266 } else {
4102 4267 assert(prop_type == PT_ALLOWED_ADDRESS);
4103 4268 (void) strlcpy(in_progress_nwiftab.zone_nwif_allowed_address,
4104 4269 prop_id,
4105 4270 sizeof (in_progress_nwiftab.zone_nwif_allowed_address));
4106 4271 }
4107 4272 }
4108 4273
4109 4274 void
4110 4275 set_func(cmd_t *cmd)
4111 4276 {
4112 4277 char *prop_id;
4113 4278 int arg, err, res_type, prop_type;
4114 4279 property_value_ptr_t pp;
4115 4280 boolean_t autoboot;
4116 4281 zone_iptype_t iptype;
4117 4282 boolean_t force_set = B_FALSE;
4118 4283 size_t physmem_size = sizeof (in_progress_mcaptab.zone_physmem_cap);
4119 4284 uint64_t mem_cap, mem_limit;
4120 4285 float cap;
4121 4286 char *unitp;
4122 4287 struct zone_psettab tmp_psettab;
4123 4288 boolean_t arg_err = B_FALSE;
4124 4289
4125 4290 if (zone_is_read_only(CMD_SET))
4126 4291 return;
4127 4292
4128 4293 assert(cmd != NULL);
4129 4294
4130 4295 optind = opterr = 0;
4131 4296 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) {
4132 4297 switch (arg) {
4133 4298 case 'F':
4134 4299 force_set = B_TRUE;
4135 4300 break;
4136 4301 default:
4137 4302 if (optopt == '?')
4138 4303 longer_usage(CMD_SET);
4139 4304 else
4140 4305 short_usage(CMD_SET);
4141 4306 arg_err = B_TRUE;
4142 4307 break;
4143 4308 }
4144 4309 }
4145 4310 if (arg_err)
4146 4311 return;
4147 4312
4148 4313 prop_type = cmd->cmd_prop_name[0];
4149 4314 if (global_scope) {
4150 4315 if (gz_invalid_property(prop_type)) {
4151 4316 zerr(gettext("%s is not a valid property for the "
4152 4317 "global zone."), pt_to_str(prop_type));
4153 4318 saw_error = B_TRUE;
4154 4319 return;
4155 4320 }
4156 4321
4157 4322 if (prop_type == PT_ZONENAME) {
4158 4323 res_type = RT_ZONENAME;
4159 4324 } else if (prop_type == PT_ZONEPATH) {
4160 4325 res_type = RT_ZONEPATH;
4161 4326 } else if (prop_type == PT_AUTOBOOT) {
4162 4327 res_type = RT_AUTOBOOT;
4163 4328 } else if (prop_type == PT_BRAND) {
4164 4329 res_type = RT_BRAND;
4165 4330 } else if (prop_type == PT_POOL) {
4166 4331 res_type = RT_POOL;
4167 4332 } else if (prop_type == PT_LIMITPRIV) {
4168 4333 res_type = RT_LIMITPRIV;
4169 4334 } else if (prop_type == PT_BOOTARGS) {
4170 4335 res_type = RT_BOOTARGS;
4171 4336 } else if (prop_type == PT_SCHED) {
4172 4337 res_type = RT_SCHED;
4173 4338 } else if (prop_type == PT_IPTYPE) {
4174 4339 res_type = RT_IPTYPE;
4175 4340 } else if (prop_type == PT_MAXLWPS) {
4176 4341 res_type = RT_MAXLWPS;
4177 4342 } else if (prop_type == PT_MAXPROCS) {
4178 4343 res_type = RT_MAXPROCS;
4179 4344 } else if (prop_type == PT_MAXSHMMEM) {
4180 4345 res_type = RT_MAXSHMMEM;
4181 4346 } else if (prop_type == PT_MAXSHMIDS) {
4182 4347 res_type = RT_MAXSHMIDS;
4183 4348 } else if (prop_type == PT_MAXMSGIDS) {
4184 4349 res_type = RT_MAXMSGIDS;
4185 4350 } else if (prop_type == PT_MAXSEMIDS) {
4186 4351 res_type = RT_MAXSEMIDS;
4187 4352 } else if (prop_type == PT_SHARES) {
4188 4353 res_type = RT_SHARES;
4189 4354 } else if (prop_type == PT_HOSTID) {
4190 4355 res_type = RT_HOSTID;
4191 4356 } else if (prop_type == PT_FS_ALLOWED) {
4192 4357 res_type = RT_FS_ALLOWED;
4193 4358 } else {
4194 4359 zerr(gettext("Cannot set a resource-specific property "
4195 4360 "from the global scope."));
4196 4361 saw_error = B_TRUE;
4197 4362 return;
4198 4363 }
4199 4364 } else {
4200 4365 res_type = resource_scope;
4201 4366 }
4202 4367
4203 4368 if (force_set) {
4204 4369 if (res_type != RT_ZONEPATH) {
4205 4370 zerr(gettext("Only zonepath setting can be forced."));
4206 4371 saw_error = B_TRUE;
4207 4372 return;
4208 4373 }
4209 4374 if (!zonecfg_in_alt_root()) {
4210 4375 zerr(gettext("Zonepath is changeable only in an "
4211 4376 "alternate root."));
4212 4377 saw_error = B_TRUE;
4213 4378 return;
4214 4379 }
4215 4380 }
4216 4381
4217 4382 pp = cmd->cmd_property_ptr[0];
4218 4383 /*
4219 4384 * A nasty expression but not that complicated:
4220 4385 * 1. fs options are simple or list (tested below)
4221 4386 * 2. rctl value's are complex or list (tested below)
4222 4387 * Anything else should be simple.
4223 4388 */
4224 4389 if (!(res_type == RT_FS && prop_type == PT_OPTIONS) &&
4225 4390 !(res_type == RT_RCTL && prop_type == PT_VALUE) &&
4226 4391 (pp->pv_type != PROP_VAL_SIMPLE ||
4227 4392 (prop_id = pp->pv_simple) == NULL)) {
4228 4393 zerr(gettext("A %s value was expected here."),
4229 4394 pvt_to_str(PROP_VAL_SIMPLE));
4230 4395 saw_error = B_TRUE;
4231 4396 return;
4232 4397 }
4233 4398 if (prop_type == PT_UNKNOWN) {
4234 4399 long_usage(CMD_SET, B_TRUE);
4235 4400 return;
4236 4401 }
4237 4402
4238 4403 /*
4239 4404 * Special case: the user can change the zone name prior to 'create';
4240 4405 * if the zone already exists, we fall through letting initialize()
4241 4406 * and the rest of the logic run.
4242 4407 */
4243 4408 if (res_type == RT_ZONENAME && got_handle == B_FALSE &&
4244 4409 !state_atleast(ZONE_STATE_CONFIGURED)) {
4245 4410 if ((err = zonecfg_validate_zonename(prop_id)) != Z_OK) {
4246 4411 zone_perror(prop_id, err, B_TRUE);
4247 4412 usage(B_FALSE, HELP_SYNTAX);
4248 4413 return;
4249 4414 }
4250 4415 (void) strlcpy(zone, prop_id, sizeof (zone));
4251 4416 return;
4252 4417 }
4253 4418
4254 4419 if (initialize(B_TRUE) != Z_OK)
4255 4420 return;
4256 4421
4257 4422 switch (res_type) {
4258 4423 case RT_ZONENAME:
4259 4424 if ((err = zonecfg_set_name(handle, prop_id)) != Z_OK) {
4260 4425 /*
4261 4426 * Use prop_id instead of 'zone' here, since we're
4262 4427 * reporting a problem about the *new* zonename.
4263 4428 */
4264 4429 zone_perror(prop_id, err, B_TRUE);
4265 4430 usage(B_FALSE, HELP_SYNTAX);
4266 4431 } else {
4267 4432 need_to_commit = B_TRUE;
4268 4433 (void) strlcpy(zone, prop_id, sizeof (zone));
4269 4434 }
4270 4435 return;
4271 4436 case RT_ZONEPATH:
4272 4437 if (!force_set && state_atleast(ZONE_STATE_INSTALLED)) {
4273 4438 zerr(gettext("Zone %s already installed; %s %s not "
4274 4439 "allowed."), zone, cmd_to_str(CMD_SET),
4275 4440 rt_to_str(RT_ZONEPATH));
4276 4441 return;
4277 4442 }
4278 4443 if (validate_zonepath_syntax(prop_id) != Z_OK) {
4279 4444 saw_error = B_TRUE;
4280 4445 return;
4281 4446 }
4282 4447 if ((err = zonecfg_set_zonepath(handle, prop_id)) != Z_OK)
4283 4448 zone_perror(zone, err, B_TRUE);
4284 4449 else
4285 4450 need_to_commit = B_TRUE;
4286 4451 return;
4287 4452 case RT_BRAND:
4288 4453 if (state_atleast(ZONE_STATE_INSTALLED)) {
4289 4454 zerr(gettext("Zone %s already installed; %s %s not "
4290 4455 "allowed."), zone, cmd_to_str(CMD_SET),
4291 4456 rt_to_str(RT_BRAND));
4292 4457 return;
4293 4458 }
4294 4459 if ((err = zonecfg_set_brand(handle, prop_id)) != Z_OK)
4295 4460 zone_perror(zone, err, B_TRUE);
4296 4461 else
4297 4462 need_to_commit = B_TRUE;
4298 4463 return;
4299 4464 case RT_AUTOBOOT:
4300 4465 if (strcmp(prop_id, "true") == 0) {
4301 4466 autoboot = B_TRUE;
4302 4467 } else if (strcmp(prop_id, "false") == 0) {
4303 4468 autoboot = B_FALSE;
4304 4469 } else {
4305 4470 zerr(gettext("%s value must be '%s' or '%s'."),
4306 4471 pt_to_str(PT_AUTOBOOT), "true", "false");
4307 4472 saw_error = B_TRUE;
4308 4473 return;
4309 4474 }
4310 4475 if ((err = zonecfg_set_autoboot(handle, autoboot)) != Z_OK)
4311 4476 zone_perror(zone, err, B_TRUE);
4312 4477 else
4313 4478 need_to_commit = B_TRUE;
4314 4479 return;
4315 4480 case RT_POOL:
4316 4481 /* don't allow use of the reserved temporary pool names */
4317 4482 if (strncmp("SUNW", prop_id, 4) == 0) {
4318 4483 zerr(gettext("pool names starting with SUNW are "
4319 4484 "reserved."));
4320 4485 saw_error = B_TRUE;
4321 4486 return;
4322 4487 }
4323 4488
4324 4489 /* can't set pool if dedicated-cpu exists */
4325 4490 if (zonecfg_lookup_pset(handle, &tmp_psettab) == Z_OK) {
4326 4491 zerr(gettext("The %s resource already exists. "
4327 4492 "A persistent pool is incompatible\nwith the %s "
4328 4493 "resource."), rt_to_str(RT_DCPU),
4329 4494 rt_to_str(RT_DCPU));
4330 4495 saw_error = B_TRUE;
4331 4496 return;
4332 4497 }
4333 4498
4334 4499 if ((err = zonecfg_set_pool(handle, prop_id)) != Z_OK)
4335 4500 zone_perror(zone, err, B_TRUE);
4336 4501 else
4337 4502 need_to_commit = B_TRUE;
4338 4503 return;
4339 4504 case RT_LIMITPRIV:
4340 4505 if ((err = zonecfg_set_limitpriv(handle, prop_id)) != Z_OK)
4341 4506 zone_perror(zone, err, B_TRUE);
4342 4507 else
4343 4508 need_to_commit = B_TRUE;
4344 4509 return;
4345 4510 case RT_BOOTARGS:
4346 4511 if ((err = zonecfg_set_bootargs(handle, prop_id)) != Z_OK)
4347 4512 zone_perror(zone, err, B_TRUE);
4348 4513 else
4349 4514 need_to_commit = B_TRUE;
4350 4515 return;
4351 4516 case RT_SCHED:
4352 4517 if ((err = zonecfg_set_sched(handle, prop_id)) != Z_OK)
4353 4518 zone_perror(zone, err, B_TRUE);
4354 4519 else
4355 4520 need_to_commit = B_TRUE;
4356 4521 return;
4357 4522 case RT_IPTYPE:
4358 4523 if (strcmp(prop_id, "shared") == 0) {
4359 4524 iptype = ZS_SHARED;
4360 4525 } else if (strcmp(prop_id, "exclusive") == 0) {
4361 4526 iptype = ZS_EXCLUSIVE;
4362 4527 } else {
4363 4528 zerr(gettext("%s value must be '%s' or '%s'."),
4364 4529 pt_to_str(PT_IPTYPE), "shared", "exclusive");
4365 4530 saw_error = B_TRUE;
4366 4531 return;
4367 4532 }
4368 4533 if (iptype == ZS_EXCLUSIVE && !allow_exclusive()) {
4369 4534 saw_error = B_TRUE;
4370 4535 return;
4371 4536 }
4372 4537 if ((err = zonecfg_set_iptype(handle, iptype)) != Z_OK)
4373 4538 zone_perror(zone, err, B_TRUE);
4374 4539 else
4375 4540 need_to_commit = B_TRUE;
4376 4541 return;
4377 4542 case RT_MAXLWPS:
4378 4543 set_aliased_rctl(ALIAS_MAXLWPS, prop_type, prop_id);
4379 4544 return;
4380 4545 case RT_MAXPROCS:
4381 4546 set_aliased_rctl(ALIAS_MAXPROCS, prop_type, prop_id);
4382 4547 return;
4383 4548 case RT_MAXSHMMEM:
4384 4549 set_aliased_rctl(ALIAS_MAXSHMMEM, prop_type, prop_id);
4385 4550 return;
4386 4551 case RT_MAXSHMIDS:
4387 4552 set_aliased_rctl(ALIAS_MAXSHMIDS, prop_type, prop_id);
4388 4553 return;
4389 4554 case RT_MAXMSGIDS:
4390 4555 set_aliased_rctl(ALIAS_MAXMSGIDS, prop_type, prop_id);
4391 4556 return;
4392 4557 case RT_MAXSEMIDS:
4393 4558 set_aliased_rctl(ALIAS_MAXSEMIDS, prop_type, prop_id);
4394 4559 return;
4395 4560 case RT_SHARES:
4396 4561 set_aliased_rctl(ALIAS_SHARES, prop_type, prop_id);
4397 4562 return;
4398 4563 case RT_HOSTID:
4399 4564 if ((err = zonecfg_set_hostid(handle, prop_id)) != Z_OK) {
4400 4565 if (err == Z_TOO_BIG) {
4401 4566 zerr(gettext("hostid string is too large: %s"),
4402 4567 prop_id);
4403 4568 saw_error = B_TRUE;
4404 4569 } else {
4405 4570 zone_perror(pt_to_str(prop_type), err, B_TRUE);
4406 4571 }
4407 4572 return;
4408 4573 }
4409 4574 need_to_commit = B_TRUE;
4410 4575 return;
4411 4576 case RT_FS_ALLOWED:
4412 4577 if ((err = zonecfg_set_fs_allowed(handle, prop_id)) != Z_OK)
4413 4578 zone_perror(zone, err, B_TRUE);
4414 4579 else
4415 4580 need_to_commit = B_TRUE;
4416 4581 return;
4417 4582 case RT_FS:
4418 4583 switch (prop_type) {
4419 4584 case PT_DIR:
4420 4585 (void) strlcpy(in_progress_fstab.zone_fs_dir, prop_id,
4421 4586 sizeof (in_progress_fstab.zone_fs_dir));
4422 4587 return;
4423 4588 case PT_SPECIAL:
4424 4589 (void) strlcpy(in_progress_fstab.zone_fs_special,
4425 4590 prop_id,
4426 4591 sizeof (in_progress_fstab.zone_fs_special));
4427 4592 return;
4428 4593 case PT_RAW:
4429 4594 (void) strlcpy(in_progress_fstab.zone_fs_raw,
4430 4595 prop_id, sizeof (in_progress_fstab.zone_fs_raw));
4431 4596 return;
4432 4597 case PT_TYPE:
4433 4598 if (!valid_fs_type(prop_id)) {
4434 4599 zerr(gettext("\"%s\" is not a valid %s."),
4435 4600 prop_id, pt_to_str(PT_TYPE));
4436 4601 saw_error = B_TRUE;
4437 4602 return;
4438 4603 }
4439 4604 (void) strlcpy(in_progress_fstab.zone_fs_type, prop_id,
4440 4605 sizeof (in_progress_fstab.zone_fs_type));
4441 4606 return;
4442 4607 case PT_OPTIONS:
4443 4608 if (pp->pv_type != PROP_VAL_SIMPLE &&
4444 4609 pp->pv_type != PROP_VAL_LIST) {
4445 4610 zerr(gettext("A %s or %s value was expected "
4446 4611 "here."), pvt_to_str(PROP_VAL_SIMPLE),
4447 4612 pvt_to_str(PROP_VAL_LIST));
4448 4613 saw_error = B_TRUE;
4449 4614 return;
4450 4615 }
4451 4616 zonecfg_free_fs_option_list(
4452 4617 in_progress_fstab.zone_fs_options);
4453 4618 in_progress_fstab.zone_fs_options = NULL;
4454 4619 if (!(pp->pv_type == PROP_VAL_LIST &&
4455 4620 pp->pv_list == NULL))
4456 4621 add_property(cmd);
4457 4622 return;
4458 4623 default:
4459 4624 break;
4460 4625 }
4461 4626 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE);
4462 4627 long_usage(CMD_SET, B_TRUE);
4463 4628 usage(B_FALSE, HELP_PROPS);
4464 4629 return;
4465 4630 case RT_NET:
4466 4631 switch (prop_type) {
4467 4632 case PT_ADDRESS:
4468 4633 case PT_ALLOWED_ADDRESS:
4469 4634 if (validate_net_address_syntax(prop_id, B_FALSE)
4470 4635 != Z_OK) {
4471 4636 saw_error = B_TRUE;
4472 4637 return;
4473 4638 }
4474 4639 set_in_progress_nwiftab_address(prop_id, prop_type);
4475 4640 break;
4476 4641 case PT_PHYSICAL:
4477 4642 if (validate_net_physical_syntax(prop_id) != Z_OK) {
4478 4643 saw_error = B_TRUE;
4479 4644 return;
4480 4645 }
4481 4646 (void) strlcpy(in_progress_nwiftab.zone_nwif_physical,
4482 4647 prop_id,
4483 4648 sizeof (in_progress_nwiftab.zone_nwif_physical));
4484 4649 break;
4485 4650 case PT_DEFROUTER:
4486 4651 if (validate_net_address_syntax(prop_id, B_TRUE)
4487 4652 != Z_OK) {
4488 4653 saw_error = B_TRUE;
4489 4654 return;
4490 4655 }
4491 4656 (void) strlcpy(in_progress_nwiftab.zone_nwif_defrouter,
4492 4657 prop_id,
4493 4658 sizeof (in_progress_nwiftab.zone_nwif_defrouter));
4494 4659 break;
4495 4660 default:
4496 4661 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4497 4662 B_TRUE);
4498 4663 long_usage(CMD_SET, B_TRUE);
4499 4664 usage(B_FALSE, HELP_PROPS);
4500 4665 return;
4501 4666 }
4502 4667 return;
4503 4668 case RT_DEVICE:
4504 4669 switch (prop_type) {
4505 4670 case PT_MATCH:
4506 4671 (void) strlcpy(in_progress_devtab.zone_dev_match,
4507 4672 prop_id,
4508 4673 sizeof (in_progress_devtab.zone_dev_match));
4509 4674 break;
4510 4675 default:
4511 4676 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4512 4677 B_TRUE);
4513 4678 long_usage(CMD_SET, B_TRUE);
4514 4679 usage(B_FALSE, HELP_PROPS);
4515 4680 return;
4516 4681 }
4517 4682 return;
4518 4683 case RT_RCTL:
4519 4684 switch (prop_type) {
4520 4685 case PT_NAME:
4521 4686 if (!zonecfg_valid_rctlname(prop_id)) {
4522 4687 zerr(gettext("'%s' is not a valid zone %s "
4523 4688 "name."), prop_id, rt_to_str(RT_RCTL));
4524 4689 return;
4525 4690 }
4526 4691 (void) strlcpy(in_progress_rctltab.zone_rctl_name,
4527 4692 prop_id,
4528 4693 sizeof (in_progress_rctltab.zone_rctl_name));
4529 4694 break;
4530 4695 case PT_VALUE:
4531 4696 if (pp->pv_type != PROP_VAL_COMPLEX &&
4532 4697 pp->pv_type != PROP_VAL_LIST) {
4533 4698 zerr(gettext("A %s or %s value was expected "
4534 4699 "here."), pvt_to_str(PROP_VAL_COMPLEX),
4535 4700 pvt_to_str(PROP_VAL_LIST));
4536 4701 saw_error = B_TRUE;
4537 4702 return;
4538 4703 }
4539 4704 zonecfg_free_rctl_value_list(
4540 4705 in_progress_rctltab.zone_rctl_valptr);
4541 4706 in_progress_rctltab.zone_rctl_valptr = NULL;
4542 4707 if (!(pp->pv_type == PROP_VAL_LIST &&
4543 4708 pp->pv_list == NULL))
4544 4709 add_property(cmd);
4545 4710 break;
4546 4711 default:
4547 4712 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4548 4713 B_TRUE);
4549 4714 long_usage(CMD_SET, B_TRUE);
4550 4715 usage(B_FALSE, HELP_PROPS);
4551 4716 return;
4552 4717 }
4553 4718 return;
4554 4719 case RT_ATTR:
4555 4720 switch (prop_type) {
4556 4721 case PT_NAME:
4557 4722 (void) strlcpy(in_progress_attrtab.zone_attr_name,
4558 4723 prop_id,
4559 4724 sizeof (in_progress_attrtab.zone_attr_name));
4560 4725 break;
4561 4726 case PT_TYPE:
4562 4727 (void) strlcpy(in_progress_attrtab.zone_attr_type,
4563 4728 prop_id,
4564 4729 sizeof (in_progress_attrtab.zone_attr_type));
4565 4730 break;
4566 4731 case PT_VALUE:
4567 4732 (void) strlcpy(in_progress_attrtab.zone_attr_value,
4568 4733 prop_id,
4569 4734 sizeof (in_progress_attrtab.zone_attr_value));
4570 4735 break;
4571 4736 default:
4572 4737 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4573 4738 B_TRUE);
4574 4739 long_usage(CMD_SET, B_TRUE);
4575 4740 usage(B_FALSE, HELP_PROPS);
4576 4741 return;
4577 4742 }
4578 4743 return;
4579 4744 case RT_DATASET:
4580 4745 switch (prop_type) {
4581 4746 case PT_NAME:
4582 4747 (void) strlcpy(in_progress_dstab.zone_dataset_name,
4583 4748 prop_id,
4584 4749 sizeof (in_progress_dstab.zone_dataset_name));
4585 4750 return;
4586 4751 default:
4587 4752 break;
4588 4753 }
4589 4754 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE);
4590 4755 long_usage(CMD_SET, B_TRUE);
4591 4756 usage(B_FALSE, HELP_PROPS);
4592 4757 return;
4593 4758 case RT_DCPU:
4594 4759 switch (prop_type) {
4595 4760 char *lowp, *highp;
4596 4761
4597 4762 case PT_NCPUS:
4598 4763 lowp = prop_id;
4599 4764 if ((highp = strchr(prop_id, '-')) != NULL)
4600 4765 *highp++ = '\0';
4601 4766 else
4602 4767 highp = lowp;
4603 4768
4604 4769 /* Make sure the input makes sense. */
4605 4770 if (!zonecfg_valid_ncpus(lowp, highp)) {
4606 4771 zerr(gettext("%s property is out of range."),
4607 4772 pt_to_str(PT_NCPUS));
4608 4773 saw_error = B_TRUE;
4609 4774 return;
4610 4775 }
4611 4776
4612 4777 (void) strlcpy(
4613 4778 in_progress_psettab.zone_ncpu_min, lowp,
4614 4779 sizeof (in_progress_psettab.zone_ncpu_min));
4615 4780 (void) strlcpy(
4616 4781 in_progress_psettab.zone_ncpu_max, highp,
4617 4782 sizeof (in_progress_psettab.zone_ncpu_max));
4618 4783 return;
4619 4784 case PT_IMPORTANCE:
4620 4785 /* Make sure the value makes sense. */
4621 4786 if (!zonecfg_valid_importance(prop_id)) {
4622 4787 zerr(gettext("%s property is out of range."),
4623 4788 pt_to_str(PT_IMPORTANCE));
4624 4789 saw_error = B_TRUE;
4625 4790 return;
4626 4791 }
4627 4792
4628 4793 (void) strlcpy(in_progress_psettab.zone_importance,
4629 4794 prop_id,
4630 4795 sizeof (in_progress_psettab.zone_importance));
4631 4796 return;
4632 4797 default:
4633 4798 break;
4634 4799 }
4635 4800 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE);
4636 4801 long_usage(CMD_SET, B_TRUE);
4637 4802 usage(B_FALSE, HELP_PROPS);
4638 4803 return;
4639 4804 case RT_PCAP:
4640 4805 if (prop_type != PT_NCPUS) {
4641 4806 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4642 4807 B_TRUE);
4643 4808 long_usage(CMD_SET, B_TRUE);
4644 4809 usage(B_FALSE, HELP_PROPS);
4645 4810 return;
4646 4811 }
4647 4812
4648 4813 /*
4649 4814 * We already checked that an rctl alias is allowed in
4650 4815 * the add_resource() function.
4651 4816 */
4652 4817
4653 4818 if ((cap = strtof(prop_id, &unitp)) <= 0 || *unitp != '\0' ||
4654 4819 (int)(cap * 100) < 1) {
4655 4820 zerr(gettext("%s property is out of range."),
4656 4821 pt_to_str(PT_NCPUS));
4657 4822 saw_error = B_TRUE;
4658 4823 return;
4659 4824 }
4660 4825
4661 4826 if ((err = zonecfg_set_aliased_rctl(handle, ALIAS_CPUCAP,
4662 4827 (int)(cap * 100))) != Z_OK)
4663 4828 zone_perror(zone, err, B_TRUE);
4664 4829 else
4665 4830 need_to_commit = B_TRUE;
4666 4831 return;
4667 4832 case RT_MCAP:
4668 4833 switch (prop_type) {
4669 4834 case PT_PHYSICAL:
4670 4835 if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) {
4671 4836 zerr(gettext("A positive number with a "
4672 4837 "required scale suffix (K, M, G or T) was "
4673 4838 "expected here."));
4674 4839 saw_error = B_TRUE;
4675 4840 } else if (mem_cap < ONE_MB) {
4676 4841 zerr(gettext("%s value is too small. It must "
4677 4842 "be at least 1M."), pt_to_str(PT_PHYSICAL));
4678 4843 saw_error = B_TRUE;
4679 4844 } else {
4680 4845 snprintf(in_progress_mcaptab.zone_physmem_cap,
4681 4846 physmem_size, "%llu", mem_cap);
4682 4847 }
4683 4848 break;
4684 4849 case PT_SWAP:
4685 4850 /*
4686 4851 * We have to check if an rctl is allowed here since
4687 4852 * there might already be a rctl defined that blocks
4688 4853 * the alias.
4689 4854 */
4690 4855 if (!zonecfg_aliased_rctl_ok(handle, ALIAS_MAXSWAP)) {
4691 4856 zone_perror(pt_to_str(PT_MAXSWAP),
4692 4857 Z_ALIAS_DISALLOW, B_FALSE);
4693 4858 saw_error = B_TRUE;
4694 4859 return;
4695 4860 }
4696 4861
4697 4862 if (global_zone)
4698 4863 mem_limit = ONE_MB * 100;
4699 4864 else
4700 4865 mem_limit = ONE_MB * 50;
4701 4866
4702 4867 if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) {
4703 4868 zerr(gettext("A positive number with a "
4704 4869 "required scale suffix (K, M, G or T) was "
4705 4870 "expected here."));
4706 4871 saw_error = B_TRUE;
4707 4872 } else if (mem_cap < mem_limit) {
4708 4873 char buf[128];
4709 4874
4710 4875 (void) snprintf(buf, sizeof (buf), "%llu",
4711 4876 mem_limit);
4712 4877 bytes_to_units(buf, buf, sizeof (buf));
4713 4878 zerr(gettext("%s value is too small. It must "
4714 4879 "be at least %s."), pt_to_str(PT_SWAP),
4715 4880 buf);
4716 4881 saw_error = B_TRUE;
4717 4882 } else {
4718 4883 if ((err = zonecfg_set_aliased_rctl(handle,
4719 4884 ALIAS_MAXSWAP, mem_cap)) != Z_OK)
4720 4885 zone_perror(zone, err, B_TRUE);
4721 4886 else
4722 4887 need_to_commit = B_TRUE;
4723 4888 }
4724 4889 break;
4725 4890 case PT_LOCKED:
4726 4891 /*
4727 4892 * We have to check if an rctl is allowed here since
4728 4893 * there might already be a rctl defined that blocks
4729 4894 * the alias.
4730 4895 */
4731 4896 if (!zonecfg_aliased_rctl_ok(handle,
4732 4897 ALIAS_MAXLOCKEDMEM)) {
4733 4898 zone_perror(pt_to_str(PT_LOCKED),
4734 4899 Z_ALIAS_DISALLOW, B_FALSE);
4735 4900 saw_error = B_TRUE;
4736 4901 return;
4737 4902 }
4738 4903
4739 4904 if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) {
4740 4905 zerr(gettext("A non-negative number with a "
4741 4906 "required scale suffix (K, M, G or T) was "
4742 4907 "expected\nhere."));
4743 4908 saw_error = B_TRUE;
4744 4909 } else {
4745 4910 if ((err = zonecfg_set_aliased_rctl(handle,
4746 4911 ALIAS_MAXLOCKEDMEM, mem_cap)) != Z_OK)
4747 4912 zone_perror(zone, err, B_TRUE);
4748 4913 else
4749 4914 need_to_commit = B_TRUE;
4750 4915 }
4751 4916 break;
4752 4917 default:
4753 4918 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4754 4919 B_TRUE);
4755 4920 long_usage(CMD_SET, B_TRUE);
4756 4921 usage(B_FALSE, HELP_PROPS);
4757 4922 return;
4758 4923 }
4759 4924 return;
4760 4925 case RT_ADMIN:
4761 4926 switch (prop_type) {
4762 4927 case PT_USER:
4763 4928 (void) strlcpy(in_progress_admintab.zone_admin_user,
4764 4929 prop_id,
4765 4930 sizeof (in_progress_admintab.zone_admin_user));
4766 4931 return;
4767 4932 case PT_AUTHS:
4768 4933 (void) strlcpy(in_progress_admintab.zone_admin_auths,
↓ open down ↓ |
896 lines elided |
↑ open up ↑ |
4769 4934 prop_id,
4770 4935 sizeof (in_progress_admintab.zone_admin_auths));
4771 4936 return;
4772 4937 default:
4773 4938 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4774 4939 B_TRUE);
4775 4940 long_usage(CMD_SET, B_TRUE);
4776 4941 usage(B_FALSE, HELP_PROPS);
4777 4942 return;
4778 4943 }
4944 + case RT_SECFLAGS: {
4945 + char *propstr;
4946 +
4947 + switch (prop_type) {
4948 + case PT_DEFAULT:
4949 + propstr = in_progress_secflagstab.zone_secflags_default;
4950 + break;
4951 + case PT_UPPER:
4952 + propstr = in_progress_secflagstab.zone_secflags_upper;
4953 + break;
4954 + case PT_LOWER:
4955 + propstr = in_progress_secflagstab.zone_secflags_lower;
4956 + break;
4957 + default:
4958 + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4959 + B_TRUE);
4960 + long_usage(CMD_SET, B_TRUE);
4961 + usage(B_FALSE, HELP_PROPS);
4962 + return;
4963 + }
4964 + (void) strlcpy(propstr, prop_id, ZONECFG_SECFLAGS_MAX);
4965 + return;
4966 + }
4779 4967 default:
4780 4968 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
4781 4969 long_usage(CMD_SET, B_TRUE);
4782 4970 usage(B_FALSE, HELP_RESOURCES);
4783 4971 return;
4784 4972 }
4785 4973 }
4786 4974
4787 4975 static void
4788 4976 output_prop(FILE *fp, int pnum, char *pval, boolean_t print_notspec)
4789 4977 {
4790 4978 char *qstr;
4791 4979
4792 4980 if (*pval != '\0') {
4793 4981 qstr = quoteit(pval);
4794 4982 if (pnum == PT_SWAP || pnum == PT_LOCKED)
4795 4983 (void) fprintf(fp, "\t[%s: %s]\n", pt_to_str(pnum),
4796 4984 qstr);
4797 4985 else
4798 4986 (void) fprintf(fp, "\t%s: %s\n", pt_to_str(pnum), qstr);
4799 4987 free(qstr);
4800 4988 } else if (print_notspec)
4801 4989 (void) fprintf(fp, gettext("\t%s not specified\n"),
4802 4990 pt_to_str(pnum));
4803 4991 }
4804 4992
4805 4993 static void
4806 4994 info_zonename(zone_dochandle_t handle, FILE *fp)
4807 4995 {
4808 4996 char zonename[ZONENAME_MAX];
4809 4997
4810 4998 if (zonecfg_get_name(handle, zonename, sizeof (zonename)) == Z_OK)
4811 4999 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_ZONENAME),
4812 5000 zonename);
4813 5001 else
4814 5002 (void) fprintf(fp, gettext("%s not specified\n"),
4815 5003 pt_to_str(PT_ZONENAME));
4816 5004 }
4817 5005
4818 5006 static void
4819 5007 info_zonepath(zone_dochandle_t handle, FILE *fp)
4820 5008 {
4821 5009 char zonepath[MAXPATHLEN];
4822 5010
4823 5011 if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) == Z_OK)
4824 5012 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_ZONEPATH),
4825 5013 zonepath);
4826 5014 else {
4827 5015 (void) fprintf(fp, gettext("%s not specified\n"),
4828 5016 pt_to_str(PT_ZONEPATH));
4829 5017 }
4830 5018 }
4831 5019
4832 5020 static void
4833 5021 info_brand(zone_dochandle_t handle, FILE *fp)
4834 5022 {
4835 5023 char brand[MAXNAMELEN];
4836 5024
4837 5025 if (zonecfg_get_brand(handle, brand, sizeof (brand)) == Z_OK)
4838 5026 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_BRAND),
4839 5027 brand);
4840 5028 else
4841 5029 (void) fprintf(fp, "%s %s\n", pt_to_str(PT_BRAND),
4842 5030 gettext("not specified"));
4843 5031 }
4844 5032
4845 5033 static void
4846 5034 info_autoboot(zone_dochandle_t handle, FILE *fp)
4847 5035 {
4848 5036 boolean_t autoboot;
4849 5037 int err;
4850 5038
4851 5039 if ((err = zonecfg_get_autoboot(handle, &autoboot)) == Z_OK)
4852 5040 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_AUTOBOOT),
4853 5041 autoboot ? "true" : "false");
4854 5042 else
4855 5043 zone_perror(zone, err, B_TRUE);
4856 5044 }
4857 5045
4858 5046 static void
4859 5047 info_pool(zone_dochandle_t handle, FILE *fp)
4860 5048 {
4861 5049 char pool[MAXNAMELEN];
4862 5050 int err;
4863 5051
4864 5052 if ((err = zonecfg_get_pool(handle, pool, sizeof (pool))) == Z_OK)
4865 5053 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_POOL), pool);
4866 5054 else
4867 5055 zone_perror(zone, err, B_TRUE);
4868 5056 }
4869 5057
4870 5058 static void
4871 5059 info_limitpriv(zone_dochandle_t handle, FILE *fp)
4872 5060 {
4873 5061 char *limitpriv;
4874 5062 int err;
4875 5063
4876 5064 if ((err = zonecfg_get_limitpriv(handle, &limitpriv)) == Z_OK) {
4877 5065 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_LIMITPRIV),
4878 5066 limitpriv);
4879 5067 free(limitpriv);
4880 5068 } else {
4881 5069 zone_perror(zone, err, B_TRUE);
4882 5070 }
4883 5071 }
4884 5072
4885 5073 static void
4886 5074 info_bootargs(zone_dochandle_t handle, FILE *fp)
4887 5075 {
4888 5076 char bootargs[BOOTARGS_MAX];
4889 5077 int err;
4890 5078
4891 5079 if ((err = zonecfg_get_bootargs(handle, bootargs,
4892 5080 sizeof (bootargs))) == Z_OK) {
4893 5081 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_BOOTARGS),
4894 5082 bootargs);
4895 5083 } else {
4896 5084 zone_perror(zone, err, B_TRUE);
4897 5085 }
4898 5086 }
4899 5087
4900 5088 static void
4901 5089 info_sched(zone_dochandle_t handle, FILE *fp)
4902 5090 {
4903 5091 char sched[MAXNAMELEN];
4904 5092 int err;
4905 5093
4906 5094 if ((err = zonecfg_get_sched_class(handle, sched, sizeof (sched)))
4907 5095 == Z_OK) {
4908 5096 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_SCHED), sched);
4909 5097 } else {
4910 5098 zone_perror(zone, err, B_TRUE);
4911 5099 }
4912 5100 }
4913 5101
4914 5102 static void
4915 5103 info_iptype(zone_dochandle_t handle, FILE *fp)
4916 5104 {
4917 5105 zone_iptype_t iptype;
4918 5106 int err;
4919 5107
4920 5108 if ((err = zonecfg_get_iptype(handle, &iptype)) == Z_OK) {
4921 5109 switch (iptype) {
4922 5110 case ZS_SHARED:
4923 5111 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_IPTYPE),
4924 5112 "shared");
4925 5113 break;
4926 5114 case ZS_EXCLUSIVE:
4927 5115 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_IPTYPE),
4928 5116 "exclusive");
4929 5117 break;
4930 5118 }
4931 5119 } else {
4932 5120 zone_perror(zone, err, B_TRUE);
4933 5121 }
4934 5122 }
4935 5123
4936 5124 static void
4937 5125 info_hostid(zone_dochandle_t handle, FILE *fp)
4938 5126 {
4939 5127 char hostidp[HW_HOSTID_LEN];
4940 5128 int err;
4941 5129
4942 5130 if ((err = zonecfg_get_hostid(handle, hostidp,
4943 5131 sizeof (hostidp))) == Z_OK) {
4944 5132 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_HOSTID), hostidp);
4945 5133 } else if (err == Z_BAD_PROPERTY) {
4946 5134 (void) fprintf(fp, "%s: \n", pt_to_str(PT_HOSTID));
4947 5135 } else {
4948 5136 zone_perror(zone, err, B_TRUE);
4949 5137 }
4950 5138 }
4951 5139
4952 5140 static void
4953 5141 info_fs_allowed(zone_dochandle_t handle, FILE *fp)
4954 5142 {
4955 5143 char fsallowedp[ZONE_FS_ALLOWED_MAX];
4956 5144 int err;
4957 5145
4958 5146 if ((err = zonecfg_get_fs_allowed(handle, fsallowedp,
4959 5147 sizeof (fsallowedp))) == Z_OK) {
4960 5148 (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_FS_ALLOWED),
4961 5149 fsallowedp);
4962 5150 } else if (err == Z_BAD_PROPERTY) {
4963 5151 (void) fprintf(fp, "%s: \n", pt_to_str(PT_FS_ALLOWED));
4964 5152 } else {
4965 5153 zone_perror(zone, err, B_TRUE);
4966 5154 }
4967 5155 }
4968 5156
4969 5157 static void
4970 5158 output_fs(FILE *fp, struct zone_fstab *fstab)
4971 5159 {
4972 5160 zone_fsopt_t *this;
4973 5161
4974 5162 (void) fprintf(fp, "%s:\n", rt_to_str(RT_FS));
4975 5163 output_prop(fp, PT_DIR, fstab->zone_fs_dir, B_TRUE);
4976 5164 output_prop(fp, PT_SPECIAL, fstab->zone_fs_special, B_TRUE);
4977 5165 output_prop(fp, PT_RAW, fstab->zone_fs_raw, B_TRUE);
4978 5166 output_prop(fp, PT_TYPE, fstab->zone_fs_type, B_TRUE);
4979 5167 (void) fprintf(fp, "\t%s: [", pt_to_str(PT_OPTIONS));
4980 5168 for (this = fstab->zone_fs_options; this != NULL;
4981 5169 this = this->zone_fsopt_next) {
4982 5170 if (strchr(this->zone_fsopt_opt, '='))
4983 5171 (void) fprintf(fp, "\"%s\"", this->zone_fsopt_opt);
4984 5172 else
4985 5173 (void) fprintf(fp, "%s", this->zone_fsopt_opt);
4986 5174 if (this->zone_fsopt_next != NULL)
4987 5175 (void) fprintf(fp, ",");
4988 5176 }
4989 5177 (void) fprintf(fp, "]\n");
4990 5178 }
4991 5179
4992 5180 static void
4993 5181 info_fs(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
4994 5182 {
4995 5183 struct zone_fstab lookup, user;
4996 5184 boolean_t output = B_FALSE;
4997 5185
4998 5186 if (zonecfg_setfsent(handle) != Z_OK)
4999 5187 return;
5000 5188 while (zonecfg_getfsent(handle, &lookup) == Z_OK) {
5001 5189 if (cmd->cmd_prop_nv_pairs == 0) {
5002 5190 output_fs(fp, &lookup);
5003 5191 goto loopend;
5004 5192 }
5005 5193 if (fill_in_fstab(cmd, &user, B_TRUE) != Z_OK)
5006 5194 goto loopend;
5007 5195 if (strlen(user.zone_fs_dir) > 0 &&
5008 5196 strcmp(user.zone_fs_dir, lookup.zone_fs_dir) != 0)
5009 5197 goto loopend; /* no match */
5010 5198 if (strlen(user.zone_fs_special) > 0 &&
5011 5199 strcmp(user.zone_fs_special, lookup.zone_fs_special) != 0)
5012 5200 goto loopend; /* no match */
5013 5201 if (strlen(user.zone_fs_type) > 0 &&
5014 5202 strcmp(user.zone_fs_type, lookup.zone_fs_type) != 0)
5015 5203 goto loopend; /* no match */
5016 5204 output_fs(fp, &lookup);
5017 5205 output = B_TRUE;
5018 5206 loopend:
5019 5207 zonecfg_free_fs_option_list(lookup.zone_fs_options);
5020 5208 }
5021 5209 (void) zonecfg_endfsent(handle);
5022 5210 /*
5023 5211 * If a property n/v pair was specified, warn the user if there was
5024 5212 * nothing to output.
5025 5213 */
5026 5214 if (!output && cmd->cmd_prop_nv_pairs > 0)
5027 5215 (void) printf(gettext("No such %s resource.\n"),
5028 5216 rt_to_str(RT_FS));
5029 5217 }
5030 5218
5031 5219 static void
5032 5220 output_net(FILE *fp, struct zone_nwiftab *nwiftab)
5033 5221 {
5034 5222 (void) fprintf(fp, "%s:\n", rt_to_str(RT_NET));
5035 5223 output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE);
5036 5224 output_prop(fp, PT_ALLOWED_ADDRESS,
5037 5225 nwiftab->zone_nwif_allowed_address, B_TRUE);
5038 5226 output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE);
5039 5227 output_prop(fp, PT_DEFROUTER, nwiftab->zone_nwif_defrouter, B_TRUE);
5040 5228 }
5041 5229
5042 5230 static void
5043 5231 info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5044 5232 {
5045 5233 struct zone_nwiftab lookup, user;
5046 5234 boolean_t output = B_FALSE;
5047 5235
5048 5236 if (zonecfg_setnwifent(handle) != Z_OK)
5049 5237 return;
5050 5238 while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
5051 5239 if (cmd->cmd_prop_nv_pairs == 0) {
5052 5240 output_net(fp, &lookup);
5053 5241 continue;
5054 5242 }
5055 5243 if (fill_in_nwiftab(cmd, &user, B_TRUE) != Z_OK)
5056 5244 continue;
5057 5245 if (strlen(user.zone_nwif_physical) > 0 &&
5058 5246 strcmp(user.zone_nwif_physical,
5059 5247 lookup.zone_nwif_physical) != 0)
5060 5248 continue; /* no match */
5061 5249 /* If present make sure it matches */
5062 5250 if (strlen(user.zone_nwif_address) > 0 &&
5063 5251 !zonecfg_same_net_address(user.zone_nwif_address,
5064 5252 lookup.zone_nwif_address))
5065 5253 continue; /* no match */
5066 5254 output_net(fp, &lookup);
5067 5255 output = B_TRUE;
5068 5256 }
5069 5257 (void) zonecfg_endnwifent(handle);
5070 5258 /*
5071 5259 * If a property n/v pair was specified, warn the user if there was
5072 5260 * nothing to output.
5073 5261 */
5074 5262 if (!output && cmd->cmd_prop_nv_pairs > 0)
5075 5263 (void) printf(gettext("No such %s resource.\n"),
5076 5264 rt_to_str(RT_NET));
5077 5265 }
5078 5266
5079 5267 static void
5080 5268 output_dev(FILE *fp, struct zone_devtab *devtab)
5081 5269 {
5082 5270 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DEVICE));
5083 5271 output_prop(fp, PT_MATCH, devtab->zone_dev_match, B_TRUE);
5084 5272 }
5085 5273
5086 5274 static void
5087 5275 info_dev(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5088 5276 {
5089 5277 struct zone_devtab lookup, user;
5090 5278 boolean_t output = B_FALSE;
5091 5279
5092 5280 if (zonecfg_setdevent(handle) != Z_OK)
5093 5281 return;
5094 5282 while (zonecfg_getdevent(handle, &lookup) == Z_OK) {
5095 5283 if (cmd->cmd_prop_nv_pairs == 0) {
5096 5284 output_dev(fp, &lookup);
5097 5285 continue;
5098 5286 }
5099 5287 if (fill_in_devtab(cmd, &user, B_TRUE) != Z_OK)
5100 5288 continue;
5101 5289 if (strlen(user.zone_dev_match) > 0 &&
5102 5290 strcmp(user.zone_dev_match, lookup.zone_dev_match) != 0)
5103 5291 continue; /* no match */
5104 5292 output_dev(fp, &lookup);
5105 5293 output = B_TRUE;
5106 5294 }
5107 5295 (void) zonecfg_enddevent(handle);
5108 5296 /*
5109 5297 * If a property n/v pair was specified, warn the user if there was
5110 5298 * nothing to output.
5111 5299 */
5112 5300 if (!output && cmd->cmd_prop_nv_pairs > 0)
5113 5301 (void) printf(gettext("No such %s resource.\n"),
5114 5302 rt_to_str(RT_DEVICE));
5115 5303 }
5116 5304
5117 5305 static void
5118 5306 output_rctl(FILE *fp, struct zone_rctltab *rctltab)
5119 5307 {
5120 5308 struct zone_rctlvaltab *valptr;
5121 5309
5122 5310 (void) fprintf(fp, "%s:\n", rt_to_str(RT_RCTL));
5123 5311 output_prop(fp, PT_NAME, rctltab->zone_rctl_name, B_TRUE);
5124 5312 for (valptr = rctltab->zone_rctl_valptr; valptr != NULL;
5125 5313 valptr = valptr->zone_rctlval_next) {
5126 5314 fprintf(fp, "\t%s: (%s=%s,%s=%s,%s=%s)\n",
5127 5315 pt_to_str(PT_VALUE),
5128 5316 pt_to_str(PT_PRIV), valptr->zone_rctlval_priv,
5129 5317 pt_to_str(PT_LIMIT), valptr->zone_rctlval_limit,
5130 5318 pt_to_str(PT_ACTION), valptr->zone_rctlval_action);
5131 5319 }
5132 5320 }
5133 5321
5134 5322 static void
5135 5323 info_rctl(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5136 5324 {
5137 5325 struct zone_rctltab lookup, user;
5138 5326 boolean_t output = B_FALSE;
5139 5327
5140 5328 if (zonecfg_setrctlent(handle) != Z_OK)
5141 5329 return;
5142 5330 while (zonecfg_getrctlent(handle, &lookup) == Z_OK) {
5143 5331 if (cmd->cmd_prop_nv_pairs == 0) {
5144 5332 output_rctl(fp, &lookup);
5145 5333 } else if (fill_in_rctltab(cmd, &user, B_TRUE) == Z_OK &&
5146 5334 (strlen(user.zone_rctl_name) == 0 ||
5147 5335 strcmp(user.zone_rctl_name, lookup.zone_rctl_name) == 0)) {
5148 5336 output_rctl(fp, &lookup);
5149 5337 output = B_TRUE;
5150 5338 }
5151 5339 zonecfg_free_rctl_value_list(lookup.zone_rctl_valptr);
5152 5340 }
5153 5341 (void) zonecfg_endrctlent(handle);
5154 5342 /*
5155 5343 * If a property n/v pair was specified, warn the user if there was
5156 5344 * nothing to output.
5157 5345 */
5158 5346 if (!output && cmd->cmd_prop_nv_pairs > 0)
5159 5347 (void) printf(gettext("No such %s resource.\n"),
5160 5348 rt_to_str(RT_RCTL));
5161 5349 }
5162 5350
5163 5351 static void
5164 5352 output_attr(FILE *fp, struct zone_attrtab *attrtab)
5165 5353 {
5166 5354 (void) fprintf(fp, "%s:\n", rt_to_str(RT_ATTR));
5167 5355 output_prop(fp, PT_NAME, attrtab->zone_attr_name, B_TRUE);
5168 5356 output_prop(fp, PT_TYPE, attrtab->zone_attr_type, B_TRUE);
5169 5357 output_prop(fp, PT_VALUE, attrtab->zone_attr_value, B_TRUE);
5170 5358 }
5171 5359
5172 5360 static void
5173 5361 info_attr(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5174 5362 {
5175 5363 struct zone_attrtab lookup, user;
5176 5364 boolean_t output = B_FALSE;
5177 5365
5178 5366 if (zonecfg_setattrent(handle) != Z_OK)
5179 5367 return;
5180 5368 while (zonecfg_getattrent(handle, &lookup) == Z_OK) {
5181 5369 if (cmd->cmd_prop_nv_pairs == 0) {
5182 5370 output_attr(fp, &lookup);
5183 5371 continue;
5184 5372 }
5185 5373 if (fill_in_attrtab(cmd, &user, B_TRUE) != Z_OK)
5186 5374 continue;
5187 5375 if (strlen(user.zone_attr_name) > 0 &&
5188 5376 strcmp(user.zone_attr_name, lookup.zone_attr_name) != 0)
5189 5377 continue; /* no match */
5190 5378 if (strlen(user.zone_attr_type) > 0 &&
5191 5379 strcmp(user.zone_attr_type, lookup.zone_attr_type) != 0)
5192 5380 continue; /* no match */
5193 5381 if (strlen(user.zone_attr_value) > 0 &&
5194 5382 strcmp(user.zone_attr_value, lookup.zone_attr_value) != 0)
5195 5383 continue; /* no match */
5196 5384 output_attr(fp, &lookup);
5197 5385 output = B_TRUE;
5198 5386 }
5199 5387 (void) zonecfg_endattrent(handle);
5200 5388 /*
5201 5389 * If a property n/v pair was specified, warn the user if there was
5202 5390 * nothing to output.
5203 5391 */
5204 5392 if (!output && cmd->cmd_prop_nv_pairs > 0)
5205 5393 (void) printf(gettext("No such %s resource.\n"),
5206 5394 rt_to_str(RT_ATTR));
5207 5395 }
5208 5396
5209 5397 static void
5210 5398 output_ds(FILE *fp, struct zone_dstab *dstab)
5211 5399 {
5212 5400 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DATASET));
5213 5401 output_prop(fp, PT_NAME, dstab->zone_dataset_name, B_TRUE);
5214 5402 }
5215 5403
5216 5404 static void
5217 5405 info_ds(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5218 5406 {
5219 5407 struct zone_dstab lookup, user;
5220 5408 boolean_t output = B_FALSE;
5221 5409
5222 5410 if (zonecfg_setdsent(handle) != Z_OK)
5223 5411 return;
5224 5412 while (zonecfg_getdsent(handle, &lookup) == Z_OK) {
5225 5413 if (cmd->cmd_prop_nv_pairs == 0) {
5226 5414 output_ds(fp, &lookup);
5227 5415 continue;
5228 5416 }
5229 5417 if (fill_in_dstab(cmd, &user, B_TRUE) != Z_OK)
5230 5418 continue;
5231 5419 if (strlen(user.zone_dataset_name) > 0 &&
5232 5420 strcmp(user.zone_dataset_name,
5233 5421 lookup.zone_dataset_name) != 0)
5234 5422 continue; /* no match */
5235 5423 output_ds(fp, &lookup);
5236 5424 output = B_TRUE;
5237 5425 }
5238 5426 (void) zonecfg_enddsent(handle);
5239 5427 /*
5240 5428 * If a property n/v pair was specified, warn the user if there was
5241 5429 * nothing to output.
5242 5430 */
5243 5431 if (!output && cmd->cmd_prop_nv_pairs > 0)
5244 5432 (void) printf(gettext("No such %s resource.\n"),
5245 5433 rt_to_str(RT_DATASET));
5246 5434 }
5247 5435
5248 5436 static void
5249 5437 output_pset(FILE *fp, struct zone_psettab *psettab)
5250 5438 {
5251 5439 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DCPU));
5252 5440 if (strcmp(psettab->zone_ncpu_min, psettab->zone_ncpu_max) == 0)
5253 5441 (void) fprintf(fp, "\t%s: %s\n", pt_to_str(PT_NCPUS),
5254 5442 psettab->zone_ncpu_max);
5255 5443 else
5256 5444 (void) fprintf(fp, "\t%s: %s-%s\n", pt_to_str(PT_NCPUS),
5257 5445 psettab->zone_ncpu_min, psettab->zone_ncpu_max);
5258 5446 if (psettab->zone_importance[0] != '\0')
5259 5447 (void) fprintf(fp, "\t%s: %s\n", pt_to_str(PT_IMPORTANCE),
5260 5448 psettab->zone_importance);
5261 5449 }
5262 5450
5263 5451 static void
5264 5452 info_pset(zone_dochandle_t handle, FILE *fp)
5265 5453 {
5266 5454 struct zone_psettab lookup;
5267 5455
5268 5456 if (zonecfg_getpsetent(handle, &lookup) == Z_OK)
5269 5457 output_pset(fp, &lookup);
5270 5458 }
5271 5459
5272 5460 static void
5273 5461 output_pcap(FILE *fp)
5274 5462 {
5275 5463 uint64_t cap;
5276 5464
5277 5465 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &cap) == Z_OK) {
5278 5466 float scaled = (float)cap / 100;
5279 5467 (void) fprintf(fp, "%s:\n", rt_to_str(RT_PCAP));
5280 5468 (void) fprintf(fp, "\t[%s: %.2f]\n", pt_to_str(PT_NCPUS),
5281 5469 scaled);
5282 5470 }
5283 5471 }
5284 5472
5285 5473 static void
5286 5474 info_pcap(FILE *fp)
5287 5475 {
5288 5476 output_pcap(fp);
5289 5477 }
5290 5478
5291 5479
5292 5480 static void
5293 5481 info_aliased_rctl(zone_dochandle_t handle, FILE *fp, char *alias)
5294 5482 {
5295 5483 uint64_t limit;
5296 5484
5297 5485 if (zonecfg_get_aliased_rctl(handle, alias, &limit) == Z_OK) {
5298 5486 /* convert memory based properties */
5299 5487 if (strcmp(alias, ALIAS_MAXSHMMEM) == 0) {
5300 5488 char buf[128];
5301 5489
5302 5490 (void) snprintf(buf, sizeof (buf), "%llu", limit);
5303 5491 bytes_to_units(buf, buf, sizeof (buf));
5304 5492 (void) fprintf(fp, "[%s: %s]\n", alias, buf);
5305 5493 return;
5306 5494 }
5307 5495
5308 5496 (void) fprintf(fp, "[%s: %llu]\n", alias, limit);
5309 5497 }
5310 5498 }
5311 5499
5312 5500 static void
5313 5501 bytes_to_units(char *str, char *buf, int bufsize)
5314 5502 {
5315 5503 unsigned long long num;
5316 5504 unsigned long long save = 0;
5317 5505 char *units = "BKMGT";
5318 5506 char *up = units;
5319 5507
5320 5508 num = strtoll(str, NULL, 10);
5321 5509
5322 5510 if (num < 1024) {
5323 5511 (void) snprintf(buf, bufsize, "%llu", num);
5324 5512 return;
5325 5513 }
5326 5514
5327 5515 while ((num >= 1024) && (*up != 'T')) {
5328 5516 up++; /* next unit of measurement */
5329 5517 save = num;
5330 5518 num = (num + 512) >> 10;
5331 5519 }
5332 5520
5333 5521 /* check if we should output a fraction. snprintf will round for us */
5334 5522 if (save % 1024 != 0 && ((save >> 10) < 10))
5335 5523 (void) snprintf(buf, bufsize, "%2.1f%c", ((float)save / 1024),
5336 5524 *up);
5337 5525 else
5338 5526 (void) snprintf(buf, bufsize, "%llu%c", num, *up);
5339 5527 }
5340 5528
5341 5529 static void
5342 5530 output_mcap(FILE *fp, struct zone_mcaptab *mcaptab, int showswap,
5343 5531 uint64_t maxswap, int showlocked, uint64_t maxlocked)
5344 5532 {
5345 5533 char buf[128];
5346 5534
5347 5535 (void) fprintf(fp, "%s:\n", rt_to_str(RT_MCAP));
5348 5536 if (mcaptab->zone_physmem_cap[0] != '\0') {
5349 5537 bytes_to_units(mcaptab->zone_physmem_cap, buf, sizeof (buf));
5350 5538 output_prop(fp, PT_PHYSICAL, buf, B_TRUE);
5351 5539 }
5352 5540
5353 5541 if (showswap == Z_OK) {
5354 5542 (void) snprintf(buf, sizeof (buf), "%llu", maxswap);
5355 5543 bytes_to_units(buf, buf, sizeof (buf));
5356 5544 output_prop(fp, PT_SWAP, buf, B_TRUE);
5357 5545 }
5358 5546
5359 5547 if (showlocked == Z_OK) {
5360 5548 (void) snprintf(buf, sizeof (buf), "%llu", maxlocked);
5361 5549 bytes_to_units(buf, buf, sizeof (buf));
5362 5550 output_prop(fp, PT_LOCKED, buf, B_TRUE);
5363 5551 }
5364 5552 }
5365 5553
5366 5554 static void
5367 5555 info_mcap(zone_dochandle_t handle, FILE *fp)
5368 5556 {
5369 5557 int res1, res2, res3;
5370 5558 uint64_t swap_limit;
5371 5559 uint64_t locked_limit;
5372 5560 struct zone_mcaptab lookup;
5373 5561
5374 5562 bzero(&lookup, sizeof (lookup));
5375 5563 res1 = zonecfg_getmcapent(handle, &lookup);
5376 5564 res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &swap_limit);
5377 5565 res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM,
5378 5566 &locked_limit);
5379 5567
5380 5568 if (res1 == Z_OK || res2 == Z_OK || res3 == Z_OK)
5381 5569 output_mcap(fp, &lookup, res2, swap_limit, res3, locked_limit);
5382 5570 }
↓ open down ↓ |
594 lines elided |
↑ open up ↑ |
5383 5571
5384 5572 static void
5385 5573 output_auth(FILE *fp, struct zone_admintab *admintab)
5386 5574 {
5387 5575 (void) fprintf(fp, "%s:\n", rt_to_str(RT_ADMIN));
5388 5576 output_prop(fp, PT_USER, admintab->zone_admin_user, B_TRUE);
5389 5577 output_prop(fp, PT_AUTHS, admintab->zone_admin_auths, B_TRUE);
5390 5578 }
5391 5579
5392 5580 static void
5581 +output_secflags(FILE *fp, struct zone_secflagstab *sftab)
5582 +{
5583 + (void) fprintf(fp, "%s:\n", rt_to_str(RT_SECFLAGS));
5584 + output_prop(fp, PT_DEFAULT, sftab->zone_secflags_default, B_TRUE);
5585 + output_prop(fp, PT_LOWER, sftab->zone_secflags_lower, B_TRUE);
5586 + output_prop(fp, PT_UPPER, sftab->zone_secflags_upper, B_TRUE);
5587 +}
5588 +
5589 +static void
5393 5590 info_auth(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5394 5591 {
5395 5592 struct zone_admintab lookup, user;
5396 5593 boolean_t output = B_FALSE;
5397 5594 int err;
5398 5595
5399 5596 if ((err = zonecfg_setadminent(handle)) != Z_OK) {
5400 5597 zone_perror(zone, err, B_TRUE);
5401 5598 return;
5402 5599 }
5403 5600 while (zonecfg_getadminent(handle, &lookup) == Z_OK) {
5404 5601 if (cmd->cmd_prop_nv_pairs == 0) {
5405 5602 output_auth(fp, &lookup);
5406 5603 continue;
5407 5604 }
5408 5605 if (fill_in_admintab(cmd, &user, B_TRUE) != Z_OK)
5409 5606 continue;
5410 5607 if (strlen(user.zone_admin_user) > 0 &&
5411 5608 strcmp(user.zone_admin_user, lookup.zone_admin_user) != 0)
5412 5609 continue; /* no match */
5413 5610 output_auth(fp, &lookup);
5414 5611 output = B_TRUE;
5415 5612 }
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
5416 5613 (void) zonecfg_endadminent(handle);
5417 5614 /*
5418 5615 * If a property n/v pair was specified, warn the user if there was
5419 5616 * nothing to output.
5420 5617 */
5421 5618 if (!output && cmd->cmd_prop_nv_pairs > 0)
5422 5619 (void) printf(gettext("No such %s resource.\n"),
5423 5620 rt_to_str(RT_ADMIN));
5424 5621 }
5425 5622
5623 +static void
5624 +info_secflags(zone_dochandle_t handle, FILE *fp)
5625 +{
5626 + struct zone_secflagstab sftab;
5627 + int err;
5628 +
5629 + if ((err = zonecfg_lookup_secflags(handle, &sftab)) != Z_OK) {
5630 + zone_perror(zone, err, B_TRUE);
5631 + return;
5632 + }
5633 +
5634 + output_secflags(fp, &sftab);
5635 +}
5636 +
5426 5637 void
5427 5638 info_func(cmd_t *cmd)
5428 5639 {
5429 5640 FILE *fp = stdout;
5430 5641 boolean_t need_to_close = B_FALSE;
5431 5642 int type;
5432 5643 int res1, res2;
5433 5644 uint64_t swap_limit;
5434 5645 uint64_t locked_limit;
5435 5646
5436 5647 assert(cmd != NULL);
5437 5648
5438 5649 if (initialize(B_TRUE) != Z_OK)
5439 5650 return;
5440 5651
5441 5652 /* don't page error output */
5442 5653 if (interactive_mode) {
5443 5654 if ((fp = pager_open()) != NULL)
5444 5655 need_to_close = B_TRUE;
5445 5656 else
5446 5657 fp = stdout;
5447 5658
5448 5659 setbuf(fp, NULL);
5449 5660 }
5450 5661
5451 5662 if (!global_scope) {
5452 5663 switch (resource_scope) {
5453 5664 case RT_FS:
5454 5665 output_fs(fp, &in_progress_fstab);
5455 5666 break;
5456 5667 case RT_NET:
5457 5668 output_net(fp, &in_progress_nwiftab);
5458 5669 break;
5459 5670 case RT_DEVICE:
5460 5671 output_dev(fp, &in_progress_devtab);
5461 5672 break;
5462 5673 case RT_RCTL:
5463 5674 output_rctl(fp, &in_progress_rctltab);
5464 5675 break;
5465 5676 case RT_ATTR:
5466 5677 output_attr(fp, &in_progress_attrtab);
5467 5678 break;
5468 5679 case RT_DATASET:
5469 5680 output_ds(fp, &in_progress_dstab);
5470 5681 break;
5471 5682 case RT_DCPU:
5472 5683 output_pset(fp, &in_progress_psettab);
5473 5684 break;
5474 5685 case RT_PCAP:
5475 5686 output_pcap(fp);
5476 5687 break;
5477 5688 case RT_MCAP:
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
5478 5689 res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP,
5479 5690 &swap_limit);
5480 5691 res2 = zonecfg_get_aliased_rctl(handle,
5481 5692 ALIAS_MAXLOCKEDMEM, &locked_limit);
5482 5693 output_mcap(fp, &in_progress_mcaptab, res1, swap_limit,
5483 5694 res2, locked_limit);
5484 5695 break;
5485 5696 case RT_ADMIN:
5486 5697 output_auth(fp, &in_progress_admintab);
5487 5698 break;
5699 + case RT_SECFLAGS:
5700 + output_secflags(fp, &in_progress_secflagstab);
5701 + break;
5488 5702 }
5489 5703 goto cleanup;
5490 5704 }
5491 5705
5492 5706 type = cmd->cmd_res_type;
5493 5707
5494 5708 if (gz_invalid_rt_property(type)) {
5495 5709 zerr(gettext("%s is not a valid property for the global zone."),
5496 5710 rt_to_str(type));
5497 5711 goto cleanup;
5498 5712 }
5499 5713
5500 5714 if (gz_invalid_resource(type)) {
5501 5715 zerr(gettext("%s is not a valid resource for the global zone."),
5502 5716 rt_to_str(type));
5503 5717 goto cleanup;
5504 5718 }
5505 5719
5506 5720 switch (cmd->cmd_res_type) {
5507 5721 case RT_UNKNOWN:
5508 5722 info_zonename(handle, fp);
5509 5723 if (!global_zone) {
5510 5724 info_zonepath(handle, fp);
5511 5725 info_brand(handle, fp);
5512 5726 info_autoboot(handle, fp);
5513 5727 info_bootargs(handle, fp);
5514 5728 }
5515 5729 info_pool(handle, fp);
5516 5730 if (!global_zone) {
5517 5731 info_limitpriv(handle, fp);
5518 5732 info_sched(handle, fp);
5519 5733 info_iptype(handle, fp);
5520 5734 info_hostid(handle, fp);
5521 5735 info_fs_allowed(handle, fp);
5522 5736 }
5523 5737 info_aliased_rctl(handle, fp, ALIAS_MAXLWPS);
5524 5738 info_aliased_rctl(handle, fp, ALIAS_MAXPROCS);
5525 5739 info_aliased_rctl(handle, fp, ALIAS_MAXSHMMEM);
5526 5740 info_aliased_rctl(handle, fp, ALIAS_MAXSHMIDS);
5527 5741 info_aliased_rctl(handle, fp, ALIAS_MAXMSGIDS);
5528 5742 info_aliased_rctl(handle, fp, ALIAS_MAXSEMIDS);
5529 5743 info_aliased_rctl(handle, fp, ALIAS_SHARES);
5530 5744 if (!global_zone) {
5531 5745 info_fs(handle, fp, cmd);
5532 5746 info_net(handle, fp, cmd);
5533 5747 info_dev(handle, fp, cmd);
↓ open down ↓ |
36 lines elided |
↑ open up ↑ |
5534 5748 }
5535 5749 info_pset(handle, fp);
5536 5750 info_pcap(fp);
5537 5751 info_mcap(handle, fp);
5538 5752 if (!global_zone) {
5539 5753 info_attr(handle, fp, cmd);
5540 5754 info_ds(handle, fp, cmd);
5541 5755 info_auth(handle, fp, cmd);
5542 5756 }
5543 5757 info_rctl(handle, fp, cmd);
5758 + info_secflags(handle, fp);
5544 5759 break;
5545 5760 case RT_ZONENAME:
5546 5761 info_zonename(handle, fp);
5547 5762 break;
5548 5763 case RT_ZONEPATH:
5549 5764 info_zonepath(handle, fp);
5550 5765 break;
5551 5766 case RT_BRAND:
5552 5767 info_brand(handle, fp);
5553 5768 break;
5554 5769 case RT_AUTOBOOT:
5555 5770 info_autoboot(handle, fp);
5556 5771 break;
5557 5772 case RT_POOL:
5558 5773 info_pool(handle, fp);
5559 5774 break;
5560 5775 case RT_LIMITPRIV:
5561 5776 info_limitpriv(handle, fp);
5562 5777 break;
5563 5778 case RT_BOOTARGS:
5564 5779 info_bootargs(handle, fp);
5565 5780 break;
5566 5781 case RT_SCHED:
5567 5782 info_sched(handle, fp);
5568 5783 break;
5569 5784 case RT_IPTYPE:
5570 5785 info_iptype(handle, fp);
5571 5786 break;
5572 5787 case RT_MAXLWPS:
5573 5788 info_aliased_rctl(handle, fp, ALIAS_MAXLWPS);
5574 5789 break;
5575 5790 case RT_MAXPROCS:
5576 5791 info_aliased_rctl(handle, fp, ALIAS_MAXPROCS);
5577 5792 break;
5578 5793 case RT_MAXSHMMEM:
5579 5794 info_aliased_rctl(handle, fp, ALIAS_MAXSHMMEM);
5580 5795 break;
5581 5796 case RT_MAXSHMIDS:
5582 5797 info_aliased_rctl(handle, fp, ALIAS_MAXSHMIDS);
5583 5798 break;
5584 5799 case RT_MAXMSGIDS:
5585 5800 info_aliased_rctl(handle, fp, ALIAS_MAXMSGIDS);
5586 5801 break;
5587 5802 case RT_MAXSEMIDS:
5588 5803 info_aliased_rctl(handle, fp, ALIAS_MAXSEMIDS);
5589 5804 break;
5590 5805 case RT_SHARES:
5591 5806 info_aliased_rctl(handle, fp, ALIAS_SHARES);
5592 5807 break;
5593 5808 case RT_FS:
5594 5809 info_fs(handle, fp, cmd);
5595 5810 break;
5596 5811 case RT_NET:
5597 5812 info_net(handle, fp, cmd);
5598 5813 break;
5599 5814 case RT_DEVICE:
5600 5815 info_dev(handle, fp, cmd);
5601 5816 break;
5602 5817 case RT_RCTL:
5603 5818 info_rctl(handle, fp, cmd);
5604 5819 break;
5605 5820 case RT_ATTR:
5606 5821 info_attr(handle, fp, cmd);
5607 5822 break;
5608 5823 case RT_DATASET:
5609 5824 info_ds(handle, fp, cmd);
5610 5825 break;
5611 5826 case RT_DCPU:
5612 5827 info_pset(handle, fp);
5613 5828 break;
5614 5829 case RT_PCAP:
5615 5830 info_pcap(fp);
5616 5831 break;
5617 5832 case RT_MCAP:
5618 5833 info_mcap(handle, fp);
↓ open down ↓ |
65 lines elided |
↑ open up ↑ |
5619 5834 break;
5620 5835 case RT_HOSTID:
5621 5836 info_hostid(handle, fp);
5622 5837 break;
5623 5838 case RT_ADMIN:
5624 5839 info_auth(handle, fp, cmd);
5625 5840 break;
5626 5841 case RT_FS_ALLOWED:
5627 5842 info_fs_allowed(handle, fp);
5628 5843 break;
5844 + case RT_SECFLAGS:
5845 + info_secflags(handle, fp);
5846 + break;
5629 5847 default:
5630 5848 zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
5631 5849 B_TRUE);
5632 5850 }
5633 5851
5634 5852 cleanup:
5635 5853 if (need_to_close)
5636 5854 (void) pager_close(fp);
5637 5855 }
5638 5856
5639 5857 /*
5640 5858 * Helper function for verify-- checks that a required string property
5641 5859 * exists.
5642 5860 */
5643 5861 static void
5644 5862 check_reqd_prop(char *attr, int rt, int pt, int *ret_val)
5645 5863 {
5646 5864 if (strlen(attr) == 0) {
5647 5865 zerr(gettext("%s: %s not specified"), rt_to_str(rt),
5648 5866 pt_to_str(pt));
5649 5867 saw_error = B_TRUE;
5650 5868 if (*ret_val == Z_OK)
5651 5869 *ret_val = Z_REQD_PROPERTY_MISSING;
5652 5870 }
5653 5871 }
5654 5872
5655 5873 static int
5656 5874 do_subproc(char *cmdbuf)
5657 5875 {
5658 5876 char inbuf[MAX_CMD_LEN];
5659 5877 FILE *file;
5660 5878 int status;
5661 5879
5662 5880 file = popen(cmdbuf, "r");
5663 5881 if (file == NULL) {
5664 5882 zerr(gettext("Could not launch: %s"), cmdbuf);
5665 5883 return (-1);
5666 5884 }
5667 5885
5668 5886 while (fgets(inbuf, sizeof (inbuf), file) != NULL)
5669 5887 fprintf(stderr, "%s", inbuf);
5670 5888 status = pclose(file);
5671 5889
5672 5890 if (WIFSIGNALED(status)) {
5673 5891 zerr(gettext("%s unexpectedly terminated due to signal %d"),
5674 5892 cmdbuf, WTERMSIG(status));
5675 5893 return (-1);
5676 5894 }
5677 5895 assert(WIFEXITED(status));
5678 5896 return (WEXITSTATUS(status));
5679 5897 }
5680 5898
5681 5899 static int
5682 5900 brand_verify(zone_dochandle_t handle)
5683 5901 {
5684 5902 char xml_file[32];
5685 5903 char cmdbuf[MAX_CMD_LEN];
5686 5904 brand_handle_t bh;
5687 5905 char brand[MAXNAMELEN];
5688 5906 int err;
5689 5907
5690 5908 if (zonecfg_get_brand(handle, brand, sizeof (brand)) != Z_OK) {
5691 5909 zerr("%s: %s\n", zone, gettext("could not get zone brand"));
5692 5910 return (Z_INVALID_DOCUMENT);
5693 5911 }
5694 5912 if ((bh = brand_open(brand)) == NULL) {
5695 5913 zerr("%s: %s\n", zone, gettext("unknown brand."));
5696 5914 return (Z_INVALID_DOCUMENT);
5697 5915 }
5698 5916
5699 5917 /*
5700 5918 * Fetch the verify command, if any, from the brand configuration
5701 5919 * and build the command line to execute it.
5702 5920 */
5703 5921 strcpy(cmdbuf, EXEC_PREFIX);
5704 5922 err = brand_get_verify_cfg(bh, cmdbuf + EXEC_LEN,
5705 5923 sizeof (cmdbuf) - (EXEC_LEN + (strlen(xml_file) + 1)));
5706 5924 brand_close(bh);
5707 5925 if (err != Z_OK) {
5708 5926 zerr("%s: %s\n", zone,
5709 5927 gettext("could not get brand verification command"));
5710 5928 return (Z_INVALID_DOCUMENT);
5711 5929 }
5712 5930
5713 5931 /*
5714 5932 * If the brand doesn't provide a verification routine, we just
5715 5933 * return success.
5716 5934 */
5717 5935 if (strlen(cmdbuf) == EXEC_LEN)
5718 5936 return (Z_OK);
5719 5937
5720 5938 /*
5721 5939 * Dump the current config information for this zone to a file.
5722 5940 */
5723 5941 strcpy(xml_file, "/tmp/zonecfg_verify.XXXXXX");
5724 5942 if (mkstemp(xml_file) == NULL)
5725 5943 return (Z_TEMP_FILE);
5726 5944 if ((err = zonecfg_verify_save(handle, xml_file)) != Z_OK) {
5727 5945 (void) unlink(xml_file);
5728 5946 return (err);
5729 5947 }
5730 5948
5731 5949 /*
5732 5950 * Execute the verification command.
5733 5951 */
5734 5952 if ((strlcat(cmdbuf, " ", MAX_CMD_LEN) >= MAX_CMD_LEN) ||
5735 5953 (strlcat(cmdbuf, xml_file, MAX_CMD_LEN) >= MAX_CMD_LEN)) {
5736 5954 err = Z_BRAND_ERROR;
5737 5955 } else {
5738 5956 err = do_subproc(cmdbuf);
5739 5957 }
5740 5958
5741 5959 (void) unlink(xml_file);
5742 5960 return ((err == Z_OK) ? Z_OK : Z_BRAND_ERROR);
5743 5961 }
5744 5962
5745 5963 /*
5746 5964 * Track the network interfaces listed in zonecfg(1m) in a linked list
5747 5965 * so that we can later check that defrouter is specified for an exclusive IP
5748 5966 * zone if and only if at least one allowed-address has been specified.
5749 5967 */
5750 5968 static boolean_t
5751 5969 add_nwif(struct zone_nwiftab *nwif)
5752 5970 {
5753 5971 struct xif *tmp;
5754 5972
5755 5973 for (tmp = xif; tmp != NULL; tmp = tmp->xif_next) {
5756 5974 if (strcmp(tmp->xif_name, nwif->zone_nwif_physical) == 0) {
5757 5975 if (strlen(nwif->zone_nwif_allowed_address) > 0)
5758 5976 tmp->xif_has_address = B_TRUE;
5759 5977 if (strlen(nwif->zone_nwif_defrouter) > 0)
5760 5978 tmp->xif_has_defrouter = B_TRUE;
5761 5979 return (B_TRUE);
5762 5980 }
5763 5981 }
5764 5982
5765 5983 tmp = malloc(sizeof (*tmp));
5766 5984 if (tmp == NULL) {
5767 5985 zerr(gettext("memory allocation failed for %s"),
5768 5986 nwif->zone_nwif_physical);
5769 5987 return (B_FALSE);
↓ open down ↓ |
131 lines elided |
↑ open up ↑ |
5770 5988 }
5771 5989 strlcpy(tmp->xif_name, nwif->zone_nwif_physical,
5772 5990 sizeof (tmp->xif_name));
5773 5991 tmp->xif_has_defrouter = (strlen(nwif->zone_nwif_defrouter) > 0);
5774 5992 tmp->xif_has_address = (strlen(nwif->zone_nwif_allowed_address) > 0);
5775 5993 tmp->xif_next = xif;
5776 5994 xif = tmp;
5777 5995 return (B_TRUE);
5778 5996 }
5779 5997
5998 +boolean_t
5999 +verify_secflags(struct zone_secflagstab *tab)
6000 +{
6001 + secflagdelta_t def = {0};
6002 + secflagdelta_t upper = {0};
6003 + secflagdelta_t lower = {0};
6004 + boolean_t def_set = B_FALSE;
6005 + boolean_t upper_set = B_FALSE;
6006 + boolean_t lower_set = B_FALSE;
6007 + boolean_t ret = B_TRUE;
6008 +
6009 + if (strlen(tab->zone_secflags_default) > 0) {
6010 + def_set = B_TRUE;
6011 + if (secflags_parse(NULL, tab->zone_secflags_default,
6012 + &def) == -1) {
6013 + zerr(gettext("default security flags '%s' are invalid"),
6014 + tab->zone_secflags_default);
6015 + ret = B_FALSE;
6016 + }
6017 + } else {
6018 + secflags_zero(&def.psd_assign);
6019 + def.psd_ass_active = B_TRUE;
6020 + }
6021 +
6022 + if (strlen(tab->zone_secflags_upper) > 0) {
6023 + upper_set = B_TRUE;
6024 + if (secflags_parse(NULL, tab->zone_secflags_upper,
6025 + &upper) == -1) {
6026 + zerr(gettext("upper security flags '%s' are invalid"),
6027 + tab->zone_secflags_upper);
6028 + ret = B_FALSE;
6029 + }
6030 + } else {
6031 + secflags_fullset(&upper.psd_assign);
6032 + upper.psd_ass_active = B_TRUE;
6033 + }
6034 +
6035 + if (strlen(tab->zone_secflags_lower) > 0) {
6036 + lower_set = B_TRUE;
6037 + if (secflags_parse(NULL, tab->zone_secflags_lower,
6038 + &lower) == -1) {
6039 + zerr(gettext("lower security flags '%s' are invalid"),
6040 + tab->zone_secflags_lower);
6041 + ret = B_FALSE;
6042 + }
6043 + } else {
6044 + secflags_zero(&lower.psd_assign);
6045 + lower.psd_ass_active = B_TRUE;
6046 + }
6047 +
6048 + if (def_set && !def.psd_ass_active) {
6049 + zerr(gettext("only assignment of security flags is "
6050 + "allowed (default: %s)"), tab->zone_secflags_default);
6051 + }
6052 +
6053 + if (lower_set && !lower.psd_ass_active) {
6054 + zerr(gettext("only assignment of security flags is "
6055 + "allowed (lower: %s)"), tab->zone_secflags_lower);
6056 + }
6057 +
6058 + if (upper_set && !upper.psd_ass_active) {
6059 + zerr(gettext("only assignment of security flags is "
6060 + "allowed (upper: %s)"), tab->zone_secflags_upper);
6061 + }
6062 +
6063 + if (def.psd_assign & ~upper.psd_assign) { /* In default but not upper */
6064 + zerr(gettext("default secflags must be within the "
6065 + "upper limit"));
6066 + ret = B_FALSE;
6067 + }
6068 + if (lower.psd_assign & ~def.psd_assign) { /* In lower but not default */
6069 + zerr(gettext("default secflags must be above the lower limit"));
6070 + ret = B_FALSE;
6071 + }
6072 + if (lower.psd_assign & ~upper.psd_assign) { /* In lower but not upper */
6073 + zerr(gettext("lower secflags must be within the upper limit"));
6074 + ret = B_FALSE;
6075 + }
6076 +
6077 + return (ret);
6078 +}
6079 +
5780 6080 /*
5781 6081 * See the DTD for which attributes are required for which resources.
5782 6082 *
5783 6083 * This function can be called by commit_func(), which needs to save things,
5784 6084 * in addition to the general call from parse_and_run(), which doesn't need
5785 6085 * things saved. Since the parameters are standardized, we distinguish by
5786 6086 * having commit_func() call here with cmd->cmd_arg set to "save" to indicate
5787 6087 * that a save is needed.
5788 6088 */
5789 6089 void
5790 6090 verify_func(cmd_t *cmd)
5791 6091 {
5792 6092 struct zone_nwiftab nwiftab;
5793 6093 struct zone_fstab fstab;
5794 6094 struct zone_attrtab attrtab;
5795 6095 struct zone_rctltab rctltab;
5796 6096 struct zone_dstab dstab;
5797 6097 struct zone_psettab psettab;
5798 6098 struct zone_admintab admintab;
6099 + struct zone_secflagstab secflagstab;
5799 6100 char zonepath[MAXPATHLEN];
5800 6101 char sched[MAXNAMELEN];
5801 6102 char brand[MAXNAMELEN];
5802 6103 char hostidp[HW_HOSTID_LEN];
5803 6104 char fsallowedp[ZONE_FS_ALLOWED_MAX];
5804 6105 priv_set_t *privs;
5805 6106 char *privname = NULL;
5806 6107 int err, ret_val = Z_OK, arg;
5807 6108 int pset_res;
5808 6109 boolean_t save = B_FALSE;
5809 6110 boolean_t arg_err = B_FALSE;
5810 6111 zone_iptype_t iptype;
5811 6112 boolean_t has_cpu_shares = B_FALSE;
5812 6113 boolean_t has_cpu_cap = B_FALSE;
5813 6114 struct xif *tmp;
5814 6115
5815 6116 optind = 0;
5816 6117 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
5817 6118 switch (arg) {
5818 6119 case '?':
5819 6120 longer_usage(CMD_VERIFY);
5820 6121 arg_err = B_TRUE;
5821 6122 break;
5822 6123 default:
5823 6124 short_usage(CMD_VERIFY);
5824 6125 arg_err = B_TRUE;
5825 6126 break;
5826 6127 }
5827 6128 }
5828 6129 if (arg_err)
5829 6130 return;
5830 6131
5831 6132 if (optind > cmd->cmd_argc) {
5832 6133 short_usage(CMD_VERIFY);
5833 6134 return;
5834 6135 }
5835 6136
5836 6137 if (zone_is_read_only(CMD_VERIFY))
5837 6138 return;
5838 6139
5839 6140 assert(cmd != NULL);
5840 6141
5841 6142 if (cmd->cmd_argc > 0 && (strcmp(cmd->cmd_argv[0], "save") == 0))
5842 6143 save = B_TRUE;
5843 6144 if (initialize(B_TRUE) != Z_OK)
5844 6145 return;
5845 6146
5846 6147 if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) != Z_OK &&
5847 6148 !global_zone) {
5848 6149 zerr(gettext("%s not specified"), pt_to_str(PT_ZONEPATH));
5849 6150 ret_val = Z_REQD_RESOURCE_MISSING;
5850 6151 saw_error = B_TRUE;
5851 6152 }
5852 6153 if (strlen(zonepath) == 0 && !global_zone) {
5853 6154 zerr(gettext("%s cannot be empty."), pt_to_str(PT_ZONEPATH));
5854 6155 ret_val = Z_REQD_RESOURCE_MISSING;
5855 6156 saw_error = B_TRUE;
5856 6157 }
5857 6158
5858 6159 if ((err = zonecfg_get_brand(handle, brand, sizeof (brand))) != Z_OK) {
5859 6160 zone_perror(zone, err, B_TRUE);
5860 6161 return;
5861 6162 }
5862 6163 if ((err = brand_verify(handle)) != Z_OK) {
5863 6164 zone_perror(zone, err, B_TRUE);
5864 6165 return;
5865 6166 }
5866 6167
5867 6168 if (zonecfg_get_iptype(handle, &iptype) != Z_OK) {
5868 6169 zerr("%s %s", gettext("cannot get"), pt_to_str(PT_IPTYPE));
5869 6170 ret_val = Z_REQD_RESOURCE_MISSING;
5870 6171 saw_error = B_TRUE;
5871 6172 }
5872 6173
5873 6174 if ((privs = priv_allocset()) == NULL) {
5874 6175 zerr(gettext("%s: priv_allocset failed"), zone);
5875 6176 return;
5876 6177 }
5877 6178 if (zonecfg_get_privset(handle, privs, &privname) != Z_OK) {
5878 6179 zerr(gettext("%s: invalid privilege: %s"), zone, privname);
5879 6180 priv_freeset(privs);
5880 6181 free(privname);
5881 6182 return;
5882 6183 }
5883 6184 priv_freeset(privs);
5884 6185
5885 6186 if (zonecfg_get_hostid(handle, hostidp,
5886 6187 sizeof (hostidp)) == Z_INVALID_PROPERTY) {
5887 6188 zerr(gettext("%s: invalid hostid: %s"),
5888 6189 zone, hostidp);
5889 6190 return;
5890 6191 }
5891 6192
5892 6193 if (zonecfg_get_fs_allowed(handle, fsallowedp,
5893 6194 sizeof (fsallowedp)) == Z_INVALID_PROPERTY) {
5894 6195 zerr(gettext("%s: invalid fs-allowed: %s"),
5895 6196 zone, fsallowedp);
5896 6197 return;
5897 6198 }
5898 6199
5899 6200 if ((err = zonecfg_setfsent(handle)) != Z_OK) {
5900 6201 zone_perror(zone, err, B_TRUE);
5901 6202 return;
5902 6203 }
5903 6204 while (zonecfg_getfsent(handle, &fstab) == Z_OK) {
5904 6205 check_reqd_prop(fstab.zone_fs_dir, RT_FS, PT_DIR, &ret_val);
5905 6206 check_reqd_prop(fstab.zone_fs_special, RT_FS, PT_SPECIAL,
5906 6207 &ret_val);
5907 6208 check_reqd_prop(fstab.zone_fs_type, RT_FS, PT_TYPE, &ret_val);
5908 6209
5909 6210 zonecfg_free_fs_option_list(fstab.zone_fs_options);
5910 6211 }
5911 6212 (void) zonecfg_endfsent(handle);
5912 6213
5913 6214 if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
5914 6215 zone_perror(zone, err, B_TRUE);
5915 6216 return;
5916 6217 }
5917 6218 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
5918 6219 /*
5919 6220 * physical is required in all cases.
5920 6221 * A shared IP requires an address,
5921 6222 * and may include a default router, while
5922 6223 * an exclusive IP must have neither an address
5923 6224 * nor a default router.
5924 6225 * The physical interface name must be valid in all cases.
5925 6226 */
5926 6227 check_reqd_prop(nwiftab.zone_nwif_physical, RT_NET,
5927 6228 PT_PHYSICAL, &ret_val);
5928 6229 if (validate_net_physical_syntax(nwiftab.zone_nwif_physical) !=
5929 6230 Z_OK) {
5930 6231 saw_error = B_TRUE;
5931 6232 if (ret_val == Z_OK)
5932 6233 ret_val = Z_INVAL;
5933 6234 }
5934 6235
5935 6236 switch (iptype) {
5936 6237 case ZS_SHARED:
5937 6238 check_reqd_prop(nwiftab.zone_nwif_address, RT_NET,
5938 6239 PT_ADDRESS, &ret_val);
5939 6240 if (strlen(nwiftab.zone_nwif_allowed_address) > 0) {
5940 6241 zerr(gettext("%s: %s cannot be specified "
5941 6242 "for a shared IP type"),
5942 6243 rt_to_str(RT_NET),
5943 6244 pt_to_str(PT_ALLOWED_ADDRESS));
5944 6245 saw_error = B_TRUE;
5945 6246 if (ret_val == Z_OK)
5946 6247 ret_val = Z_INVAL;
5947 6248 }
5948 6249 break;
5949 6250 case ZS_EXCLUSIVE:
5950 6251 if (strlen(nwiftab.zone_nwif_address) > 0) {
5951 6252 zerr(gettext("%s: %s cannot be specified "
5952 6253 "for an exclusive IP type"),
5953 6254 rt_to_str(RT_NET), pt_to_str(PT_ADDRESS));
5954 6255 saw_error = B_TRUE;
5955 6256 if (ret_val == Z_OK)
5956 6257 ret_val = Z_INVAL;
5957 6258 } else {
5958 6259 if (!add_nwif(&nwiftab)) {
5959 6260 saw_error = B_TRUE;
5960 6261 if (ret_val == Z_OK)
5961 6262 ret_val = Z_INVAL;
5962 6263 }
5963 6264 }
5964 6265 break;
5965 6266 }
5966 6267 }
5967 6268 for (tmp = xif; tmp != NULL; tmp = tmp->xif_next) {
5968 6269 if (!tmp->xif_has_address && tmp->xif_has_defrouter) {
5969 6270 zerr(gettext("%s: %s for %s cannot be specified "
5970 6271 "without %s for an exclusive IP type"),
5971 6272 rt_to_str(RT_NET), pt_to_str(PT_DEFROUTER),
5972 6273 tmp->xif_name, pt_to_str(PT_ALLOWED_ADDRESS));
5973 6274 saw_error = B_TRUE;
5974 6275 ret_val = Z_INVAL;
5975 6276 }
5976 6277 }
5977 6278 free(xif);
5978 6279 xif = NULL;
5979 6280 (void) zonecfg_endnwifent(handle);
5980 6281
5981 6282 if ((err = zonecfg_setrctlent(handle)) != Z_OK) {
5982 6283 zone_perror(zone, err, B_TRUE);
5983 6284 return;
5984 6285 }
5985 6286 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
5986 6287 check_reqd_prop(rctltab.zone_rctl_name, RT_RCTL, PT_NAME,
5987 6288 &ret_val);
5988 6289
5989 6290 if (strcmp(rctltab.zone_rctl_name, "zone.cpu-shares") == 0)
5990 6291 has_cpu_shares = B_TRUE;
5991 6292
5992 6293 if (strcmp(rctltab.zone_rctl_name, "zone.cpu-cap") == 0)
5993 6294 has_cpu_cap = B_TRUE;
5994 6295
5995 6296 if (rctltab.zone_rctl_valptr == NULL) {
5996 6297 zerr(gettext("%s: no %s specified"),
5997 6298 rt_to_str(RT_RCTL), pt_to_str(PT_VALUE));
5998 6299 saw_error = B_TRUE;
5999 6300 if (ret_val == Z_OK)
6000 6301 ret_val = Z_REQD_PROPERTY_MISSING;
6001 6302 } else {
6002 6303 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
6003 6304 }
6004 6305 }
6005 6306 (void) zonecfg_endrctlent(handle);
6006 6307
6007 6308 if ((pset_res = zonecfg_lookup_pset(handle, &psettab)) == Z_OK &&
6008 6309 has_cpu_shares) {
6009 6310 zerr(gettext("%s zone.cpu-shares and %s are incompatible."),
6010 6311 rt_to_str(RT_RCTL), rt_to_str(RT_DCPU));
6011 6312 saw_error = B_TRUE;
6012 6313 if (ret_val == Z_OK)
6013 6314 ret_val = Z_INCOMPATIBLE;
6014 6315 }
6015 6316
6016 6317 if (has_cpu_shares && zonecfg_get_sched_class(handle, sched,
6017 6318 sizeof (sched)) == Z_OK && strlen(sched) > 0 &&
6018 6319 strcmp(sched, "FSS") != 0) {
6019 6320 zerr(gettext("WARNING: %s zone.cpu-shares and %s=%s are "
6020 6321 "incompatible"),
6021 6322 rt_to_str(RT_RCTL), rt_to_str(RT_SCHED), sched);
6022 6323 saw_error = B_TRUE;
6023 6324 if (ret_val == Z_OK)
6024 6325 ret_val = Z_INCOMPATIBLE;
6025 6326 }
6026 6327
6027 6328 if (pset_res == Z_OK && has_cpu_cap) {
6028 6329 zerr(gettext("%s zone.cpu-cap and the %s are incompatible."),
6029 6330 rt_to_str(RT_RCTL), rt_to_str(RT_DCPU));
6030 6331 saw_error = B_TRUE;
6031 6332 if (ret_val == Z_OK)
6032 6333 ret_val = Z_INCOMPATIBLE;
6033 6334 }
6034 6335
6035 6336 if ((err = zonecfg_setattrent(handle)) != Z_OK) {
6036 6337 zone_perror(zone, err, B_TRUE);
6037 6338 return;
6038 6339 }
6039 6340 while (zonecfg_getattrent(handle, &attrtab) == Z_OK) {
6040 6341 check_reqd_prop(attrtab.zone_attr_name, RT_ATTR, PT_NAME,
6041 6342 &ret_val);
6042 6343 check_reqd_prop(attrtab.zone_attr_type, RT_ATTR, PT_TYPE,
6043 6344 &ret_val);
6044 6345 check_reqd_prop(attrtab.zone_attr_value, RT_ATTR, PT_VALUE,
6045 6346 &ret_val);
6046 6347 }
6047 6348 (void) zonecfg_endattrent(handle);
6048 6349
6049 6350 if ((err = zonecfg_setdsent(handle)) != Z_OK) {
6050 6351 zone_perror(zone, err, B_TRUE);
6051 6352 return;
6052 6353 }
6053 6354 while (zonecfg_getdsent(handle, &dstab) == Z_OK) {
6054 6355 if (strlen(dstab.zone_dataset_name) == 0) {
6055 6356 zerr("%s: %s %s", rt_to_str(RT_DATASET),
6056 6357 pt_to_str(PT_NAME), gettext("not specified"));
6057 6358 saw_error = B_TRUE;
6058 6359 if (ret_val == Z_OK)
6059 6360 ret_val = Z_REQD_PROPERTY_MISSING;
6060 6361 } else if (!zfs_name_valid(dstab.zone_dataset_name,
6061 6362 ZFS_TYPE_FILESYSTEM)) {
6062 6363 zerr("%s: %s %s", rt_to_str(RT_DATASET),
6063 6364 pt_to_str(PT_NAME), gettext("invalid"));
6064 6365 saw_error = B_TRUE;
6065 6366 if (ret_val == Z_OK)
6066 6367 ret_val = Z_BAD_PROPERTY;
6067 6368 }
6068 6369
6069 6370 }
6070 6371 (void) zonecfg_enddsent(handle);
6071 6372
6072 6373 if ((err = zonecfg_setadminent(handle)) != Z_OK) {
6073 6374 zone_perror(zone, err, B_TRUE);
6074 6375 return;
6075 6376 }
6076 6377 while (zonecfg_getadminent(handle, &admintab) == Z_OK) {
6077 6378 check_reqd_prop(admintab.zone_admin_user, RT_ADMIN,
6078 6379 PT_USER, &ret_val);
6079 6380 check_reqd_prop(admintab.zone_admin_auths, RT_ADMIN,
6080 6381 PT_AUTHS, &ret_val);
6081 6382 if ((ret_val == Z_OK) && (getpwnam(admintab.zone_admin_user)
6082 6383 == NULL)) {
6083 6384 zerr(gettext("%s %s is not a valid username"),
6084 6385 pt_to_str(PT_USER),
↓ open down ↓ |
276 lines elided |
↑ open up ↑ |
6085 6386 admintab.zone_admin_user);
6086 6387 ret_val = Z_BAD_PROPERTY;
6087 6388 }
6088 6389 if ((ret_val == Z_OK) && (!zonecfg_valid_auths(
6089 6390 admintab.zone_admin_auths, zone))) {
6090 6391 ret_val = Z_BAD_PROPERTY;
6091 6392 }
6092 6393 }
6093 6394 (void) zonecfg_endadminent(handle);
6094 6395
6396 + if ((err = zonecfg_getsecflagsent(handle, &secflagstab)) != Z_OK) {
6397 + zone_perror(zone, err, B_TRUE);
6398 + return;
6399 + }
6400 +
6401 + /*
6402 + * No properties are required, but any specified should be
6403 + * valid
6404 + */
6405 + if (verify_secflags(&secflagstab) != B_TRUE) {
6406 + /* Error is reported from verify_secflags */
6407 + ret_val = Z_BAD_PROPERTY;
6408 + }
6409 +
6095 6410 if (!global_scope) {
6096 6411 zerr(gettext("resource specification incomplete"));
6097 6412 saw_error = B_TRUE;
6098 6413 if (ret_val == Z_OK)
6099 6414 ret_val = Z_INSUFFICIENT_SPEC;
6100 6415 }
6101 6416
6102 6417 if (save) {
6103 6418 if (ret_val == Z_OK) {
6104 6419 if ((ret_val = zonecfg_save(handle)) == Z_OK) {
6105 6420 need_to_commit = B_FALSE;
6106 6421 (void) strlcpy(revert_zone, zone,
6107 6422 sizeof (revert_zone));
6108 6423 }
6109 6424 } else {
6110 6425 zerr(gettext("Zone %s failed to verify"), zone);
6111 6426 }
6112 6427 }
6113 6428 if (ret_val != Z_OK)
6114 6429 zone_perror(zone, ret_val, B_TRUE);
6115 6430 }
6116 6431
6117 6432 void
6118 6433 cancel_func(cmd_t *cmd)
6119 6434 {
6120 6435 int arg;
6121 6436 boolean_t arg_err = B_FALSE;
6122 6437
6123 6438 assert(cmd != NULL);
6124 6439
6125 6440 optind = 0;
6126 6441 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
6127 6442 switch (arg) {
6128 6443 case '?':
6129 6444 longer_usage(CMD_CANCEL);
6130 6445 arg_err = B_TRUE;
6131 6446 break;
6132 6447 default:
6133 6448 short_usage(CMD_CANCEL);
6134 6449 arg_err = B_TRUE;
6135 6450 break;
6136 6451 }
6137 6452 }
6138 6453 if (arg_err)
6139 6454 return;
6140 6455
6141 6456 if (optind != cmd->cmd_argc) {
6142 6457 short_usage(CMD_CANCEL);
6143 6458 return;
6144 6459 }
6145 6460
6146 6461 if (global_scope)
6147 6462 scope_usage(CMD_CANCEL);
6148 6463 global_scope = B_TRUE;
6149 6464 zonecfg_free_fs_option_list(in_progress_fstab.zone_fs_options);
6150 6465 bzero(&in_progress_fstab, sizeof (in_progress_fstab));
6151 6466 bzero(&in_progress_nwiftab, sizeof (in_progress_nwiftab));
6152 6467 bzero(&in_progress_devtab, sizeof (in_progress_devtab));
6153 6468 zonecfg_free_rctl_value_list(in_progress_rctltab.zone_rctl_valptr);
6154 6469 bzero(&in_progress_rctltab, sizeof (in_progress_rctltab));
6155 6470 bzero(&in_progress_attrtab, sizeof (in_progress_attrtab));
6156 6471 bzero(&in_progress_dstab, sizeof (in_progress_dstab));
6157 6472 }
6158 6473
6159 6474 static int
6160 6475 validate_attr_name(char *name)
6161 6476 {
6162 6477 int i;
6163 6478
6164 6479 if (!isalnum(name[0])) {
6165 6480 zerr(gettext("Invalid %s %s %s: must start with an alpha-"
6166 6481 "numeric character."), rt_to_str(RT_ATTR),
6167 6482 pt_to_str(PT_NAME), name);
6168 6483 return (Z_INVAL);
6169 6484 }
6170 6485 for (i = 1; name[i]; i++)
6171 6486 if (!isalnum(name[i]) && name[i] != '-' && name[i] != '.') {
6172 6487 zerr(gettext("Invalid %s %s %s: can only contain "
6173 6488 "alpha-numeric characters, plus '-' and '.'."),
6174 6489 rt_to_str(RT_ATTR), pt_to_str(PT_NAME), name);
6175 6490 return (Z_INVAL);
6176 6491 }
6177 6492 return (Z_OK);
6178 6493 }
6179 6494
6180 6495 static int
6181 6496 validate_attr_type_val(struct zone_attrtab *attrtab)
6182 6497 {
6183 6498 boolean_t boolval;
6184 6499 int64_t intval;
6185 6500 char strval[MAXNAMELEN];
6186 6501 uint64_t uintval;
6187 6502
6188 6503 if (strcmp(attrtab->zone_attr_type, "boolean") == 0) {
6189 6504 if (zonecfg_get_attr_boolean(attrtab, &boolval) == Z_OK)
6190 6505 return (Z_OK);
6191 6506 zerr(gettext("invalid %s value for %s=%s"),
6192 6507 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "boolean");
6193 6508 return (Z_ERR);
6194 6509 }
6195 6510
6196 6511 if (strcmp(attrtab->zone_attr_type, "int") == 0) {
6197 6512 if (zonecfg_get_attr_int(attrtab, &intval) == Z_OK)
6198 6513 return (Z_OK);
6199 6514 zerr(gettext("invalid %s value for %s=%s"),
6200 6515 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "int");
6201 6516 return (Z_ERR);
6202 6517 }
6203 6518
6204 6519 if (strcmp(attrtab->zone_attr_type, "string") == 0) {
6205 6520 if (zonecfg_get_attr_string(attrtab, strval,
6206 6521 sizeof (strval)) == Z_OK)
6207 6522 return (Z_OK);
6208 6523 zerr(gettext("invalid %s value for %s=%s"),
6209 6524 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "string");
6210 6525 return (Z_ERR);
6211 6526 }
6212 6527
6213 6528 if (strcmp(attrtab->zone_attr_type, "uint") == 0) {
6214 6529 if (zonecfg_get_attr_uint(attrtab, &uintval) == Z_OK)
6215 6530 return (Z_OK);
6216 6531 zerr(gettext("invalid %s value for %s=%s"),
6217 6532 rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "uint");
6218 6533 return (Z_ERR);
6219 6534 }
6220 6535
6221 6536 zerr(gettext("invalid %s %s '%s'"), rt_to_str(RT_ATTR),
6222 6537 pt_to_str(PT_TYPE), attrtab->zone_attr_type);
6223 6538 return (Z_ERR);
6224 6539 }
6225 6540
6226 6541 /*
6227 6542 * Helper function for end_func-- checks the existence of a given property
6228 6543 * and emits a message if not specified.
6229 6544 */
6230 6545 static int
6231 6546 end_check_reqd(char *attr, int pt, boolean_t *validation_failed)
6232 6547 {
6233 6548 if (strlen(attr) == 0) {
6234 6549 *validation_failed = B_TRUE;
6235 6550 zerr(gettext("%s not specified"), pt_to_str(pt));
6236 6551 return (Z_ERR);
6237 6552 }
6238 6553 return (Z_OK);
6239 6554 }
6240 6555
6241 6556 static void
6242 6557 net_exists_error(struct zone_nwiftab nwif)
6243 6558 {
6244 6559 if (strlen(nwif.zone_nwif_address) > 0) {
6245 6560 zerr(gettext("A %s resource with the %s '%s', "
6246 6561 "and %s '%s' already exists."),
6247 6562 rt_to_str(RT_NET),
6248 6563 pt_to_str(PT_PHYSICAL),
6249 6564 nwif.zone_nwif_physical,
6250 6565 pt_to_str(PT_ADDRESS),
6251 6566 in_progress_nwiftab.zone_nwif_address);
6252 6567 } else {
6253 6568 zerr(gettext("A %s resource with the %s '%s', "
6254 6569 "and %s '%s' already exists."),
6255 6570 rt_to_str(RT_NET),
6256 6571 pt_to_str(PT_PHYSICAL),
6257 6572 nwif.zone_nwif_physical,
6258 6573 pt_to_str(PT_ALLOWED_ADDRESS),
6259 6574 nwif.zone_nwif_allowed_address);
6260 6575 }
6261 6576 }
6262 6577
6263 6578 void
6264 6579 end_func(cmd_t *cmd)
6265 6580 {
6266 6581 boolean_t validation_failed = B_FALSE;
6267 6582 boolean_t arg_err = B_FALSE;
6268 6583 struct zone_fstab tmp_fstab;
6269 6584 struct zone_nwiftab tmp_nwiftab;
6270 6585 struct zone_devtab tmp_devtab;
6271 6586 struct zone_rctltab tmp_rctltab;
6272 6587 struct zone_attrtab tmp_attrtab;
6273 6588 struct zone_dstab tmp_dstab;
6274 6589 struct zone_admintab tmp_admintab;
6275 6590 int err, arg, res1, res2, res3;
6276 6591 uint64_t swap_limit;
6277 6592 uint64_t locked_limit;
6278 6593 uint64_t proc_cap;
6279 6594
6280 6595 assert(cmd != NULL);
6281 6596
6282 6597 optind = 0;
6283 6598 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
6284 6599 switch (arg) {
6285 6600 case '?':
6286 6601 longer_usage(CMD_END);
6287 6602 arg_err = B_TRUE;
6288 6603 break;
6289 6604 default:
6290 6605 short_usage(CMD_END);
6291 6606 arg_err = B_TRUE;
6292 6607 break;
6293 6608 }
6294 6609 }
6295 6610 if (arg_err)
6296 6611 return;
6297 6612
6298 6613 if (optind != cmd->cmd_argc) {
6299 6614 short_usage(CMD_END);
6300 6615 return;
6301 6616 }
6302 6617
6303 6618 if (global_scope) {
6304 6619 scope_usage(CMD_END);
6305 6620 return;
6306 6621 }
6307 6622
6308 6623 assert(end_op == CMD_ADD || end_op == CMD_SELECT);
6309 6624
6310 6625 switch (resource_scope) {
6311 6626 case RT_FS:
6312 6627 /* First make sure everything was filled in. */
6313 6628 if (end_check_reqd(in_progress_fstab.zone_fs_dir,
6314 6629 PT_DIR, &validation_failed) == Z_OK) {
6315 6630 if (in_progress_fstab.zone_fs_dir[0] != '/') {
6316 6631 zerr(gettext("%s %s is not an absolute path."),
6317 6632 pt_to_str(PT_DIR),
6318 6633 in_progress_fstab.zone_fs_dir);
6319 6634 validation_failed = B_TRUE;
6320 6635 }
6321 6636 }
6322 6637
6323 6638 (void) end_check_reqd(in_progress_fstab.zone_fs_special,
6324 6639 PT_SPECIAL, &validation_failed);
6325 6640
6326 6641 if (in_progress_fstab.zone_fs_raw[0] != '\0' &&
6327 6642 in_progress_fstab.zone_fs_raw[0] != '/') {
6328 6643 zerr(gettext("%s %s is not an absolute path."),
6329 6644 pt_to_str(PT_RAW),
6330 6645 in_progress_fstab.zone_fs_raw);
6331 6646 validation_failed = B_TRUE;
6332 6647 }
6333 6648
6334 6649 (void) end_check_reqd(in_progress_fstab.zone_fs_type, PT_TYPE,
6335 6650 &validation_failed);
6336 6651
6337 6652 if (validation_failed) {
6338 6653 saw_error = B_TRUE;
6339 6654 return;
6340 6655 }
6341 6656
6342 6657 if (end_op == CMD_ADD) {
6343 6658 /* Make sure there isn't already one like this. */
6344 6659 bzero(&tmp_fstab, sizeof (tmp_fstab));
6345 6660 (void) strlcpy(tmp_fstab.zone_fs_dir,
6346 6661 in_progress_fstab.zone_fs_dir,
6347 6662 sizeof (tmp_fstab.zone_fs_dir));
6348 6663 err = zonecfg_lookup_filesystem(handle, &tmp_fstab);
6349 6664 zonecfg_free_fs_option_list(tmp_fstab.zone_fs_options);
6350 6665 if (err == Z_OK) {
6351 6666 zerr(gettext("A %s resource "
6352 6667 "with the %s '%s' already exists."),
6353 6668 rt_to_str(RT_FS), pt_to_str(PT_DIR),
6354 6669 in_progress_fstab.zone_fs_dir);
6355 6670 saw_error = B_TRUE;
6356 6671 return;
6357 6672 }
6358 6673 err = zonecfg_add_filesystem(handle,
6359 6674 &in_progress_fstab);
6360 6675 } else {
6361 6676 err = zonecfg_modify_filesystem(handle, &old_fstab,
6362 6677 &in_progress_fstab);
6363 6678 }
6364 6679 zonecfg_free_fs_option_list(in_progress_fstab.zone_fs_options);
6365 6680 in_progress_fstab.zone_fs_options = NULL;
6366 6681 break;
6367 6682
6368 6683 case RT_NET:
6369 6684 /*
6370 6685 * First make sure everything was filled in.
6371 6686 * Since we don't know whether IP will be shared
6372 6687 * or exclusive here, some checks are deferred until
6373 6688 * the verify command.
6374 6689 */
6375 6690 (void) end_check_reqd(in_progress_nwiftab.zone_nwif_physical,
6376 6691 PT_PHYSICAL, &validation_failed);
6377 6692
6378 6693 if (validation_failed) {
6379 6694 saw_error = B_TRUE;
6380 6695 return;
6381 6696 }
6382 6697 if (end_op == CMD_ADD) {
6383 6698 /* Make sure there isn't already one like this. */
6384 6699 bzero(&tmp_nwiftab, sizeof (tmp_nwiftab));
6385 6700 (void) strlcpy(tmp_nwiftab.zone_nwif_physical,
6386 6701 in_progress_nwiftab.zone_nwif_physical,
6387 6702 sizeof (tmp_nwiftab.zone_nwif_physical));
6388 6703 (void) strlcpy(tmp_nwiftab.zone_nwif_address,
6389 6704 in_progress_nwiftab.zone_nwif_address,
6390 6705 sizeof (tmp_nwiftab.zone_nwif_address));
6391 6706 (void) strlcpy(tmp_nwiftab.zone_nwif_allowed_address,
6392 6707 in_progress_nwiftab.zone_nwif_allowed_address,
6393 6708 sizeof (tmp_nwiftab.zone_nwif_allowed_address));
6394 6709 (void) strlcpy(tmp_nwiftab.zone_nwif_defrouter,
6395 6710 in_progress_nwiftab.zone_nwif_defrouter,
6396 6711 sizeof (tmp_nwiftab.zone_nwif_defrouter));
6397 6712 if (zonecfg_lookup_nwif(handle, &tmp_nwiftab) == Z_OK) {
6398 6713 net_exists_error(in_progress_nwiftab);
6399 6714 saw_error = B_TRUE;
6400 6715 return;
6401 6716 }
6402 6717 err = zonecfg_add_nwif(handle, &in_progress_nwiftab);
6403 6718 } else {
6404 6719 err = zonecfg_modify_nwif(handle, &old_nwiftab,
6405 6720 &in_progress_nwiftab);
6406 6721 }
6407 6722 break;
6408 6723
6409 6724 case RT_DEVICE:
6410 6725 /* First make sure everything was filled in. */
6411 6726 (void) end_check_reqd(in_progress_devtab.zone_dev_match,
6412 6727 PT_MATCH, &validation_failed);
6413 6728
6414 6729 if (validation_failed) {
6415 6730 saw_error = B_TRUE;
6416 6731 return;
6417 6732 }
6418 6733
6419 6734 if (end_op == CMD_ADD) {
6420 6735 /* Make sure there isn't already one like this. */
6421 6736 (void) strlcpy(tmp_devtab.zone_dev_match,
6422 6737 in_progress_devtab.zone_dev_match,
6423 6738 sizeof (tmp_devtab.zone_dev_match));
6424 6739 if (zonecfg_lookup_dev(handle, &tmp_devtab) == Z_OK) {
6425 6740 zerr(gettext("A %s resource with the %s '%s' "
6426 6741 "already exists."), rt_to_str(RT_DEVICE),
6427 6742 pt_to_str(PT_MATCH),
6428 6743 in_progress_devtab.zone_dev_match);
6429 6744 saw_error = B_TRUE;
6430 6745 return;
6431 6746 }
6432 6747 err = zonecfg_add_dev(handle, &in_progress_devtab);
6433 6748 } else {
6434 6749 err = zonecfg_modify_dev(handle, &old_devtab,
6435 6750 &in_progress_devtab);
6436 6751 }
6437 6752 break;
6438 6753
6439 6754 case RT_RCTL:
6440 6755 /* First make sure everything was filled in. */
6441 6756 (void) end_check_reqd(in_progress_rctltab.zone_rctl_name,
6442 6757 PT_NAME, &validation_failed);
6443 6758
6444 6759 if (in_progress_rctltab.zone_rctl_valptr == NULL) {
6445 6760 zerr(gettext("no %s specified"), pt_to_str(PT_VALUE));
6446 6761 validation_failed = B_TRUE;
6447 6762 }
6448 6763
6449 6764 if (validation_failed) {
6450 6765 saw_error = B_TRUE;
6451 6766 return;
6452 6767 }
6453 6768
6454 6769 if (end_op == CMD_ADD) {
6455 6770 /* Make sure there isn't already one like this. */
6456 6771 (void) strlcpy(tmp_rctltab.zone_rctl_name,
6457 6772 in_progress_rctltab.zone_rctl_name,
6458 6773 sizeof (tmp_rctltab.zone_rctl_name));
6459 6774 tmp_rctltab.zone_rctl_valptr = NULL;
6460 6775 err = zonecfg_lookup_rctl(handle, &tmp_rctltab);
6461 6776 zonecfg_free_rctl_value_list(
6462 6777 tmp_rctltab.zone_rctl_valptr);
6463 6778 if (err == Z_OK) {
6464 6779 zerr(gettext("A %s resource "
6465 6780 "with the %s '%s' already exists."),
6466 6781 rt_to_str(RT_RCTL), pt_to_str(PT_NAME),
6467 6782 in_progress_rctltab.zone_rctl_name);
6468 6783 saw_error = B_TRUE;
6469 6784 return;
6470 6785 }
6471 6786 err = zonecfg_add_rctl(handle, &in_progress_rctltab);
6472 6787 } else {
6473 6788 err = zonecfg_modify_rctl(handle, &old_rctltab,
6474 6789 &in_progress_rctltab);
6475 6790 }
6476 6791 if (err == Z_OK) {
6477 6792 zonecfg_free_rctl_value_list(
6478 6793 in_progress_rctltab.zone_rctl_valptr);
6479 6794 in_progress_rctltab.zone_rctl_valptr = NULL;
6480 6795 }
6481 6796 break;
6482 6797
6483 6798 case RT_ATTR:
6484 6799 /* First make sure everything was filled in. */
6485 6800 (void) end_check_reqd(in_progress_attrtab.zone_attr_name,
6486 6801 PT_NAME, &validation_failed);
6487 6802 (void) end_check_reqd(in_progress_attrtab.zone_attr_type,
6488 6803 PT_TYPE, &validation_failed);
6489 6804 (void) end_check_reqd(in_progress_attrtab.zone_attr_value,
6490 6805 PT_VALUE, &validation_failed);
6491 6806
6492 6807 if (validate_attr_name(in_progress_attrtab.zone_attr_name) !=
6493 6808 Z_OK)
6494 6809 validation_failed = B_TRUE;
6495 6810
6496 6811 if (validate_attr_type_val(&in_progress_attrtab) != Z_OK)
6497 6812 validation_failed = B_TRUE;
6498 6813
6499 6814 if (validation_failed) {
6500 6815 saw_error = B_TRUE;
6501 6816 return;
6502 6817 }
6503 6818 if (end_op == CMD_ADD) {
6504 6819 /* Make sure there isn't already one like this. */
6505 6820 bzero(&tmp_attrtab, sizeof (tmp_attrtab));
6506 6821 (void) strlcpy(tmp_attrtab.zone_attr_name,
6507 6822 in_progress_attrtab.zone_attr_name,
6508 6823 sizeof (tmp_attrtab.zone_attr_name));
6509 6824 if (zonecfg_lookup_attr(handle, &tmp_attrtab) == Z_OK) {
6510 6825 zerr(gettext("An %s resource "
6511 6826 "with the %s '%s' already exists."),
6512 6827 rt_to_str(RT_ATTR), pt_to_str(PT_NAME),
6513 6828 in_progress_attrtab.zone_attr_name);
6514 6829 saw_error = B_TRUE;
6515 6830 return;
6516 6831 }
6517 6832 err = zonecfg_add_attr(handle, &in_progress_attrtab);
6518 6833 } else {
6519 6834 err = zonecfg_modify_attr(handle, &old_attrtab,
6520 6835 &in_progress_attrtab);
6521 6836 }
6522 6837 break;
6523 6838 case RT_DATASET:
6524 6839 /* First make sure everything was filled in. */
6525 6840 if (strlen(in_progress_dstab.zone_dataset_name) == 0) {
6526 6841 zerr("%s %s", pt_to_str(PT_NAME),
6527 6842 gettext("not specified"));
6528 6843 saw_error = B_TRUE;
6529 6844 validation_failed = B_TRUE;
6530 6845 }
6531 6846 if (validation_failed)
6532 6847 return;
6533 6848 if (end_op == CMD_ADD) {
6534 6849 /* Make sure there isn't already one like this. */
6535 6850 bzero(&tmp_dstab, sizeof (tmp_dstab));
6536 6851 (void) strlcpy(tmp_dstab.zone_dataset_name,
6537 6852 in_progress_dstab.zone_dataset_name,
6538 6853 sizeof (tmp_dstab.zone_dataset_name));
6539 6854 err = zonecfg_lookup_ds(handle, &tmp_dstab);
6540 6855 if (err == Z_OK) {
6541 6856 zerr(gettext("A %s resource "
6542 6857 "with the %s '%s' already exists."),
6543 6858 rt_to_str(RT_DATASET), pt_to_str(PT_NAME),
6544 6859 in_progress_dstab.zone_dataset_name);
6545 6860 saw_error = B_TRUE;
6546 6861 return;
6547 6862 }
6548 6863 err = zonecfg_add_ds(handle, &in_progress_dstab);
6549 6864 } else {
6550 6865 err = zonecfg_modify_ds(handle, &old_dstab,
6551 6866 &in_progress_dstab);
6552 6867 }
6553 6868 break;
6554 6869 case RT_DCPU:
6555 6870 /* Make sure everything was filled in. */
6556 6871 if (end_check_reqd(in_progress_psettab.zone_ncpu_min,
6557 6872 PT_NCPUS, &validation_failed) != Z_OK) {
6558 6873 saw_error = B_TRUE;
6559 6874 return;
6560 6875 }
6561 6876
6562 6877 if (end_op == CMD_ADD) {
6563 6878 err = zonecfg_add_pset(handle, &in_progress_psettab);
6564 6879 } else {
6565 6880 err = zonecfg_modify_pset(handle, &in_progress_psettab);
6566 6881 }
6567 6882 break;
6568 6883 case RT_PCAP:
6569 6884 /* Make sure everything was filled in. */
6570 6885 if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &proc_cap)
6571 6886 != Z_OK) {
6572 6887 zerr(gettext("%s not specified"), pt_to_str(PT_NCPUS));
6573 6888 saw_error = B_TRUE;
6574 6889 validation_failed = B_TRUE;
6575 6890 return;
6576 6891 }
6577 6892 err = Z_OK;
6578 6893 break;
6579 6894 case RT_MCAP:
6580 6895 /* Make sure everything was filled in. */
6581 6896 res1 = strlen(in_progress_mcaptab.zone_physmem_cap) == 0 ?
6582 6897 Z_ERR : Z_OK;
6583 6898 res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP,
6584 6899 &swap_limit);
6585 6900 res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM,
6586 6901 &locked_limit);
6587 6902
6588 6903 if (res1 != Z_OK && res2 != Z_OK && res3 != Z_OK) {
6589 6904 zerr(gettext("No property was specified. One of %s, "
6590 6905 "%s or %s is required."), pt_to_str(PT_PHYSICAL),
6591 6906 pt_to_str(PT_SWAP), pt_to_str(PT_LOCKED));
6592 6907 saw_error = B_TRUE;
6593 6908 return;
6594 6909 }
6595 6910
6596 6911 /* if phys & locked are both set, verify locked <= phys */
6597 6912 if (res1 == Z_OK && res3 == Z_OK) {
6598 6913 uint64_t phys_limit;
6599 6914 char *endp;
6600 6915
6601 6916 phys_limit = strtoull(
6602 6917 in_progress_mcaptab.zone_physmem_cap, &endp, 10);
6603 6918 if (phys_limit < locked_limit) {
6604 6919 zerr(gettext("The %s cap must be less than or "
6605 6920 "equal to the %s cap."),
6606 6921 pt_to_str(PT_LOCKED),
6607 6922 pt_to_str(PT_PHYSICAL));
6608 6923 saw_error = B_TRUE;
6609 6924 return;
6610 6925 }
6611 6926 }
6612 6927
6613 6928 err = Z_OK;
6614 6929 if (res1 == Z_OK) {
6615 6930 /*
6616 6931 * We could be ending from either an add operation
6617 6932 * or a select operation. Since all of the properties
6618 6933 * within this resource are optional, we always use
6619 6934 * modify on the mcap entry. zonecfg_modify_mcap()
6620 6935 * will handle both adding and modifying a memory cap.
6621 6936 */
6622 6937 err = zonecfg_modify_mcap(handle, &in_progress_mcaptab);
6623 6938 } else if (end_op == CMD_SELECT) {
6624 6939 /*
6625 6940 * If we're ending from a select and the physical
6626 6941 * memory cap is empty then the user could have cleared
6627 6942 * the physical cap value, so try to delete the entry.
6628 6943 */
6629 6944 (void) zonecfg_delete_mcap(handle);
6630 6945 }
6631 6946 break;
6632 6947 case RT_ADMIN:
6633 6948 /* First make sure everything was filled in. */
6634 6949 if (end_check_reqd(in_progress_admintab.zone_admin_user,
6635 6950 PT_USER, &validation_failed) == Z_OK) {
6636 6951 if (getpwnam(in_progress_admintab.zone_admin_user)
6637 6952 == NULL) {
6638 6953 zerr(gettext("%s %s is not a valid username"),
6639 6954 pt_to_str(PT_USER),
6640 6955 in_progress_admintab.zone_admin_user);
6641 6956 validation_failed = B_TRUE;
6642 6957 }
6643 6958 }
6644 6959
6645 6960 if (end_check_reqd(in_progress_admintab.zone_admin_auths,
6646 6961 PT_AUTHS, &validation_failed) == Z_OK) {
6647 6962 if (!zonecfg_valid_auths(
6648 6963 in_progress_admintab.zone_admin_auths,
6649 6964 zone)) {
6650 6965 validation_failed = B_TRUE;
6651 6966 }
6652 6967 }
6653 6968
6654 6969 if (validation_failed) {
6655 6970 saw_error = B_TRUE;
6656 6971 return;
6657 6972 }
6658 6973
6659 6974 if (end_op == CMD_ADD) {
6660 6975 /* Make sure there isn't already one like this. */
6661 6976 bzero(&tmp_admintab, sizeof (tmp_admintab));
6662 6977 (void) strlcpy(tmp_admintab.zone_admin_user,
6663 6978 in_progress_admintab.zone_admin_user,
6664 6979 sizeof (tmp_admintab.zone_admin_user));
6665 6980 err = zonecfg_lookup_admin(
6666 6981 handle, &tmp_admintab);
6667 6982 if (err == Z_OK) {
6668 6983 zerr(gettext("A %s resource "
6669 6984 "with the %s '%s' already exists."),
6670 6985 rt_to_str(RT_ADMIN),
6671 6986 pt_to_str(PT_USER),
6672 6987 in_progress_admintab.zone_admin_user);
6673 6988 saw_error = B_TRUE;
↓ open down ↓ |
569 lines elided |
↑ open up ↑ |
6674 6989 return;
6675 6990 }
6676 6991 err = zonecfg_add_admin(handle,
6677 6992 &in_progress_admintab, zone);
6678 6993 } else {
6679 6994 err = zonecfg_modify_admin(handle,
6680 6995 &old_admintab, &in_progress_admintab,
6681 6996 zone);
6682 6997 }
6683 6998 break;
6999 + case RT_SECFLAGS:
7000 + if (verify_secflags(&in_progress_secflagstab) != B_TRUE) {
7001 + saw_error = B_TRUE;
7002 + return;
7003 + }
7004 +
7005 + if (end_op == CMD_ADD) {
7006 + err = zonecfg_add_secflags(handle,
7007 + &in_progress_secflagstab);
7008 + } else {
7009 + err = zonecfg_modify_secflags(handle,
7010 + &old_secflagstab, &in_progress_secflagstab);
7011 + }
7012 + break;
6684 7013 default:
6685 7014 zone_perror(rt_to_str(resource_scope), Z_NO_RESOURCE_TYPE,
6686 7015 B_TRUE);
6687 7016 saw_error = B_TRUE;
6688 7017 return;
6689 7018 }
6690 7019
6691 7020 if (err != Z_OK) {
6692 7021 zone_perror(zone, err, B_TRUE);
6693 7022 } else {
6694 7023 need_to_commit = B_TRUE;
6695 7024 global_scope = B_TRUE;
6696 7025 end_op = -1;
6697 7026 }
6698 7027 }
6699 7028
6700 7029 void
6701 7030 commit_func(cmd_t *cmd)
6702 7031 {
6703 7032 int arg;
6704 7033 boolean_t arg_err = B_FALSE;
6705 7034
6706 7035 optind = 0;
6707 7036 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) {
6708 7037 switch (arg) {
6709 7038 case '?':
6710 7039 longer_usage(CMD_COMMIT);
6711 7040 arg_err = B_TRUE;
6712 7041 break;
6713 7042 default:
6714 7043 short_usage(CMD_COMMIT);
6715 7044 arg_err = B_TRUE;
6716 7045 break;
6717 7046 }
6718 7047 }
6719 7048 if (arg_err)
6720 7049 return;
6721 7050
6722 7051 if (optind != cmd->cmd_argc) {
6723 7052 short_usage(CMD_COMMIT);
6724 7053 return;
6725 7054 }
6726 7055
6727 7056 if (zone_is_read_only(CMD_COMMIT))
6728 7057 return;
6729 7058
6730 7059 assert(cmd != NULL);
6731 7060
6732 7061 cmd->cmd_argc = 1;
6733 7062 /*
6734 7063 * cmd_arg normally comes from a strdup() in the lexer, and the
6735 7064 * whole cmd structure and its (char *) attributes are freed at
6736 7065 * the completion of each command, so the strdup() below is needed
6737 7066 * to match this and prevent a core dump from trying to free()
6738 7067 * something that can't be.
6739 7068 */
6740 7069 if ((cmd->cmd_argv[0] = strdup("save")) == NULL) {
6741 7070 zone_perror(zone, Z_NOMEM, B_TRUE);
6742 7071 exit(Z_ERR);
6743 7072 }
6744 7073 cmd->cmd_argv[1] = NULL;
6745 7074 verify_func(cmd);
6746 7075 }
6747 7076
6748 7077 void
6749 7078 revert_func(cmd_t *cmd)
6750 7079 {
6751 7080 char line[128]; /* enough to ask a question */
6752 7081 boolean_t force = B_FALSE;
6753 7082 boolean_t arg_err = B_FALSE;
6754 7083 int err, arg, answer;
6755 7084
6756 7085 optind = 0;
6757 7086 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
6758 7087 switch (arg) {
6759 7088 case '?':
6760 7089 longer_usage(CMD_REVERT);
6761 7090 arg_err = B_TRUE;
6762 7091 break;
6763 7092 case 'F':
6764 7093 force = B_TRUE;
6765 7094 break;
6766 7095 default:
6767 7096 short_usage(CMD_REVERT);
6768 7097 arg_err = B_TRUE;
6769 7098 break;
6770 7099 }
6771 7100 }
6772 7101 if (arg_err)
6773 7102 return;
6774 7103
6775 7104 if (optind != cmd->cmd_argc) {
6776 7105 short_usage(CMD_REVERT);
6777 7106 return;
6778 7107 }
6779 7108
6780 7109 if (zone_is_read_only(CMD_REVERT))
6781 7110 return;
6782 7111
6783 7112 if (!global_scope) {
6784 7113 zerr(gettext("You can only use %s in the global scope.\nUse"
6785 7114 " '%s' to cancel changes to a resource specification."),
6786 7115 cmd_to_str(CMD_REVERT), cmd_to_str(CMD_CANCEL));
6787 7116 saw_error = B_TRUE;
6788 7117 return;
6789 7118 }
6790 7119
6791 7120 if (zonecfg_check_handle(handle) != Z_OK) {
6792 7121 zerr(gettext("No changes to revert."));
6793 7122 saw_error = B_TRUE;
6794 7123 return;
6795 7124 }
6796 7125
6797 7126 if (!force) {
6798 7127 (void) snprintf(line, sizeof (line),
6799 7128 gettext("Are you sure you want to revert"));
6800 7129 if ((answer = ask_yesno(B_FALSE, line)) == -1) {
6801 7130 zerr(gettext("Input not from terminal and -F not "
6802 7131 "specified:\n%s command ignored, exiting."),
6803 7132 cmd_to_str(CMD_REVERT));
6804 7133 exit(Z_ERR);
6805 7134 }
6806 7135 if (answer != 1)
6807 7136 return;
6808 7137 }
6809 7138
6810 7139 /*
6811 7140 * Reset any pending admins that were
6812 7141 * removed from the previous zone
6813 7142 */
6814 7143 zonecfg_remove_userauths(handle, "", zone, B_FALSE);
6815 7144
6816 7145 /*
6817 7146 * Time for a new handle: finish the old one off first
6818 7147 * then get a new one properly to avoid leaks.
6819 7148 */
6820 7149 zonecfg_fini_handle(handle);
6821 7150 if ((handle = zonecfg_init_handle()) == NULL) {
6822 7151 zone_perror(execname, Z_NOMEM, B_TRUE);
6823 7152 exit(Z_ERR);
6824 7153 }
6825 7154
6826 7155 if ((err = zonecfg_get_handle(revert_zone, handle)) != Z_OK) {
6827 7156 saw_error = B_TRUE;
6828 7157 got_handle = B_FALSE;
6829 7158 if (err == Z_NO_ZONE)
6830 7159 zerr(gettext("%s: no such saved zone to revert to."),
6831 7160 revert_zone);
6832 7161 else
6833 7162 zone_perror(zone, err, B_TRUE);
6834 7163 }
6835 7164 (void) strlcpy(zone, revert_zone, sizeof (zone));
6836 7165 }
6837 7166
6838 7167 void
6839 7168 help_func(cmd_t *cmd)
6840 7169 {
6841 7170 int i;
6842 7171
6843 7172 assert(cmd != NULL);
6844 7173
6845 7174 if (cmd->cmd_argc == 0) {
6846 7175 usage(B_TRUE, global_scope ? HELP_SUBCMDS : HELP_RES_SCOPE);
6847 7176 return;
6848 7177 }
6849 7178 if (strcmp(cmd->cmd_argv[0], "usage") == 0) {
6850 7179 usage(B_TRUE, HELP_USAGE);
6851 7180 return;
6852 7181 }
6853 7182 if (strcmp(cmd->cmd_argv[0], "commands") == 0) {
6854 7183 usage(B_TRUE, HELP_SUBCMDS);
6855 7184 return;
6856 7185 }
6857 7186 if (strcmp(cmd->cmd_argv[0], "syntax") == 0) {
6858 7187 usage(B_TRUE, HELP_SYNTAX | HELP_RES_PROPS);
6859 7188 return;
6860 7189 }
6861 7190 if (strcmp(cmd->cmd_argv[0], "-?") == 0) {
6862 7191 longer_usage(CMD_HELP);
6863 7192 return;
6864 7193 }
6865 7194
6866 7195 for (i = 0; i <= CMD_MAX; i++) {
6867 7196 if (strcmp(cmd->cmd_argv[0], cmd_to_str(i)) == 0) {
6868 7197 longer_usage(i);
6869 7198 return;
6870 7199 }
6871 7200 }
6872 7201 /* We do not use zerr() here because we do not want its extra \n. */
6873 7202 (void) fprintf(stderr, gettext("Unknown help subject %s. "),
6874 7203 cmd->cmd_argv[0]);
6875 7204 usage(B_FALSE, HELP_META);
6876 7205 }
6877 7206
6878 7207 static int
6879 7208 string_to_yyin(char *string)
6880 7209 {
6881 7210 if ((yyin = tmpfile()) == NULL) {
6882 7211 zone_perror(execname, Z_TEMP_FILE, B_TRUE);
6883 7212 return (Z_ERR);
6884 7213 }
6885 7214 if (fwrite(string, strlen(string), 1, yyin) != 1) {
6886 7215 zone_perror(execname, Z_TEMP_FILE, B_TRUE);
6887 7216 return (Z_ERR);
6888 7217 }
6889 7218 if (fseek(yyin, 0, SEEK_SET) != 0) {
6890 7219 zone_perror(execname, Z_TEMP_FILE, B_TRUE);
6891 7220 return (Z_ERR);
6892 7221 }
6893 7222 return (Z_OK);
6894 7223 }
6895 7224
6896 7225 /* This is the back-end helper function for read_input() below. */
6897 7226
6898 7227 static int
6899 7228 cleanup()
6900 7229 {
6901 7230 int answer;
6902 7231 cmd_t *cmd;
6903 7232
6904 7233 if (!interactive_mode && !cmd_file_mode) {
6905 7234 /*
6906 7235 * If we're not in interactive mode, and we're not in command
6907 7236 * file mode, then we must be in commands-from-the-command-line
6908 7237 * mode. As such, we can't loop back and ask for more input.
6909 7238 * It was OK to prompt for such things as whether or not to
6910 7239 * really delete a zone in the command handler called from
6911 7240 * yyparse() above, but "really quit?" makes no sense in this
6912 7241 * context. So disable prompting.
6913 7242 */
6914 7243 ok_to_prompt = B_FALSE;
6915 7244 }
6916 7245 if (!global_scope) {
6917 7246 if (!time_to_exit) {
6918 7247 /*
6919 7248 * Just print a simple error message in the -1 case,
6920 7249 * since exit_func() already handles that case, and
6921 7250 * EOF means we are finished anyway.
6922 7251 */
6923 7252 answer = ask_yesno(B_FALSE,
6924 7253 gettext("Resource incomplete; really quit"));
6925 7254 if (answer == -1) {
6926 7255 zerr(gettext("Resource incomplete."));
6927 7256 return (Z_ERR);
6928 7257 }
6929 7258 if (answer != 1) {
6930 7259 yyin = stdin;
6931 7260 return (Z_REPEAT);
6932 7261 }
6933 7262 } else {
6934 7263 saw_error = B_TRUE;
6935 7264 }
6936 7265 }
6937 7266 /*
6938 7267 * Make sure we tried something and that the handle checks
6939 7268 * out, or we would get a false error trying to commit.
6940 7269 */
6941 7270 if (need_to_commit && zonecfg_check_handle(handle) == Z_OK) {
6942 7271 if ((cmd = alloc_cmd()) == NULL) {
6943 7272 zone_perror(zone, Z_NOMEM, B_TRUE);
6944 7273 return (Z_ERR);
6945 7274 }
6946 7275 cmd->cmd_argc = 0;
6947 7276 cmd->cmd_argv[0] = NULL;
6948 7277 commit_func(cmd);
6949 7278 free_cmd(cmd);
6950 7279 /*
6951 7280 * need_to_commit will get set back to FALSE if the
6952 7281 * configuration is saved successfully.
6953 7282 */
6954 7283 if (need_to_commit) {
6955 7284 if (force_exit) {
6956 7285 zerr(gettext("Configuration not saved."));
6957 7286 return (Z_ERR);
6958 7287 }
6959 7288 answer = ask_yesno(B_FALSE,
6960 7289 gettext("Configuration not saved; really quit"));
6961 7290 if (answer == -1) {
6962 7291 zerr(gettext("Configuration not saved."));
6963 7292 return (Z_ERR);
6964 7293 }
6965 7294 if (answer != 1) {
6966 7295 time_to_exit = B_FALSE;
6967 7296 yyin = stdin;
6968 7297 return (Z_REPEAT);
6969 7298 }
6970 7299 }
6971 7300 }
6972 7301 return ((need_to_commit || saw_error) ? Z_ERR : Z_OK);
6973 7302 }
6974 7303
6975 7304 /*
6976 7305 * read_input() is the driver of this program. It is a wrapper around
6977 7306 * yyparse(), printing appropriate prompts when needed, checking for
6978 7307 * exit conditions and reacting appropriately [the latter in its cleanup()
6979 7308 * helper function].
6980 7309 *
6981 7310 * Like most zonecfg functions, it returns Z_OK or Z_ERR, *or* Z_REPEAT
6982 7311 * so do_interactive() knows that we are not really done (i.e, we asked
6983 7312 * the user if we should really quit and the user said no).
6984 7313 */
6985 7314 static int
6986 7315 read_input()
6987 7316 {
6988 7317 boolean_t yyin_is_a_tty = isatty(fileno(yyin));
6989 7318 /*
6990 7319 * The prompt is "e:z> " or "e:z:r> " where e is execname, z is zone
6991 7320 * and r is resource_scope: 5 is for the two ":"s + "> " + terminator.
6992 7321 */
6993 7322 char prompt[MAXPATHLEN + ZONENAME_MAX + MAX_RT_STRLEN + 5], *line;
6994 7323
6995 7324 /* yyin should have been set to the appropriate (FILE *) if not stdin */
6996 7325 newline_terminated = B_TRUE;
6997 7326 for (;;) {
6998 7327 if (yyin_is_a_tty) {
6999 7328 if (newline_terminated) {
7000 7329 if (global_scope)
7001 7330 (void) snprintf(prompt, sizeof (prompt),
7002 7331 "%s:%s> ", execname, zone);
7003 7332 else
7004 7333 (void) snprintf(prompt, sizeof (prompt),
7005 7334 "%s:%s:%s> ", execname, zone,
7006 7335 rt_to_str(resource_scope));
7007 7336 }
7008 7337 /*
7009 7338 * If the user hits ^C then we want to catch it and
7010 7339 * start over. If the user hits EOF then we want to
7011 7340 * bail out.
7012 7341 */
7013 7342 line = gl_get_line(gl, prompt, NULL, -1);
7014 7343 if (gl_return_status(gl) == GLR_SIGNAL) {
7015 7344 gl_abandon_line(gl);
7016 7345 continue;
7017 7346 }
7018 7347 if (line == NULL)
7019 7348 break;
7020 7349 (void) string_to_yyin(line);
7021 7350 while (!feof(yyin))
7022 7351 yyparse();
7023 7352 } else {
7024 7353 yyparse();
7025 7354 }
7026 7355 /* Bail out on an error in command file mode. */
7027 7356 if (saw_error && cmd_file_mode && !interactive_mode)
7028 7357 time_to_exit = B_TRUE;
7029 7358 if (time_to_exit || (!yyin_is_a_tty && feof(yyin)))
7030 7359 break;
7031 7360 }
7032 7361 return (cleanup());
7033 7362 }
7034 7363
7035 7364 /*
7036 7365 * This function is used in the zonecfg-interactive-mode scenario: it just
7037 7366 * calls read_input() until we are done.
7038 7367 */
7039 7368
7040 7369 static int
7041 7370 do_interactive(void)
7042 7371 {
7043 7372 int err;
7044 7373
7045 7374 interactive_mode = B_TRUE;
7046 7375 if (!read_only_mode) {
7047 7376 /*
7048 7377 * Try to set things up proactively in interactive mode, so
7049 7378 * that if the zone in question does not exist yet, we can
7050 7379 * provide the user with a clue.
7051 7380 */
7052 7381 (void) initialize(B_FALSE);
7053 7382 }
7054 7383 do {
7055 7384 err = read_input();
7056 7385 } while (err == Z_REPEAT);
7057 7386 return (err);
7058 7387 }
7059 7388
7060 7389 /*
7061 7390 * cmd_file is slightly more complicated, as it has to open the command file
7062 7391 * and set yyin appropriately. Once that is done, though, it just calls
7063 7392 * read_input(), and only once, since prompting is not possible.
7064 7393 */
7065 7394
7066 7395 static int
7067 7396 cmd_file(char *file)
7068 7397 {
7069 7398 FILE *infile;
7070 7399 int err;
7071 7400 struct stat statbuf;
7072 7401 boolean_t using_real_file = (strcmp(file, "-") != 0);
7073 7402
7074 7403 if (using_real_file) {
7075 7404 /*
7076 7405 * zerr() prints a line number in cmd_file_mode, which we do
7077 7406 * not want here, so temporarily unset it.
7078 7407 */
7079 7408 cmd_file_mode = B_FALSE;
7080 7409 if ((infile = fopen(file, "r")) == NULL) {
7081 7410 zerr(gettext("could not open file %s: %s"),
7082 7411 file, strerror(errno));
7083 7412 return (Z_ERR);
7084 7413 }
7085 7414 if ((err = fstat(fileno(infile), &statbuf)) != 0) {
7086 7415 zerr(gettext("could not stat file %s: %s"),
7087 7416 file, strerror(errno));
7088 7417 err = Z_ERR;
7089 7418 goto done;
7090 7419 }
7091 7420 if (!S_ISREG(statbuf.st_mode)) {
7092 7421 zerr(gettext("%s is not a regular file."), file);
7093 7422 err = Z_ERR;
7094 7423 goto done;
7095 7424 }
7096 7425 yyin = infile;
7097 7426 cmd_file_mode = B_TRUE;
7098 7427 ok_to_prompt = B_FALSE;
7099 7428 } else {
7100 7429 /*
7101 7430 * "-f -" is essentially the same as interactive mode,
7102 7431 * so treat it that way.
7103 7432 */
7104 7433 interactive_mode = B_TRUE;
7105 7434 }
7106 7435 /* Z_REPEAT is for interactive mode; treat it like Z_ERR here. */
7107 7436 if ((err = read_input()) == Z_REPEAT)
7108 7437 err = Z_ERR;
7109 7438 done:
7110 7439 if (using_real_file)
7111 7440 (void) fclose(infile);
7112 7441 return (err);
7113 7442 }
7114 7443
7115 7444 /*
7116 7445 * Since yacc is based on reading from a (FILE *) whereas what we get from
7117 7446 * the command line is in argv format, we need to convert when the user
7118 7447 * gives us commands directly from the command line. That is done here by
7119 7448 * concatenating the argv list into a space-separated string, writing it
7120 7449 * to a temp file, and rewinding the file so yyin can be set to it. Then
7121 7450 * we call read_input(), and only once, since prompting about whether to
7122 7451 * continue or quit would make no sense in this context.
7123 7452 */
7124 7453
7125 7454 static int
7126 7455 one_command_at_a_time(int argc, char *argv[])
7127 7456 {
7128 7457 char *command;
7129 7458 size_t len = 2; /* terminal \n\0 */
7130 7459 int i, err;
7131 7460
7132 7461 for (i = 0; i < argc; i++)
7133 7462 len += strlen(argv[i]) + 1;
7134 7463 if ((command = malloc(len)) == NULL) {
7135 7464 zone_perror(execname, Z_NOMEM, B_TRUE);
7136 7465 return (Z_ERR);
7137 7466 }
7138 7467 (void) strlcpy(command, argv[0], len);
7139 7468 for (i = 1; i < argc; i++) {
7140 7469 (void) strlcat(command, " ", len);
7141 7470 (void) strlcat(command, argv[i], len);
7142 7471 }
7143 7472 (void) strlcat(command, "\n", len);
7144 7473 err = string_to_yyin(command);
7145 7474 free(command);
7146 7475 if (err != Z_OK)
7147 7476 return (err);
7148 7477 while (!feof(yyin))
7149 7478 yyparse();
7150 7479 return (cleanup());
7151 7480 }
7152 7481
7153 7482 static char *
7154 7483 get_execbasename(char *execfullname)
7155 7484 {
7156 7485 char *last_slash, *execbasename;
7157 7486
7158 7487 /* guard against '/' at end of command invocation */
7159 7488 for (;;) {
7160 7489 last_slash = strrchr(execfullname, '/');
7161 7490 if (last_slash == NULL) {
7162 7491 execbasename = execfullname;
7163 7492 break;
7164 7493 } else {
7165 7494 execbasename = last_slash + 1;
7166 7495 if (*execbasename == '\0') {
7167 7496 *last_slash = '\0';
7168 7497 continue;
7169 7498 }
7170 7499 break;
7171 7500 }
7172 7501 }
7173 7502 return (execbasename);
7174 7503 }
7175 7504
7176 7505 int
7177 7506 main(int argc, char *argv[])
7178 7507 {
7179 7508 int err, arg;
7180 7509 struct stat st;
7181 7510
7182 7511 /* This must be before anything goes to stdout. */
7183 7512 setbuf(stdout, NULL);
7184 7513
7185 7514 saw_error = B_FALSE;
7186 7515 cmd_file_mode = B_FALSE;
7187 7516 execname = get_execbasename(argv[0]);
7188 7517
7189 7518 (void) setlocale(LC_ALL, "");
7190 7519 (void) textdomain(TEXT_DOMAIN);
7191 7520
7192 7521 if (getzoneid() != GLOBAL_ZONEID) {
7193 7522 zerr(gettext("%s can only be run from the global zone."),
7194 7523 execname);
7195 7524 exit(Z_ERR);
7196 7525 }
7197 7526
7198 7527 if (argc < 2) {
7199 7528 usage(B_FALSE, HELP_USAGE | HELP_SUBCMDS);
7200 7529 exit(Z_USAGE);
7201 7530 }
7202 7531 if (strcmp(argv[1], cmd_to_str(CMD_HELP)) == 0) {
7203 7532 (void) one_command_at_a_time(argc - 1, &(argv[1]));
7204 7533 exit(Z_OK);
7205 7534 }
7206 7535
7207 7536 while ((arg = getopt(argc, argv, "?f:R:z:")) != EOF) {
7208 7537 switch (arg) {
7209 7538 case '?':
7210 7539 if (optopt == '?')
7211 7540 usage(B_TRUE, HELP_USAGE | HELP_SUBCMDS);
7212 7541 else
7213 7542 usage(B_FALSE, HELP_USAGE);
7214 7543 exit(Z_USAGE);
7215 7544 /* NOTREACHED */
7216 7545 case 'f':
7217 7546 cmd_file_name = optarg;
7218 7547 cmd_file_mode = B_TRUE;
7219 7548 break;
7220 7549 case 'R':
7221 7550 if (*optarg != '/') {
7222 7551 zerr(gettext("root path must be absolute: %s"),
7223 7552 optarg);
7224 7553 exit(Z_USAGE);
7225 7554 }
7226 7555 if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) {
7227 7556 zerr(gettext(
7228 7557 "root path must be a directory: %s"),
7229 7558 optarg);
7230 7559 exit(Z_USAGE);
7231 7560 }
7232 7561 zonecfg_set_root(optarg);
7233 7562 break;
7234 7563 case 'z':
7235 7564 if (strcmp(optarg, GLOBAL_ZONENAME) == 0) {
7236 7565 global_zone = B_TRUE;
7237 7566 } else if (zonecfg_validate_zonename(optarg) != Z_OK) {
7238 7567 zone_perror(optarg, Z_BOGUS_ZONE_NAME, B_TRUE);
7239 7568 usage(B_FALSE, HELP_SYNTAX);
7240 7569 exit(Z_USAGE);
7241 7570 }
7242 7571 (void) strlcpy(zone, optarg, sizeof (zone));
7243 7572 (void) strlcpy(revert_zone, optarg, sizeof (zone));
7244 7573 break;
7245 7574 default:
7246 7575 usage(B_FALSE, HELP_USAGE);
7247 7576 exit(Z_USAGE);
7248 7577 }
7249 7578 }
7250 7579
7251 7580 if (optind > argc || strcmp(zone, "") == 0) {
7252 7581 usage(B_FALSE, HELP_USAGE);
7253 7582 exit(Z_USAGE);
7254 7583 }
7255 7584
7256 7585 if ((err = zonecfg_access(zone, W_OK)) == Z_OK) {
7257 7586 read_only_mode = B_FALSE;
7258 7587 } else if (err == Z_ACCES) {
7259 7588 read_only_mode = B_TRUE;
7260 7589 /* skip this message in one-off from command line mode */
7261 7590 if (optind == argc)
7262 7591 (void) fprintf(stderr, gettext("WARNING: you do not "
7263 7592 "have write access to this zone's configuration "
7264 7593 "file;\ngoing into read-only mode.\n"));
7265 7594 } else {
7266 7595 fprintf(stderr, "%s: Could not access zone configuration "
7267 7596 "store: %s\n", execname, zonecfg_strerror(err));
7268 7597 exit(Z_ERR);
7269 7598 }
7270 7599
7271 7600 if ((handle = zonecfg_init_handle()) == NULL) {
7272 7601 zone_perror(execname, Z_NOMEM, B_TRUE);
7273 7602 exit(Z_ERR);
7274 7603 }
7275 7604
7276 7605 /*
7277 7606 * This may get set back to FALSE again in cmd_file() if cmd_file_name
7278 7607 * is a "real" file as opposed to "-" (i.e. meaning use stdin).
7279 7608 */
7280 7609 if (isatty(STDIN_FILENO))
7281 7610 ok_to_prompt = B_TRUE;
7282 7611 if ((gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL)
7283 7612 exit(Z_ERR);
7284 7613 if (gl_customize_completion(gl, NULL, cmd_cpl_fn) != 0)
7285 7614 exit(Z_ERR);
7286 7615 (void) sigset(SIGINT, SIG_IGN);
7287 7616 if (optind == argc) {
7288 7617 if (!cmd_file_mode)
7289 7618 err = do_interactive();
7290 7619 else
7291 7620 err = cmd_file(cmd_file_name);
7292 7621 } else {
7293 7622 err = one_command_at_a_time(argc - optind, &(argv[optind]));
7294 7623 }
7295 7624 zonecfg_fini_handle(handle);
7296 7625 if (brand != NULL)
7297 7626 brand_close(brand);
7298 7627 (void) del_GetLine(gl);
7299 7628 return (err);
7300 7629 }
↓ open down ↓ |
607 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX