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