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