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