218 "importance",
219 "swap",
220 "locked",
221 ALIAS_SHARES,
222 ALIAS_MAXLWPS,
223 ALIAS_MAXSHMMEM,
224 ALIAS_MAXSHMIDS,
225 ALIAS_MAXMSGIDS,
226 ALIAS_MAXSEMIDS,
227 ALIAS_MAXLOCKEDMEM,
228 ALIAS_MAXSWAP,
229 "scheduling-class",
230 "ip-type",
231 "defrouter",
232 "hostid",
233 "user",
234 "auths",
235 "fs-allowed",
236 ALIAS_MAXPROCS,
237 "allowed-address",
238 NULL
239 };
240
241 /* These *must* match the order of the PROP_VAL_ define's from zonecfg.h */
242 static char *prop_val_types[] = {
243 "simple",
244 "complex",
245 "list",
246 };
247
248 /*
249 * The various _cmds[] lists below are for command tab-completion.
250 */
251
252 /*
253 * remove has a space afterwards because it has qualifiers; the other commands
254 * that have qualifiers (add, select, etc.) don't need a space here because
255 * they have their own _cmds[] lists below.
256 */
257 static const char *global_scope_cmds[] = {
390 "cancel",
391 "end",
392 "exit",
393 "help",
394 "info",
395 "remove options ",
396 "set dir=",
397 "set raw=",
398 "set special=",
399 "set type=",
400 "clear raw",
401 NULL
402 };
403
404 static const char *net_res_scope_cmds[] = {
405 "cancel",
406 "end",
407 "exit",
408 "help",
409 "info",
410 "set address=",
411 "set physical=",
412 "set defrouter=",
413 NULL
414 };
415
416 static const char *device_res_scope_cmds[] = {
417 "cancel",
418 "end",
419 "exit",
420 "help",
421 "info",
422 "set match=",
423 NULL
424 };
425
426 static const char *attr_res_scope_cmds[] = {
427 "cancel",
428 "end",
429 "exit",
430 "help",
431 "info",
432 "set name=",
433 "set type=",
434 "set value=",
435 NULL
436 };
437
438 static const char *rctl_res_scope_cmds[] = {
439 "add value ",
440 "cancel",
441 "end",
1061 pt_to_str(PT_OPTIONS),
1062 gettext("<file-system options>"));
1063 (void) fprintf(fp, "\t%s %s %s\n",
1064 cmd_to_str(CMD_REMOVE), pt_to_str(PT_OPTIONS),
1065 gettext("<file-system options>"));
1066 (void) fprintf(fp, gettext("Consult the file-system "
1067 "specific manual page, such as mount_ufs(1M), "
1068 "for\ndetails about file-system options. Note "
1069 "that any file-system options with an\nembedded "
1070 "'=' character must be enclosed in double quotes, "
1071 /*CSTYLED*/
1072 "such as \"%s=5\".\n"), MNTOPT_RETRY);
1073 break;
1074 case RT_NET:
1075 (void) fprintf(fp, gettext("The '%s' resource scope is "
1076 "used to configure a network interface.\n"),
1077 rt_to_str(resource_scope));
1078 (void) fprintf(fp, gettext("Valid commands:\n"));
1079 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1080 pt_to_str(PT_ADDRESS), gettext("<IP-address>"));
1081 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1082 pt_to_str(PT_ALLOWED_ADDRESS),
1083 gettext("<IP-address>"));
1084 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1085 pt_to_str(PT_PHYSICAL), gettext("<interface>"));
1086 (void) fprintf(fp, gettext("See ifconfig(1M) for "
1087 "details of the <interface> string.\n"));
1088 (void) fprintf(fp, gettext("%s %s is valid "
1089 "if the %s property is set to %s, otherwise it "
1090 "must not be set.\n"),
1091 cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS),
1092 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),
1097 pt_to_str(PT_IPTYPE), gettext("exclusive"));
1098 (void) fprintf(fp, gettext("\t%s %s=%s\n%s %s "
1099 "is valid if the %s or %s property is set, "
1100 "otherwise it must not be set\n"),
1101 cmd_to_str(CMD_SET),
1102 pt_to_str(PT_DEFROUTER), gettext("<IP-address>"),
1103 cmd_to_str(CMD_SET), pt_to_str(PT_DEFROUTER),
1104 gettext(pt_to_str(PT_ADDRESS)),
1105 gettext(pt_to_str(PT_ALLOWED_ADDRESS)));
1106 break;
1107 case RT_DEVICE:
1108 (void) fprintf(fp, gettext("The '%s' resource scope is "
1109 "used to configure a device node.\n"),
1110 rt_to_str(resource_scope));
1111 (void) fprintf(fp, gettext("Valid commands:\n"));
1112 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1113 pt_to_str(PT_MATCH), gettext("<device-path>"));
1114 break;
1115 case RT_RCTL:
1116 (void) fprintf(fp, gettext("The '%s' resource scope is "
1117 "used to configure a resource control.\n"),
1118 rt_to_str(resource_scope));
1119 (void) fprintf(fp, gettext("Valid commands:\n"));
1120 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1121 pt_to_str(PT_NAME), gettext("<string>"));
1122 (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n",
1123 cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE),
1124 pt_to_str(PT_PRIV), gettext("<priv-value>"),
1125 pt_to_str(PT_LIMIT), gettext("<number>"),
1126 pt_to_str(PT_ACTION), gettext("<action-value>"));
1127 (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n",
1128 cmd_to_str(CMD_REMOVE), pt_to_str(PT_VALUE),
1129 pt_to_str(PT_PRIV), gettext("<priv-value>"),
1130 pt_to_str(PT_LIMIT), gettext("<number>"),
1131 pt_to_str(PT_ACTION), gettext("<action-value>"));
1319 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1320 pt_to_str(PT_FS_ALLOWED));
1321 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1322 pt_to_str(PT_MAXLWPS));
1323 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1324 pt_to_str(PT_MAXPROCS));
1325 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1326 pt_to_str(PT_MAXSHMMEM));
1327 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1328 pt_to_str(PT_MAXSHMIDS));
1329 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1330 pt_to_str(PT_MAXMSGIDS));
1331 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1332 pt_to_str(PT_MAXSEMIDS));
1333 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1334 pt_to_str(PT_SHARES));
1335 (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s\n",
1336 rt_to_str(RT_FS), pt_to_str(PT_DIR),
1337 pt_to_str(PT_SPECIAL), pt_to_str(PT_RAW),
1338 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),
1340 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));
1344 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL),
1345 pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
1346 (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR),
1347 pt_to_str(PT_NAME), pt_to_str(PT_TYPE),
1348 pt_to_str(PT_VALUE));
1349 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DATASET),
1350 pt_to_str(PT_NAME));
1351 (void) fprintf(fp, "\t%s\t%s, %s\n", rt_to_str(RT_DCPU),
1352 pt_to_str(PT_NCPUS), pt_to_str(PT_IMPORTANCE));
1353 (void) fprintf(fp, "\t%s\t%s\n", rt_to_str(RT_PCAP),
1354 pt_to_str(PT_NCPUS));
1355 (void) fprintf(fp, "\t%s\t%s, %s, %s\n", rt_to_str(RT_MCAP),
1356 pt_to_str(PT_PHYSICAL), pt_to_str(PT_SWAP),
1357 pt_to_str(PT_LOCKED));
1358 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_ADMIN),
1359 pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
1360 }
1361 if (need_to_close)
1362 (void) pager_close(fp);
1363 }
1681 else
1682 short_usage(CMD_CREATE);
1683 arg_err = B_TRUE;
1684 break;
1685 case 'a':
1686 (void) strlcpy(attach_path, optarg,
1687 sizeof (attach_path));
1688 attach = B_TRUE;
1689 break;
1690 case 'b':
1691 (void) strlcpy(zone_template, "SUNWblank",
1692 sizeof (zone_template));
1693 break;
1694 case 'F':
1695 force = B_TRUE;
1696 break;
1697 case 't':
1698 (void) strlcpy(zone_template, optarg,
1699 sizeof (zone_template));
1700 break;
1701 default:
1702 short_usage(CMD_CREATE);
1703 arg_err = B_TRUE;
1704 break;
1705 }
1706 }
1707 if (arg_err)
1708 return;
1709
1710 if (optind != cmd->cmd_argc) {
1711 short_usage(CMD_CREATE);
1712 return;
1713 }
1714
1715 if (zone_is_read_only(CMD_CREATE))
1716 return;
1717
1718 if (check_if_zone_already_exists(force) != Z_OK)
1719 return;
1720
1784
1785 if (strlen(prop_id) == 0)
1786 return;
1787 quote_str = quoteit(prop_id);
1788 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1789 pt_to_str(prop_num), quote_str);
1790 free(quote_str);
1791 }
1792
1793 void
1794 export_func(cmd_t *cmd)
1795 {
1796 struct zone_nwiftab nwiftab;
1797 struct zone_fstab fstab;
1798 struct zone_devtab devtab;
1799 struct zone_attrtab attrtab;
1800 struct zone_rctltab rctltab;
1801 struct zone_dstab dstab;
1802 struct zone_psettab psettab;
1803 struct zone_rctlvaltab *valptr;
1804 struct zone_admintab admintab;
1805 int err, arg;
1806 char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN];
1807 char bootargs[BOOTARGS_MAX];
1808 char sched[MAXNAMELEN];
1809 char brand[MAXNAMELEN];
1810 char hostidp[HW_HOSTID_LEN];
1811 char fsallowedp[ZONE_FS_ALLOWED_MAX];
1812 char *limitpriv;
1813 FILE *of;
1814 boolean_t autoboot;
1815 zone_iptype_t iptype;
1816 boolean_t need_to_close = B_FALSE;
1817 boolean_t arg_err = B_FALSE;
1818
1819 assert(cmd != NULL);
1820
1821 outfile[0] = '\0';
1822 optind = 0;
1823 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?f:")) != EOF) {
1953 cmd_to_str(CMD_ADD),
1954 pt_to_str(PT_OPTIONS),
1955 optptr->zone_fsopt_opt);
1956 }
1957 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
1958 zonecfg_free_fs_option_list(fstab.zone_fs_options);
1959 }
1960 (void) zonecfg_endfsent(handle);
1961
1962 if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
1963 zone_perror(zone, err, B_FALSE);
1964 goto done;
1965 }
1966 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
1967 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
1968 rt_to_str(RT_NET));
1969 export_prop(of, PT_ADDRESS, nwiftab.zone_nwif_address);
1970 export_prop(of, PT_ALLOWED_ADDRESS,
1971 nwiftab.zone_nwif_allowed_address);
1972 export_prop(of, PT_PHYSICAL, nwiftab.zone_nwif_physical);
1973 export_prop(of, PT_DEFROUTER, nwiftab.zone_nwif_defrouter);
1974 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
1975 }
1976 (void) zonecfg_endnwifent(handle);
1977
1978 if ((err = zonecfg_setdevent(handle)) != Z_OK) {
1979 zone_perror(zone, err, B_FALSE);
1980 goto done;
1981 }
1982 while (zonecfg_getdevent(handle, &devtab) == Z_OK) {
1983 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
1984 rt_to_str(RT_DEVICE));
1985 export_prop(of, PT_MATCH, devtab.zone_dev_match);
1986 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
1987 }
1988 (void) zonecfg_enddevent(handle);
1989
1990 if ((err = zonecfg_setrctlent(handle)) != Z_OK) {
1991 zone_perror(zone, err, B_FALSE);
1992 goto done;
1993 }
1994 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
1995 (void) fprintf(of, "%s rctl\n", cmd_to_str(CMD_ADD));
1996 export_prop(of, PT_NAME, rctltab.zone_rctl_name);
1997 for (valptr = rctltab.zone_rctl_valptr; valptr != NULL;
1998 valptr = valptr->zone_rctlval_next) {
1999 fprintf(of, "%s %s (%s=%s,%s=%s,%s=%s)\n",
2000 cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE),
2001 pt_to_str(PT_PRIV), valptr->zone_rctlval_priv,
2002 pt_to_str(PT_LIMIT), valptr->zone_rctlval_limit,
2003 pt_to_str(PT_ACTION), valptr->zone_rctlval_action);
2004 }
2005 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2332 /*
2333 * Make sure the rctl value looks roughly correct; we won't know if
2334 * it's truly OK until we verify the configuration on the target
2335 * system.
2336 */
2337 if (zonecfg_construct_rctlblk(rctlvaltab, rctlblk) != Z_OK ||
2338 !zonecfg_valid_rctlblk(rctlblk)) {
2339 zerr(gettext("Invalid %s %s specification"), rt_to_str(RT_RCTL),
2340 pt_to_str(PT_VALUE));
2341 goto bad;
2342 }
2343 err = zonecfg_add_rctl_value(&in_progress_rctltab, rctlvaltab);
2344 if (err != Z_OK)
2345 zone_perror(pt_to_str(PT_VALUE), err, B_TRUE);
2346 return;
2347
2348 bad:
2349 zonecfg_free_rctl_value_list(rctlvaltab);
2350 }
2351
2352 static void
2353 add_property(cmd_t *cmd)
2354 {
2355 char *prop_id;
2356 int err, res_type, prop_type;
2357 property_value_ptr_t pp;
2358 list_property_ptr_t l;
2359
2360 res_type = resource_scope;
2361 prop_type = cmd->cmd_prop_name[0];
2362 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
2363 long_usage(CMD_ADD, B_TRUE);
2364 return;
2365 }
2366
2367 if (cmd->cmd_prop_nv_pairs != 1) {
2368 long_usage(CMD_ADD, B_TRUE);
2369 return;
2370 }
2371
2372 if (initialize(B_TRUE) != Z_OK)
2399 err = zonecfg_add_fs_option(&in_progress_fstab,
2400 prop_id);
2401 if (err != Z_OK)
2402 zone_perror(pt_to_str(prop_type), err, B_TRUE);
2403 } else {
2404 list_property_ptr_t list;
2405
2406 for (list = pp->pv_list; list != NULL;
2407 list = list->lp_next) {
2408 prop_id = list->lp_simple;
2409 if (prop_id == NULL)
2410 break;
2411 err = zonecfg_add_fs_option(
2412 &in_progress_fstab, prop_id);
2413 if (err != Z_OK)
2414 zone_perror(pt_to_str(prop_type), err,
2415 B_TRUE);
2416 }
2417 }
2418 return;
2419 case RT_RCTL:
2420 if (prop_type != PT_VALUE) {
2421 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
2422 B_TRUE);
2423 long_usage(CMD_ADD, B_TRUE);
2424 usage(B_FALSE, HELP_PROPS);
2425 return;
2426 }
2427 pp = cmd->cmd_property_ptr[0];
2428 if (pp->pv_type != PROP_VAL_COMPLEX &&
2429 pp->pv_type != PROP_VAL_LIST) {
2430 zerr(gettext("A %s or %s value was expected here."),
2431 pvt_to_str(PROP_VAL_COMPLEX),
2432 pvt_to_str(PROP_VAL_LIST));
2433 saw_error = B_TRUE;
2434 return;
2435 }
2436 if (pp->pv_type == PROP_VAL_COMPLEX) {
2437 do_complex_rctl_val(pp->pv_complex);
2438 return;
2503 return;
2504 }
2505
2506 if (zone_is_read_only(CMD_ADD))
2507 return;
2508
2509 if (initialize(B_TRUE) != Z_OK)
2510 return;
2511 if (global_scope) {
2512 if (gz_invalid_resource(cmd->cmd_res_type)) {
2513 zerr(gettext("Cannot add a %s resource to the "
2514 "global zone."), rt_to_str(cmd->cmd_res_type));
2515 saw_error = B_TRUE;
2516 return;
2517 }
2518
2519 global_scope = B_FALSE;
2520 resource_scope = cmd->cmd_res_type;
2521 end_op = CMD_ADD;
2522 add_resource(cmd);
2523 } else
2524 add_property(cmd);
2525 }
2526
2527 /*
2528 * This routine has an unusual implementation, because it tries very
2529 * hard to succeed in the face of a variety of failure modes.
2530 * The most common and most vexing occurs when the index file and
2531 * the /etc/zones/<zonename.xml> file are not both present. In
2532 * this case, delete must eradicate as much of the zone state as is left
2533 * so that the user can later create a new zone with the same name.
2534 */
2535 void
2536 delete_func(cmd_t *cmd)
2537 {
2538 int err, arg, answer;
2539 char line[ZONENAME_MAX + 128]; /* enough to ask a question */
2540 boolean_t force = B_FALSE;
2541 boolean_t arg_err = B_FALSE;
2542
2543 optind = 0;
2544 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
2702 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2703 zerr(gettext("A simple value was expected here."));
2704 saw_error = B_TRUE;
2705 return (Z_INSUFFICIENT_SPEC);
2706 }
2707 switch (cmd->cmd_prop_name[i]) {
2708 case PT_ADDRESS:
2709 (void) strlcpy(nwiftab->zone_nwif_address,
2710 pp->pv_simple, sizeof (nwiftab->zone_nwif_address));
2711 break;
2712 case PT_ALLOWED_ADDRESS:
2713 (void) strlcpy(nwiftab->zone_nwif_allowed_address,
2714 pp->pv_simple,
2715 sizeof (nwiftab->zone_nwif_allowed_address));
2716 break;
2717 case PT_PHYSICAL:
2718 (void) strlcpy(nwiftab->zone_nwif_physical,
2719 pp->pv_simple,
2720 sizeof (nwiftab->zone_nwif_physical));
2721 break;
2722 case PT_DEFROUTER:
2723 (void) strlcpy(nwiftab->zone_nwif_defrouter,
2724 pp->pv_simple,
2725 sizeof (nwiftab->zone_nwif_defrouter));
2726 break;
2727 default:
2728 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2729 Z_NO_PROPERTY_TYPE, B_TRUE);
2730 return (Z_INSUFFICIENT_SPEC);
2731 }
2732 }
2733 if (fill_in_only)
2734 return (Z_OK);
2735 err = zonecfg_lookup_nwif(handle, nwiftab);
2736 return (err);
2737 }
2738
2739 static int
2740 fill_in_devtab(cmd_t *cmd, struct zone_devtab *devtab, boolean_t fill_in_only)
2741 {
3384 remove_mcap();
3385 return;
3386 case RT_ADMIN:
3387 remove_admin(cmd);
3388 return;
3389 default:
3390 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3391 long_usage(CMD_REMOVE, B_TRUE);
3392 usage(B_FALSE, HELP_RESOURCES);
3393 return;
3394 }
3395 }
3396
3397 static void
3398 remove_property(cmd_t *cmd)
3399 {
3400 char *prop_id;
3401 int err, res_type, prop_type;
3402 property_value_ptr_t pp;
3403 struct zone_rctlvaltab *rctlvaltab;
3404 complex_property_ptr_t cx;
3405
3406 res_type = resource_scope;
3407 prop_type = cmd->cmd_prop_name[0];
3408 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
3409 long_usage(CMD_REMOVE, B_TRUE);
3410 return;
3411 }
3412
3413 if (cmd->cmd_prop_nv_pairs != 1) {
3414 long_usage(CMD_ADD, B_TRUE);
3415 return;
3416 }
3417
3418 if (initialize(B_TRUE) != Z_OK)
3419 return;
3420
3421 switch (res_type) {
3422 case RT_FS:
3423 if (prop_type != PT_OPTIONS) {
3444 err = zonecfg_remove_fs_option(&in_progress_fstab,
3445 prop_id);
3446 if (err != Z_OK)
3447 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3448 } else {
3449 list_property_ptr_t list;
3450
3451 for (list = pp->pv_list; list != NULL;
3452 list = list->lp_next) {
3453 prop_id = list->lp_simple;
3454 if (prop_id == NULL)
3455 break;
3456 err = zonecfg_remove_fs_option(
3457 &in_progress_fstab, prop_id);
3458 if (err != Z_OK)
3459 zone_perror(pt_to_str(prop_type), err,
3460 B_TRUE);
3461 }
3462 }
3463 return;
3464 case RT_RCTL:
3465 if (prop_type != PT_VALUE) {
3466 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3467 B_TRUE);
3468 long_usage(CMD_REMOVE, B_TRUE);
3469 usage(B_FALSE, HELP_PROPS);
3470 return;
3471 }
3472 pp = cmd->cmd_property_ptr[0];
3473 if (pp->pv_type != PROP_VAL_COMPLEX) {
3474 zerr(gettext("A %s value was expected here."),
3475 pvt_to_str(PROP_VAL_COMPLEX));
3476 saw_error = B_TRUE;
3477 return;
3478 }
3479 if ((rctlvaltab = alloc_rctlvaltab()) == NULL) {
3480 zone_perror(zone, Z_NOMEM, B_TRUE);
3481 exit(Z_ERR);
3482 }
3483 for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) {
3496 (void) strlcpy(rctlvaltab->zone_rctlval_action,
3497 cx->cp_value,
3498 sizeof (rctlvaltab->zone_rctlval_action));
3499 break;
3500 default:
3501 zone_perror(pt_to_str(prop_type),
3502 Z_NO_PROPERTY_TYPE, B_TRUE);
3503 long_usage(CMD_ADD, B_TRUE);
3504 usage(B_FALSE, HELP_PROPS);
3505 zonecfg_free_rctl_value_list(rctlvaltab);
3506 return;
3507 }
3508 }
3509 rctlvaltab->zone_rctlval_next = NULL;
3510 err = zonecfg_remove_rctl_value(&in_progress_rctltab,
3511 rctlvaltab);
3512 if (err != Z_OK)
3513 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3514 zonecfg_free_rctl_value_list(rctlvaltab);
3515 return;
3516 case RT_NET:
3517 if (prop_type != PT_DEFROUTER) {
3518 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3519 B_TRUE);
3520 long_usage(CMD_REMOVE, B_TRUE);
3521 usage(B_FALSE, HELP_PROPS);
3522 return;
3523 } else {
3524 bzero(&in_progress_nwiftab.zone_nwif_defrouter,
3525 sizeof (in_progress_nwiftab.zone_nwif_defrouter));
3526 return;
3527 }
3528 default:
3529 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
3530 long_usage(CMD_REMOVE, B_TRUE);
3531 usage(B_FALSE, HELP_RESOURCES);
3532 return;
3533 }
3534 }
3535
3536 void
3537 remove_func(cmd_t *cmd)
3538 {
3539 if (zone_is_read_only(CMD_REMOVE))
3540 return;
3541
3542 assert(cmd != NULL);
3543
3544 if (global_scope) {
3545 if (gz_invalid_resource(cmd->cmd_res_type)) {
3546 zerr(gettext("%s is not a valid resource for the "
3547 "global zone."), rt_to_str(cmd->cmd_res_type));
3580 case RT_DCPU:
3581 if (prop_type == PT_IMPORTANCE) {
3582 in_progress_psettab.zone_importance[0] = '\0';
3583 need_to_commit = B_TRUE;
3584 return;
3585 }
3586 break;
3587 case RT_MCAP:
3588 switch (prop_type) {
3589 case PT_PHYSICAL:
3590 remove_aliased_rctl(PT_PHYSICAL, ALIAS_MAXPHYSMEM);
3591 return;
3592 case PT_SWAP:
3593 remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP);
3594 return;
3595 case PT_LOCKED:
3596 remove_aliased_rctl(PT_LOCKED, ALIAS_MAXLOCKEDMEM);
3597 return;
3598 }
3599 break;
3600 default:
3601 break;
3602 }
3603
3604 zone_perror(pt_to_str(prop_type), Z_CLEAR_DISALLOW, B_TRUE);
3605 }
3606
3607 static void
3608 clear_global(cmd_t *cmd)
3609 {
3610 int err, type;
3611
3612 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3613 long_usage(CMD_CLEAR, B_TRUE);
3614 return;
3615 }
3616
3617 if (initialize(B_TRUE) != Z_OK)
3618 return;
3619
4186
4187 if (force_set) {
4188 if (res_type != RT_ZONEPATH) {
4189 zerr(gettext("Only zonepath setting can be forced."));
4190 saw_error = B_TRUE;
4191 return;
4192 }
4193 if (!zonecfg_in_alt_root()) {
4194 zerr(gettext("Zonepath is changeable only in an "
4195 "alternate root."));
4196 saw_error = B_TRUE;
4197 return;
4198 }
4199 }
4200
4201 pp = cmd->cmd_property_ptr[0];
4202 /*
4203 * A nasty expression but not that complicated:
4204 * 1. fs options are simple or list (tested below)
4205 * 2. rctl value's are complex or list (tested below)
4206 * Anything else should be simple.
4207 */
4208 if (!(res_type == RT_FS && prop_type == PT_OPTIONS) &&
4209 !(res_type == RT_RCTL && prop_type == PT_VALUE) &&
4210 (pp->pv_type != PROP_VAL_SIMPLE ||
4211 (prop_id = pp->pv_simple) == NULL)) {
4212 zerr(gettext("A %s value was expected here."),
4213 pvt_to_str(PROP_VAL_SIMPLE));
4214 saw_error = B_TRUE;
4215 return;
4216 }
4217 if (prop_type == PT_UNKNOWN) {
4218 long_usage(CMD_SET, B_TRUE);
4219 return;
4220 }
4221
4222 /*
4223 * Special case: the user can change the zone name prior to 'create';
4224 * if the zone already exists, we fall through letting initialize()
4225 * and the rest of the logic run.
4226 */
4227 if (res_type == RT_ZONENAME && got_handle == B_FALSE &&
4228 !state_atleast(ZONE_STATE_CONFIGURED)) {
4229 if ((err = zonecfg_validate_zonename(prop_id)) != Z_OK) {
4449 case RT_NET:
4450 switch (prop_type) {
4451 case PT_ADDRESS:
4452 case PT_ALLOWED_ADDRESS:
4453 if (validate_net_address_syntax(prop_id, B_FALSE)
4454 != Z_OK) {
4455 saw_error = B_TRUE;
4456 return;
4457 }
4458 set_in_progress_nwiftab_address(prop_id, prop_type);
4459 break;
4460 case PT_PHYSICAL:
4461 if (validate_net_physical_syntax(prop_id) != Z_OK) {
4462 saw_error = B_TRUE;
4463 return;
4464 }
4465 (void) strlcpy(in_progress_nwiftab.zone_nwif_physical,
4466 prop_id,
4467 sizeof (in_progress_nwiftab.zone_nwif_physical));
4468 break;
4469 case PT_DEFROUTER:
4470 if (validate_net_address_syntax(prop_id, B_TRUE)
4471 != Z_OK) {
4472 saw_error = B_TRUE;
4473 return;
4474 }
4475 (void) strlcpy(in_progress_nwiftab.zone_nwif_defrouter,
4476 prop_id,
4477 sizeof (in_progress_nwiftab.zone_nwif_defrouter));
4478 break;
4479 default:
4480 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4481 B_TRUE);
4482 long_usage(CMD_SET, B_TRUE);
4483 usage(B_FALSE, HELP_PROPS);
4484 return;
4485 }
4486 return;
4487 case RT_DEVICE:
4488 switch (prop_type) {
4489 case PT_MATCH:
4490 (void) strlcpy(in_progress_devtab.zone_dev_match,
4491 prop_id,
4492 sizeof (in_progress_devtab.zone_dev_match));
4493 break;
4494 default:
4495 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4496 B_TRUE);
4497 long_usage(CMD_SET, B_TRUE);
4498 usage(B_FALSE, HELP_PROPS);
4499 return;
4500 }
4501 return;
4502 case RT_RCTL:
4503 switch (prop_type) {
4504 case PT_NAME:
4505 if (!zonecfg_valid_rctlname(prop_id)) {
4506 zerr(gettext("'%s' is not a valid zone %s "
4507 "name."), prop_id, rt_to_str(RT_RCTL));
4508 return;
4509 }
4510 (void) strlcpy(in_progress_rctltab.zone_rctl_name,
4511 prop_id,
4512 sizeof (in_progress_rctltab.zone_rctl_name));
4513 break;
5013 strcmp(user.zone_fs_type, lookup.zone_fs_type) != 0)
5014 goto loopend; /* no match */
5015 output_fs(fp, &lookup);
5016 output = B_TRUE;
5017 loopend:
5018 zonecfg_free_fs_option_list(lookup.zone_fs_options);
5019 }
5020 (void) zonecfg_endfsent(handle);
5021 /*
5022 * If a property n/v pair was specified, warn the user if there was
5023 * nothing to output.
5024 */
5025 if (!output && cmd->cmd_prop_nv_pairs > 0)
5026 (void) printf(gettext("No such %s resource.\n"),
5027 rt_to_str(RT_FS));
5028 }
5029
5030 static void
5031 output_net(FILE *fp, struct zone_nwiftab *nwiftab)
5032 {
5033 (void) fprintf(fp, "%s:\n", rt_to_str(RT_NET));
5034 output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE);
5035 output_prop(fp, PT_ALLOWED_ADDRESS,
5036 nwiftab->zone_nwif_allowed_address, B_TRUE);
5037 output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE);
5038 output_prop(fp, PT_DEFROUTER, nwiftab->zone_nwif_defrouter, B_TRUE);
5039 }
5040
5041 static void
5042 info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5043 {
5044 struct zone_nwiftab lookup, user;
5045 boolean_t output = B_FALSE;
5046
5047 if (zonecfg_setnwifent(handle) != Z_OK)
5048 return;
5049 while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
5050 if (cmd->cmd_prop_nv_pairs == 0) {
5051 output_net(fp, &lookup);
5052 continue;
5053 }
5054 if (fill_in_nwiftab(cmd, &user, B_TRUE) != Z_OK)
5055 continue;
5056 if (strlen(user.zone_nwif_physical) > 0 &&
5057 strcmp(user.zone_nwif_physical,
5058 lookup.zone_nwif_physical) != 0)
5061 if (strlen(user.zone_nwif_address) > 0 &&
5062 !zonecfg_same_net_address(user.zone_nwif_address,
5063 lookup.zone_nwif_address))
5064 continue; /* no match */
5065 output_net(fp, &lookup);
5066 output = B_TRUE;
5067 }
5068 (void) zonecfg_endnwifent(handle);
5069 /*
5070 * If a property n/v pair was specified, warn the user if there was
5071 * nothing to output.
5072 */
5073 if (!output && cmd->cmd_prop_nv_pairs > 0)
5074 (void) printf(gettext("No such %s resource.\n"),
5075 rt_to_str(RT_NET));
5076 }
5077
5078 static void
5079 output_dev(FILE *fp, struct zone_devtab *devtab)
5080 {
5081 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DEVICE));
5082 output_prop(fp, PT_MATCH, devtab->zone_dev_match, B_TRUE);
5083 }
5084
5085 static void
5086 info_dev(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5087 {
5088 struct zone_devtab lookup, user;
5089 boolean_t output = B_FALSE;
5090
5091 if (zonecfg_setdevent(handle) != Z_OK)
5092 return;
5093 while (zonecfg_getdevent(handle, &lookup) == Z_OK) {
5094 if (cmd->cmd_prop_nv_pairs == 0) {
5095 output_dev(fp, &lookup);
5096 continue;
5097 }
5098 if (fill_in_devtab(cmd, &user, B_TRUE) != Z_OK)
5099 continue;
5100 if (strlen(user.zone_dev_match) > 0 &&
5101 strcmp(user.zone_dev_match, lookup.zone_dev_match) != 0)
5102 continue; /* no match */
6089 pt_to_str(PT_USER),
6090 admintab.zone_admin_user);
6091 ret_val = Z_BAD_PROPERTY;
6092 }
6093 if ((ret_val == Z_OK) && (!zonecfg_valid_auths(
6094 admintab.zone_admin_auths, zone))) {
6095 ret_val = Z_BAD_PROPERTY;
6096 }
6097 }
6098 (void) zonecfg_endadminent(handle);
6099
6100 if (!global_scope) {
6101 zerr(gettext("resource specification incomplete"));
6102 saw_error = B_TRUE;
6103 if (ret_val == Z_OK)
6104 ret_val = Z_INSUFFICIENT_SPEC;
6105 }
6106
6107 if (save) {
6108 if (ret_val == Z_OK) {
6109 if ((ret_val = zonecfg_save(handle)) == Z_OK) {
6110 need_to_commit = B_FALSE;
6111 (void) strlcpy(revert_zone, zone,
6112 sizeof (revert_zone));
6113 }
6114 } else {
6115 zerr(gettext("Zone %s failed to verify"), zone);
6116 }
6117 }
6118 if (ret_val != Z_OK)
6119 zone_perror(zone, ret_val, B_TRUE);
6120 }
6121
6122 void
6123 cancel_func(cmd_t *cmd)
6124 {
6125 int arg;
6126 boolean_t arg_err = B_FALSE;
6127
6128 assert(cmd != NULL);
|
218 "importance",
219 "swap",
220 "locked",
221 ALIAS_SHARES,
222 ALIAS_MAXLWPS,
223 ALIAS_MAXSHMMEM,
224 ALIAS_MAXSHMIDS,
225 ALIAS_MAXMSGIDS,
226 ALIAS_MAXSEMIDS,
227 ALIAS_MAXLOCKEDMEM,
228 ALIAS_MAXSWAP,
229 "scheduling-class",
230 "ip-type",
231 "defrouter",
232 "hostid",
233 "user",
234 "auths",
235 "fs-allowed",
236 ALIAS_MAXPROCS,
237 "allowed-address",
238 ALIAS_ZFSPRI,
239 "mac-addr",
240 "vlan-id",
241 "global-nic",
242 "property",
243 NULL
244 };
245
246 /* These *must* match the order of the PROP_VAL_ define's from zonecfg.h */
247 static char *prop_val_types[] = {
248 "simple",
249 "complex",
250 "list",
251 };
252
253 /*
254 * The various _cmds[] lists below are for command tab-completion.
255 */
256
257 /*
258 * remove has a space afterwards because it has qualifiers; the other commands
259 * that have qualifiers (add, select, etc.) don't need a space here because
260 * they have their own _cmds[] lists below.
261 */
262 static const char *global_scope_cmds[] = {
395 "cancel",
396 "end",
397 "exit",
398 "help",
399 "info",
400 "remove options ",
401 "set dir=",
402 "set raw=",
403 "set special=",
404 "set type=",
405 "clear raw",
406 NULL
407 };
408
409 static const char *net_res_scope_cmds[] = {
410 "cancel",
411 "end",
412 "exit",
413 "help",
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 ",
422 "set address=",
423 "set allowed-address=",
424 "set defrouter=",
425 "set global-nic=",
426 "set mac-addr=",
427 "set physical=",
428 "set vlan-id=",
429 NULL
430 };
431
432 static const char *device_res_scope_cmds[] = {
433 "cancel",
434 "end",
435 "exit",
436 "help",
437 "info",
438 "add property ",
439 "set match=",
440 NULL
441 };
442
443 static const char *attr_res_scope_cmds[] = {
444 "cancel",
445 "end",
446 "exit",
447 "help",
448 "info",
449 "set name=",
450 "set type=",
451 "set value=",
452 NULL
453 };
454
455 static const char *rctl_res_scope_cmds[] = {
456 "add value ",
457 "cancel",
458 "end",
1078 pt_to_str(PT_OPTIONS),
1079 gettext("<file-system options>"));
1080 (void) fprintf(fp, "\t%s %s %s\n",
1081 cmd_to_str(CMD_REMOVE), pt_to_str(PT_OPTIONS),
1082 gettext("<file-system options>"));
1083 (void) fprintf(fp, gettext("Consult the file-system "
1084 "specific manual page, such as mount_ufs(1M), "
1085 "for\ndetails about file-system options. Note "
1086 "that any file-system options with an\nembedded "
1087 "'=' character must be enclosed in double quotes, "
1088 /*CSTYLED*/
1089 "such as \"%s=5\".\n"), MNTOPT_RETRY);
1090 break;
1091 case RT_NET:
1092 (void) fprintf(fp, gettext("The '%s' resource scope is "
1093 "used to configure a network interface.\n"),
1094 rt_to_str(resource_scope));
1095 (void) fprintf(fp, gettext("Valid commands:\n"));
1096 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
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));
1101 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1102 pt_to_str(PT_ALLOWED_ADDRESS),
1103 gettext("<IP-address>"));
1104 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
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>"));
1112 (void) fprintf(fp, gettext("See ifconfig(1M) for "
1113 "details of the <interface> string.\n"));
1114 (void) fprintf(fp, gettext("%s %s is valid "
1115 "if the %s property is set to %s, otherwise it "
1116 "must not be set.\n"),
1117 cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS),
1118 pt_to_str(PT_IPTYPE), gettext("shared"));
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),
1125 pt_to_str(PT_IPTYPE), gettext("exclusive"));
1126 (void) fprintf(fp, gettext("\t%s %s=%s\n%s %s "
1127 "is valid if the %s or %s property is set, "
1128 "otherwise it must not be set\n"),
1129 cmd_to_str(CMD_SET),
1130 pt_to_str(PT_DEFROUTER), gettext("<IP-address>"),
1131 cmd_to_str(CMD_SET), pt_to_str(PT_DEFROUTER),
1132 gettext(pt_to_str(PT_ADDRESS)),
1133 gettext(pt_to_str(PT_ALLOWED_ADDRESS)));
1134 break;
1135 case RT_DEVICE:
1136 (void) fprintf(fp, gettext("The '%s' resource scope is "
1137 "used to configure a device node.\n"),
1138 rt_to_str(resource_scope));
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));
1143 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1144 pt_to_str(PT_MATCH), gettext("<device-path>"));
1145 break;
1146 case RT_RCTL:
1147 (void) fprintf(fp, gettext("The '%s' resource scope is "
1148 "used to configure a resource control.\n"),
1149 rt_to_str(resource_scope));
1150 (void) fprintf(fp, gettext("Valid commands:\n"));
1151 (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
1152 pt_to_str(PT_NAME), gettext("<string>"));
1153 (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n",
1154 cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE),
1155 pt_to_str(PT_PRIV), gettext("<priv-value>"),
1156 pt_to_str(PT_LIMIT), gettext("<number>"),
1157 pt_to_str(PT_ACTION), gettext("<action-value>"));
1158 (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n",
1159 cmd_to_str(CMD_REMOVE), pt_to_str(PT_VALUE),
1160 pt_to_str(PT_PRIV), gettext("<priv-value>"),
1161 pt_to_str(PT_LIMIT), gettext("<number>"),
1162 pt_to_str(PT_ACTION), gettext("<action-value>"));
1350 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1351 pt_to_str(PT_FS_ALLOWED));
1352 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1353 pt_to_str(PT_MAXLWPS));
1354 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1355 pt_to_str(PT_MAXPROCS));
1356 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1357 pt_to_str(PT_MAXSHMMEM));
1358 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1359 pt_to_str(PT_MAXSHMIDS));
1360 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1361 pt_to_str(PT_MAXMSGIDS));
1362 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1363 pt_to_str(PT_MAXSEMIDS));
1364 (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
1365 pt_to_str(PT_SHARES));
1366 (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s\n",
1367 rt_to_str(RT_FS), pt_to_str(PT_DIR),
1368 pt_to_str(PT_SPECIAL), pt_to_str(PT_RAW),
1369 pt_to_str(PT_TYPE), pt_to_str(PT_OPTIONS));
1370 (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s, %s, %s %s\n",
1371 rt_to_str(RT_NET),
1372 pt_to_str(PT_ADDRESS), pt_to_str(PT_ALLOWED_ADDRESS),
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));
1378 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL),
1379 pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
1380 (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR),
1381 pt_to_str(PT_NAME), pt_to_str(PT_TYPE),
1382 pt_to_str(PT_VALUE));
1383 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DATASET),
1384 pt_to_str(PT_NAME));
1385 (void) fprintf(fp, "\t%s\t%s, %s\n", rt_to_str(RT_DCPU),
1386 pt_to_str(PT_NCPUS), pt_to_str(PT_IMPORTANCE));
1387 (void) fprintf(fp, "\t%s\t%s\n", rt_to_str(RT_PCAP),
1388 pt_to_str(PT_NCPUS));
1389 (void) fprintf(fp, "\t%s\t%s, %s, %s\n", rt_to_str(RT_MCAP),
1390 pt_to_str(PT_PHYSICAL), pt_to_str(PT_SWAP),
1391 pt_to_str(PT_LOCKED));
1392 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_ADMIN),
1393 pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
1394 }
1395 if (need_to_close)
1396 (void) pager_close(fp);
1397 }
1715 else
1716 short_usage(CMD_CREATE);
1717 arg_err = B_TRUE;
1718 break;
1719 case 'a':
1720 (void) strlcpy(attach_path, optarg,
1721 sizeof (attach_path));
1722 attach = B_TRUE;
1723 break;
1724 case 'b':
1725 (void) strlcpy(zone_template, "SUNWblank",
1726 sizeof (zone_template));
1727 break;
1728 case 'F':
1729 force = B_TRUE;
1730 break;
1731 case 't':
1732 (void) strlcpy(zone_template, optarg,
1733 sizeof (zone_template));
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;
1746 default:
1747 short_usage(CMD_CREATE);
1748 arg_err = B_TRUE;
1749 break;
1750 }
1751 }
1752 if (arg_err)
1753 return;
1754
1755 if (optind != cmd->cmd_argc) {
1756 short_usage(CMD_CREATE);
1757 return;
1758 }
1759
1760 if (zone_is_read_only(CMD_CREATE))
1761 return;
1762
1763 if (check_if_zone_already_exists(force) != Z_OK)
1764 return;
1765
1829
1830 if (strlen(prop_id) == 0)
1831 return;
1832 quote_str = quoteit(prop_id);
1833 (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
1834 pt_to_str(prop_num), quote_str);
1835 free(quote_str);
1836 }
1837
1838 void
1839 export_func(cmd_t *cmd)
1840 {
1841 struct zone_nwiftab nwiftab;
1842 struct zone_fstab fstab;
1843 struct zone_devtab devtab;
1844 struct zone_attrtab attrtab;
1845 struct zone_rctltab rctltab;
1846 struct zone_dstab dstab;
1847 struct zone_psettab psettab;
1848 struct zone_rctlvaltab *valptr;
1849 struct zone_res_attrtab *rap;
1850 struct zone_admintab admintab;
1851 int err, arg;
1852 char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN];
1853 char bootargs[BOOTARGS_MAX];
1854 char sched[MAXNAMELEN];
1855 char brand[MAXNAMELEN];
1856 char hostidp[HW_HOSTID_LEN];
1857 char fsallowedp[ZONE_FS_ALLOWED_MAX];
1858 char *limitpriv;
1859 FILE *of;
1860 boolean_t autoboot;
1861 zone_iptype_t iptype;
1862 boolean_t need_to_close = B_FALSE;
1863 boolean_t arg_err = B_FALSE;
1864
1865 assert(cmd != NULL);
1866
1867 outfile[0] = '\0';
1868 optind = 0;
1869 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?f:")) != EOF) {
1999 cmd_to_str(CMD_ADD),
2000 pt_to_str(PT_OPTIONS),
2001 optptr->zone_fsopt_opt);
2002 }
2003 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2004 zonecfg_free_fs_option_list(fstab.zone_fs_options);
2005 }
2006 (void) zonecfg_endfsent(handle);
2007
2008 if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
2009 zone_perror(zone, err, B_FALSE);
2010 goto done;
2011 }
2012 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
2013 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2014 rt_to_str(RT_NET));
2015 export_prop(of, PT_ADDRESS, nwiftab.zone_nwif_address);
2016 export_prop(of, PT_ALLOWED_ADDRESS,
2017 nwiftab.zone_nwif_allowed_address);
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);
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 }
2030 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2031 }
2032 (void) zonecfg_endnwifent(handle);
2033
2034 if ((err = zonecfg_setdevent(handle)) != Z_OK) {
2035 zone_perror(zone, err, B_FALSE);
2036 goto done;
2037 }
2038 while (zonecfg_getdevent(handle, &devtab) == Z_OK) {
2039 (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
2040 rt_to_str(RT_DEVICE));
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 }
2049 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2050 }
2051 (void) zonecfg_enddevent(handle);
2052
2053 if ((err = zonecfg_setrctlent(handle)) != Z_OK) {
2054 zone_perror(zone, err, B_FALSE);
2055 goto done;
2056 }
2057 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
2058 (void) fprintf(of, "%s rctl\n", cmd_to_str(CMD_ADD));
2059 export_prop(of, PT_NAME, rctltab.zone_rctl_name);
2060 for (valptr = rctltab.zone_rctl_valptr; valptr != NULL;
2061 valptr = valptr->zone_rctlval_next) {
2062 fprintf(of, "%s %s (%s=%s,%s=%s,%s=%s)\n",
2063 cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE),
2064 pt_to_str(PT_PRIV), valptr->zone_rctlval_priv,
2065 pt_to_str(PT_LIMIT), valptr->zone_rctlval_limit,
2066 pt_to_str(PT_ACTION), valptr->zone_rctlval_action);
2067 }
2068 (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
2395 /*
2396 * Make sure the rctl value looks roughly correct; we won't know if
2397 * it's truly OK until we verify the configuration on the target
2398 * system.
2399 */
2400 if (zonecfg_construct_rctlblk(rctlvaltab, rctlblk) != Z_OK ||
2401 !zonecfg_valid_rctlblk(rctlblk)) {
2402 zerr(gettext("Invalid %s %s specification"), rt_to_str(RT_RCTL),
2403 pt_to_str(PT_VALUE));
2404 goto bad;
2405 }
2406 err = zonecfg_add_rctl_value(&in_progress_rctltab, rctlvaltab);
2407 if (err != Z_OK)
2408 zone_perror(pt_to_str(PT_VALUE), err, B_TRUE);
2409 return;
2410
2411 bad:
2412 zonecfg_free_rctl_value_list(rctlvaltab);
2413 }
2414
2415 /*
2416 * Resource attribute ("property" resource embedded on net or dev resource)
2417 */
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
2478 add_property(cmd_t *cmd)
2479 {
2480 char *prop_id;
2481 int err, res_type, prop_type;
2482 property_value_ptr_t pp;
2483 list_property_ptr_t l;
2484
2485 res_type = resource_scope;
2486 prop_type = cmd->cmd_prop_name[0];
2487 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
2488 long_usage(CMD_ADD, B_TRUE);
2489 return;
2490 }
2491
2492 if (cmd->cmd_prop_nv_pairs != 1) {
2493 long_usage(CMD_ADD, B_TRUE);
2494 return;
2495 }
2496
2497 if (initialize(B_TRUE) != Z_OK)
2524 err = zonecfg_add_fs_option(&in_progress_fstab,
2525 prop_id);
2526 if (err != Z_OK)
2527 zone_perror(pt_to_str(prop_type), err, B_TRUE);
2528 } else {
2529 list_property_ptr_t list;
2530
2531 for (list = pp->pv_list; list != NULL;
2532 list = list->lp_next) {
2533 prop_id = list->lp_simple;
2534 if (prop_id == NULL)
2535 break;
2536 err = zonecfg_add_fs_option(
2537 &in_progress_fstab, prop_id);
2538 if (err != Z_OK)
2539 zone_perror(pt_to_str(prop_type), err,
2540 B_TRUE);
2541 }
2542 }
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;
2582 case RT_RCTL:
2583 if (prop_type != PT_VALUE) {
2584 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
2585 B_TRUE);
2586 long_usage(CMD_ADD, B_TRUE);
2587 usage(B_FALSE, HELP_PROPS);
2588 return;
2589 }
2590 pp = cmd->cmd_property_ptr[0];
2591 if (pp->pv_type != PROP_VAL_COMPLEX &&
2592 pp->pv_type != PROP_VAL_LIST) {
2593 zerr(gettext("A %s or %s value was expected here."),
2594 pvt_to_str(PROP_VAL_COMPLEX),
2595 pvt_to_str(PROP_VAL_LIST));
2596 saw_error = B_TRUE;
2597 return;
2598 }
2599 if (pp->pv_type == PROP_VAL_COMPLEX) {
2600 do_complex_rctl_val(pp->pv_complex);
2601 return;
2666 return;
2667 }
2668
2669 if (zone_is_read_only(CMD_ADD))
2670 return;
2671
2672 if (initialize(B_TRUE) != Z_OK)
2673 return;
2674 if (global_scope) {
2675 if (gz_invalid_resource(cmd->cmd_res_type)) {
2676 zerr(gettext("Cannot add a %s resource to the "
2677 "global zone."), rt_to_str(cmd->cmd_res_type));
2678 saw_error = B_TRUE;
2679 return;
2680 }
2681
2682 global_scope = B_FALSE;
2683 resource_scope = cmd->cmd_res_type;
2684 end_op = CMD_ADD;
2685 add_resource(cmd);
2686 } else {
2687 add_property(cmd);
2688 }
2689 }
2690
2691 /*
2692 * This routine has an unusual implementation, because it tries very
2693 * hard to succeed in the face of a variety of failure modes.
2694 * The most common and most vexing occurs when the index file and
2695 * the /etc/zones/<zonename.xml> file are not both present. In
2696 * this case, delete must eradicate as much of the zone state as is left
2697 * so that the user can later create a new zone with the same name.
2698 */
2699 void
2700 delete_func(cmd_t *cmd)
2701 {
2702 int err, arg, answer;
2703 char line[ZONENAME_MAX + 128]; /* enough to ask a question */
2704 boolean_t force = B_FALSE;
2705 boolean_t arg_err = B_FALSE;
2706
2707 optind = 0;
2708 while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) {
2866 if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
2867 zerr(gettext("A simple value was expected here."));
2868 saw_error = B_TRUE;
2869 return (Z_INSUFFICIENT_SPEC);
2870 }
2871 switch (cmd->cmd_prop_name[i]) {
2872 case PT_ADDRESS:
2873 (void) strlcpy(nwiftab->zone_nwif_address,
2874 pp->pv_simple, sizeof (nwiftab->zone_nwif_address));
2875 break;
2876 case PT_ALLOWED_ADDRESS:
2877 (void) strlcpy(nwiftab->zone_nwif_allowed_address,
2878 pp->pv_simple,
2879 sizeof (nwiftab->zone_nwif_allowed_address));
2880 break;
2881 case PT_PHYSICAL:
2882 (void) strlcpy(nwiftab->zone_nwif_physical,
2883 pp->pv_simple,
2884 sizeof (nwiftab->zone_nwif_physical));
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;
2901 case PT_DEFROUTER:
2902 (void) strlcpy(nwiftab->zone_nwif_defrouter,
2903 pp->pv_simple,
2904 sizeof (nwiftab->zone_nwif_defrouter));
2905 break;
2906 default:
2907 zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
2908 Z_NO_PROPERTY_TYPE, B_TRUE);
2909 return (Z_INSUFFICIENT_SPEC);
2910 }
2911 }
2912 if (fill_in_only)
2913 return (Z_OK);
2914 err = zonecfg_lookup_nwif(handle, nwiftab);
2915 return (err);
2916 }
2917
2918 static int
2919 fill_in_devtab(cmd_t *cmd, struct zone_devtab *devtab, boolean_t fill_in_only)
2920 {
3563 remove_mcap();
3564 return;
3565 case RT_ADMIN:
3566 remove_admin(cmd);
3567 return;
3568 default:
3569 zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
3570 long_usage(CMD_REMOVE, B_TRUE);
3571 usage(B_FALSE, HELP_RESOURCES);
3572 return;
3573 }
3574 }
3575
3576 static void
3577 remove_property(cmd_t *cmd)
3578 {
3579 char *prop_id;
3580 int err, res_type, prop_type;
3581 property_value_ptr_t pp;
3582 struct zone_rctlvaltab *rctlvaltab;
3583 struct zone_res_attrtab *np;
3584 complex_property_ptr_t cx;
3585
3586 res_type = resource_scope;
3587 prop_type = cmd->cmd_prop_name[0];
3588 if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) {
3589 long_usage(CMD_REMOVE, B_TRUE);
3590 return;
3591 }
3592
3593 if (cmd->cmd_prop_nv_pairs != 1) {
3594 long_usage(CMD_ADD, B_TRUE);
3595 return;
3596 }
3597
3598 if (initialize(B_TRUE) != Z_OK)
3599 return;
3600
3601 switch (res_type) {
3602 case RT_FS:
3603 if (prop_type != PT_OPTIONS) {
3624 err = zonecfg_remove_fs_option(&in_progress_fstab,
3625 prop_id);
3626 if (err != Z_OK)
3627 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3628 } else {
3629 list_property_ptr_t list;
3630
3631 for (list = pp->pv_list; list != NULL;
3632 list = list->lp_next) {
3633 prop_id = list->lp_simple;
3634 if (prop_id == NULL)
3635 break;
3636 err = zonecfg_remove_fs_option(
3637 &in_progress_fstab, prop_id);
3638 if (err != Z_OK)
3639 zone_perror(pt_to_str(prop_type), err,
3640 B_TRUE);
3641 }
3642 }
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;
3694 case RT_RCTL:
3695 if (prop_type != PT_VALUE) {
3696 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
3697 B_TRUE);
3698 long_usage(CMD_REMOVE, B_TRUE);
3699 usage(B_FALSE, HELP_PROPS);
3700 return;
3701 }
3702 pp = cmd->cmd_property_ptr[0];
3703 if (pp->pv_type != PROP_VAL_COMPLEX) {
3704 zerr(gettext("A %s value was expected here."),
3705 pvt_to_str(PROP_VAL_COMPLEX));
3706 saw_error = B_TRUE;
3707 return;
3708 }
3709 if ((rctlvaltab = alloc_rctlvaltab()) == NULL) {
3710 zone_perror(zone, Z_NOMEM, B_TRUE);
3711 exit(Z_ERR);
3712 }
3713 for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) {
3726 (void) strlcpy(rctlvaltab->zone_rctlval_action,
3727 cx->cp_value,
3728 sizeof (rctlvaltab->zone_rctlval_action));
3729 break;
3730 default:
3731 zone_perror(pt_to_str(prop_type),
3732 Z_NO_PROPERTY_TYPE, B_TRUE);
3733 long_usage(CMD_ADD, B_TRUE);
3734 usage(B_FALSE, HELP_PROPS);
3735 zonecfg_free_rctl_value_list(rctlvaltab);
3736 return;
3737 }
3738 }
3739 rctlvaltab->zone_rctlval_next = NULL;
3740 err = zonecfg_remove_rctl_value(&in_progress_rctltab,
3741 rctlvaltab);
3742 if (err != Z_OK)
3743 zone_perror(pt_to_str(prop_type), err, B_TRUE);
3744 zonecfg_free_rctl_value_list(rctlvaltab);
3745 return;
3746 default:
3747 zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
3748 long_usage(CMD_REMOVE, B_TRUE);
3749 usage(B_FALSE, HELP_RESOURCES);
3750 return;
3751 }
3752 }
3753
3754 void
3755 remove_func(cmd_t *cmd)
3756 {
3757 if (zone_is_read_only(CMD_REMOVE))
3758 return;
3759
3760 assert(cmd != NULL);
3761
3762 if (global_scope) {
3763 if (gz_invalid_resource(cmd->cmd_res_type)) {
3764 zerr(gettext("%s is not a valid resource for the "
3765 "global zone."), rt_to_str(cmd->cmd_res_type));
3798 case RT_DCPU:
3799 if (prop_type == PT_IMPORTANCE) {
3800 in_progress_psettab.zone_importance[0] = '\0';
3801 need_to_commit = B_TRUE;
3802 return;
3803 }
3804 break;
3805 case RT_MCAP:
3806 switch (prop_type) {
3807 case PT_PHYSICAL:
3808 remove_aliased_rctl(PT_PHYSICAL, ALIAS_MAXPHYSMEM);
3809 return;
3810 case PT_SWAP:
3811 remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP);
3812 return;
3813 case PT_LOCKED:
3814 remove_aliased_rctl(PT_LOCKED, ALIAS_MAXLOCKEDMEM);
3815 return;
3816 }
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;
3842 default:
3843 break;
3844 }
3845
3846 zone_perror(pt_to_str(prop_type), Z_CLEAR_DISALLOW, B_TRUE);
3847 }
3848
3849 static void
3850 clear_global(cmd_t *cmd)
3851 {
3852 int err, type;
3853
3854 if ((type = cmd->cmd_res_type) == RT_UNKNOWN) {
3855 long_usage(CMD_CLEAR, B_TRUE);
3856 return;
3857 }
3858
3859 if (initialize(B_TRUE) != Z_OK)
3860 return;
3861
4428
4429 if (force_set) {
4430 if (res_type != RT_ZONEPATH) {
4431 zerr(gettext("Only zonepath setting can be forced."));
4432 saw_error = B_TRUE;
4433 return;
4434 }
4435 if (!zonecfg_in_alt_root()) {
4436 zerr(gettext("Zonepath is changeable only in an "
4437 "alternate root."));
4438 saw_error = B_TRUE;
4439 return;
4440 }
4441 }
4442
4443 pp = cmd->cmd_property_ptr[0];
4444 /*
4445 * A nasty expression but not that complicated:
4446 * 1. fs options are simple or list (tested below)
4447 * 2. rctl value's are complex or list (tested below)
4448 * 3. net attr's are complex (tested below)
4449 * Anything else should be simple.
4450 */
4451 if (!(res_type == RT_FS && prop_type == PT_OPTIONS) &&
4452 !(res_type == RT_RCTL && prop_type == PT_VALUE) &&
4453 !(res_type == RT_NET && prop_type == PT_NPROP) &&
4454 (pp->pv_type != PROP_VAL_SIMPLE ||
4455 (prop_id = pp->pv_simple) == NULL)) {
4456 zerr(gettext("A %s value was expected here."),
4457 pvt_to_str(PROP_VAL_SIMPLE));
4458 saw_error = B_TRUE;
4459 return;
4460 }
4461 if (prop_type == PT_UNKNOWN) {
4462 long_usage(CMD_SET, B_TRUE);
4463 return;
4464 }
4465
4466 /*
4467 * Special case: the user can change the zone name prior to 'create';
4468 * if the zone already exists, we fall through letting initialize()
4469 * and the rest of the logic run.
4470 */
4471 if (res_type == RT_ZONENAME && got_handle == B_FALSE &&
4472 !state_atleast(ZONE_STATE_CONFIGURED)) {
4473 if ((err = zonecfg_validate_zonename(prop_id)) != Z_OK) {
4693 case RT_NET:
4694 switch (prop_type) {
4695 case PT_ADDRESS:
4696 case PT_ALLOWED_ADDRESS:
4697 if (validate_net_address_syntax(prop_id, B_FALSE)
4698 != Z_OK) {
4699 saw_error = B_TRUE;
4700 return;
4701 }
4702 set_in_progress_nwiftab_address(prop_id, prop_type);
4703 break;
4704 case PT_PHYSICAL:
4705 if (validate_net_physical_syntax(prop_id) != Z_OK) {
4706 saw_error = B_TRUE;
4707 return;
4708 }
4709 (void) strlcpy(in_progress_nwiftab.zone_nwif_physical,
4710 prop_id,
4711 sizeof (in_progress_nwiftab.zone_nwif_physical));
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;
4728 case PT_DEFROUTER:
4729 if (validate_net_address_syntax(prop_id, B_TRUE)
4730 != Z_OK) {
4731 saw_error = B_TRUE;
4732 return;
4733 }
4734 (void) strlcpy(in_progress_nwiftab.zone_nwif_defrouter,
4735 prop_id,
4736 sizeof (in_progress_nwiftab.zone_nwif_defrouter));
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;
4752 default:
4753 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4754 B_TRUE);
4755 long_usage(CMD_SET, B_TRUE);
4756 usage(B_FALSE, HELP_PROPS);
4757 return;
4758 }
4759 return;
4760 case RT_DEVICE:
4761 switch (prop_type) {
4762 case PT_MATCH:
4763 (void) strlcpy(in_progress_devtab.zone_dev_match,
4764 prop_id,
4765 sizeof (in_progress_devtab.zone_dev_match));
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;
4781 default:
4782 zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
4783 B_TRUE);
4784 long_usage(CMD_SET, B_TRUE);
4785 usage(B_FALSE, HELP_PROPS);
4786 return;
4787 }
4788 return;
4789 case RT_RCTL:
4790 switch (prop_type) {
4791 case PT_NAME:
4792 if (!zonecfg_valid_rctlname(prop_id)) {
4793 zerr(gettext("'%s' is not a valid zone %s "
4794 "name."), prop_id, rt_to_str(RT_RCTL));
4795 return;
4796 }
4797 (void) strlcpy(in_progress_rctltab.zone_rctl_name,
4798 prop_id,
4799 sizeof (in_progress_rctltab.zone_rctl_name));
4800 break;
5300 strcmp(user.zone_fs_type, lookup.zone_fs_type) != 0)
5301 goto loopend; /* no match */
5302 output_fs(fp, &lookup);
5303 output = B_TRUE;
5304 loopend:
5305 zonecfg_free_fs_option_list(lookup.zone_fs_options);
5306 }
5307 (void) zonecfg_endfsent(handle);
5308 /*
5309 * If a property n/v pair was specified, warn the user if there was
5310 * nothing to output.
5311 */
5312 if (!output && cmd->cmd_prop_nv_pairs > 0)
5313 (void) printf(gettext("No such %s resource.\n"),
5314 rt_to_str(RT_FS));
5315 }
5316
5317 static void
5318 output_net(FILE *fp, struct zone_nwiftab *nwiftab)
5319 {
5320 struct zone_res_attrtab *np;
5321
5322 (void) fprintf(fp, "%s:\n", rt_to_str(RT_NET));
5323 output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE);
5324 output_prop(fp, PT_ALLOWED_ADDRESS,
5325 nwiftab->zone_nwif_allowed_address, B_TRUE);
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 }
5339 }
5340
5341 static void
5342 info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5343 {
5344 struct zone_nwiftab lookup, user;
5345 boolean_t output = B_FALSE;
5346
5347 if (zonecfg_setnwifent(handle) != Z_OK)
5348 return;
5349 while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
5350 if (cmd->cmd_prop_nv_pairs == 0) {
5351 output_net(fp, &lookup);
5352 continue;
5353 }
5354 if (fill_in_nwiftab(cmd, &user, B_TRUE) != Z_OK)
5355 continue;
5356 if (strlen(user.zone_nwif_physical) > 0 &&
5357 strcmp(user.zone_nwif_physical,
5358 lookup.zone_nwif_physical) != 0)
5361 if (strlen(user.zone_nwif_address) > 0 &&
5362 !zonecfg_same_net_address(user.zone_nwif_address,
5363 lookup.zone_nwif_address))
5364 continue; /* no match */
5365 output_net(fp, &lookup);
5366 output = B_TRUE;
5367 }
5368 (void) zonecfg_endnwifent(handle);
5369 /*
5370 * If a property n/v pair was specified, warn the user if there was
5371 * nothing to output.
5372 */
5373 if (!output && cmd->cmd_prop_nv_pairs > 0)
5374 (void) printf(gettext("No such %s resource.\n"),
5375 rt_to_str(RT_NET));
5376 }
5377
5378 static void
5379 output_dev(FILE *fp, struct zone_devtab *devtab)
5380 {
5381 struct zone_res_attrtab *np;
5382
5383 (void) fprintf(fp, "%s:\n", rt_to_str(RT_DEVICE));
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 }
5393 }
5394
5395 static void
5396 info_dev(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
5397 {
5398 struct zone_devtab lookup, user;
5399 boolean_t output = B_FALSE;
5400
5401 if (zonecfg_setdevent(handle) != Z_OK)
5402 return;
5403 while (zonecfg_getdevent(handle, &lookup) == Z_OK) {
5404 if (cmd->cmd_prop_nv_pairs == 0) {
5405 output_dev(fp, &lookup);
5406 continue;
5407 }
5408 if (fill_in_devtab(cmd, &user, B_TRUE) != Z_OK)
5409 continue;
5410 if (strlen(user.zone_dev_match) > 0 &&
5411 strcmp(user.zone_dev_match, lookup.zone_dev_match) != 0)
5412 continue; /* no match */
6399 pt_to_str(PT_USER),
6400 admintab.zone_admin_user);
6401 ret_val = Z_BAD_PROPERTY;
6402 }
6403 if ((ret_val == Z_OK) && (!zonecfg_valid_auths(
6404 admintab.zone_admin_auths, zone))) {
6405 ret_val = Z_BAD_PROPERTY;
6406 }
6407 }
6408 (void) zonecfg_endadminent(handle);
6409
6410 if (!global_scope) {
6411 zerr(gettext("resource specification incomplete"));
6412 saw_error = B_TRUE;
6413 if (ret_val == Z_OK)
6414 ret_val = Z_INSUFFICIENT_SPEC;
6415 }
6416
6417 if (save) {
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
6425 if ((ret_val = zonecfg_save(handle)) == Z_OK) {
6426 need_to_commit = B_FALSE;
6427 (void) strlcpy(revert_zone, zone,
6428 sizeof (revert_zone));
6429 }
6430 } else {
6431 zerr(gettext("Zone %s failed to verify"), zone);
6432 }
6433 }
6434 if (ret_val != Z_OK)
6435 zone_perror(zone, ret_val, B_TRUE);
6436 }
6437
6438 void
6439 cancel_func(cmd_t *cmd)
6440 {
6441 int arg;
6442 boolean_t arg_err = B_FALSE;
6443
6444 assert(cmd != NULL);
|