diff options
Diffstat (limited to 'usr/src/cmd/zonecfg')
-rw-r--r-- | usr/src/cmd/zonecfg/Makefile | 3 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg.c | 889 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg.h | 13 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg_grammar.y | 89 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg_lex.l | 29 |
5 files changed, 823 insertions, 200 deletions
diff --git a/usr/src/cmd/zonecfg/Makefile b/usr/src/cmd/zonecfg/Makefile index ae8f5c11d1..94d725776b 100644 --- a/usr/src/cmd/zonecfg/Makefile +++ b/usr/src/cmd/zonecfg/Makefile @@ -27,6 +27,7 @@ PROG= zonecfg OBJS= zonecfg.o zonecfg_lex.o zonecfg_grammar.tab.o include ../Makefile.cmd +include ../Makefile.ctf # zonecfg has a name clash with main() and libl.so.1. However, zonecfg must # still export a number of "yy*" (libl) interfaces. Reduce all other symbols @@ -36,7 +37,7 @@ MAPOPTS = $(MAPFILES:%=-M%) LFLAGS = -t YFLAGS = -d -b zonecfg_grammar -LDLIBS += -lzonecfg -ll -lnsl -ltecla -lzfs -lbrand -ldladm -linetutil +LDLIBS += -lzonecfg -ll -lnsl -ltecla -lzfs -lbrand -ldladm -linetutil -luuid CPPFLAGS += -I. LDFLAGS += $(MAPOPTS) CLEANFILES += zonecfg_lex.c zonecfg_grammar.tab.c zonecfg_grammar.tab.h diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c index 3dbec383bf..235019ef46 100644 --- a/usr/src/cmd/zonecfg/zonecfg.c +++ b/usr/src/cmd/zonecfg/zonecfg.c @@ -23,6 +23,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. * Copyright 2014 Gary Mills + * Copyright 2013, Joyent Inc. All rights reserved. */ /* @@ -79,6 +80,7 @@ #include <libinetutil.h> #include <pwd.h> #include <inet/ip.h> +#include <uuid/uuid.h> #include <libzonecfg.h> #include "zonecfg.h" @@ -126,7 +128,7 @@ extern int lex_lineno; #define SHELP_REMOVE "remove [-F] <resource-type> " \ "[ <property-name>=<property-value> ]*\n" \ "\t(global scope)\n" \ - "remove <property-name> <property-value>\n" \ + "remove [-F] <property-name> <property-value>\n" \ "\t(resource scope)" #define SHELP_REVERT "revert [-F]" #define SHELP_SELECT "select <resource-type> { <property-name>=" \ @@ -187,6 +189,8 @@ char *res_types[] = { "admin", "fs-allowed", ALIAS_MAXPROCS, + ALIAS_ZFSPRI, + "uuid", NULL }; @@ -234,6 +238,12 @@ char *prop_types[] = { "fs-allowed", ALIAS_MAXPROCS, "allowed-address", + ALIAS_ZFSPRI, + "mac-addr", + "vlan-id", + "global-nic", + "property", + "uuid", NULL }; @@ -299,6 +309,7 @@ static const char *clear_cmds[] = { "clear " ALIAS_MAXSEMIDS, "clear " ALIAS_SHARES, "clear " ALIAS_MAXPROCS, + "clear " ALIAS_ZFSPRI, NULL }; @@ -349,6 +360,8 @@ static const char *set_cmds[] = { "set hostid=", "set fs-allowed=", "set " ALIAS_MAXPROCS "=", + "set " ALIAS_ZFSPRI "=", + "set uuid=", NULL }; @@ -381,6 +394,7 @@ static const char *info_cmds[] = { "info admin", "info fs-allowed", "info max-processes", + "info uuid", NULL }; @@ -406,9 +420,20 @@ static const char *net_res_scope_cmds[] = { "exit", "help", "info", + "add property ", + "clear allowed-address", + "clear defrouter", + "clear global-nic", + "clear mac-addr", + "clear vlan-id", + "remove property ", "set address=", - "set physical=", + "set allowed-address=", "set defrouter=", + "set global-nic=", + "set mac-addr=", + "set physical=", + "set vlan-id=", NULL }; @@ -418,6 +443,7 @@ static const char *device_res_scope_cmds[] = { "exit", "help", "info", + "add property ", "set match=", NULL }; @@ -525,6 +551,7 @@ static zone_dochandle_t handle; /* used all over the place */ static char zone[ZONENAME_MAX]; static char revert_zone[ZONENAME_MAX]; +static char new_uuid[UUID_PRINTABLE_STRING_LENGTH]; /* global brand operations */ static brand_handle_t brand; @@ -579,7 +606,6 @@ static struct zone_rctltab old_rctltab, in_progress_rctltab; static struct zone_attrtab old_attrtab, in_progress_attrtab; static struct zone_dstab old_dstab, in_progress_dstab; static struct zone_psettab old_psettab, in_progress_psettab; -static struct zone_mcaptab old_mcaptab, in_progress_mcaptab; static struct zone_admintab old_admintab, in_progress_admintab; static GetLine *gl; /* The gl_get_line() resource object */ @@ -1078,11 +1104,20 @@ usage(boolean_t verbose, uint_t flags) (void) fprintf(fp, gettext("Valid commands:\n")); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS), gettext("<IP-address>")); + (void) fprintf(fp, "\t%s %s (%s=<value>,%s=<value>)\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), pt_to_str(PT_VALUE)); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_ALLOWED_ADDRESS), gettext("<IP-address>")); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_PHYSICAL), gettext("<interface>")); + (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_MAC), gettext("<mac-address>")); + (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_GNIC), gettext("<global zone NIC>")); + (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_VLANID), gettext("<vlan ID>")); (void) fprintf(fp, gettext("See ifconfig(1M) for " "details of the <interface> string.\n")); (void) fprintf(fp, gettext("%s %s is valid " @@ -1090,10 +1125,12 @@ usage(boolean_t verbose, uint_t flags) "must not be set.\n"), cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS), pt_to_str(PT_IPTYPE), gettext("shared")); - (void) fprintf(fp, gettext("%s %s is valid " - "if the %s property is set to %s, otherwise it " - "must not be set.\n"), - cmd_to_str(CMD_SET), pt_to_str(PT_ALLOWED_ADDRESS), + (void) fprintf(fp, gettext("%s (%s, %s, %s, %s) are " + "valid if the %s property is set to %s, otherwise " + "they must not be set.\n"), + cmd_to_str(CMD_SET), + pt_to_str(PT_ALLOWED_ADDRESS), pt_to_str(PT_MAC), + pt_to_str(PT_VLANID), pt_to_str(PT_GNIC), pt_to_str(PT_IPTYPE), gettext("exclusive")); (void) fprintf(fp, gettext("\t%s %s=%s\n%s %s " "is valid if the %s or %s property is set, " @@ -1109,6 +1146,9 @@ usage(boolean_t verbose, uint_t flags) "used to configure a device node.\n"), rt_to_str(resource_scope)); (void) fprintf(fp, gettext("Valid commands:\n")); + (void) fprintf(fp, "\t%s %s (%s=<value>,%s=<value>)\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), pt_to_str(PT_VALUE)); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_MATCH), gettext("<device-path>")); break; @@ -1240,10 +1280,12 @@ usage(boolean_t verbose, uint_t flags) if (flags & HELP_USAGE) { (void) fprintf(fp, "%s:\t%s %s\n", gettext("usage"), execname, cmd_to_str(CMD_HELP)); - (void) fprintf(fp, "\t%s -z <zone>\t\t\t(%s)\n", + (void) fprintf(fp, "\t%s {-z <zone>|-u <uuid>}\t\t\t(%s)\n", execname, gettext("interactive")); - (void) fprintf(fp, "\t%s -z <zone> <command>\n", execname); - (void) fprintf(fp, "\t%s -z <zone> -f <command-file>\n", + (void) fprintf(fp, "\t%s {-z <zone>|-u <uuid>} <command>\n", + execname); + (void) fprintf(fp, + "\t%s {-z <zone>|-u <uuid>} -f <command-file>\n", execname); } if (flags & HELP_SUBCMDS) { @@ -1332,15 +1374,22 @@ usage(boolean_t verbose, uint_t flags) pt_to_str(PT_MAXSEMIDS)); (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), pt_to_str(PT_SHARES)); + (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), + pt_to_str(PT_UUID)); + (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), + pt_to_str(PT_ZFSPRI)); (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s\n", rt_to_str(RT_FS), pt_to_str(PT_DIR), pt_to_str(PT_SPECIAL), pt_to_str(PT_RAW), pt_to_str(PT_TYPE), pt_to_str(PT_OPTIONS)); - (void) fprintf(fp, "\t%s\t\t%s, %s, %s|%s\n", rt_to_str(RT_NET), + (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s, %s, %s %s\n", + rt_to_str(RT_NET), pt_to_str(PT_ADDRESS), pt_to_str(PT_ALLOWED_ADDRESS), - pt_to_str(PT_PHYSICAL), pt_to_str(PT_DEFROUTER)); - (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE), - pt_to_str(PT_MATCH)); + pt_to_str(PT_GNIC), pt_to_str(PT_MAC), + pt_to_str(PT_PHYSICAL), pt_to_str(PT_NPROP), + pt_to_str(PT_VLANID), pt_to_str(PT_DEFROUTER)); + (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_DEVICE), + pt_to_str(PT_MATCH), pt_to_str(PT_NPROP)); (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL), pt_to_str(PT_NAME), pt_to_str(PT_VALUE)); (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR), @@ -1395,6 +1444,9 @@ initialize(boolean_t handle_expected) if (zonecfg_check_handle(handle) != Z_OK) { if ((err = zonecfg_get_handle(zone, handle)) == Z_OK) { got_handle = B_TRUE; + + (void) zonecfg_fix_obsolete(handle); + if (zonecfg_get_brand(handle, brandname, sizeof (brandname)) != Z_OK) { zerr("Zone %s is inconsistent: missing " @@ -1662,6 +1714,7 @@ create_func(cmd_t *cmd) boolean_t force = B_FALSE; boolean_t attach = B_FALSE; boolean_t arg_err = B_FALSE; + uuid_t uuid; assert(cmd != NULL); @@ -1669,7 +1722,7 @@ create_func(cmd_t *cmd) (void) strlcpy(zone_template, "SUNWdefault", sizeof (zone_template)); optind = 0; - while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?a:bFt:")) + while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?a:bFt:X")) != EOF) { switch (arg) { case '?': @@ -1695,6 +1748,17 @@ create_func(cmd_t *cmd) (void) strlcpy(zone_template, optarg, sizeof (zone_template)); break; + case 'X': + (void) snprintf(zone_template, sizeof (zone_template), + "%s/%s.xml", ZONE_CONFIG_ROOT, zone); + err = zonecfg_get_xml_handle(zone_template, handle); + if (err != Z_OK) { + zone_perror(execname, err, B_TRUE); + exit(Z_ERR); + } + got_handle = B_TRUE; + need_to_commit = B_TRUE; + return; default: short_usage(CMD_CREATE); arg_err = B_TRUE; @@ -1751,6 +1815,10 @@ create_func(cmd_t *cmd) zonecfg_fini_handle(handle); handle = tmphandle; got_handle = B_TRUE; + + /* Allocate a new uuid for this new zone */ + uuid_generate(uuid); + uuid_unparse(uuid, new_uuid); } /* @@ -1797,8 +1865,8 @@ export_func(cmd_t *cmd) struct zone_rctltab rctltab; struct zone_dstab dstab; struct zone_psettab psettab; - struct zone_mcaptab mcaptab; struct zone_rctlvaltab *valptr; + struct zone_res_attrtab *rap; struct zone_admintab admintab; int err, arg; char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN]; @@ -1811,6 +1879,7 @@ export_func(cmd_t *cmd) FILE *of; boolean_t autoboot; zone_iptype_t iptype; + uuid_t uuid; boolean_t need_to_close = B_FALSE; boolean_t arg_err = B_FALSE; @@ -1921,6 +1990,14 @@ export_func(cmd_t *cmd) pt_to_str(PT_FS_ALLOWED), fsallowedp); } + if (zonecfg_get_uuid(zone, uuid) == Z_OK && !uuid_is_null(uuid)) { + char suuid[UUID_PRINTABLE_STRING_LENGTH]; + + uuid_unparse(uuid, suuid); + (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_UUID), suuid); + } + if ((err = zonecfg_setfsent(handle)) != Z_OK) { zone_perror(zone, err, B_FALSE); goto done; @@ -1968,7 +2045,17 @@ export_func(cmd_t *cmd) export_prop(of, PT_ALLOWED_ADDRESS, nwiftab.zone_nwif_allowed_address); export_prop(of, PT_PHYSICAL, nwiftab.zone_nwif_physical); + export_prop(of, PT_MAC, nwiftab.zone_nwif_mac); + export_prop(of, PT_VLANID, nwiftab.zone_nwif_vlan_id); + export_prop(of, PT_GNIC, nwiftab.zone_nwif_gnic); export_prop(of, PT_DEFROUTER, nwiftab.zone_nwif_defrouter); + for (rap = nwiftab.zone_nwif_attrp; rap != NULL; + rap = rap->zone_res_attr_next) { + fprintf(of, "%s %s (%s=%s,%s=\"%s\")\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), rap->zone_res_attr_name, + pt_to_str(PT_VALUE), rap->zone_res_attr_value); + } (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); } (void) zonecfg_endnwifent(handle); @@ -1981,21 +2068,17 @@ export_func(cmd_t *cmd) (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), rt_to_str(RT_DEVICE)); export_prop(of, PT_MATCH, devtab.zone_dev_match); + for (rap = devtab.zone_dev_attrp; rap != NULL; + rap = rap->zone_res_attr_next) { + fprintf(of, "%s %s (%s=%s,%s=\"%s\")\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), rap->zone_res_attr_name, + pt_to_str(PT_VALUE), rap->zone_res_attr_value); + } (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); } (void) zonecfg_enddevent(handle); - if (zonecfg_getmcapent(handle, &mcaptab) == Z_OK) { - char buf[128]; - - (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), - rt_to_str(RT_MCAP)); - bytes_to_units(mcaptab.zone_physmem_cap, buf, sizeof (buf)); - (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), - pt_to_str(PT_PHYSICAL), buf); - (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); - } - if ((err = zonecfg_setrctlent(handle)) != Z_OK) { zone_perror(zone, err, B_FALSE); goto done; @@ -2149,7 +2232,6 @@ add_resource(cmd_t *cmd) { int type; struct zone_psettab tmp_psettab; - struct zone_mcaptab tmp_mcaptab; uint64_t tmp; uint64_t tmp_mcap; char pool[MAXNAMELEN]; @@ -2241,9 +2323,10 @@ add_resource(cmd_t *cmd) * Make sure there isn't already a mem-cap entry or max-swap * or max-locked rctl. */ - if (zonecfg_lookup_mcap(handle, &tmp_mcaptab) == Z_OK || - zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp_mcap) - == Z_OK || + if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, + &tmp_mcap) == Z_OK || + zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, + &tmp_mcap) == Z_OK || zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &tmp_mcap) == Z_OK) { zerr(gettext("The %s resource or a related resource " @@ -2256,7 +2339,6 @@ add_resource(cmd_t *cmd) "to even the root user; " "this could render the system impossible\n" "to administer. Please use caution.")); - bzero(&in_progress_mcaptab, sizeof (in_progress_mcaptab)); return; case RT_ADMIN: bzero(&in_progress_admintab, sizeof (in_progress_admintab)); @@ -2359,6 +2441,68 @@ bad: zonecfg_free_rctl_value_list(rctlvaltab); } +/* + * Resource attribute ("property" resource embedded on net or dev resource) + */ +static void +do_res_attr(struct zone_res_attrtab **headp, complex_property_ptr_t cpp) +{ + complex_property_ptr_t cp; + struct zone_res_attrtab *np; + int err; + boolean_t seen_name = B_FALSE, seen_value = B_FALSE; + + if ((np = calloc(1, sizeof (struct zone_res_attrtab))) == NULL) { + zone_perror(zone, Z_NOMEM, B_TRUE); + exit(Z_ERR); + } + + for (cp = cpp; cp != NULL; cp = cp->cp_next) { + switch (cp->cp_type) { + case PT_NAME: + if (seen_name) { + zerr(gettext("%s already specified"), + pt_to_str(PT_NAME)); + goto bad; + } + (void) strlcpy(np->zone_res_attr_name, cp->cp_value, + sizeof (np->zone_res_attr_name)); + seen_name = B_TRUE; + break; + case PT_VALUE: + if (seen_value) { + zerr(gettext("%s already specified"), + pt_to_str(PT_VALUE)); + goto bad; + } + (void) strlcpy(np->zone_res_attr_value, cp->cp_value, + sizeof (np->zone_res_attr_value)); + seen_value = B_TRUE; + break; + default: + zone_perror(pt_to_str(PT_NPROP), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_ADD, B_TRUE); + usage(B_FALSE, HELP_PROPS); + zonecfg_free_res_attr_list(np); + return; + } + } + + if (!seen_name) + zerr(gettext("%s not specified"), pt_to_str(PT_NAME)); + if (!seen_value) + zerr(gettext("%s not specified"), pt_to_str(PT_VALUE)); + + err = zonecfg_add_res_attr(headp, np); + if (err != Z_OK) + zone_perror(pt_to_str(PT_NPROP), err, B_TRUE); + return; + +bad: + zonecfg_free_res_attr_list(np); +} + static void add_property(cmd_t *cmd) { @@ -2426,6 +2570,44 @@ add_property(cmd_t *cmd) } } return; + case RT_NET: + if (prop_type != PT_NPROP) { + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_ADD, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + pp = cmd->cmd_property_ptr[0]; + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + + do_res_attr(&(in_progress_nwiftab.zone_nwif_attrp), + pp->pv_complex); + return; + case RT_DEVICE: + if (prop_type != PT_NPROP) { + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_ADD, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + pp = cmd->cmd_property_ptr[0]; + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + + do_res_attr(&(in_progress_devtab.zone_dev_attrp), + pp->pv_complex); + return; case RT_RCTL: if (prop_type != PT_VALUE) { zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, @@ -2470,7 +2652,7 @@ static boolean_t gz_invalid_rt_property(int type) { return (global_zone && (type == RT_ZONENAME || type == RT_ZONEPATH || - type == RT_AUTOBOOT || type == RT_LIMITPRIV || + type == RT_AUTOBOOT || type == RT_LIMITPRIV || type == RT_UUID || type == RT_BOOTARGS || type == RT_BRAND || type == RT_SCHED || type == RT_IPTYPE || type == RT_HOSTID || type == RT_FS_ALLOWED)); } @@ -2479,7 +2661,7 @@ static boolean_t gz_invalid_property(int type) { return (global_zone && (type == PT_ZONENAME || type == PT_ZONEPATH || - type == PT_AUTOBOOT || type == PT_LIMITPRIV || + type == PT_AUTOBOOT || type == PT_LIMITPRIV || type == PT_UUID || type == PT_BOOTARGS || type == PT_BRAND || type == PT_SCHED || type == PT_IPTYPE || type == PT_HOSTID || type == PT_FS_ALLOWED)); } @@ -2530,8 +2712,9 @@ add_func(cmd_t *cmd) resource_scope = cmd->cmd_res_type; end_op = CMD_ADD; add_resource(cmd); - } else + } else { add_property(cmd); + } } /* @@ -2696,6 +2879,32 @@ fill_in_fstab(cmd_t *cmd, struct zone_fstab *fstab, boolean_t fill_in_only) return (zonecfg_lookup_filesystem(handle, fstab)); } +/* + * Turn an addr that looks like f:2:0:44:5:6C into 0f:02:00:44:05:6c + * We're expecting a dst of at least MAXMACADDRLEN size here. + */ +static void +normalize_mac_addr(char *dst, const char *src, int len) +{ + char *p, *e, *sep = ""; + long n; + char buf[MAXMACADDRLEN], tmp[4]; + + *dst = '\0'; + (void) strlcpy(buf, src, sizeof (buf)); + p = strtok(buf, ":"); + while (p != NULL) { + n = strtol(p, &e, 16); + if (*e != NULL || n > 0xff) + return; + (void) snprintf(tmp, sizeof (tmp), "%s%02x", sep, n); + (void) strlcat(dst, tmp, len); + + sep = ":"; + p = strtok(NULL, ":"); + } +} + static int fill_in_nwiftab(cmd_t *cmd, struct zone_nwiftab *nwiftab, boolean_t fill_in_only) @@ -2729,6 +2938,21 @@ fill_in_nwiftab(cmd_t *cmd, struct zone_nwiftab *nwiftab, pp->pv_simple, sizeof (nwiftab->zone_nwif_physical)); break; + case PT_MAC: + normalize_mac_addr(nwiftab->zone_nwif_mac, + pp->pv_simple, + sizeof (nwiftab->zone_nwif_mac)); + break; + case PT_VLANID: + (void) strlcpy(nwiftab->zone_nwif_vlan_id, + pp->pv_simple, + sizeof (nwiftab->zone_nwif_vlan_id)); + break; + case PT_GNIC: + (void) strlcpy(nwiftab->zone_nwif_gnic, + pp->pv_simple, + sizeof (nwiftab->zone_nwif_gnic)); + break; case PT_DEFROUTER: (void) strlcpy(nwiftab->zone_nwif_defrouter, pp->pv_simple, @@ -2979,6 +3203,8 @@ prompt_remove_resource(cmd_t *cmd, char *rsrc) num = zonecfg_num_resources(handle, rsrc); if (num == 0) { + if (force) + return (B_TRUE); z_cmd_rt_perror(CMD_REMOVE, cmd->cmd_res_type, Z_NO_ENTRY, B_TRUE); return (B_FALSE); @@ -3007,7 +3233,7 @@ prompt_remove_resource(cmd_t *cmd, char *rsrc) } static void -remove_fs(cmd_t *cmd) +remove_fs(cmd_t *cmd, boolean_t force) { int err; @@ -3016,13 +3242,16 @@ remove_fs(cmd_t *cmd) struct zone_fstab fstab; if ((err = fill_in_fstab(cmd, &fstab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); return; } - if ((err = zonecfg_delete_filesystem(handle, &fstab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); - else + if ((err = zonecfg_delete_filesystem(handle, &fstab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); + } else { need_to_commit = B_TRUE; + } zonecfg_free_fs_option_list(fstab.zone_fs_options); return; } @@ -3041,7 +3270,7 @@ remove_fs(cmd_t *cmd) } static void -remove_net(cmd_t *cmd) +remove_net(cmd_t *cmd, boolean_t force) { int err; @@ -3050,13 +3279,18 @@ remove_net(cmd_t *cmd) struct zone_nwiftab nwiftab; if ((err = fill_in_nwiftab(cmd, &nwiftab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, + B_TRUE); return; } - if ((err = zonecfg_delete_nwif(handle, &nwiftab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE); - else + if ((err = zonecfg_delete_nwif(handle, &nwiftab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3074,7 +3308,7 @@ remove_net(cmd_t *cmd) } static void -remove_device(cmd_t *cmd) +remove_device(cmd_t *cmd, boolean_t force) { int err; @@ -3083,13 +3317,18 @@ remove_device(cmd_t *cmd) struct zone_devtab devtab; if ((err = fill_in_devtab(cmd, &devtab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, + B_TRUE); return; } - if ((err = zonecfg_delete_dev(handle, &devtab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE); - else + if ((err = zonecfg_delete_dev(handle, &devtab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3107,7 +3346,7 @@ remove_device(cmd_t *cmd) } static void -remove_attr(cmd_t *cmd) +remove_attr(cmd_t *cmd, boolean_t force) { int err; @@ -3116,13 +3355,18 @@ remove_attr(cmd_t *cmd) struct zone_attrtab attrtab; if ((err = fill_in_attrtab(cmd, &attrtab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, + B_TRUE); return; } - if ((err = zonecfg_delete_attr(handle, &attrtab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE); - else + if ((err = zonecfg_delete_attr(handle, &attrtab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3140,7 +3384,7 @@ remove_attr(cmd_t *cmd) } static void -remove_dataset(cmd_t *cmd) +remove_dataset(cmd_t *cmd, boolean_t force) { int err; @@ -3149,13 +3393,18 @@ remove_dataset(cmd_t *cmd) struct zone_dstab dstab; if ((err = fill_in_dstab(cmd, &dstab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, + B_TRUE); return; } - if ((err = zonecfg_delete_ds(handle, &dstab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE); - else + if ((err = zonecfg_delete_ds(handle, &dstab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3173,7 +3422,7 @@ remove_dataset(cmd_t *cmd) } static void -remove_rctl(cmd_t *cmd) +remove_rctl(cmd_t *cmd, boolean_t force) { int err; @@ -3182,13 +3431,18 @@ remove_rctl(cmd_t *cmd) struct zone_rctltab rctltab; if ((err = fill_in_rctltab(cmd, &rctltab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, + B_TRUE); return; } - if ((err = zonecfg_delete_rctl(handle, &rctltab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE); - else + if ((err = zonecfg_delete_rctl(handle, &rctltab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); return; } @@ -3207,72 +3461,90 @@ remove_rctl(cmd_t *cmd) } static void -remove_pset() +remove_pset(boolean_t force) { int err; struct zone_psettab psettab; if ((err = zonecfg_lookup_pset(handle, &psettab)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); return; } - if ((err = zonecfg_delete_pset(handle)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); - else + if ((err = zonecfg_delete_pset(handle)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); + } else { need_to_commit = B_TRUE; + } } static void -remove_pcap() +remove_pcap(boolean_t force) { int err; uint64_t tmp; if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp) != Z_OK) { - zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_PCAP), - zonecfg_strerror(Z_NO_RESOURCE_TYPE)); - saw_error = B_TRUE; + if (!force) { + zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), + rt_to_str(RT_PCAP), + zonecfg_strerror(Z_NO_RESOURCE_TYPE)); + saw_error = B_TRUE; + } return; } - if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_CPUCAP)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_PCAP, err, B_TRUE); - else + if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_CPUCAP)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_PCAP, err, B_TRUE); + } else { need_to_commit = B_TRUE; + } } static void -remove_mcap() +remove_mcap(boolean_t force) { int err, res1, res2, res3; uint64_t tmp; - struct zone_mcaptab mcaptab; boolean_t revert = B_FALSE; - res1 = zonecfg_lookup_mcap(handle, &mcaptab); + res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &tmp); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp); res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &tmp); /* if none of these exist, there is no resource to remove */ if (res1 != Z_OK && res2 != Z_OK && res3 != Z_OK) { - zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_MCAP), - zonecfg_strerror(Z_NO_RESOURCE_TYPE)); - saw_error = B_TRUE; + if (!force) { + zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), + rt_to_str(RT_MCAP), + zonecfg_strerror(Z_NO_RESOURCE_TYPE)); + saw_error = B_TRUE; + } return; } if (res1 == Z_OK) { - if ((err = zonecfg_delete_mcap(handle)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE); - revert = B_TRUE; + if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXPHYSMEM)) + != Z_OK) { + if (!force) { + z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, + B_TRUE); + revert = B_TRUE; + } } else { need_to_commit = B_TRUE; } } + if (res2 == Z_OK) { if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXSWAP)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE); - revert = B_TRUE; + if (!force) { + z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, + B_TRUE); + revert = B_TRUE; + } } else { need_to_commit = B_TRUE; } @@ -3280,8 +3552,11 @@ remove_mcap() if (res3 == Z_OK) { if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE); - revert = B_TRUE; + if (!force) { + z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, + B_TRUE); + revert = B_TRUE; + } } else { need_to_commit = B_TRUE; } @@ -3292,7 +3567,7 @@ remove_mcap() } static void -remove_admin(cmd_t *cmd) +remove_admin(cmd_t *cmd, boolean_t force) { int err; @@ -3301,34 +3576,33 @@ remove_admin(cmd_t *cmd) struct zone_admintab admintab; if ((err = fill_in_admintab(cmd, &admintab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, - err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, err, + B_TRUE); return; } if ((err = zonecfg_delete_admin(handle, &admintab, - zone)) - != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, - err, B_TRUE); - else + zone)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; - } else { - /* - * unqualified admin removal. - * remove all admins but prompt if more - * than one. - */ - if (!prompt_remove_resource(cmd, "admin")) - return; - - if ((err = zonecfg_delete_admins(handle, zone)) - != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, - err, B_TRUE); - else - need_to_commit = B_TRUE; } + + /* + * unqualified admin removal. + * remove all admins but prompt if more than one. + */ + if (!prompt_remove_resource(cmd, "admin")) + return; + + if ((err = zonecfg_delete_admins(handle, zone)) != Z_OK) + z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, err, B_TRUE); + else + need_to_commit = B_TRUE; } static void @@ -3337,6 +3611,7 @@ remove_resource(cmd_t *cmd) int type; int arg; boolean_t arg_err = B_FALSE; + boolean_t force = B_FALSE; if ((type = cmd->cmd_res_type) == RT_UNKNOWN) { long_usage(CMD_REMOVE, B_TRUE); @@ -3351,6 +3626,7 @@ remove_resource(cmd_t *cmd) arg_err = B_TRUE; break; case 'F': + force = B_TRUE; break; default: short_usage(CMD_REMOVE); @@ -3366,34 +3642,34 @@ remove_resource(cmd_t *cmd) switch (type) { case RT_FS: - remove_fs(cmd); + remove_fs(cmd, force); return; case RT_NET: - remove_net(cmd); + remove_net(cmd, force); return; case RT_DEVICE: - remove_device(cmd); + remove_device(cmd, force); return; case RT_RCTL: - remove_rctl(cmd); + remove_rctl(cmd, force); return; case RT_ATTR: - remove_attr(cmd); + remove_attr(cmd, force); return; case RT_DATASET: - remove_dataset(cmd); + remove_dataset(cmd, force); return; case RT_DCPU: - remove_pset(); + remove_pset(force); return; case RT_PCAP: - remove_pcap(); + remove_pcap(force); return; case RT_MCAP: - remove_mcap(); + remove_mcap(force); return; case RT_ADMIN: - remove_admin(cmd); + remove_admin(cmd, force); return; default: zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE); @@ -3410,7 +3686,27 @@ remove_property(cmd_t *cmd) int err, res_type, prop_type; property_value_ptr_t pp; struct zone_rctlvaltab *rctlvaltab; + struct zone_res_attrtab *np; complex_property_ptr_t cx; + int arg; + boolean_t force = B_FALSE; + boolean_t arg_err = B_FALSE; + + optind = 0; + while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) { + switch (arg) { + case 'F': + force = B_TRUE; + break; + default: + arg_err = B_TRUE; + break; + } + } + if (arg_err) { + saw_error = B_TRUE; + return; + } res_type = resource_scope; prop_type = cmd->cmd_prop_name[0]; @@ -3452,7 +3748,7 @@ remove_property(cmd_t *cmd) prop_id = pp->pv_simple; err = zonecfg_remove_fs_option(&in_progress_fstab, prop_id); - if (err != Z_OK) + if (err != Z_OK && !force) zone_perror(pt_to_str(prop_type), err, B_TRUE); } else { list_property_ptr_t list; @@ -3464,12 +3760,62 @@ remove_property(cmd_t *cmd) break; err = zonecfg_remove_fs_option( &in_progress_fstab, prop_id); - if (err != Z_OK) + if (err != Z_OK && !force) zone_perror(pt_to_str(prop_type), err, B_TRUE); } } return; + case RT_NET: /* FALLTHRU */ + case RT_DEVICE: + if (prop_type != PT_NPROP) { + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_REMOVE, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + pp = cmd->cmd_property_ptr[0]; + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + + np = alloca(sizeof (struct zone_res_attrtab)); + for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) { + switch (cx->cp_type) { + case PT_NAME: + (void) strlcpy(np->zone_res_attr_name, + cx->cp_value, + sizeof (np->zone_res_attr_name)); + break; + case PT_VALUE: + (void) strlcpy(np->zone_res_attr_value, + cx->cp_value, + sizeof (np->zone_res_attr_value)); + break; + default: + zone_perror(pt_to_str(prop_type), + Z_NO_PROPERTY_TYPE, B_TRUE); + long_usage(CMD_REMOVE, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + } + np->zone_res_attr_next = NULL; + + if (res_type == RT_NET) { + err = zonecfg_remove_res_attr( + &(in_progress_nwiftab.zone_nwif_attrp), np); + } else { /* RT_DEVICE */ + err = zonecfg_remove_res_attr( + &(in_progress_devtab.zone_dev_attrp), np); + } + if (err != Z_OK && !force) + zone_perror(pt_to_str(prop_type), err, B_TRUE); + return; case RT_RCTL: if (prop_type != PT_VALUE) { zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, @@ -3518,22 +3864,10 @@ remove_property(cmd_t *cmd) rctlvaltab->zone_rctlval_next = NULL; err = zonecfg_remove_rctl_value(&in_progress_rctltab, rctlvaltab); - if (err != Z_OK) + if (err != Z_OK && !force) zone_perror(pt_to_str(prop_type), err, B_TRUE); zonecfg_free_rctl_value_list(rctlvaltab); return; - case RT_NET: - if (prop_type != PT_DEFROUTER) { - zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, - B_TRUE); - long_usage(CMD_REMOVE, B_TRUE); - usage(B_FALSE, HELP_PROPS); - return; - } else { - bzero(&in_progress_nwiftab.zone_nwif_defrouter, - sizeof (in_progress_nwiftab.zone_nwif_defrouter)); - return; - } default: zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE); long_usage(CMD_REMOVE, B_TRUE); @@ -3596,8 +3930,7 @@ clear_property(cmd_t *cmd) case RT_MCAP: switch (prop_type) { case PT_PHYSICAL: - in_progress_mcaptab.zone_physmem_cap[0] = '\0'; - need_to_commit = B_TRUE; + remove_aliased_rctl(PT_PHYSICAL, ALIAS_MAXPHYSMEM); return; case PT_SWAP: remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP); @@ -3607,6 +3940,30 @@ clear_property(cmd_t *cmd) return; } break; + case RT_NET: + switch (prop_type) { + case PT_ALLOWED_ADDRESS: + in_progress_nwiftab.zone_nwif_allowed_address[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_DEFROUTER: + in_progress_nwiftab.zone_nwif_defrouter[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_GNIC: + in_progress_nwiftab.zone_nwif_gnic[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_MAC: + in_progress_nwiftab.zone_nwif_mac[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_VLANID: + in_progress_nwiftab.zone_nwif_vlan_id[0] = '\0'; + need_to_commit = B_TRUE; + return; + } + break; default: break; } @@ -3632,6 +3989,8 @@ clear_global(cmd_t *cmd) /* FALLTHRU */ case PT_ZONEPATH: /* FALLTHRU */ + case PT_UUID: + /* FALLTHRU */ case PT_BRAND: zone_perror(pt_to_str(type), Z_CLEAR_DISALLOW, B_TRUE); return; @@ -3694,6 +4053,9 @@ clear_global(cmd_t *cmd) case PT_SHARES: remove_aliased_rctl(PT_SHARES, ALIAS_SHARES); return; + case PT_ZFSPRI: + remove_aliased_rctl(PT_ZFSPRI, ALIAS_ZFSPRI); + return; case PT_HOSTID: if ((err = zonecfg_set_hostid(handle, NULL)) != Z_OK) z_cmd_rt_perror(CMD_CLEAR, RT_HOSTID, err, B_TRUE); @@ -3739,7 +4101,7 @@ clear_func(cmd_t *cmd) void select_func(cmd_t *cmd) { - int type, err, res; + int type, err; uint64_t limit; uint64_t tmp; @@ -3834,7 +4196,8 @@ select_func(cmd_t *cmd) return; case RT_MCAP: /* if none of these exist, there is no resource to select */ - if ((res = zonecfg_lookup_mcap(handle, &old_mcaptab)) != Z_OK && + if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &limit) + != Z_OK && zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &limit) != Z_OK && zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &limit) @@ -3843,12 +4206,6 @@ select_func(cmd_t *cmd) B_TRUE); global_scope = B_TRUE; } - if (res == Z_OK) - bcopy(&old_mcaptab, &in_progress_mcaptab, - sizeof (struct zone_mcaptab)); - else - bzero(&in_progress_mcaptab, - sizeof (in_progress_mcaptab)); return; case RT_ADMIN: if ((err = fill_in_admintab(cmd, &old_admintab, B_FALSE)) @@ -4115,7 +4472,6 @@ set_func(cmd_t *cmd) boolean_t autoboot; zone_iptype_t iptype; boolean_t force_set = B_FALSE; - size_t physmem_size = sizeof (in_progress_mcaptab.zone_physmem_cap); uint64_t mem_cap, mem_limit; float cap; char *unitp; @@ -4190,6 +4546,10 @@ set_func(cmd_t *cmd) res_type = RT_HOSTID; } else if (prop_type == PT_FS_ALLOWED) { res_type = RT_FS_ALLOWED; + } else if (prop_type == PT_ZFSPRI) { + res_type = RT_ZFSPRI; + } else if (prop_type == PT_UUID) { + res_type = RT_UUID; } else { zerr(gettext("Cannot set a resource-specific property " "from the global scope.")); @@ -4219,10 +4579,12 @@ set_func(cmd_t *cmd) * A nasty expression but not that complicated: * 1. fs options are simple or list (tested below) * 2. rctl value's are complex or list (tested below) + * 3. net attr's are complex (tested below) * Anything else should be simple. */ if (!(res_type == RT_FS && prop_type == PT_OPTIONS) && !(res_type == RT_RCTL && prop_type == PT_VALUE) && + !(res_type == RT_NET && prop_type == PT_NPROP) && (pp->pv_type != PROP_VAL_SIMPLE || (prop_id = pp->pv_simple) == NULL)) { zerr(gettext("A %s value was expected here."), @@ -4395,6 +4757,9 @@ set_func(cmd_t *cmd) case RT_SHARES: set_aliased_rctl(ALIAS_SHARES, prop_type, prop_id); return; + case RT_ZFSPRI: + set_aliased_rctl(ALIAS_ZFSPRI, prop_type, prop_id); + return; case RT_HOSTID: if ((err = zonecfg_set_hostid(handle, prop_id)) != Z_OK) { if (err == Z_TOO_BIG) { @@ -4408,6 +4773,15 @@ set_func(cmd_t *cmd) } need_to_commit = B_TRUE; return; + case RT_UUID: + /* + * We can't set here. We have to wait until commit since the + * uuid will be updating the index file and we may not have + * created the zone yet. + */ + (void) strlcpy(new_uuid, prop_id, sizeof (new_uuid)); + need_to_commit = B_TRUE; + return; case RT_FS_ALLOWED: if ((err = zonecfg_set_fs_allowed(handle, prop_id)) != Z_OK) zone_perror(zone, err, B_TRUE); @@ -4482,6 +4856,21 @@ set_func(cmd_t *cmd) prop_id, sizeof (in_progress_nwiftab.zone_nwif_physical)); break; + case PT_MAC: + normalize_mac_addr(in_progress_nwiftab.zone_nwif_mac, + prop_id, + sizeof (in_progress_nwiftab.zone_nwif_mac)); + break; + case PT_VLANID: + (void) strlcpy(in_progress_nwiftab.zone_nwif_vlan_id, + prop_id, + sizeof (in_progress_nwiftab.zone_nwif_vlan_id)); + break; + case PT_GNIC: + (void) strlcpy(in_progress_nwiftab.zone_nwif_gnic, + prop_id, + sizeof (in_progress_nwiftab.zone_nwif_gnic)); + break; case PT_DEFROUTER: if (validate_net_address_syntax(prop_id, B_TRUE) != Z_OK) { @@ -4492,6 +4881,20 @@ set_func(cmd_t *cmd) prop_id, sizeof (in_progress_nwiftab.zone_nwif_defrouter)); break; + case PT_NPROP: + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + zonecfg_free_res_attr_list( + in_progress_nwiftab.zone_nwif_attrp); + in_progress_nwiftab.zone_nwif_attrp = NULL; + if (!(pp->pv_type == PROP_VAL_LIST && + pp->pv_list == NULL)) + add_property(cmd); + break; default: zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE); @@ -4507,6 +4910,20 @@ set_func(cmd_t *cmd) prop_id, sizeof (in_progress_devtab.zone_dev_match)); break; + case PT_NPROP: + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + zonecfg_free_res_attr_list( + in_progress_devtab.zone_dev_attrp); + in_progress_devtab.zone_dev_attrp = NULL; + if (!(pp->pv_type == PROP_VAL_LIST && + pp->pv_list == NULL)) + add_property(cmd); + break; default: zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE); @@ -4667,18 +5084,30 @@ set_func(cmd_t *cmd) case RT_MCAP: switch (prop_type) { case PT_PHYSICAL: + /* + * We have to check if an rctl is allowed here since + * there might already be a rctl defined that blocks + * the alias. + */ + if (!zonecfg_aliased_rctl_ok(handle, + ALIAS_MAXPHYSMEM)) { + zone_perror(pt_to_str(PT_LOCKED), + Z_ALIAS_DISALLOW, B_FALSE); + saw_error = B_TRUE; + return; + } + if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) { - zerr(gettext("A positive number with a " + zerr(gettext("A non-negative number with a " "required scale suffix (K, M, G or T) was " - "expected here.")); - saw_error = B_TRUE; - } else if (mem_cap < ONE_MB) { - zerr(gettext("%s value is too small. It must " - "be at least 1M."), pt_to_str(PT_PHYSICAL)); + "expected\nhere.")); saw_error = B_TRUE; } else { - snprintf(in_progress_mcaptab.zone_physmem_cap, - physmem_size, "%llu", mem_cap); + if ((err = zonecfg_set_aliased_rctl(handle, + ALIAS_MAXPHYSMEM, mem_cap)) != Z_OK) + zone_perror(zone, err, B_TRUE); + else + need_to_commit = B_TRUE; } break; case PT_SWAP: @@ -4950,6 +5379,23 @@ info_hostid(zone_dochandle_t handle, FILE *fp) } static void +info_uuid(FILE *fp) +{ + uuid_t uuid; + char suuid[UUID_PRINTABLE_STRING_LENGTH]; + + if (new_uuid[0] != '\0') { + (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_UUID), new_uuid); + } else if (zonecfg_get_uuid(zone, uuid) == Z_OK && + !uuid_is_null(uuid)) { + uuid_unparse(uuid, suuid); + (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_UUID), suuid); + } else { + (void) fprintf(fp, "%s:\n", pt_to_str(PT_UUID)); + } +} + +static void info_fs_allowed(zone_dochandle_t handle, FILE *fp) { char fsallowedp[ZONE_FS_ALLOWED_MAX]; @@ -5031,12 +5477,25 @@ loopend: static void output_net(FILE *fp, struct zone_nwiftab *nwiftab) { + struct zone_res_attrtab *np; + (void) fprintf(fp, "%s:\n", rt_to_str(RT_NET)); output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE); output_prop(fp, PT_ALLOWED_ADDRESS, nwiftab->zone_nwif_allowed_address, B_TRUE); - output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE); output_prop(fp, PT_DEFROUTER, nwiftab->zone_nwif_defrouter, B_TRUE); + output_prop(fp, PT_GNIC, nwiftab->zone_nwif_gnic, B_TRUE); + output_prop(fp, PT_MAC, nwiftab->zone_nwif_mac, B_TRUE); + output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE); + output_prop(fp, PT_VLANID, nwiftab->zone_nwif_vlan_id, B_TRUE); + + for (np = nwiftab->zone_nwif_attrp; np != NULL; + np = np->zone_res_attr_next) { + fprintf(fp, "\t%s: (%s=%s,%s=\"%s\")\n", + pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), np->zone_res_attr_name, + pt_to_str(PT_VALUE), np->zone_res_attr_value); + } } static void @@ -5079,8 +5538,18 @@ info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) static void output_dev(FILE *fp, struct zone_devtab *devtab) { + struct zone_res_attrtab *np; + (void) fprintf(fp, "%s:\n", rt_to_str(RT_DEVICE)); output_prop(fp, PT_MATCH, devtab->zone_dev_match, B_TRUE); + + for (np = devtab->zone_dev_attrp; np != NULL; + np = np->zone_res_attr_next) { + fprintf(fp, "\t%s: (%s=%s,%s=\"%s\")\n", + pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), np->zone_res_attr_name, + pt_to_str(PT_VALUE), np->zone_res_attr_value); + } } static void @@ -5339,15 +5808,18 @@ bytes_to_units(char *str, char *buf, int bufsize) } static void -output_mcap(FILE *fp, struct zone_mcaptab *mcaptab, int showswap, +output_mcap(FILE *fp, int showphys, uint64_t maxphys, int showswap, uint64_t maxswap, int showlocked, uint64_t maxlocked) { char buf[128]; (void) fprintf(fp, "%s:\n", rt_to_str(RT_MCAP)); - if (mcaptab->zone_physmem_cap[0] != '\0') { - bytes_to_units(mcaptab->zone_physmem_cap, buf, sizeof (buf)); - output_prop(fp, PT_PHYSICAL, buf, B_TRUE); + + if (showphys == Z_OK) { + (void) snprintf(buf, sizeof (buf), "%llu", maxphys); + bytes_to_units(buf, buf, sizeof (buf)); + /* Print directly since "physical" also is a net property. */ + (void) fprintf(fp, "\t[%s: %s]\n", pt_to_str(PT_PHYSICAL), buf); } if (showswap == Z_OK) { @@ -5369,16 +5841,16 @@ info_mcap(zone_dochandle_t handle, FILE *fp) int res1, res2, res3; uint64_t swap_limit; uint64_t locked_limit; - struct zone_mcaptab lookup; + uint64_t phys_limit; - bzero(&lookup, sizeof (lookup)); - res1 = zonecfg_getmcapent(handle, &lookup); + res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &phys_limit); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &swap_limit); res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &locked_limit); if (res1 == Z_OK || res2 == Z_OK || res3 == Z_OK) - output_mcap(fp, &lookup, res2, swap_limit, res3, locked_limit); + output_mcap(fp, res1, phys_limit, res2, swap_limit, + res3, locked_limit); } static void @@ -5429,9 +5901,11 @@ info_func(cmd_t *cmd) FILE *fp = stdout; boolean_t need_to_close = B_FALSE; int type; - int res1, res2; + int res1, res2, res3; uint64_t swap_limit; uint64_t locked_limit; + uint64_t phys_limit; + struct stat statbuf; assert(cmd != NULL); @@ -5479,7 +5953,9 @@ info_func(cmd_t *cmd) &swap_limit); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &locked_limit); - output_mcap(fp, &in_progress_mcaptab, res1, swap_limit, + res3 = zonecfg_get_aliased_rctl(handle, + ALIAS_MAXPHYSMEM, &phys_limit); + output_mcap(fp, res3, phys_limit, res1, swap_limit, res2, locked_limit); break; case RT_ADMIN: @@ -5519,6 +5995,7 @@ info_func(cmd_t *cmd) info_iptype(handle, fp); info_hostid(handle, fp); info_fs_allowed(handle, fp); + info_uuid(fp); } info_aliased_rctl(handle, fp, ALIAS_MAXLWPS); info_aliased_rctl(handle, fp, ALIAS_MAXPROCS); @@ -5527,6 +6004,7 @@ info_func(cmd_t *cmd) info_aliased_rctl(handle, fp, ALIAS_MAXMSGIDS); info_aliased_rctl(handle, fp, ALIAS_MAXSEMIDS); info_aliased_rctl(handle, fp, ALIAS_SHARES); + info_aliased_rctl(handle, fp, ALIAS_ZFSPRI); if (!global_zone) { info_fs(handle, fp, cmd); info_net(handle, fp, cmd); @@ -5590,6 +6068,9 @@ info_func(cmd_t *cmd) case RT_SHARES: info_aliased_rctl(handle, fp, ALIAS_SHARES); break; + case RT_ZFSPRI: + info_aliased_rctl(handle, fp, ALIAS_ZFSPRI); + break; case RT_FS: info_fs(handle, fp, cmd); break; @@ -5620,6 +6101,9 @@ info_func(cmd_t *cmd) case RT_HOSTID: info_hostid(handle, fp); break; + case RT_UUID: + info_uuid(fp); + break; case RT_ADMIN: info_auth(handle, fp, cmd); break; @@ -6101,11 +6585,29 @@ verify_func(cmd_t *cmd) if (save) { if (ret_val == Z_OK) { + /* + * If the zone doesn't yet have a debug ID, set one now. + */ + if (zonecfg_get_did(handle) == -1) + zonecfg_set_did(handle); + if ((ret_val = zonecfg_save(handle)) == Z_OK) { need_to_commit = B_FALSE; (void) strlcpy(revert_zone, zone, sizeof (revert_zone)); } + + /* + * Commit a new uuid at this point since we now know the + * zone index entry will exist. + */ + if (new_uuid[0] != '\0') { + if ((err = zonecfg_set_uuid(zone, zonepath, + new_uuid)) != Z_OK) + zone_perror(zone, err, B_FALSE); + else + new_uuid[0] = '\0'; + } } else { zerr(gettext("Zone %s failed to verify"), zone); } @@ -6275,6 +6777,7 @@ end_func(cmd_t *cmd) int err, arg, res1, res2, res3; uint64_t swap_limit; uint64_t locked_limit; + uint64_t phys_limit; uint64_t proc_cap; assert(cmd != NULL); @@ -6578,8 +7081,8 @@ end_func(cmd_t *cmd) break; case RT_MCAP: /* Make sure everything was filled in. */ - res1 = strlen(in_progress_mcaptab.zone_physmem_cap) == 0 ? - Z_ERR : Z_OK; + res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, + &phys_limit); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &swap_limit); res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, @@ -6595,11 +7098,6 @@ end_func(cmd_t *cmd) /* if phys & locked are both set, verify locked <= phys */ if (res1 == Z_OK && res3 == Z_OK) { - uint64_t phys_limit; - char *endp; - - phys_limit = strtoull( - in_progress_mcaptab.zone_physmem_cap, &endp, 10); if (phys_limit < locked_limit) { zerr(gettext("The %s cap must be less than or " "equal to the %s cap."), @@ -6611,23 +7109,6 @@ end_func(cmd_t *cmd) } err = Z_OK; - if (res1 == Z_OK) { - /* - * We could be ending from either an add operation - * or a select operation. Since all of the properties - * within this resource are optional, we always use - * modify on the mcap entry. zonecfg_modify_mcap() - * will handle both adding and modifying a memory cap. - */ - err = zonecfg_modify_mcap(handle, &in_progress_mcaptab); - } else if (end_op == CMD_SELECT) { - /* - * If we're ending from a select and the physical - * memory cap is empty then the user could have cleared - * the physical cap value, so try to delete the entry. - */ - (void) zonecfg_delete_mcap(handle); - } break; case RT_ADMIN: /* First make sure everything was filled in. */ @@ -7176,8 +7657,10 @@ get_execbasename(char *execfullname) int main(int argc, char *argv[]) { - int err, arg; + int err, arg, uflag = 0, zflag = 0; struct stat st; + uuid_t uuidin; + char zonename[ZONENAME_MAX + 1]; /* This must be before anything goes to stdout. */ setbuf(stdout, NULL); @@ -7204,7 +7687,7 @@ main(int argc, char *argv[]) exit(Z_OK); } - while ((arg = getopt(argc, argv, "?f:R:z:")) != EOF) { + while ((arg = getopt(argc, argv, "?f:R:z:u:")) != EOF) { switch (arg) { case '?': if (optopt == '?') @@ -7231,6 +7714,21 @@ main(int argc, char *argv[]) } zonecfg_set_root(optarg); break; + case 'u': + if (uuid_parse((char *)optarg, uuidin) == -1) + return (Z_INVALID_PROPERTY); + + if (zonecfg_get_name_by_uuid(uuidin, zonename, + ZONENAME_MAX) != Z_OK) { + zone_perror(optarg, Z_BOGUS_ZONE_NAME, B_TRUE); + usage(B_FALSE, HELP_SYNTAX); + exit(Z_USAGE); + } + + (void) strlcpy(zone, zonename, sizeof (zone)); + (void) strlcpy(revert_zone, zonename, sizeof (zone)); + uflag = 1; + break; case 'z': if (strcmp(optarg, GLOBAL_ZONENAME) == 0) { global_zone = B_TRUE; @@ -7241,6 +7739,7 @@ main(int argc, char *argv[]) } (void) strlcpy(zone, optarg, sizeof (zone)); (void) strlcpy(revert_zone, optarg, sizeof (zone)); + zflag = 1; break; default: usage(B_FALSE, HELP_USAGE); @@ -7248,7 +7747,7 @@ main(int argc, char *argv[]) } } - if (optind > argc || strcmp(zone, "") == 0) { + if (optind > argc || strcmp(zone, "") == 0 || (uflag && zflag)) { usage(B_FALSE, HELP_USAGE); exit(Z_USAGE); } diff --git a/usr/src/cmd/zonecfg/zonecfg.h b/usr/src/cmd/zonecfg/zonecfg.h index d8f8b14ce8..f8c78437ad 100644 --- a/usr/src/cmd/zonecfg/zonecfg.h +++ b/usr/src/cmd/zonecfg/zonecfg.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #ifndef _ZONECFG_H @@ -90,9 +91,11 @@ extern "C" { #define RT_ADMIN 26 #define RT_FS_ALLOWED 27 #define RT_MAXPROCS 28 /* really a rctl alias property, but for info */ +#define RT_ZFSPRI 29 /* really a rctl alias property, but for info */ +#define RT_UUID 30 /* really a property, but for info */ #define RT_MIN RT_UNKNOWN -#define RT_MAX RT_MAXPROCS +#define RT_MAX RT_UUID /* property types: increment PT_MAX when expanding this list */ #define PT_UNKNOWN 0 @@ -137,9 +140,15 @@ extern "C" { #define PT_FS_ALLOWED 39 #define PT_MAXPROCS 40 #define PT_ALLOWED_ADDRESS 41 +#define PT_ZFSPRI 42 +#define PT_MAC 43 +#define PT_VLANID 44 +#define PT_GNIC 45 +#define PT_NPROP 46 +#define PT_UUID 47 #define PT_MIN PT_UNKNOWN -#define PT_MAX PT_ALLOWED_ADDRESS +#define PT_MAX PT_UUID #define MAX_EQ_PROP_PAIRS 3 diff --git a/usr/src/cmd/zonecfg/zonecfg_grammar.y b/usr/src/cmd/zonecfg/zonecfg_grammar.y index d7f11b6a46..13a17876b7 100644 --- a/usr/src/cmd/zonecfg/zonecfg_grammar.y +++ b/usr/src/cmd/zonecfg/zonecfg_grammar.y @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013, Joyent Inc. All rights reserved. */ /* @@ -136,6 +137,7 @@ complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next) %token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV BOOTARGS BRAND PSET PCAP %token MCAP NCPUS IMPORTANCE SHARES MAXLWPS MAXSHMMEM MAXSHMIDS MAXMSGIDS %token MAXSEMIDS LOCKED SWAP SCHED CLEAR DEFROUTER ADMIN USER AUTHS MAXPROCS +%token ZFSPRI MAC VLANID GNIC NPROP UUID %type <strval> TOKEN EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET property_value OPEN_PAREN CLOSE_PAREN COMMA simple_prop_val @@ -145,7 +147,7 @@ complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next) %type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV BOOTARGS VALUE PRIV LIMIT ACTION BRAND SCHED IPTYPE DEFROUTER HOSTID USER AUTHS FS_ALLOWED - ALLOWED_ADDRESS + ALLOWED_ADDRESS MAC VLANID GNIC NPROP UUID %type <cmd> command %type <cmd> add_command ADD %type <cmd> cancel_command CANCEL @@ -650,6 +652,24 @@ info_command: INFO $$->cmd_res_type = RT_FS_ALLOWED; $$->cmd_prop_nv_pairs = 0; } + | INFO UUID + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &info_func; + $$->cmd_res_type = RT_UUID; + $$->cmd_prop_nv_pairs = 0; + } + | INFO ZFSPRI + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &info_func; + $$->cmd_res_type = RT_ZFSPRI; + $$->cmd_prop_nv_pairs = 0; + } | INFO resource_type property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -734,6 +754,19 @@ remove_command: REMOVE $$->cmd_prop_name[0] = $2; $$->cmd_property_ptr[0] = &property[0]; } + | REMOVE TOKEN property_name property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 1; + $$->cmd_prop_name[0] = $3; + $$->cmd_property_ptr[0] = &property[0]; + } | REMOVE resource_type property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -745,6 +778,20 @@ remove_command: REMOVE $$->cmd_prop_name[0] = $3; $$->cmd_property_ptr[0] = &property[0]; } + | REMOVE TOKEN resource_type property_name EQUAL property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_res_type = $3; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 1; + $$->cmd_prop_name[0] = $4; + $$->cmd_property_ptr[0] = &property[0]; + } | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -758,6 +805,22 @@ remove_command: REMOVE $$->cmd_prop_name[1] = $6; $$->cmd_property_ptr[1] = &property[1]; } + | REMOVE TOKEN resource_type property_name EQUAL property_value property_name EQUAL property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_res_type = $3; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 2; + $$->cmd_prop_name[0] = $4; + $$->cmd_property_ptr[0] = &property[0]; + $$->cmd_prop_name[1] = $7; + $$->cmd_property_ptr[1] = &property[1]; + } | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -773,6 +836,24 @@ remove_command: REMOVE $$->cmd_prop_name[2] = $9; $$->cmd_property_ptr[2] = &property[2]; } + | REMOVE TOKEN resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_res_type = $3; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 3; + $$->cmd_prop_name[0] = $4; + $$->cmd_property_ptr[0] = &property[0]; + $$->cmd_prop_name[1] = $7; + $$->cmd_property_ptr[1] = &property[1]; + $$->cmd_prop_name[2] = $10; + $$->cmd_property_ptr[2] = &property[2]; + } revert_command: REVERT { @@ -976,6 +1057,10 @@ property_name: SPECIAL { $$ = PT_SPECIAL; } | ALLOWED_ADDRESS { $$ = PT_ALLOWED_ADDRESS; } | PHYSICAL { $$ = PT_PHYSICAL; } | DEFROUTER { $$ = PT_DEFROUTER; } + | MAC { $$ = PT_MAC; } + | VLANID { $$ = PT_VLANID; } + | GNIC { $$ = PT_GNIC; } + | NPROP { $$ = PT_NPROP; } | NAME { $$ = PT_NAME; } | VALUE { $$ = PT_VALUE; } | MATCH { $$ = PT_MATCH; } @@ -999,6 +1084,8 @@ property_name: SPECIAL { $$ = PT_SPECIAL; } | USER { $$ = PT_USER; } | AUTHS { $$ = PT_AUTHS; } | FS_ALLOWED { $$ = PT_FS_ALLOWED; } + | UUID { $$ = PT_UUID; } + | ZFSPRI { $$ = PT_ZFSPRI; } /* * The grammar builds data structures from the bottom up. Thus various diff --git a/usr/src/cmd/zonecfg/zonecfg_lex.l b/usr/src/cmd/zonecfg/zonecfg_lex.l index 6a0b577b75..328a75c922 100644 --- a/usr/src/cmd/zonecfg/zonecfg_lex.l +++ b/usr/src/cmd/zonecfg/zonecfg_lex.l @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #include <assert.h> @@ -57,10 +58,11 @@ extern void yyerror(char *s); static char *create_token(char *s); %} -%a 7000 +%a 8000 %p 5000 %e 2000 %n 1000 +%o 13000 %{ /* @@ -236,6 +238,18 @@ static char *create_token(char *s); <TSTATE>defrouter { return DEFROUTER; } <CSTATE>defrouter { return DEFROUTER; } +<TSTATE>mac-addr { return MAC; } +<CSTATE>mac-addr { return MAC; } + +<TSTATE>vlan-id { return VLANID; } +<CSTATE>vlan-id { return VLANID; } + +<TSTATE>global-nic { return GNIC; } +<CSTATE>global-nic { return GNIC; } + +<TSTATE>property { return NPROP; } +<CSTATE>property { return NPROP; } + <TSTATE>dir { return DIR; } <CSTATE>dir { return DIR; } @@ -308,6 +322,12 @@ static char *create_token(char *s); <TSTATE>fs-allowed { return FS_ALLOWED; } <CSTATE>fs-allowed { return FS_ALLOWED; } +<TSTATE>uuid { return UUID; } +<CSTATE>uuid { return UUID; } + +<TSTATE>zfs-io-priority { return ZFSPRI; } +<CSTATE>zfs-io-priority { return ZFSPRI; } + <TSTATE>= { return EQUAL; } <LSTATE>= { return EQUAL; } <CSTATE>= { return EQUAL; } @@ -357,6 +377,13 @@ static char *create_token(char *s); return TOKEN; } +<CSTATE>\"[^\"\n]*[\"\n] { + yylval.strval = create_token(yytext + 1); + if (yylval.strval[yyleng - 2] == '"') + yylval.strval[yyleng - 2] = 0; + return TOKEN; + } + <TSTATE>\"[^\"\n]*[\"\n] { yylval.strval = create_token(yytext + 1); if (yylval.strval[yyleng - 2] == '"') |