summaryrefslogtreecommitdiff
path: root/usr/src/cmd/zonecfg/zonecfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/zonecfg/zonecfg.c')
-rw-r--r--usr/src/cmd/zonecfg/zonecfg.c167
1 files changed, 155 insertions, 12 deletions
diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c
index 34d6b99480..443c0895b1 100644
--- a/usr/src/cmd/zonecfg/zonecfg.c
+++ b/usr/src/cmd/zonecfg/zonecfg.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -178,6 +178,7 @@ static char *res_types[] = {
ALIAS_MAXSEMIDS,
ALIAS_SHARES,
"scheduling-class",
+ "ip-type",
NULL
};
@@ -217,6 +218,7 @@ static char *prop_types[] = {
ALIAS_MAXLOCKEDMEM,
ALIAS_MAXSWAP,
"scheduling-class",
+ "ip-type",
NULL
};
@@ -273,6 +275,7 @@ static const char *clear_cmds[] = {
"clear limitpriv",
"clear bootargs",
"clear scheduling-class",
+ "clear ip-type",
"clear " ALIAS_MAXLWPS,
"clear " ALIAS_MAXSHMMEM,
"clear " ALIAS_MAXSHMIDS,
@@ -317,6 +320,7 @@ static const char *set_cmds[] = {
"set limitpriv=",
"set bootargs=",
"set scheduling-class=",
+ "set ip-type=",
"set " ALIAS_MAXLWPS "=",
"set " ALIAS_MAXSHMMEM "=",
"set " ALIAS_MAXSHMIDS "=",
@@ -344,6 +348,7 @@ static const char *info_cmds[] = {
"info bootargs",
"info brand",
"info scheduling-class",
+ "info ip-type",
"info max-lwps",
"info max-shm-memory",
"info max-shm-ids",
@@ -914,6 +919,11 @@ usage(bool verbose, uint_t flags)
pt_to_str(PT_PHYSICAL), gettext("<interface>"));
(void) fprintf(fp, gettext("See ifconfig(1M) for "
"details of the <interface> string.\n"));
+ (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_ADDRESS),
+ pt_to_str(PT_IPTYPE), "shared");
break;
case RT_DEVICE:
(void) fprintf(fp, gettext("The '%s' resource scope is "
@@ -1095,6 +1105,8 @@ usage(bool verbose, uint_t flags)
(void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
pt_to_str(PT_SCHED));
(void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
+ pt_to_str(PT_IPTYPE));
+ (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
pt_to_str(PT_MAXLWPS));
(void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
pt_to_str(PT_MAXSHMMEM));
@@ -1571,6 +1583,7 @@ export_func(cmd_t *cmd)
char *limitpriv;
FILE *of;
boolean_t autoboot;
+ zone_iptype_t iptype;
bool need_to_close = FALSE;
assert(cmd != NULL);
@@ -1651,6 +1664,19 @@ export_func(cmd_t *cmd)
(void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
pt_to_str(PT_SCHED), sched);
+ if (zonecfg_get_iptype(handle, &iptype) == Z_OK) {
+ switch (iptype) {
+ case ZS_SHARED:
+ (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
+ pt_to_str(PT_IPTYPE), "shared");
+ break;
+ case ZS_EXCLUSIVE:
+ (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
+ pt_to_str(PT_IPTYPE), "exclusive");
+ break;
+ }
+ }
+
if ((err = zonecfg_setipdent(handle)) != Z_OK) {
zone_perror(zone, err, FALSE);
goto done;
@@ -2157,7 +2183,8 @@ gz_invalid_rt_property(int type)
{
return (global_zone && (type == RT_ZONENAME || type == RT_ZONEPATH ||
type == RT_AUTOBOOT || type == RT_LIMITPRIV ||
- type == RT_BOOTARGS || type == RT_BRAND || type == RT_SCHED));
+ type == RT_BOOTARGS || type == RT_BRAND || type == RT_SCHED ||
+ type == RT_IPTYPE));
}
static boolean_t
@@ -2165,7 +2192,8 @@ gz_invalid_property(int type)
{
return (global_zone && (type == PT_ZONENAME || type == PT_ZONEPATH ||
type == PT_AUTOBOOT || type == PT_LIMITPRIV ||
- type == PT_BOOTARGS || type == PT_BRAND || type == PT_SCHED));
+ type == PT_BOOTARGS || type == PT_BRAND || type == PT_SCHED ||
+ type == PT_IPTYPE));
}
void
@@ -3268,6 +3296,13 @@ clear_global(cmd_t *cmd)
else
need_to_commit = TRUE;
return;
+ case PT_IPTYPE:
+ /* shared is default; we'll treat as equivalent to clearing */
+ if ((err = zonecfg_set_iptype(handle, ZS_SHARED)) != Z_OK)
+ z_cmd_rt_perror(CMD_CLEAR, RT_IPTYPE, err, TRUE);
+ else
+ need_to_commit = TRUE;
+ return;
case PT_MAXLWPS:
remove_aliased_rctl(PT_MAXLWPS, ALIAS_MAXLWPS);
return;
@@ -3555,6 +3590,30 @@ valid_fs_type(const char *type)
return (B_TRUE);
}
+static boolean_t
+allow_exclusive()
+{
+ brand_handle_t bh;
+ char brand[MAXNAMELEN];
+ boolean_t ret;
+
+ if (zonecfg_get_brand(handle, brand, sizeof (brand)) != Z_OK) {
+ zerr("%s: %s\n", zone, gettext("could not get zone brand"));
+ return (B_FALSE);
+ }
+ if ((bh = brand_open(brand)) == NULL) {
+ zerr("%s: %s\n", zone, gettext("unknown brand."));
+ return (B_FALSE);
+ }
+ ret = brand_allow_exclusive_ip(bh);
+ brand_close(bh);
+ if (!ret)
+ zerr(gettext("%s cannot be '%s' when %s is '%s'."),
+ pt_to_str(PT_IPTYPE), "exclusive",
+ pt_to_str(PT_BRAND), brand);
+ return (ret);
+}
+
static void
set_aliased_rctl(char *alias, int prop_type, char *s)
{
@@ -3605,6 +3664,7 @@ set_func(cmd_t *cmd)
int arg, err, res_type, prop_type;
property_value_ptr_t pp;
boolean_t autoboot;
+ zone_iptype_t iptype;
boolean_t force_set = FALSE;
size_t physmem_size = sizeof (in_progress_mcaptab.zone_physmem_cap);
uint64_t mem_cap, mem_limit;
@@ -3655,6 +3715,8 @@ set_func(cmd_t *cmd)
res_type = RT_BOOTARGS;
} else if (prop_type == PT_SCHED) {
res_type = RT_SCHED;
+ } else if (prop_type == PT_IPTYPE) {
+ res_type = RT_IPTYPE;
} else if (prop_type == PT_MAXLWPS) {
res_type = RT_MAXLWPS;
} else if (prop_type == PT_MAXSHMMEM) {
@@ -3831,6 +3893,26 @@ set_func(cmd_t *cmd)
else
need_to_commit = TRUE;
return;
+ case RT_IPTYPE:
+ if (strcmp(prop_id, "shared") == 0) {
+ iptype = ZS_SHARED;
+ } else if (strcmp(prop_id, "exclusive") == 0) {
+ iptype = ZS_EXCLUSIVE;
+ } else {
+ zerr(gettext("%s value must be '%s' or '%s'."),
+ pt_to_str(PT_IPTYPE), "shared", "exclusive");
+ saw_error = TRUE;
+ return;
+ }
+ if (iptype == ZS_EXCLUSIVE && !allow_exclusive()) {
+ saw_error = TRUE;
+ return;
+ }
+ if ((err = zonecfg_set_iptype(handle, iptype)) != Z_OK)
+ zone_perror(zone, err, TRUE);
+ else
+ need_to_commit = TRUE;
+ return;
case RT_MAXLWPS:
set_aliased_rctl(ALIAS_MAXLWPS, prop_type, prop_id);
return;
@@ -4304,6 +4386,28 @@ info_sched(zone_dochandle_t handle, FILE *fp)
}
static void
+info_iptype(zone_dochandle_t handle, FILE *fp)
+{
+ zone_iptype_t iptype;
+ int err;
+
+ if ((err = zonecfg_get_iptype(handle, &iptype)) == Z_OK) {
+ switch (iptype) {
+ case ZS_SHARED:
+ (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_IPTYPE),
+ "shared");
+ break;
+ case ZS_EXCLUSIVE:
+ (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_IPTYPE),
+ "exclusive");
+ break;
+ }
+ } else {
+ zone_perror(zone, err, TRUE);
+ }
+}
+
+static void
output_fs(FILE *fp, struct zone_fstab *fstab)
{
zone_fsopt_t *this;
@@ -4430,6 +4534,7 @@ info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
strcmp(user.zone_nwif_physical,
lookup.zone_nwif_physical) != 0)
continue; /* no match */
+ /* If present make sure it matches */
if (strlen(user.zone_nwif_address) > 0 &&
!zonecfg_same_net_address(user.zone_nwif_address,
lookup.zone_nwif_address))
@@ -4822,6 +4927,7 @@ info_func(cmd_t *cmd)
if (!global_zone) {
info_limitpriv(handle, fp);
info_sched(handle, fp);
+ info_iptype(handle, fp);
}
info_aliased_rctl(handle, fp, ALIAS_MAXLWPS);
info_aliased_rctl(handle, fp, ALIAS_MAXSHMMEM);
@@ -4867,6 +4973,9 @@ info_func(cmd_t *cmd)
case RT_SCHED:
info_sched(handle, fp);
break;
+ case RT_IPTYPE:
+ info_iptype(handle, fp);
+ break;
case RT_MAXLWPS:
info_aliased_rctl(handle, fp, ALIAS_MAXLWPS);
break;
@@ -5051,6 +5160,7 @@ verify_func(cmd_t *cmd)
char brand[MAXNAMELEN];
int err, ret_val = Z_OK, arg;
bool save = FALSE;
+ zone_iptype_t iptype;
boolean_t has_cpu_shares = B_FALSE;
optind = 0;
@@ -5102,6 +5212,11 @@ verify_func(cmd_t *cmd)
}
}
+ if (zonecfg_get_iptype(handle, &iptype) != Z_OK) {
+ zerr("%s %s", gettext("cannot get"), pt_to_str(PT_IPTYPE));
+ ret_val = Z_REQD_RESOURCE_MISSING;
+ saw_error = TRUE;
+ }
if ((err = zonecfg_setipdent(handle)) != Z_OK) {
zone_perror(zone, err, TRUE);
return;
@@ -5130,10 +5245,30 @@ verify_func(cmd_t *cmd)
return;
}
while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
- check_reqd_prop(nwiftab.zone_nwif_address, RT_NET,
- PT_ADDRESS, &ret_val);
+ /*
+ * physical is required in all cases.
+ * A shared IP requires an address, while
+ * an exclusive IP must not have an address.
+ */
check_reqd_prop(nwiftab.zone_nwif_physical, RT_NET,
PT_PHYSICAL, &ret_val);
+
+ switch (iptype) {
+ case ZS_SHARED:
+ check_reqd_prop(nwiftab.zone_nwif_address, RT_NET,
+ PT_ADDRESS, &ret_val);
+ break;
+ case ZS_EXCLUSIVE:
+ if (strlen(nwiftab.zone_nwif_address) > 0) {
+ zerr(gettext("%s: %s cannot be specified "
+ "for an exclusive IP type"),
+ rt_to_str(RT_NET), pt_to_str(PT_ADDRESS));
+ saw_error = TRUE;
+ if (ret_val == Z_OK)
+ ret_val = Z_INVAL;
+ }
+ break;
+ }
}
(void) zonecfg_endnwifent(handle);
@@ -5492,27 +5627,35 @@ end_func(cmd_t *cmd)
}
break;
case RT_NET:
- /* First make sure everything was filled in. */
+ /*
+ * First make sure everything was filled in.
+ * Since we don't know whether IP will be shared
+ * or exclusive here, some checks are deferred until
+ * the verify command.
+ */
(void) end_check_reqd(in_progress_nwiftab.zone_nwif_physical,
PT_PHYSICAL, &validation_failed);
- (void) end_check_reqd(in_progress_nwiftab.zone_nwif_address,
- PT_ADDRESS, &validation_failed);
if (validation_failed) {
saw_error = TRUE;
return;
}
-
if (end_op == CMD_ADD) {
/* Make sure there isn't already one like this. */
bzero(&tmp_nwiftab, sizeof (tmp_nwiftab));
+ (void) strlcpy(tmp_nwiftab.zone_nwif_physical,
+ in_progress_nwiftab.zone_nwif_physical,
+ sizeof (tmp_nwiftab.zone_nwif_physical));
(void) strlcpy(tmp_nwiftab.zone_nwif_address,
in_progress_nwiftab.zone_nwif_address,
sizeof (tmp_nwiftab.zone_nwif_address));
if (zonecfg_lookup_nwif(handle, &tmp_nwiftab) == Z_OK) {
- zerr(gettext("A %s resource "
- "with the %s '%s' already exists."),
- rt_to_str(RT_NET), pt_to_str(PT_ADDRESS),
+ zerr(gettext("A %s resource with the %s '%s', "
+ "and %s '%s' already exists."),
+ rt_to_str(RT_NET),
+ pt_to_str(PT_PHYSICAL),
+ in_progress_nwiftab.zone_nwif_physical,
+ pt_to_str(PT_ADDRESS),
in_progress_nwiftab.zone_nwif_address);
saw_error = TRUE;
return;