summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorcarlsonj <none@none>2005-10-27 04:35:13 -0700
committercarlsonj <none@none>2005-10-27 04:35:13 -0700
commit108322fb1c3ed341aba9c80c9774df0ed9e35768 (patch)
tree61abe7b187db6042e0a010756a82a6c7d9d9c5ad /usr/src
parented9df62ee8252b9df6f24409276deabf199dcd40 (diff)
downloadillumos-joyent-108322fb1c3ed341aba9c80c9774df0ed9e35768.tar.gz
PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
6328286 need scratch zone support for upgrade 6328296 need temporary NFS feature to support cross-zone traffic in miniroot environment (only) 6328310 zone_destroy shouldn't camp on the root vnode 6329667 zoneadm fails, but still exits with status zero
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/zlogin/zlogin.c55
-rw-r--r--usr/src/cmd/zoneadm/zoneadm.c280
-rw-r--r--usr/src/cmd/zoneadmd/vplat.c941
-rw-r--r--usr/src/cmd/zoneadmd/zoneadmd.c201
-rw-r--r--usr/src/cmd/zoneadmd/zoneadmd.h8
-rw-r--r--usr/src/cmd/zonename/Makefile6
-rw-r--r--usr/src/cmd/zonename/zonename.c20
-rw-r--r--usr/src/head/libzonecfg.h46
-rw-r--r--usr/src/lib/libzonecfg/Makefile.com6
-rw-r--r--usr/src/lib/libzonecfg/common/getzoneent.c158
-rw-r--r--usr/src/lib/libzonecfg/common/libzonecfg.c239
-rw-r--r--usr/src/lib/libzonecfg/common/scratchops.c268
-rw-r--r--usr/src/lib/libzonecfg/common/zonecfg_impl.h21
-rw-r--r--usr/src/lib/libzonecfg/spec/libzonecfg.spec99
-rw-r--r--usr/src/uts/common/fs/nfs/nfs3_vfsops.c14
-rw-r--r--usr/src/uts/common/fs/nfs/nfs3_vnops.c128
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_callback.c18
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_client.c8
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_idmap.c12
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_recovery.c4
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_rnode.c2
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_subr.c6
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_vfsops.c23
-rw-r--r--usr/src/uts/common/fs/nfs/nfs4_vnops.c186
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_client.c6
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_subr.c37
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_vfsops.c12
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_vnops.c98
-rw-r--r--usr/src/uts/common/fs/vnode.c6
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c7
-rw-r--r--usr/src/uts/common/ktli/t_kopen.c7
-rw-r--r--usr/src/uts/common/nfs/rnode.h2
-rw-r--r--usr/src/uts/common/os/zone.c9
-rw-r--r--usr/src/uts/common/rpc/clnt.h3
-rw-r--r--usr/src/uts/common/rpc/clnt_clts.c6
-rw-r--r--usr/src/uts/common/rpc/clnt_cots.c6
-rw-r--r--usr/src/uts/common/rpc/mt_rpcinit.c19
-rw-r--r--usr/src/uts/common/rpc/rpcmod.c6
-rw-r--r--usr/src/uts/common/sys/systm.h6
-rw-r--r--usr/src/uts/common/sys/zone.h3
40 files changed, 2358 insertions, 624 deletions
diff --git a/usr/src/cmd/zlogin/zlogin.c b/usr/src/cmd/zlogin/zlogin.c
index 3332a5fa55..a48d10c310 100644
--- a/usr/src/cmd/zlogin/zlogin.c
+++ b/usr/src/cmd/zlogin/zlogin.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1342,13 +1342,15 @@ main(int argc, char **argv)
char *slavename, slaveshortname[MAXPATHLEN];
priv_set_t *privset;
int tmpl_fd;
+ struct stat sb;
+ char kernzone[ZONENAME_MAX];
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
(void) getpname(argv[0]);
- while ((arg = getopt(argc, argv, "ECSe:l:")) != EOF) {
+ while ((arg = getopt(argc, argv, "ECR:Se:l:")) != EOF) {
switch (arg) {
case 'C':
console = 1;
@@ -1356,6 +1358,18 @@ main(int argc, char **argv)
case 'E':
nocmdchar = 1;
break;
+ case 'R': /* undocumented */
+ if (*optarg != '/') {
+ zerror(gettext("root path must be absolute."));
+ exit(2);
+ }
+ if (stat(optarg, &sb) == -1 || !S_ISDIR(sb.st_mode)) {
+ zerror(
+ gettext("root path must be a directory."));
+ exit(2);
+ }
+ zonecfg_set_root(optarg);
+ break;
case 'S':
failsafe = 1;
break;
@@ -1381,6 +1395,11 @@ main(int argc, char **argv)
usage();
}
+ if (console != 0 && zonecfg_in_alt_root()) {
+ zerror(gettext("-R may not be specified for console login"));
+ exit(2);
+ }
+
if (failsafe != 0 && lflag != 0) {
zerror(gettext("-l may not be specified for failsafe login"));
usage();
@@ -1503,22 +1522,36 @@ main(int argc, char **argv)
return (0);
}
- if (st != ZONE_STATE_RUNNING) {
+ if (st != ZONE_STATE_RUNNING && st != ZONE_STATE_MOUNTED) {
zerror(gettext("login allowed only to running zones "
"(%s is '%s')."), zonename, zone_state_str(st));
return (1);
}
- /*
- * We only need the zone root path and zoneid if we are setting up a
- * pty.
- */
- if ((zoneid = getzoneidbyname(zonename)) == -1) {
+ (void) strlcpy(kernzone, zonename, sizeof (kernzone));
+ if (zonecfg_in_alt_root()) {
+ FILE *fp = zonecfg_open_scratch("", B_FALSE);
+
+ if (fp == NULL || zonecfg_find_scratch(fp, zonename,
+ zonecfg_get_root(), kernzone, sizeof (kernzone)) == -1) {
+ zerror(gettext("cannot find scratch zone %s"),
+ zonename);
+ if (fp != NULL)
+ zonecfg_close_scratch(fp);
+ return (1);
+ }
+ zonecfg_close_scratch(fp);
+ }
+
+ if ((zoneid = getzoneidbyname(kernzone)) == -1) {
zerror(gettext("failed to get zoneid for zone '%s'"),
zonename);
return (1);
}
+ /*
+ * We need the zone path only if we are setting up a pty.
+ */
if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) == -1) {
zerror(gettext("could not get root path for zone %s"),
zonename);
@@ -1539,6 +1572,12 @@ main(int argc, char **argv)
return (noninteractive_login(zonename, zoneid, login, new_args,
new_env));
+ if (zonecfg_in_alt_root()) {
+ zerror(gettext("cannot use interactive login with scratch "
+ "zone"));
+ return (1);
+ }
+
/*
* Things are more complex in interactive mode; we get the
* master side of the pty, then place the user's terminal into
diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c
index 4a0b9eae44..287aa4ca95 100644
--- a/usr/src/cmd/zoneadm/zoneadm.c
+++ b/usr/src/cmd/zoneadm/zoneadm.c
@@ -108,9 +108,11 @@ static size_t nzents;
#define CMD_VERIFY 6
#define CMD_INSTALL 7
#define CMD_UNINSTALL 8
+#define CMD_MOUNT 9
+#define CMD_UNMOUNT 10
#define CMD_MIN CMD_HELP
-#define CMD_MAX CMD_UNINSTALL
+#define CMD_MAX CMD_UNMOUNT
struct cmd {
uint_t cmd_num; /* command number */
@@ -139,6 +141,8 @@ static int list_func(int argc, char *argv[]);
static int verify_func(int argc, char *argv[]);
static int install_func(int argc, char *argv[]);
static int uninstall_func(int argc, char *argv[]);
+static int mount_func(int argc, char *argv[]);
+static int unmount_func(int argc, char *argv[]);
static int sanity_check(char *zone, int cmd_num, boolean_t running,
boolean_t unsafe_when_running);
static int cmd_match(char *cmd);
@@ -154,7 +158,10 @@ static struct cmd cmdtab[] = {
{ CMD_VERIFY, "verify", SHELP_VERIFY, verify_func },
{ CMD_INSTALL, "install", SHELP_INSTALL, install_func },
{ CMD_UNINSTALL, "uninstall", SHELP_UNINSTALL,
- uninstall_func }
+ uninstall_func },
+ /* Private commands for admin/install */
+ { CMD_MOUNT, "mount", NULL, mount_func },
+ { CMD_UNMOUNT, "unmount", NULL, unmount_func }
};
/* global variables */
@@ -226,6 +233,8 @@ long_help(int cmd_num)
return (gettext("Uninstall the configuration from the "
"system. The -F flag can be used\n\tto force the "
"action."));
+ default:
+ return ("");
}
/* NOTREACHED */
return (NULL);
@@ -248,6 +257,8 @@ usage(boolean_t explicit)
gettext("subcommand"));
(void) fprintf(fd, "\n%s:\n\n", gettext("Subcommands"));
for (i = CMD_MIN; i <= CMD_MAX; i++) {
+ if (cmdtab[i].short_usage == NULL)
+ continue;
(void) fprintf(fd, "%s\n", cmdtab[i].short_usage);
if (explicit)
(void) fprintf(fd, "\t%s\n\n", long_help(i));
@@ -356,7 +367,7 @@ zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable)
}
static int
-lookup_zone_info(char *zone_name, zone_entry_t *zent)
+lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent)
{
char root[MAXPATHLEN];
int err;
@@ -365,8 +376,7 @@ lookup_zone_info(char *zone_name, zone_entry_t *zent)
(void) strlcpy(zent->zroot, "???", sizeof (zent->zroot));
zent->zstate_str = "???";
- if ((zent->zid = getzoneidbyname(zone_name)) == -1)
- zent->zid = ZONE_ID_UNDEFINED;
+ zent->zid = zid;
if ((err = zone_get_zonepath(zent->zname, root, sizeof (root))) !=
Z_OK) {
@@ -395,11 +405,14 @@ lookup_zone_info(char *zone_name, zone_entry_t *zent)
*/
static int
-fetch_zents()
+fetch_zents(void)
{
zoneid_t *zids = NULL;
uint_t nzents_saved;
- int i;
+ int i, retv;
+ FILE *fp;
+ boolean_t inaltroot;
+ zone_entry_t *zentp;
if (nzents > 0)
return (Z_OK);
@@ -429,20 +442,56 @@ again:
zents = safe_calloc(nzents, sizeof (zone_entry_t));
+ inaltroot = zonecfg_in_alt_root();
+ if (inaltroot)
+ fp = zonecfg_open_scratch("", B_FALSE);
+ else
+ fp = NULL;
+ zentp = zents;
+ retv = Z_OK;
for (i = 0; i < nzents; i++) {
char name[ZONENAME_MAX];
+ char altname[ZONENAME_MAX];
- if (getzonenamebyid(zids[i], name, sizeof (name)) < 0)
+ if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) {
zperror(gettext("failed to get zone name"), B_FALSE);
- else if (lookup_zone_info(name, &zents[i]) != Z_OK)
- zerror(gettext("failed to get zone list"));
+ retv = Z_ERR;
+ continue;
+ }
+ if (zonecfg_is_scratch(name)) {
+ /* Ignore scratch zones by default */
+ if (!inaltroot)
+ continue;
+ if (fp == NULL ||
+ zonecfg_reverse_scratch(fp, name, altname,
+ sizeof (altname), NULL, 0) == -1) {
+ zerror(gettext("cannot resolve scratch "
+ "zone %s"), name);
+ retv = Z_ERR;
+ continue;
+ }
+ (void) strcpy(name, altname);
+ } else {
+ /* Ignore non-scratch when in an alternate root */
+ if (inaltroot && strcmp(name, GLOBAL_ZONENAME) != 0)
+ continue;
+ }
+ if (lookup_zone_info(name, zids[i], zentp) != Z_OK) {
+ zerror(gettext("failed to get zone data"));
+ retv = Z_ERR;
+ continue;
+ }
+ zentp++;
}
+ nzents = zentp - zents;
+ if (fp != NULL)
+ zonecfg_close_scratch(fp);
free(zids);
- return (Z_OK);
+ return (retv);
}
-static void
+static int
zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
{
int i;
@@ -454,22 +503,17 @@ zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
* First get the list of running zones from the kernel and print them.
* If that is all we need, then return.
*/
- if (fetch_zents() != Z_OK) {
+ if ((i = fetch_zents()) != Z_OK) {
/*
* No need for error messages; fetch_zents() has already taken
* care of this.
*/
- return;
+ return (i);
}
- for (i = 0; i < nzents; i++) {
- if (!verbose && !parsable) {
- zone_print(&zents[i], verbose, parsable);
- continue;
- }
+ for (i = 0; i < nzents; i++)
zone_print(&zents[i], verbose, parsable);
- }
if (min_state >= ZONE_STATE_RUNNING)
- return;
+ return (Z_OK);
/*
* Next, get the full list of zones from the configuration, skipping
* any we have already printed.
@@ -484,7 +528,7 @@ zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
free(name);
continue;
}
- if (lookup_zone_info(name, &zent) != Z_OK) {
+ if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
free(name);
continue;
}
@@ -493,6 +537,7 @@ zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
zone_print(&zent, verbose, parsable);
}
endzoneent(cookie);
+ return (Z_OK);
}
static zone_entry_t *
@@ -635,16 +680,18 @@ crosscheck_zonepaths(char *path)
continue;
}
}
- res = resolvepath(ze->zone_path, rpath, sizeof (rpath));
+ (void) snprintf(path_copy, sizeof (path_copy), "%s%s",
+ zonecfg_get_root(), ze->zone_path);
+ res = resolvepath(path_copy, rpath, sizeof (rpath));
if (res == -1) {
if (errno != ENOENT) {
- zperror(ze->zone_path, B_FALSE);
+ zperror(path_copy, B_FALSE);
free(ze);
return (Z_ERR);
}
(void) printf(gettext("WARNING: zone %s is installed, "
"but its %s %s does not exist.\n"), ze->zone_name,
- "zonepath", ze->zone_path);
+ "zonepath", path_copy);
free(ze);
continue;
}
@@ -848,12 +895,17 @@ grab_lock_file(const char *zone_name, int *lockfd)
char pathbuf[PATH_MAX];
struct flock flock;
- if (mkdir(ZONES_TMPDIR, S_IRWXU) < 0 && errno != EEXIST) {
- zerror(gettext("could not mkdir %s: %s"), ZONES_TMPDIR,
+ if (snprintf(pathbuf, sizeof (pathbuf), "%s%s", zonecfg_get_root(),
+ ZONES_TMPDIR) >= sizeof (pathbuf)) {
+ zerror(gettext("alternate root path is too long"));
+ return (Z_ERR);
+ }
+ if (mkdir(pathbuf, S_IRWXU) < 0 && errno != EEXIST) {
+ zerror(gettext("could not mkdir %s: %s"), pathbuf,
strerror(errno));
return (Z_ERR);
}
- (void) chmod(ZONES_TMPDIR, S_IRWXU);
+ (void) chmod(pathbuf, S_IRWXU);
/*
* One of these lock files is created for each zone (when needed).
@@ -861,8 +913,11 @@ grab_lock_file(const char *zone_name, int *lockfd)
* but since there is only one per zone, there is no resource
* starvation issue.
*/
- (void) snprintf(pathbuf, sizeof (pathbuf), "%s/%s.zoneadm.lock",
- ZONES_TMPDIR, zone_name);
+ if (snprintf(pathbuf, sizeof (pathbuf), "%s%s/%s.zoneadm.lock",
+ zonecfg_get_root(), ZONES_TMPDIR, zone_name) >= sizeof (pathbuf)) {
+ zerror(gettext("alternate root path is too long"));
+ return (Z_ERR);
+ }
if ((*lockfd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
zerror(gettext("could not open %s: %s"), pathbuf,
strerror(errno));
@@ -884,10 +939,11 @@ grab_lock_file(const char *zone_name, int *lockfd)
return (Z_OK);
}
-static void
+static boolean_t
get_doorname(const char *zone_name, char *buffer)
{
- (void) snprintf(buffer, PATH_MAX, ZONE_DOOR_PATH, zone_name);
+ return (snprintf(buffer, PATH_MAX, "%s" ZONE_DOOR_PATH,
+ zonecfg_get_root(), zone_name) < PATH_MAX);
}
/*
@@ -931,7 +987,8 @@ start_zoneadmd(const char *zone_name)
int doorfd, lockfd;
struct door_info info;
- get_doorname(zone_name, doorpath);
+ if (!get_doorname(zone_name, doorpath))
+ return (Z_ERR);
if (grab_lock_file(zone_name, &lockfd) != Z_OK)
return (Z_ERR);
@@ -960,12 +1017,22 @@ start_zoneadmd(const char *zone_name)
zperror(gettext("could not fork"), B_FALSE);
goto out;
} else if (child_pid == 0) {
- /* child process */
+ const char *argv[6], **ap;
+ /* child process */
prepare_audit_context();
- (void) execl("/usr/lib/zones/zoneadmd", "zoneadmd", "-z",
- zone_name, NULL);
+ ap = argv;
+ *ap++ = "zoneadmd";
+ *ap++ = "-z";
+ *ap++ = zone_name;
+ if (zonecfg_in_alt_root()) {
+ *ap++ = "-R";
+ *ap++ = zonecfg_get_root();
+ }
+ *ap = NULL;
+
+ (void) execv("/usr/lib/zones/zoneadmd", (char * const *)argv);
zperror(gettext("could not exec zoneadmd"), B_FALSE);
_exit(Z_ERR);
} else {
@@ -995,7 +1062,8 @@ ping_zoneadmd(const char *zone_name)
int doorfd;
struct door_info info;
- get_doorname(zone_name, doorpath);
+ if (!get_doorname(zone_name, doorpath))
+ return (Z_ERR);
if ((doorfd = open(doorpath, O_RDONLY)) < 0) {
return (Z_ERR);
@@ -1036,7 +1104,11 @@ call_zoneadmd(const char *zone_name, zone_cmd_arg_t *arg)
}
arg->uniqid = uniqid;
(void) strlcpy(arg->locale, locale, sizeof (arg->locale));
- get_doorname(zone_name, doorpath);
+ if (!get_doorname(zone_name, doorpath)) {
+ zerror(gettext("alternate root path is too long"));
+ free(rvalp);
+ return (-1);
+ }
/*
* Loop trying to start zoneadmd; if something goes seriously
@@ -1104,6 +1176,11 @@ ready_func(int argc, char *argv[])
zone_cmd_arg_t zarg;
int arg;
+ if (zonecfg_in_alt_root()) {
+ zerror(gettext("cannot ready zone in alternate root"));
+ return (Z_ERR);
+ }
+
optind = 0;
if ((arg = getopt(argc, argv, "?")) != EOF) {
switch (arg) {
@@ -1138,6 +1215,11 @@ boot_func(int argc, char *argv[])
zone_cmd_arg_t zarg;
int arg;
+ if (zonecfg_in_alt_root()) {
+ zerror(gettext("cannot boot zone in alternate root"));
+ return (Z_ERR);
+ }
+
zarg.bootbuf[0] = '\0';
/*
@@ -1197,7 +1279,7 @@ static int
list_func(int argc, char *argv[])
{
zone_entry_t *zentp, zent;
- int arg;
+ int arg, retv;
boolean_t output = B_FALSE, verbose = B_FALSE, parsable = B_FALSE;
zone_state_t min_state = ZONE_STATE_RUNNING;
zoneid_t zone_id = getzoneid();
@@ -1233,12 +1315,13 @@ list_func(int argc, char *argv[])
return (Z_ERR);
}
if (zone_id == GLOBAL_ZONEID) {
- zone_print_list(min_state, verbose, parsable);
+ retv = zone_print_list(min_state, verbose, parsable);
} else {
+ retv = Z_OK;
fake_up_local_zone(zone_id, &zent);
zone_print(&zent, verbose, parsable);
}
- return (Z_OK);
+ return (retv);
}
/*
@@ -1284,7 +1367,8 @@ list_func(int argc, char *argv[])
} else if ((zentp = lookup_running_zone(target_zone)) != NULL) {
zone_print(zentp, verbose, parsable);
output = B_TRUE;
- } else if (lookup_zone_info(target_zone, &zent) == Z_OK) {
+ } else if (lookup_zone_info(target_zone, ZONE_ID_UNDEFINED,
+ &zent) == Z_OK) {
zone_print(&zent, verbose, parsable);
output = B_TRUE;
}
@@ -1380,6 +1464,8 @@ sanity_check(char *zone, int cmd_num, boolean_t running,
zone_entry_t *zent;
priv_set_t *privset;
zone_state_t state;
+ char kernzone[ZONENAME_MAX];
+ FILE *fp;
if (getzoneid() != GLOBAL_ZONEID) {
zerror(gettext("must be in the global zone to %s a zone."),
@@ -1411,10 +1497,7 @@ sanity_check(char *zone, int cmd_num, boolean_t running,
return (Z_ERR);
}
- zent = lookup_running_zone(zone);
-
if (strcmp(zone, GLOBAL_ZONENAME) == 0) {
- assert((zent != NULL) && (zent->zid == GLOBAL_ZONEID));
zerror(gettext("%s operation is invalid for the global zone."),
cmd_to_str(cmd_num));
return (Z_ERR);
@@ -1426,6 +1509,19 @@ sanity_check(char *zone, int cmd_num, boolean_t running,
return (Z_ERR);
}
+ if (!zonecfg_in_alt_root()) {
+ zent = lookup_running_zone(zone);
+ } else if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) {
+ zent = NULL;
+ } else {
+ if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(),
+ kernzone, sizeof (kernzone)) == 0)
+ zent = lookup_running_zone(kernzone);
+ else
+ zent = NULL;
+ zonecfg_close_scratch(fp);
+ }
+
/*
* Look up from the kernel for 'running' zones.
*/
@@ -1481,6 +1577,7 @@ sanity_check(char *zone, int cmd_num, boolean_t running,
break;
case CMD_READY:
case CMD_BOOT:
+ case CMD_MOUNT:
if (state < ZONE_STATE_INSTALLED) {
zerror(gettext("must be %s before %s."),
zone_state_str(ZONE_STATE_INSTALLED),
@@ -1496,6 +1593,14 @@ sanity_check(char *zone, int cmd_num, boolean_t running,
return (Z_ERR);
}
break;
+ case CMD_UNMOUNT:
+ if (state != ZONE_STATE_MOUNTED) {
+ zerror(gettext("must be %s before %s."),
+ zone_state_str(ZONE_STATE_MOUNTED),
+ cmd_to_str(cmd_num));
+ return (Z_ERR);
+ }
+ break;
}
}
return (Z_OK);
@@ -1507,6 +1612,11 @@ halt_func(int argc, char *argv[])
zone_cmd_arg_t zarg;
int arg;
+ if (zonecfg_in_alt_root()) {
+ zerror(gettext("cannot halt zone in alternate root"));
+ return (Z_ERR);
+ }
+
optind = 0;
if ((arg = getopt(argc, argv, "?")) != EOF) {
switch (arg) {
@@ -1540,6 +1650,11 @@ reboot_func(int argc, char *argv[])
zone_cmd_arg_t zarg;
int arg;
+ if (zonecfg_in_alt_root()) {
+ zerror(gettext("cannot reboot zone in alternate root"));
+ return (Z_ERR);
+ }
+
optind = 0;
if ((arg = getopt(argc, argv, "?")) != EOF) {
switch (arg) {
@@ -1792,6 +1907,7 @@ verify_details(int cmd_num)
char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
int return_code = Z_OK;
int err;
+ boolean_t in_alt_root;
if ((handle = zonecfg_init_handle()) == NULL) {
zperror(cmd_to_str(cmd_num), B_TRUE);
@@ -1834,6 +1950,10 @@ verify_details(int cmd_num)
return_code = Z_ERR;
}
+ in_alt_root = zonecfg_in_alt_root();
+ if (in_alt_root)
+ goto no_net;
+
if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
errno = err;
zperror(cmd_to_str(cmd_num), B_TRUE);
@@ -1881,12 +2001,13 @@ verify_details(int cmd_num)
(void) close(so);
}
(void) zonecfg_endnwifent(handle);
+no_net:
if (verify_filesystems(handle) != Z_OK)
return_code = Z_ERR;
- if (verify_rctls(handle) != Z_OK)
+ if (!in_alt_root && verify_rctls(handle) != Z_OK)
return_code = Z_ERR;
- if (verify_pool(handle) != Z_OK)
+ if (!in_alt_root && verify_pool(handle) != Z_OK)
return_code = Z_ERR;
zonecfg_fini_handle(handle);
if (return_code == Z_ERR)
@@ -1933,6 +2054,11 @@ install_func(int argc, char *argv[])
char zonepath[MAXPATHLEN];
int status;
+ if (zonecfg_in_alt_root()) {
+ zerror(gettext("cannot install zone in alternate root"));
+ return (Z_ERR);
+ }
+
optind = 0;
if ((arg = getopt(argc, argv, "?")) != EOF) {
switch (arg) {
@@ -2059,6 +2185,11 @@ uninstall_func(int argc, char *argv[])
int err, arg;
int status;
+ if (zonecfg_in_alt_root()) {
+ zerror(gettext("cannot uninstall zone in alternate root"));
+ return (Z_ERR);
+ }
+
optind = 0;
while ((arg = getopt(argc, argv, "?F")) != EOF) {
switch (arg) {
@@ -2167,6 +2298,46 @@ bad:
return (err);
}
+/* ARGSUSED */
+static int
+mount_func(int argc, char *argv[])
+{
+ zone_cmd_arg_t zarg;
+
+ if (argc > 0)
+ return (Z_USAGE);
+ if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE) != Z_OK)
+ return (Z_ERR);
+ if (verify_details(CMD_MOUNT) != Z_OK)
+ return (Z_ERR);
+
+ zarg.cmd = Z_MOUNT;
+ if (call_zoneadmd(target_zone, &zarg) != 0) {
+ zerror(gettext("call to %s failed"), "zoneadmd");
+ return (Z_ERR);
+ }
+ return (Z_OK);
+}
+
+/* ARGSUSED */
+static int
+unmount_func(int argc, char *argv[])
+{
+ zone_cmd_arg_t zarg;
+
+ if (argc > 0)
+ return (Z_USAGE);
+ if (sanity_check(target_zone, CMD_UNMOUNT, B_FALSE, B_FALSE) != Z_OK)
+ return (Z_ERR);
+
+ zarg.cmd = Z_UNMOUNT;
+ if (call_zoneadmd(target_zone, &zarg) != 0) {
+ zerror(gettext("call to %s failed"), "zoneadmd");
+ return (Z_ERR);
+ }
+ return (Z_OK);
+}
+
static int
help_func(int argc, char *argv[])
{
@@ -2253,6 +2424,7 @@ main(int argc, char **argv)
{
int arg;
zoneid_t zid;
+ struct stat st;
if ((locale = setlocale(LC_ALL, "")) == NULL)
locale = "C";
@@ -2266,13 +2438,25 @@ main(int argc, char **argv)
exit(Z_ERR);
}
- while ((arg = getopt(argc, argv, "?z:")) != EOF) {
+ while ((arg = getopt(argc, argv, "?z:R:")) != EOF) {
switch (arg) {
case '?':
return (usage(B_TRUE));
case 'z':
target_zone = optarg;
break;
+ case 'R': /* private option for admin/install use */
+ if (*optarg != '/') {
+ zerror(gettext("root path must be absolute."));
+ exit(Z_ERR);
+ }
+ if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) {
+ zerror(
+ gettext("root path must be a directory."));
+ exit(Z_ERR);
+ }
+ zonecfg_set_root(optarg);
+ break;
default:
return (usage(B_FALSE));
}
diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c
index 3b84bb82a0..75eca58961 100644
--- a/usr/src/cmd/zoneadmd/vplat.c
+++ b/usr/src/cmd/zoneadmd/vplat.c
@@ -34,6 +34,33 @@
* the way up, ready the zone; on the way down, they halt the zone.
* See the much longer block comment at the beginning of zoneadmd.c
* for a bigger picture of how the whole program functions.
+ *
+ * This module also has primary responsibility for the layout of "scratch
+ * zones." These are mounted, but inactive, zones that are used during
+ * operating system upgrade and potentially other administrative action. The
+ * scratch zone environment is similar to the miniroot environment. The zone's
+ * actual root is mounted read-write on /a, and the standard paths (/usr,
+ * /sbin, /lib) all lead to read-only copies of the running system's binaries.
+ * This allows the administrative tools to manipulate the zone using "-R /a"
+ * without relying on any binaries in the zone itself.
+ *
+ * If the scratch zone is on an alternate root (Live Upgrade [LU] boot
+ * environment), then we must resolve the lofs mounts used there to uncover
+ * writable (unshared) resources. Shared resources, though, are always
+ * read-only. In addition, if the "same" zone with a different root path is
+ * currently running, then "/b" inside the zone points to the running zone's
+ * root. This allows LU to synchronize configuration files during the upgrade
+ * process.
+ *
+ * To construct this environment, this module creates a tmpfs mount on
+ * $ZONEPATH/lu. Inside this scratch area, the miniroot-like environment as
+ * described above is constructed on the fly. The zone is then created using
+ * $ZONEPATH/lu as the root.
+ *
+ * Note that scratch zones are inactive. The zone's bits are not running and
+ * likely cannot be run correctly until upgrade is done. Init is not running
+ * there, nor is SMF. Because of this, the "mounted" state of a scratch zone
+ * is not a part of the usual halt/ready/boot state machine.
*/
#include <sys/param.h>
@@ -141,10 +168,22 @@ static struct symlink_info dev_symlinks[] = {
/* for routing socket */
static int rts_seqno = 0;
+/* mangled zone name when mounting in an alternate root environment */
+static char kernzone[ZONENAME_MAX];
+
+/* array of cached mount entries for resolve_lofs */
+static struct mnttab *resolve_lofs_mnts, *resolve_lofs_mnt_max;
+
/* from libsocket, not in any header file */
extern int getnetmaskbyaddr(struct in_addr, struct in_addr *);
/*
+ * An optimization for build_mnttable: reallocate (and potentially copy the
+ * data) only once every N times through the loop.
+ */
+#define MNTTAB_HUNK 32
+
+/*
* Private autofs system call
*/
extern int _autofssys(int, void *);
@@ -158,6 +197,244 @@ autofs_cleanup(zoneid_t zoneid)
return (_autofssys(AUTOFS_UNMOUNTALL, (void *)zoneid));
}
+static void
+free_mnttable(struct mnttab *mnt_array, uint_t nelem)
+{
+ uint_t i;
+
+ if (mnt_array == NULL)
+ return;
+ for (i = 0; i < nelem; i++) {
+ free(mnt_array[i].mnt_mountp);
+ free(mnt_array[i].mnt_fstype);
+ free(mnt_array[i].mnt_special);
+ free(mnt_array[i].mnt_mntopts);
+ assert(mnt_array[i].mnt_time == NULL);
+ }
+ free(mnt_array);
+}
+
+/*
+ * Build the mount table for the zone rooted at "zroot", storing the resulting
+ * array of struct mnttabs in "mnt_arrayp" and the number of elements in the
+ * array in "nelemp".
+ */
+static int
+build_mnttable(zlog_t *zlogp, const char *zroot, size_t zrootlen, FILE *mnttab,
+ struct mnttab **mnt_arrayp, uint_t *nelemp)
+{
+ struct mnttab mnt;
+ struct mnttab *mnts;
+ struct mnttab *mnp;
+ uint_t nmnt;
+
+ rewind(mnttab);
+ resetmnttab(mnttab);
+ nmnt = 0;
+ mnts = NULL;
+ while (getmntent(mnttab, &mnt) == 0) {
+ struct mnttab *tmp_array;
+
+ if (strncmp(mnt.mnt_mountp, zroot, zrootlen) != 0)
+ continue;
+ if (nmnt % MNTTAB_HUNK == 0) {
+ tmp_array = realloc(mnts,
+ (nmnt + MNTTAB_HUNK) * sizeof (*mnts));
+ if (tmp_array == NULL) {
+ free_mnttable(mnts, nmnt);
+ return (-1);
+ }
+ mnts = tmp_array;
+ }
+ mnp = &mnts[nmnt++];
+
+ /*
+ * Zero out any fields we're not using.
+ */
+ (void) memset(mnp, 0, sizeof (*mnp));
+
+ if (mnt.mnt_special != NULL)
+ mnp->mnt_special = strdup(mnt.mnt_special);
+ if (mnt.mnt_mntopts != NULL)
+ mnp->mnt_mntopts = strdup(mnt.mnt_mntopts);
+ mnp->mnt_mountp = strdup(mnt.mnt_mountp);
+ mnp->mnt_fstype = strdup(mnt.mnt_fstype);
+ if ((mnt.mnt_special != NULL && mnp->mnt_special == NULL) ||
+ (mnt.mnt_mntopts != NULL && mnp->mnt_mntopts == NULL) ||
+ mnp->mnt_mountp == NULL || mnp->mnt_fstype == NULL) {
+ zerror(zlogp, B_TRUE, "memory allocation failed");
+ free_mnttable(mnts, nmnt);
+ return (-1);
+ }
+ }
+ *mnt_arrayp = mnts;
+ *nelemp = nmnt;
+ return (0);
+}
+
+/*
+ * This is an optimization. The resolve_lofs function is used quite frequently
+ * to manipulate file paths, and on a machine with a large number of zones,
+ * there will be a huge number of mounted file systems. Thus, we trigger a
+ * reread of the list of mount points
+ */
+static void
+lofs_discard_mnttab(void)
+{
+ free_mnttable(resolve_lofs_mnts,
+ resolve_lofs_mnt_max - resolve_lofs_mnts);
+ resolve_lofs_mnts = resolve_lofs_mnt_max = NULL;
+}
+
+static int
+lofs_read_mnttab(zlog_t *zlogp)
+{
+ FILE *mnttab;
+ uint_t nmnts;
+
+ if ((mnttab = fopen(MNTTAB, "r")) == NULL)
+ return (-1);
+ if (build_mnttable(zlogp, "", 0, mnttab, &resolve_lofs_mnts,
+ &nmnts) == -1) {
+ (void) fclose(mnttab);
+ return (-1);
+ }
+ (void) fclose(mnttab);
+ resolve_lofs_mnt_max = resolve_lofs_mnts + nmnts;
+ return (0);
+}
+
+/*
+ * This function loops over potential loopback mounts and symlinks in a given
+ * path and resolves them all down to an absolute path.
+ */
+static void
+resolve_lofs(zlog_t *zlogp, char *path, size_t pathlen)
+{
+ int len, arlen;
+ const char *altroot;
+ char tmppath[MAXPATHLEN];
+ boolean_t outside_altroot;
+
+ if ((len = resolvepath(path, tmppath, sizeof (tmppath))) == -1)
+ return;
+ tmppath[len] = '\0';
+ (void) strlcpy(path, tmppath, sizeof (tmppath));
+
+ /* This happens once per zoneadmd operation. */
+ if (resolve_lofs_mnts == NULL && lofs_read_mnttab(zlogp) == -1)
+ return;
+
+ altroot = zonecfg_get_root();
+ arlen = strlen(altroot);
+ outside_altroot = B_FALSE;
+ for (;;) {
+ struct mnttab *mnp;
+
+ for (mnp = resolve_lofs_mnts; mnp < resolve_lofs_mnt_max;
+ mnp++) {
+ if (mnp->mnt_fstype == NULL ||
+ mnp->mnt_mountp == NULL ||
+ mnp->mnt_special == NULL ||
+ strcmp(mnp->mnt_fstype, MNTTYPE_LOFS) != 0)
+ continue;
+ len = strlen(mnp->mnt_mountp);
+ if (strncmp(mnp->mnt_mountp, path, len) == 0 &&
+ (path[len] == '/' || path[len] == '\0'))
+ break;
+ }
+ if (mnp >= resolve_lofs_mnt_max)
+ break;
+ if (outside_altroot) {
+ char *cp;
+ int olen = sizeof (MNTOPT_RO) - 1;
+
+ /*
+ * If we run into a read-only mount outside of the
+ * alternate root environment, then the user doesn't
+ * want this path to be made read-write.
+ */
+ if (mnp->mnt_mntopts != NULL &&
+ (cp = strstr(mnp->mnt_mntopts, MNTOPT_RO)) !=
+ NULL &&
+ (cp == mnp->mnt_mntopts || cp[-1] == ',') &&
+ (cp[olen] == '\0' || cp[olen] == ',')) {
+ break;
+ }
+ } else if (arlen > 0 &&
+ (strncmp(mnp->mnt_special, altroot, arlen) != 0 ||
+ (mnp->mnt_special[arlen] != '\0' &&
+ mnp->mnt_special[arlen] != '/'))) {
+ outside_altroot = B_TRUE;
+ }
+ /* use temporary buffer because new path might be longer */
+ (void) snprintf(tmppath, sizeof (tmppath), "%s%s",
+ mnp->mnt_special, path + len);
+ if ((len = resolvepath(tmppath, path, pathlen)) == -1)
+ break;
+ path[len] = '\0';
+ }
+}
+
+/*
+ * For a regular mount, check if a replacement lofs mount is needed because the
+ * referenced device is already mounted somewhere.
+ */
+static int
+check_lofs_needed(zlog_t *zlogp, struct zone_fstab *fsptr)
+{
+ struct mnttab *mnp;
+ zone_fsopt_t *optptr, *onext;
+
+ /* This happens once per zoneadmd operation. */
+ if (resolve_lofs_mnts == NULL && lofs_read_mnttab(zlogp) == -1)
+ return (-1);
+
+ /*
+ * If this special node isn't already in use, then it's ours alone;
+ * no need to worry about conflicting mounts.
+ */
+ for (mnp = resolve_lofs_mnts; mnp < resolve_lofs_mnt_max;
+ mnp++) {
+ if (strcmp(mnp->mnt_special, fsptr->zone_fs_special) == 0)
+ break;
+ }
+ if (mnp >= resolve_lofs_mnt_max)
+ return (0);
+
+ /*
+ * Convert this duplicate mount into a lofs mount.
+ */
+ (void) strlcpy(fsptr->zone_fs_special, mnp->mnt_mountp,
+ sizeof (fsptr->zone_fs_special));
+ (void) strlcpy(fsptr->zone_fs_type, MNTTYPE_LOFS,
+ sizeof (fsptr->zone_fs_type));
+ fsptr->zone_fs_raw[0] = '\0';
+
+ /*
+ * Discard all but one of the original options and set that to be the
+ * same set of options used for inherit package directory resources.
+ */
+ optptr = fsptr->zone_fs_options;
+ if (optptr == NULL) {
+ optptr = malloc(sizeof (*optptr));
+ if (optptr == NULL) {
+ zerror(zlogp, B_TRUE, "cannot mount %s",
+ fsptr->zone_fs_dir);
+ return (-1);
+ }
+ } else {
+ while ((onext = optptr->zone_fsopt_next) != NULL) {
+ optptr->zone_fsopt_next = onext->zone_fsopt_next;
+ free(onext);
+ }
+ }
+ (void) strcpy(optptr->zone_fsopt_opt, IPD_DEFAULT_OPTS);
+ optptr->zone_fsopt_next = NULL;
+ fsptr->zone_fs_options = optptr;
+ return (0);
+}
+
static int
make_one_dir(zlog_t *zlogp, const char *prefix, const char *subdir, mode_t mode)
{
@@ -237,8 +514,9 @@ make_dev_links(zlog_t *zlogp, char *zonepath)
(void) unlink(dev);
}
if (symlink(dev_symlinks[i].sl_target, dev) != 0) {
- zerror(zlogp, B_TRUE, "could not setup %s symlink",
- dev_symlinks[i].sl_source);
+ zerror(zlogp, B_TRUE, "could not setup %s->%s symlink",
+ dev_symlinks[i].sl_source,
+ dev_symlinks[i].sl_target);
return (-1);
}
}
@@ -257,6 +535,8 @@ create_dev_files(zlog_t *zlogp)
zerror(zlogp, B_TRUE, "unable to determine zone root");
return (-1);
}
+ if (zonecfg_in_alt_root())
+ resolve_lofs(zlogp, zonepath, sizeof (zonepath));
if (make_dev_dirs(zlogp, zonepath) != 0)
return (-1);
@@ -344,74 +624,16 @@ is_remote_fstype(const char *fstype, char *const *remote_fstypes)
return (B_FALSE);
}
-static void
-free_mnttable(struct mnttab *mnt_array, uint_t nelem)
-{
- uint_t i;
-
- if (mnt_array == NULL)
- return;
- for (i = 0; i < nelem; i++) {
- free(mnt_array[i].mnt_mountp);
- free(mnt_array[i].mnt_fstype);
- assert(mnt_array[i].mnt_special == NULL);
- assert(mnt_array[i].mnt_mntopts == NULL);
- assert(mnt_array[i].mnt_time == NULL);
- }
- free(mnt_array);
-}
-
/*
- * Build the mount table for the zone rooted at "zroot", storing the resulting
- * array of struct mnttabs in "mnt_arrayp" and the number of elements in the
- * array in "nelemp".
+ * This converts a zone root path (normally of the form .../root) to a Live
+ * Upgrade scratch zone root (of the form .../lu).
*/
-static int
-build_mnttable(zlog_t *zlogp, const char *zroot, size_t zrootlen, FILE *mnttab,
- struct mnttab **mnt_arrayp, uint_t *nelemp)
+static void
+root_to_lu(zlog_t *zlogp, char *zroot, size_t zrootlen, boolean_t isresolved)
{
- struct mnttab mnt;
- struct mnttab *mnts;
- struct mnttab *mnp;
- uint_t nmnt;
-
- rewind(mnttab);
- resetmnttab(mnttab);
- nmnt = 0;
- mnts = NULL;
- while (getmntent(mnttab, &mnt) == 0) {
- struct mnttab *tmp_array;
-
- if (strncmp(mnt.mnt_mountp, zroot, zrootlen) != 0)
- continue;
- nmnt++;
- tmp_array = realloc(mnts, nmnt * sizeof (*mnts));
- if (tmp_array == NULL) {
- nmnt--;
- free_mnttable(mnts, nmnt);
- return (-1);
- }
- mnts = tmp_array;
- mnp = &mnts[nmnt - 1];
- /*
- * Zero out the fields we won't be using.
- */
- mnp->mnt_special = NULL;
- mnp->mnt_mntopts = NULL;
- mnp->mnt_time = NULL;
-
- mnp->mnt_mountp = strdup(mnt.mnt_mountp);
- mnp->mnt_fstype = strdup(mnt.mnt_fstype);
- if (mnp->mnt_mountp == NULL ||
- mnp->mnt_fstype == NULL) {
- zerror(zlogp, B_TRUE, "memory allocation failed");
- free_mnttable(mnts, nmnt);
- return (-1);
- }
- }
- *mnt_arrayp = mnts;
- *nelemp = nmnt;
- return (0);
+ if (!isresolved && zonecfg_in_alt_root())
+ resolve_lofs(zlogp, zroot, zrootlen);
+ (void) strcpy(strrchr(zroot, '/') + 1, "lu");
}
/*
@@ -444,9 +666,8 @@ build_mnttable(zlog_t *zlogp, const char *zroot, size_t zrootlen, FILE *mnttab,
* Zone must be down (ie, no processes or threads active).
*/
static int
-unmount_filesystems(zlog_t *zlogp)
+unmount_filesystems(zlog_t *zlogp, zoneid_t zoneid, boolean_t unmount_cmd)
{
- zoneid_t zoneid;
int error = 0;
FILE *mnttab;
struct mnttab *mnts;
@@ -457,15 +678,12 @@ unmount_filesystems(zlog_t *zlogp)
boolean_t stuck = B_FALSE;
char **remote_fstypes = NULL;
- if ((zoneid = getzoneidbyname(zone_name)) == -1) {
- zerror(zlogp, B_TRUE, "unable to find zoneid");
- return (-1);
- }
-
if (zone_get_rootpath(zone_name, zroot, sizeof (zroot)) != Z_OK) {
zerror(zlogp, B_FALSE, "unable to determine zone root");
return (-1);
}
+ if (unmount_cmd)
+ root_to_lu(zlogp, zroot, sizeof (zroot), B_FALSE);
(void) strcat(zroot, "/");
zrootlen = strlen(zroot);
@@ -796,6 +1014,7 @@ static int
mount_one(zlog_t *zlogp, struct zone_fstab *fsptr, const char *rootpath)
{
char path[MAXPATHLEN];
+ char specpath[MAXPATHLEN];
char optstr[MAX_MNTOPT_STR];
zone_fsopt_t *optptr;
@@ -815,12 +1034,22 @@ mount_one(zlog_t *zlogp, struct zone_fstab *fsptr, const char *rootpath)
if (strlen(fsptr->zone_fs_special) == 0) {
/*
* A zero-length special is how we distinguish IPDs from
- * general-purpose FSs.
+ * general-purpose FSs. Make sure it mounts from a place that
+ * can be seen via the alternate zone's root.
*/
+ if (snprintf(specpath, sizeof (specpath), "%s%s",
+ zonecfg_get_root(), fsptr->zone_fs_dir) >=
+ sizeof (specpath)) {
+ zerror(zlogp, B_FALSE, "cannot mount %s: path too "
+ "long in alternate root", fsptr->zone_fs_dir);
+ return (-1);
+ }
+ if (zonecfg_in_alt_root())
+ resolve_lofs(zlogp, specpath, sizeof (specpath));
if (domount(zlogp, MNTTYPE_LOFS, IPD_DEFAULT_OPTS,
- fsptr->zone_fs_dir, path) != 0) {
+ specpath, path) != 0) {
zerror(zlogp, B_TRUE, "failed to loopback mount %s",
- fsptr->zone_fs_dir);
+ specpath);
return (-1);
}
return (0);
@@ -843,6 +1072,36 @@ mount_one(zlog_t *zlogp, struct zone_fstab *fsptr, const char *rootpath)
}
/*
+ * If we're looking at an alternate root environment, then construct
+ * read-only loopback mounts as necessary. For all lofs mounts, make
+ * sure that the 'special' entry points inside the alternate root. (We
+ * don't do this with other mounts, as devfs isn't in the alternate
+ * root, and we need to assume the device environment is roughly the
+ * same.)
+ */
+ if (zonecfg_in_alt_root()) {
+ struct stat64 st;
+
+ if (stat64(fsptr->zone_fs_special, &st) != -1 &&
+ S_ISBLK(st.st_mode) &&
+ check_lofs_needed(zlogp, fsptr) == -1)
+ return (-1);
+ if (strcmp(fsptr->zone_fs_type, MNTTYPE_LOFS) == 0) {
+ if (snprintf(specpath, sizeof (specpath), "%s%s",
+ zonecfg_get_root(), fsptr->zone_fs_special) >=
+ sizeof (specpath)) {
+ zerror(zlogp, B_FALSE, "cannot mount %s: path "
+ "too long in alternate root",
+ fsptr->zone_fs_special);
+ return (-1);
+ }
+ resolve_lofs(zlogp, specpath, sizeof (specpath));
+ (void) strlcpy(fsptr->zone_fs_special, specpath,
+ sizeof (fsptr->zone_fs_special));
+ }
+ }
+
+ /*
* Run 'fsck -m' if there's a device to fsck.
*/
if (fsptr->zone_fs_raw[0] != '\0' &&
@@ -879,8 +1138,174 @@ free_fs_data(struct zone_fstab *fsarray, uint_t nelem)
free(fsarray);
}
+/*
+ * This function constructs the miniroot-like "scratch zone" environment. If
+ * it returns B_FALSE, then the error has already been logged.
+ */
+static boolean_t
+build_mounted(zlog_t *zlogp, char *rootpath, size_t rootlen,
+ const char *zonepath)
+{
+ char tmp[MAXPATHLEN], fromdir[MAXPATHLEN];
+ char luroot[MAXPATHLEN];
+ const char **cpp;
+ static const char *mkdirs[] = {
+ "/system", "/system/contract", "/proc", "/dev", "/tmp",
+ "/a", NULL
+ };
+ static const char *localdirs[] = {
+ "/etc", "/var", NULL
+ };
+ static const char *loopdirs[] = {
+ "/etc/lib", "/etc/fs", "/lib", "/sbin", "/platform",
+ "/usr", NULL
+ };
+ static const char *tmpdirs[] = {
+ "/tmp", "/var/run", NULL
+ };
+ FILE *fp;
+ struct stat st;
+ char *altstr;
+ uuid_t uuid;
+
+ /*
+ * Construct a small Solaris environment, including the zone root
+ * mounted on '/a' inside that environment.
+ */
+ resolve_lofs(zlogp, rootpath, rootlen);
+ (void) snprintf(luroot, sizeof (luroot), "%s/lu", zonepath);
+ resolve_lofs(zlogp, luroot, sizeof (luroot));
+ (void) snprintf(tmp, sizeof (tmp), "%s/bin", luroot);
+ (void) symlink("./usr/bin", tmp);
+
+ /*
+ * These are mostly special mount points; not handled here. (See
+ * zone_mount_early.)
+ */
+ for (cpp = mkdirs; *cpp != NULL; cpp++) {
+ (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, *cpp);
+ if (mkdir(tmp, 0755) != 0) {
+ zerror(zlogp, B_TRUE, "cannot create %s", tmp);
+ return (B_FALSE);
+ }
+ }
+
+ /*
+ * These are mounted read-write from the zone undergoing upgrade. We
+ * must be careful not to 'leak' things from the main system into the
+ * zone, and this accomplishes that goal.
+ */
+ for (cpp = localdirs; *cpp != NULL; cpp++) {
+ (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, *cpp);
+ (void) snprintf(fromdir, sizeof (fromdir), "%s%s", rootpath,
+ *cpp);
+ if (mkdir(tmp, 0755) != 0) {
+ zerror(zlogp, B_TRUE, "cannot create %s", tmp);
+ return (B_FALSE);
+ }
+ if (domount(zlogp, MNTTYPE_LOFS, "", fromdir, tmp) != 0) {
+ zerror(zlogp, B_TRUE, "cannot mount %s on %s", tmp,
+ *cpp);
+ return (B_FALSE);
+ }
+ }
+
+ /*
+ * These are things mounted read-only from the running system because
+ * they contain binaries that must match system.
+ */
+ for (cpp = loopdirs; *cpp != NULL; cpp++) {
+ (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, *cpp);
+ if (mkdir(tmp, 0755) != 0) {
+ if (errno != EEXIST) {
+ zerror(zlogp, B_TRUE, "cannot create %s", tmp);
+ return (B_FALSE);
+ }
+ if (lstat(tmp, &st) != 0) {
+ zerror(zlogp, B_TRUE, "cannot stat %s", tmp);
+ return (B_FALSE);
+ }
+ /*
+ * Ignore any non-directories encountered. These are
+ * things that have been converted into symlinks
+ * (/etc/fs and /etc/lib) and no longer need a lofs
+ * fixup.
+ */
+ if (!S_ISDIR(st.st_mode))
+ continue;
+ }
+ if (domount(zlogp, MNTTYPE_LOFS, IPD_DEFAULT_OPTS, *cpp,
+ tmp) != 0) {
+ zerror(zlogp, B_TRUE, "cannot mount %s on %s", tmp,
+ *cpp);
+ return (B_FALSE);
+ }
+ }
+
+ /*
+ * These are things with tmpfs mounted inside.
+ */
+ for (cpp = tmpdirs; *cpp != NULL; cpp++) {
+ (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, *cpp);
+ if (mkdir(tmp, 0755) != 0 && errno != EEXIST) {
+ zerror(zlogp, B_TRUE, "cannot create %s", tmp);
+ return (B_FALSE);
+ }
+ if (domount(zlogp, MNTTYPE_TMPFS, "", "swap", tmp) != 0) {
+ zerror(zlogp, B_TRUE, "cannot mount swap on %s", *cpp);
+ return (B_FALSE);
+ }
+ }
+
+ /*
+ * This is here to support lucopy. If there's an instance of this same
+ * zone on the current running system, then we mount its root up as
+ * read-only inside the scratch zone.
+ */
+ (void) zonecfg_get_uuid(zone_name, uuid);
+ altstr = strdup(zonecfg_get_root());
+ if (altstr == NULL) {
+ zerror(zlogp, B_TRUE, "out of memory");
+ return (B_FALSE);
+ }
+ zonecfg_set_root("");
+ (void) strlcpy(tmp, zone_name, sizeof (tmp));
+ (void) zonecfg_get_name_by_uuid(uuid, tmp, sizeof (tmp));
+ if (zone_get_rootpath(tmp, fromdir, sizeof (fromdir)) == Z_OK &&
+ strcmp(fromdir, rootpath) != 0) {
+ (void) snprintf(tmp, sizeof (tmp), "%s/b", luroot);
+ if (mkdir(tmp, 0755) != 0) {
+ zerror(zlogp, B_TRUE, "cannot create %s", tmp);
+ return (B_FALSE);
+ }
+ if (domount(zlogp, MNTTYPE_LOFS, IPD_DEFAULT_OPTS, fromdir,
+ tmp) != 0) {
+ zerror(zlogp, B_TRUE, "cannot mount %s on %s", tmp,
+ fromdir);
+ return (B_FALSE);
+ }
+ }
+ zonecfg_set_root(altstr);
+ free(altstr);
+
+ if ((fp = zonecfg_open_scratch(luroot, B_TRUE)) == NULL) {
+ zerror(zlogp, B_TRUE, "cannot open zone mapfile");
+ return (B_FALSE);
+ }
+ (void) ftruncate(fileno(fp), 0);
+ if (zonecfg_add_scratch(fp, zone_name, kernzone, "/") == -1) {
+ zerror(zlogp, B_TRUE, "cannot add zone mapfile entry");
+ }
+ zonecfg_close_scratch(fp);
+ (void) snprintf(tmp, sizeof (tmp), "%s/a", luroot);
+ if (domount(zlogp, MNTTYPE_LOFS, "", rootpath, tmp) != 0)
+ return (B_FALSE);
+ (void) strlcpy(rootpath, tmp, rootlen);
+ return (B_TRUE);
+}
+
static int
-mount_filesystems(zlog_t *zlogp)
+mount_filesystems(zlog_t *zlogp, boolean_t mount_cmd)
{
char rootpath[MAXPATHLEN];
char zonepath[MAXPATHLEN];
@@ -891,10 +1316,11 @@ mount_filesystems(zlog_t *zlogp)
zone_state_t zstate;
if (zone_get_state(zone_name, &zstate) != Z_OK ||
- zstate != ZONE_STATE_READY) {
+ (zstate != ZONE_STATE_READY && zstate != ZONE_STATE_MOUNTED)) {
zerror(zlogp, B_FALSE,
- "zone must be in '%s' state to mount file-systems",
- zone_state_str(ZONE_STATE_READY));
+ "zone must be in '%s' or '%s' state to mount file-systems",
+ zone_state_str(ZONE_STATE_READY),
+ zone_state_str(ZONE_STATE_MOUNTED));
goto bad;
}
@@ -936,9 +1362,14 @@ mount_filesystems(zlog_t *zlogp)
}
fs_ptr = tmp_ptr;
fsp = &fs_ptr[num_fs - 1];
+ /*
+ * Note that mount_one will prepend the alternate root to
+ * zone_fs_special and do the necessary resolution, so all that is
+ * needed here is to strip the root added by zone_get_zonepath.
+ */
(void) strlcpy(fsp->zone_fs_dir, "/dev", sizeof (fsp->zone_fs_dir));
(void) snprintf(fsp->zone_fs_special, sizeof (fsp->zone_fs_special),
- "%s/dev", zonepath);
+ "%s/dev", zonepath + strlen(zonecfg_get_root()));
fsp->zone_fs_raw[0] = '\0';
(void) strlcpy(fsp->zone_fs_type, MNTTYPE_LOFS,
sizeof (fsp->zone_fs_type));
@@ -1011,8 +1442,28 @@ mount_filesystems(zlog_t *zlogp)
zonecfg_fini_handle(handle);
handle = NULL;
+ /*
+ * If we're mounting a zone for administration, then we need to set up
+ * the "/a" environment inside the zone so that the commands that run
+ * in there have access to both the running system's utilities and the
+ * to-be-modified zone's files.
+ */
+ if (mount_cmd &&
+ !build_mounted(zlogp, rootpath, sizeof (rootpath), zonepath))
+ goto bad;
+
qsort(fs_ptr, num_fs, sizeof (*fs_ptr), fs_compare);
for (i = 0; i < num_fs; i++) {
+ if (mount_cmd && strcmp(fs_ptr[i].zone_fs_dir, "/dev") == 0) {
+ size_t slen = strlen(rootpath) - 2;
+
+ /* /dev is special and always goes at the top */
+ rootpath[slen] = '\0';
+ if (mount_one(zlogp, &fs_ptr[i], rootpath) != 0)
+ goto bad;
+ rootpath[slen] = '/';
+ continue;
+ }
if (mount_one(zlogp, &fs_ptr[i], rootpath) != 0)
goto bad;
}
@@ -1795,7 +2246,7 @@ devfsadm_call(zlog_t *zlogp, const char *arg)
if (status == 0 || status == -1)
return (status);
zerror(zlogp, B_FALSE, "%s call (%s %s %s) unexpectedly returned %d",
- DEVFSADM, DEVFSADM_PATH, arg, zone_name, status);
+ DEVFSADM, DEVFSADM_PATH, arg, zone_name, status);
return (-1);
}
@@ -2062,21 +2513,115 @@ prtmount(const char *fs, void *x) {
return (0);
}
-int
-vplat_create(zlog_t *zlogp)
+/*
+ * Look for zones running on the main system that are using this root (or any
+ * subdirectory of it). Return B_TRUE and print an error if a conflicting zone
+ * is found or if we can't tell.
+ */
+static boolean_t
+duplicate_zone_root(zlog_t *zlogp, const char *rootpath)
{
- int rval = -1;
+ zoneid_t *zids = NULL;
+ uint_t nzids = 0;
+ boolean_t retv;
+ int rlen, zlen;
+ char zroot[MAXPATHLEN];
+ char zonename[ZONENAME_MAX];
+
+ for (;;) {
+ nzids += 10;
+ zids = malloc(nzids * sizeof (*zids));
+ if (zids == NULL) {
+ zerror(zlogp, B_TRUE, "unable to allocate memory");
+ return (B_TRUE);
+ }
+ if (zone_list(zids, &nzids) == 0)
+ break;
+ free(zids);
+ }
+ retv = B_FALSE;
+ rlen = strlen(rootpath);
+ while (nzids > 0) {
+ /*
+ * Ignore errors; they just mean that the zone has disappeared
+ * while we were busy.
+ */
+ if (zone_getattr(zids[--nzids], ZONE_ATTR_ROOT, zroot,
+ sizeof (zroot)) == -1)
+ continue;
+ zlen = strlen(zroot);
+ if (zlen > rlen)
+ zlen = rlen;
+ if (strncmp(rootpath, zroot, zlen) == 0 &&
+ (zroot[zlen] == '\0' || zroot[zlen] == '/') &&
+ (rootpath[zlen] == '\0' || rootpath[zlen] == '/')) {
+ if (getzonenamebyid(zids[nzids], zonename,
+ sizeof (zonename)) == -1)
+ (void) snprintf(zonename, sizeof (zonename),
+ "id %d", (int)zids[nzids]);
+ zerror(zlogp, B_FALSE,
+ "zone root %s already in use by zone %s",
+ rootpath, zonename);
+ retv = B_TRUE;
+ break;
+ }
+ }
+ free(zids);
+ return (retv);
+}
+
+/*
+ * Search for loopback mounts that use this same source node (same device and
+ * inode). Return B_TRUE if there is one or if we can't tell.
+ */
+static boolean_t
+duplicate_reachable_path(zlog_t *zlogp, const char *rootpath)
+{
+ struct stat64 rst, zst;
+ struct mnttab *mnp;
+
+ if (stat64(rootpath, &rst) == -1) {
+ zerror(zlogp, B_TRUE, "can't stat %s", rootpath);
+ return (B_TRUE);
+ }
+ if (resolve_lofs_mnts == NULL && lofs_read_mnttab(zlogp) == -1)
+ return (B_TRUE);
+ for (mnp = resolve_lofs_mnts; mnp < resolve_lofs_mnt_max; mnp++) {
+ if (mnp->mnt_fstype == NULL ||
+ strcmp(MNTTYPE_LOFS, mnp->mnt_fstype) != 0)
+ continue;
+ /* We're looking at a loopback mount. Stat it. */
+ if (mnp->mnt_special != NULL &&
+ stat64(mnp->mnt_special, &zst) != -1 &&
+ rst.st_dev == zst.st_dev && rst.st_ino == zst.st_ino) {
+ zerror(zlogp, B_FALSE,
+ "zone root %s is reachable through %s",
+ rootpath, mnp->mnt_mountp);
+ return (B_TRUE);
+ }
+ }
+ return (B_FALSE);
+}
+
+zoneid_t
+vplat_create(zlog_t *zlogp, boolean_t mount_cmd)
+{
+ zoneid_t rval = -1;
priv_set_t *privs;
char rootpath[MAXPATHLEN];
char *rctlbuf = NULL;
- size_t rctlbufsz;
- zoneid_t zoneid;
+ size_t rctlbufsz = 0;
+ zoneid_t zoneid = -1;
int xerr;
+ char *kzone;
+ FILE *fp = NULL;
if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) {
zerror(zlogp, B_TRUE, "unable to determine zone root");
return (-1);
}
+ if (zonecfg_in_alt_root())
+ resolve_lofs(zlogp, rootpath, sizeof (rootpath));
if ((privs = priv_allocset()) == NULL) {
zerror(zlogp, B_TRUE, "%s failed", "priv_allocset");
@@ -2087,13 +2632,80 @@ vplat_create(zlog_t *zlogp)
zerror(zlogp, B_TRUE, "Failed to initialize privileges");
goto error;
}
- if (get_rctls(zlogp, &rctlbuf, &rctlbufsz) != 0) {
+ if (!mount_cmd && get_rctls(zlogp, &rctlbuf, &rctlbufsz) != 0) {
zerror(zlogp, B_FALSE, "Unable to get list of rctls");
goto error;
}
+ kzone = zone_name;
+
+ /*
+ * We must do this scan twice. First, we look for zones running on the
+ * main system that are using this root (or any subdirectory of it).
+ * Next, we reduce to the shortest path and search for loopback mounts
+ * that use this same source node (same device and inode).
+ */
+ if (duplicate_zone_root(zlogp, rootpath))
+ goto error;
+ if (duplicate_reachable_path(zlogp, rootpath))
+ goto error;
+
+ if (mount_cmd) {
+ root_to_lu(zlogp, rootpath, sizeof (rootpath), B_TRUE);
+
+ /*
+ * Forge up a special root for this zone. When a zone is
+ * mounted, we can't let the zone have its own root because the
+ * tools that will be used in this "scratch zone" need access
+ * to both the zone's resources and the running machine's
+ * executables.
+ *
+ * Note that the mkdir here also catches read-only filesystems.
+ */
+ if (mkdir(rootpath, 0755) != 0 && errno != EEXIST) {
+ zerror(zlogp, B_TRUE, "cannot create %s", rootpath);
+ goto error;
+ }
+ if (domount(zlogp, "tmpfs", "", "swap", rootpath) != 0)
+ goto error;
+ }
+
+ if (zonecfg_in_alt_root()) {
+ /*
+ * If we are mounting up a zone in an alternate root partition,
+ * then we have some additional work to do before starting the
+ * zone. First, resolve the root path down so that we're not
+ * fooled by duplicates. Then forge up an internal name for
+ * the zone.
+ */
+ if ((fp = zonecfg_open_scratch("", B_TRUE)) == NULL) {
+ zerror(zlogp, B_TRUE, "cannot open mapfile");
+ goto error;
+ }
+ if (zonecfg_lock_scratch(fp) != 0) {
+ zerror(zlogp, B_TRUE, "cannot lock mapfile");
+ goto error;
+ }
+ if (zonecfg_find_scratch(fp, zone_name, zonecfg_get_root(),
+ NULL, 0) == 0) {
+ zerror(zlogp, B_FALSE, "scratch zone already running");
+ goto error;
+ }
+ /* This is the preferred name */
+ (void) snprintf(kernzone, sizeof (kernzone), "SUNWlu-%s",
+ zone_name);
+ srandom(getpid());
+ while (zonecfg_reverse_scratch(fp, kernzone, NULL, 0, NULL,
+ 0) == 0) {
+ /* This is just an arbitrary name; note "." usage */
+ (void) snprintf(kernzone, sizeof (kernzone),
+ "SUNWlu.%08lX%08lX", random(), random());
+ }
+ kzone = kernzone;
+ }
+
xerr = 0;
- if ((zoneid = zone_create(zone_name, rootpath, privs, rctlbuf,
+ if ((zoneid = zone_create(kzone, rootpath, privs, rctlbuf,
rctlbufsz, &xerr)) == -1) {
if (xerr == ZE_AREMOUNTS) {
if (zonecfg_find_mounts(rootpath, NULL, NULL) < 1) {
@@ -2117,42 +2729,147 @@ vplat_create(zlog_t *zlogp)
}
goto error;
}
+
+ if (zonecfg_in_alt_root() &&
+ zonecfg_add_scratch(fp, zone_name, kernzone,
+ zonecfg_get_root()) == -1) {
+ zerror(zlogp, B_TRUE, "cannot add mapfile entry");
+ goto error;
+ }
+
/*
- * The following is a warning, not an error.
+ * The following is a warning, not an error, and is not performed when
+ * merely mounting a zone for administrative use.
*/
- if (bind_to_pool(zlogp, zoneid) != 0)
+ if (!mount_cmd && bind_to_pool(zlogp, zoneid) != 0)
zerror(zlogp, B_FALSE, "WARNING: unable to bind zone to "
"requested pool; using default pool.");
- rval = 0;
+ rval = zoneid;
+ zoneid = -1;
+
error:
+ if (zoneid != -1)
+ (void) zone_destroy(zoneid);
if (rctlbuf != NULL)
free(rctlbuf);
priv_freeset(privs);
+ if (fp != NULL)
+ zonecfg_close_scratch(fp);
+ lofs_discard_mnttab();
return (rval);
}
int
-vplat_bringup(zlog_t *zlogp)
+vplat_bringup(zlog_t *zlogp, boolean_t mount_cmd)
{
- if (create_dev_files(zlogp) != 0)
+ if (create_dev_files(zlogp) != 0 ||
+ mount_filesystems(zlogp, mount_cmd) != 0) {
+ lofs_discard_mnttab();
return (-1);
- if (mount_filesystems(zlogp) != 0)
+ }
+ if (!mount_cmd && (devfsadm_register(zlogp) != 0 ||
+ configure_network_interfaces(zlogp) != 0)) {
+ lofs_discard_mnttab();
return (-1);
- if (devfsadm_register(zlogp) != 0)
+ }
+ lofs_discard_mnttab();
+ return (0);
+}
+
+static int
+lu_root_teardown(zlog_t *zlogp)
+{
+ char zroot[MAXPATHLEN];
+
+ if (zone_get_rootpath(zone_name, zroot, sizeof (zroot)) != Z_OK) {
+ zerror(zlogp, B_FALSE, "unable to determine zone root");
return (-1);
- if (configure_network_interfaces(zlogp) != 0)
+ }
+ root_to_lu(zlogp, zroot, sizeof (zroot), B_FALSE);
+
+ /*
+ * At this point, the processes are gone, the filesystems (save the
+ * root) are unmounted, and the zone is on death row. But there may
+ * still be creds floating about in the system that reference the
+ * zone_t, and which pin down zone_rootvp causing this call to fail
+ * with EBUSY. Thus, we try for a little while before just giving up.
+ * (How I wish this were not true, and umount2 just did the right
+ * thing, or tmpfs supported MS_FORCE This is a gross hack.)
+ */
+ if (umount2(zroot, MS_FORCE) != 0) {
+ if (errno == ENOTSUP && umount2(zroot, 0) == 0)
+ goto unmounted;
+ if (errno == EBUSY) {
+ int tries = 10;
+
+ while (--tries >= 0) {
+ (void) sleep(1);
+ if (umount2(zroot, 0) == 0)
+ goto unmounted;
+ if (errno != EBUSY)
+ break;
+ }
+ }
+ zerror(zlogp, B_TRUE, "unable to unmount '%s'", zroot);
return (-1);
- return (0);
+ }
+unmounted:
+
+ /*
+ * Only zones in an alternate root environment have scratch zone
+ * entries.
+ */
+ if (zonecfg_in_alt_root()) {
+ FILE *fp;
+ int retv;
+
+ if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) {
+ zerror(zlogp, B_TRUE, "cannot open mapfile");
+ return (-1);
+ }
+ retv = -1;
+ if (zonecfg_lock_scratch(fp) != 0)
+ zerror(zlogp, B_TRUE, "cannot lock mapfile");
+ else if (zonecfg_delete_scratch(fp, kernzone) != 0)
+ zerror(zlogp, B_TRUE, "cannot delete map entry");
+ else
+ retv = 0;
+ zonecfg_close_scratch(fp);
+ return (retv);
+ } else {
+ return (0);
+ }
}
int
-vplat_teardown(zlog_t *zlogp)
+vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd)
{
+ char *kzone;
zoneid_t zoneid;
- if ((zoneid = getzoneidbyname(zone_name)) == ZONE_ID_UNDEFINED) {
+ kzone = zone_name;
+ if (zonecfg_in_alt_root()) {
+ FILE *fp;
+
+ if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) {
+ zerror(zlogp, B_TRUE, "unable to open map file");
+ goto error;
+ }
+ if (zonecfg_find_scratch(fp, zone_name, zonecfg_get_root(),
+ kernzone, sizeof (kernzone)) != 0) {
+ zerror(zlogp, B_FALSE, "unable to find scratch zone");
+ zonecfg_close_scratch(fp);
+ goto error;
+ }
+ zonecfg_close_scratch(fp);
+ kzone = kernzone;
+ }
+
+ if ((zoneid = getzoneidbyname(kzone)) == ZONE_ID_UNDEFINED) {
if (!bringup_failure_recovery)
zerror(zlogp, B_TRUE, "unable to get zoneid");
+ if (unmount_cmd)
+ (void) lu_root_teardown(zlogp);
goto error;
}
@@ -2161,21 +2878,22 @@ vplat_teardown(zlog_t *zlogp)
goto error;
}
- if (devfsadm_unregister(zlogp) != 0)
+ if (!unmount_cmd && devfsadm_unregister(zlogp) != 0)
goto error;
- if (unconfigure_network_interfaces(zlogp, zoneid) != 0) {
+ if (!unmount_cmd &&
+ unconfigure_network_interfaces(zlogp, zoneid) != 0) {
zerror(zlogp, B_FALSE,
"unable to unconfigure network interfaces in zone");
goto error;
}
- if (tcp_abort_connections(zlogp, zoneid) != 0) {
+ if (!unmount_cmd && tcp_abort_connections(zlogp, zoneid) != 0) {
zerror(zlogp, B_TRUE, "unable to abort TCP connections");
goto error;
}
- if (unmount_filesystems(zlogp) != 0) {
+ if (unmount_filesystems(zlogp, zoneid, unmount_cmd) != 0) {
zerror(zlogp, B_FALSE,
"unable to unmount file systems in zone");
goto error;
@@ -2185,10 +2903,21 @@ vplat_teardown(zlog_t *zlogp)
zerror(zlogp, B_TRUE, "unable to destroy zone");
goto error;
}
- destroy_console_slave();
+ /*
+ * Special teardown for alternate boot environments: remove the tmpfs
+ * root for the zone and then remove it from the map file.
+ */
+ if (unmount_cmd && lu_root_teardown(zlogp) != 0)
+ goto error;
+
+ if (!unmount_cmd)
+ destroy_console_slave();
+
+ lofs_discard_mnttab();
return (0);
error:
+ lofs_discard_mnttab();
return (-1);
}
diff --git a/usr/src/cmd/zoneadmd/zoneadmd.c b/usr/src/cmd/zoneadmd/zoneadmd.c
index 1cd6ac3945..9b2f346883 100644
--- a/usr/src/cmd/zoneadmd/zoneadmd.c
+++ b/usr/src/cmd/zoneadmd/zoneadmd.c
@@ -103,12 +103,15 @@
static char *progname;
char *zone_name; /* zone which we are managing */
+static zoneid_t zone_id;
static zlog_t logsys;
mutex_t lock = DEFAULTMUTEX; /* to serialize stuff */
mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */
+static sema_t scratch_sem; /* for scratch zones */
+
static char zone_door_path[MAXPATHLEN];
static int zone_door = -1;
@@ -123,6 +126,21 @@ boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */
#define DEFAULT_LOCALE "C"
+static const char *
+z_cmd_name(zone_cmd_t zcmd)
+{
+ /* This list needs to match the enum in sys/zone.h */
+ static const char *zcmdstr[] = {
+ "ready", "boot", "reboot", "halt", "note_uninstalling",
+ "mount", "unmount"
+ };
+
+ if (zcmd >= sizeof (zcmdstr) / sizeof (*zcmdstr))
+ return ("unknown");
+ else
+ return (zcmdstr[(int)zcmd]);
+}
+
static char *
get_execbasename(char *execfullname)
{
@@ -244,8 +262,13 @@ mkzonedir(zlog_t *zlogp)
return (0);
}
-static zoneid_t
-zone_ready(zlog_t *zlogp)
+/*
+ * Bring a zone up to the pre-boot "ready" stage. The mount_cmd argument is
+ * 'true' if this is being invoked as part of the processing for the "mount"
+ * subcommand.
+ */
+static int
+zone_ready(zlog_t *zlogp, boolean_t mount_cmd)
{
int err;
@@ -255,15 +278,15 @@ zone_ready(zlog_t *zlogp)
return (-1);
}
- if (vplat_create(zlogp) != 0) {
+ if ((zone_id = vplat_create(zlogp, mount_cmd)) == -1) {
if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
zerror(zlogp, B_FALSE, "destroying snapshot: %s",
zonecfg_strerror(err));
return (-1);
}
- if (vplat_bringup(zlogp) != 0) {
+ if (vplat_bringup(zlogp, mount_cmd) != 0) {
bringup_failure_recovery = B_TRUE;
- (void) vplat_teardown(NULL);
+ (void) vplat_teardown(NULL, mount_cmd);
if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
zerror(zlogp, B_FALSE, "destroying snapshot: %s",
zonecfg_strerror(err));
@@ -356,6 +379,26 @@ mount_early_fs(zlog_t *zlogp, zoneid_t zoneid, const char *spec,
}
static int
+zone_mount_early(zlog_t *zlogp, zoneid_t zoneid)
+{
+ if (mount_early_fs(zlogp, zoneid, "/proc", "/proc", "proc") != 0)
+ return (-1);
+
+ if (mount_early_fs(zlogp, zoneid, "ctfs", CTFS_ROOT, "ctfs") != 0)
+ return (-1);
+
+ if (mount_early_fs(zlogp, zoneid, "swap", "/etc/svc/volatile",
+ "tmpfs") != 0)
+ return (-1);
+
+ if (mount_early_fs(zlogp, zoneid, "mnttab", "/etc/mnttab",
+ "mntfs") != 0)
+ return (-1);
+
+ return (0);
+}
+
+static int
zone_bootup(zlog_t *zlogp, const char *bootargs)
{
zoneid_t zoneid;
@@ -371,18 +414,7 @@ zone_bootup(zlog_t *zlogp, const char *bootargs)
return (-1);
}
- if (mount_early_fs(zlogp, zoneid, "/proc", "/proc", "proc") != 0)
- return (-1);
-
- if (mount_early_fs(zlogp, zoneid, "ctfs", CTFS_ROOT, "ctfs") != 0)
- return (-1);
-
- if (mount_early_fs(zlogp, zoneid, "swap", "/etc/svc/volatile",
- "tmpfs") != 0)
- return (-1);
-
- if (mount_early_fs(zlogp, zoneid, "mnttab", "/etc/mnttab",
- "mntfs") != 0)
+ if (zone_mount_early(zlogp, zoneid) != 0)
return (-1);
/*
@@ -414,11 +446,11 @@ zone_bootup(zlog_t *zlogp, const char *bootargs)
}
static int
-zone_halt(zlog_t *zlogp)
+zone_halt(zlog_t *zlogp, boolean_t unmount_cmd)
{
int err;
- if (vplat_teardown(zlogp) != 0) {
+ if (vplat_teardown(zlogp, unmount_cmd) != 0) {
if (!bringup_failure_recovery)
zerror(zlogp, B_FALSE, "unable to destroy zone");
return (-1);
@@ -504,7 +536,6 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
zlog_t *zlogp;
zone_cmd_rval_t *rvalp;
size_t rlen = getpagesize(); /* conservative */
- char *cmd_str = NULL;
/* LINTED E_BAD_PTR_CAST_ALIGN */
zargp = (zone_cmd_arg_t *)args;
@@ -579,8 +610,9 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
* Check for validity of command.
*/
if (cmd != Z_READY && cmd != Z_BOOT && cmd != Z_REBOOT &&
- cmd != Z_HALT && cmd != Z_NOTE_UNINSTALLING) {
- zerror(&logsys, B_FALSE, "invalid command");
+ cmd != Z_HALT && cmd != Z_NOTE_UNINSTALLING && cmd != Z_MOUNT &&
+ cmd != Z_UNMOUNT) {
+ zerror(&logsys, B_FALSE, "invalid command %d", (int)cmd);
goto out;
}
@@ -629,41 +661,26 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
* Not our area of expertise; we just print a nice message
* and die off.
*/
- switch (cmd) {
- case Z_READY:
- cmd_str = "ready";
- break;
- case Z_BOOT:
- cmd_str = "boot";
- break;
- case Z_HALT:
- cmd_str = "halt";
- break;
- case Z_REBOOT:
- cmd_str = "reboot";
- break;
- }
- assert(cmd_str != NULL);
zerror(zlogp, B_FALSE,
"%s operation is invalid for zones in state '%s'",
- cmd_str, zone_state_str(zstate));
+ z_cmd_name(cmd), zone_state_str(zstate));
break;
case ZONE_STATE_INSTALLED:
switch (cmd) {
case Z_READY:
- rval = zone_ready(zlogp);
+ rval = zone_ready(zlogp, B_FALSE);
if (rval == 0)
eventstream_write(Z_EVT_ZONE_READIED);
break;
case Z_BOOT:
eventstream_write(Z_EVT_ZONE_BOOTING);
- if ((rval = zone_ready(zlogp)) == 0)
+ if ((rval = zone_ready(zlogp, B_FALSE)) == 0)
rval = zone_bootup(zlogp, zargp->bootbuf);
audit_put_record(zlogp, uc, rval, "boot");
if (rval != 0) {
bringup_failure_recovery = B_TRUE;
- (void) zone_halt(zlogp);
+ (void) zone_halt(zlogp, B_FALSE);
}
break;
case Z_HALT:
@@ -682,7 +699,7 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
if (kernelcall) /* Invalid; can't happen */
abort();
zerror(zlogp, B_FALSE, "%s operation is invalid "
- "for zones in state '%s'", "reboot",
+ "for zones in state '%s'", z_cmd_name(cmd),
zone_state_str(zstate));
rval = -1;
break;
@@ -695,6 +712,28 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
*/
eventstream_write(Z_EVT_ZONE_UNINSTALLING);
break;
+ case Z_MOUNT:
+ if (kernelcall) /* Invalid; can't happen */
+ abort();
+ rval = zone_ready(zlogp, B_TRUE);
+ if (rval == 0)
+ rval = zone_mount_early(zlogp, zone_id);
+ /*
+ * Ordinarily, /dev/fd would be mounted inside the zone
+ * by svc:/system/filesystem/usr:default, but since
+ * we're not booting the zone, we need to do this
+ * manually.
+ */
+ if (rval == 0)
+ rval = mount_early_fs(zlogp, zone_id, "fd",
+ "/dev/fd", "fd");
+ break;
+ case Z_UNMOUNT:
+ if (kernelcall) /* Invalid; can't happen */
+ abort();
+ zerror(zlogp, B_FALSE, "zone is already unmounted");
+ rval = 0;
+ break;
}
break;
@@ -716,30 +755,45 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
audit_put_record(zlogp, uc, rval, "boot");
if (rval != 0) {
bringup_failure_recovery = B_TRUE;
- (void) zone_halt(zlogp);
+ (void) zone_halt(zlogp, B_FALSE);
}
break;
case Z_HALT:
if (kernelcall) /* Invalid; can't happen */
abort();
- if ((rval = zone_halt(zlogp)) != 0)
+ if ((rval = zone_halt(zlogp, B_FALSE)) != 0)
break;
eventstream_write(Z_EVT_ZONE_HALTED);
break;
case Z_REBOOT:
+ case Z_NOTE_UNINSTALLING:
+ case Z_MOUNT:
+ case Z_UNMOUNT:
if (kernelcall) /* Invalid; can't happen */
abort();
zerror(zlogp, B_FALSE, "%s operation is invalid "
- "for zones in state '%s'", "reboot",
+ "for zones in state '%s'", z_cmd_name(cmd),
zone_state_str(zstate));
rval = -1;
break;
- case Z_NOTE_UNINSTALLING:
+ }
+ break;
+
+ case ZONE_STATE_MOUNTED:
+ switch (cmd) {
+ case Z_UNMOUNT:
+ if (kernelcall) /* Invalid; can't happen */
+ abort();
+ rval = zone_halt(zlogp, B_TRUE);
+ if (rval == 0)
+ (void) sema_post(&scratch_sem);
+ break;
+ default:
if (kernelcall) /* Invalid; can't happen */
abort();
- zerror(zlogp, B_FALSE, "%s operation is "
- "invalid for zones in state '%s'",
- "note_uninstall", zone_state_str(zstate));
+ zerror(zlogp, B_FALSE, "%s operation is invalid "
+ "for zones in state '%s'", z_cmd_name(cmd),
+ zone_state_str(zstate));
rval = -1;
break;
}
@@ -750,9 +804,9 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
case ZONE_STATE_DOWN:
switch (cmd) {
case Z_READY:
- if ((rval = zone_halt(zlogp)) != 0)
+ if ((rval = zone_halt(zlogp, B_FALSE)) != 0)
break;
- if ((rval = zone_ready(zlogp)) == 0)
+ if ((rval = zone_ready(zlogp, B_FALSE)) == 0)
eventstream_write(Z_EVT_ZONE_READIED);
break;
case Z_BOOT:
@@ -766,25 +820,27 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
rval = 0;
break;
case Z_HALT:
- if ((rval = zone_halt(zlogp)) != 0)
+ if ((rval = zone_halt(zlogp, B_FALSE)) != 0)
break;
eventstream_write(Z_EVT_ZONE_HALTED);
break;
case Z_REBOOT:
eventstream_write(Z_EVT_ZONE_REBOOTING);
- if ((rval = zone_halt(zlogp)) != 0)
+ if ((rval = zone_halt(zlogp, B_FALSE)) != 0)
break;
- if ((rval = zone_ready(zlogp)) == 0) {
+ if ((rval = zone_ready(zlogp, B_FALSE)) == 0) {
rval = zone_bootup(zlogp, "");
audit_put_record(zlogp, uc, rval, "reboot");
if (rval != 0)
- (void) zone_halt(zlogp);
+ (void) zone_halt(zlogp, B_FALSE);
}
break;
case Z_NOTE_UNINSTALLING:
- zerror(zlogp, B_FALSE, "%s operation is "
- "invalid for zones in state '%s'",
- "note_uninstall", zone_state_str(zstate));
+ case Z_MOUNT:
+ case Z_UNMOUNT:
+ zerror(zlogp, B_FALSE, "%s operation is invalid "
+ "for zones in state '%s'", z_cmd_name(cmd),
+ zone_state_str(zstate));
rval = -1;
break;
}
@@ -1023,8 +1079,11 @@ main(int argc, char *argv[])
/*
* Process options.
*/
- while ((opt = getopt(argc, argv, "z:")) != EOF) {
+ while ((opt = getopt(argc, argv, "R:z:")) != EOF) {
switch (opt) {
+ case 'R':
+ zonecfg_set_root(optarg);
+ break;
case 'z':
zone_name = optarg;
break;
@@ -1206,7 +1265,7 @@ main(int argc, char *argv[])
}
(void) snprintf(zone_door_path, sizeof (zone_door_path),
- ZONE_DOOR_PATH, zone_name);
+ "%s" ZONE_DOOR_PATH, zonecfg_get_root(), zone_name);
/*
* See if another zoneadmd is running for this zone. If not, then we
@@ -1237,7 +1296,7 @@ main(int argc, char *argv[])
* serve_console_sock() below gets called, and any pending
* connection is accept()ed).
*/
- if (init_console(zlogp) == -1)
+ if (!zonecfg_in_alt_root() && init_console(zlogp) == -1)
goto child_out;
/*
@@ -1248,6 +1307,13 @@ main(int argc, char *argv[])
*/
(void) mutex_lock(&lock);
+ /* Init semaphore for scratch zones. */
+ if (sema_init(&scratch_sem, 0, USYNC_THREAD, NULL) == -1) {
+ zerror(zlogp, B_TRUE,
+ "failed to initialize semaphore for scratch zone");
+ goto child_out;
+ }
+
/*
* Note: door setup must occur *after* the console is setup.
* This is so that as zlogin tests the door to see if zoneadmd
@@ -1286,8 +1352,17 @@ main(int argc, char *argv[])
* serve_console() has returned, we are past the point of no return
* in the life of this zoneadmd.
*/
- serve_console(zlogp);
- assert(in_death_throes);
+ if (zonecfg_in_alt_root()) {
+ /*
+ * This is just awful, but mounted scratch zones don't (and
+ * can't) have consoles. We just wait for unmount instead.
+ */
+ while (sema_wait(&scratch_sem) == EINTR)
+ ;
+ } else {
+ serve_console(zlogp);
+ assert(in_death_throes);
+ }
/*
* This is the next-to-last part of the exit interlock. Upon calling
diff --git a/usr/src/cmd/zoneadmd/zoneadmd.h b/usr/src/cmd/zoneadmd/zoneadmd.h
index 6bf0034310..2afc12f456 100644
--- a/usr/src/cmd/zoneadmd/zoneadmd.h
+++ b/usr/src/cmd/zoneadmd/zoneadmd.h
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,9 +93,9 @@ extern void eventstream_write(zone_evt_t evt);
/*
* Virtual platform interfaces.
*/
-extern int vplat_create(zlog_t *);
-extern int vplat_bringup(zlog_t *);
-extern int vplat_teardown(zlog_t *);
+extern zoneid_t vplat_create(zlog_t *, boolean_t);
+extern int vplat_bringup(zlog_t *, boolean_t);
+extern int vplat_teardown(zlog_t *, boolean_t);
/*
diff --git a/usr/src/cmd/zonename/Makefile b/usr/src/cmd/zonename/Makefile
index d32cac6386..ac42810786 100644
--- a/usr/src/cmd/zonename/Makefile
+++ b/usr/src/cmd/zonename/Makefile
@@ -22,7 +22,7 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# cmd/zonename/Makefile
@@ -32,6 +32,10 @@ PROG= zonename
include ../Makefile.cmd
+LAZYLIBS = $(ZLAZYLOAD) -lzonecfg $(ZNOLAZYLOAD)
+lint := LAZYLIBS = -lzonecfg
+LDLIBS += $(LAZYLIBS)
+
.KEEP_STATE:
all: $(PROG)
diff --git a/usr/src/cmd/zonename/zonename.c b/usr/src/cmd/zonename/zonename.c
index ef2beb6701..3a3a5df27d 100644
--- a/usr/src/cmd/zonename/zonename.c
+++ b/usr/src/cmd/zonename/zonename.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,15 +31,18 @@
#include <locale.h>
#include <libintl.h>
#include <zone.h>
+#include <libzonecfg.h>
+#include <dlfcn.h>
#if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
#endif
int
-main()
+main(void)
{
char zonename[ZONENAME_MAX];
+ FILE *fp;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
@@ -49,6 +52,19 @@ main()
stderr);
return (1);
}
+
+ /*
+ * The use of dlopen here is a bit ugly, but it allows zonename to
+ * function properly before /usr is mounted. On such a system, scratch
+ * zones don't exist, so no translation is necessary.
+ */
+ if (dlopen("libzonecfg.so.1", RTLD_NOW | RTLD_GLOBAL) != NULL &&
+ zonecfg_is_scratch(zonename) &&
+ (fp = zonecfg_open_scratch("", B_FALSE)) != NULL) {
+ (void) zonecfg_reverse_scratch(fp, zonename, zonename,
+ sizeof (zonename), NULL, 0);
+ zonecfg_close_scratch(fp);
+ }
(void) puts(zonename);
return (0);
}
diff --git a/usr/src/head/libzonecfg.h b/usr/src/head/libzonecfg.h
index dd3c1d41ef..a82931928a 100644
--- a/usr/src/head/libzonecfg.h
+++ b/usr/src/head/libzonecfg.h
@@ -48,6 +48,7 @@ extern "C" {
#include <stdio.h>
#include <rctl.h>
#include <zone.h>
+#include <sys/uuid.h>
#define ZONE_ID_UNDEFINED -1
@@ -89,9 +90,10 @@ extern "C" {
#define ZONE_STATE_INCOMPLETE 1
#define ZONE_STATE_INSTALLED 2
#define ZONE_STATE_READY 3
-#define ZONE_STATE_RUNNING 4
-#define ZONE_STATE_SHUTTING_DOWN 5
-#define ZONE_STATE_DOWN 6
+#define ZONE_STATE_MOUNTED 4
+#define ZONE_STATE_RUNNING 5
+#define ZONE_STATE_SHUTTING_DOWN 6
+#define ZONE_STATE_DOWN 7
#define ZONE_STATE_MAXSTRLEN 14
@@ -107,7 +109,8 @@ extern "C" {
struct zoneent {
char zone_name[ZONENAME_MAX]; /* name of the zone */
int zone_state; /* configured | incomplete | installed */
- char zone_path[MAXPATHLEN];
+ char zone_path[MAXPATHLEN]; /* path to zone storage */
+ uuid_t zone_uuid; /* unique ID for zone */
char zone_newname[ZONENAME_MAX]; /* for doing renames */
};
@@ -159,22 +162,26 @@ struct zone_attrtab {
* Basic configuration management routines.
*/
extern zone_dochandle_t zonecfg_init_handle(void);
-extern int zonecfg_get_handle(char *, zone_dochandle_t);
-extern int zonecfg_get_snapshot_handle(char *, zone_dochandle_t);
-extern int zonecfg_get_template_handle(char *, char *, zone_dochandle_t);
+extern int zonecfg_get_handle(const char *, zone_dochandle_t);
+extern int zonecfg_get_snapshot_handle(const char *, zone_dochandle_t);
+extern int zonecfg_get_template_handle(const char *, const char *,
+ zone_dochandle_t);
extern int zonecfg_check_handle(zone_dochandle_t);
extern void zonecfg_fini_handle(zone_dochandle_t);
extern int zonecfg_destroy(const char *, boolean_t);
-extern int zonecfg_destroy_snapshot(char *);
+extern int zonecfg_destroy_snapshot(const char *);
extern int zonecfg_save(zone_dochandle_t);
-extern int zonecfg_create_snapshot(char *);
+extern int zonecfg_create_snapshot(const char *);
extern char *zonecfg_strerror(int);
extern int zonecfg_access(const char *, int);
+extern void zonecfg_set_root(const char *);
+extern const char *zonecfg_get_root(void);
+extern boolean_t zonecfg_in_alt_root(void);
/*
* Zone name, path to zone directory, autoboot setting and pool.
*/
-extern int zonecfg_validate_zonename(char *);
+extern int zonecfg_validate_zonename(const char *);
extern int zonecfg_get_name(zone_dochandle_t, char *, size_t);
extern int zonecfg_set_name(zone_dochandle_t, char *);
extern int zonecfg_get_zonepath(zone_dochandle_t, char *, size_t);
@@ -289,6 +296,8 @@ extern int zone_get_zonepath(char *, char *, size_t);
extern int zone_get_state(char *, zone_state_t *);
extern int zone_set_state(char *, zone_state_t);
extern char *zone_state_str(zone_state_t);
+extern int zonecfg_get_name_by_uuid(const uuid_t, char *, size_t);
+extern int zonecfg_get_uuid(const char *, uuid_t);
/*
* Iterator for configured zones.
@@ -319,6 +328,23 @@ extern boolean_t zonecfg_valid_rctl(const char *, const rctlblk_t *);
extern int zonecfg_construct_rctlblk(const struct zone_rctlvaltab *,
rctlblk_t *);
+/*
+ * Live Upgrade support functions. Shared between ON and install gate.
+ */
+extern FILE *zonecfg_open_scratch(const char *, boolean_t);
+extern int zonecfg_lock_scratch(FILE *);
+extern void zonecfg_close_scratch(FILE *);
+extern int zonecfg_get_scratch(FILE *, char *, size_t, char *, size_t, char *,
+ size_t);
+extern int zonecfg_find_scratch(FILE *, const char *, const char *, char *,
+ size_t);
+extern int zonecfg_reverse_scratch(FILE *, const char *, char *, size_t,
+ char *, size_t);
+extern int zonecfg_add_scratch(FILE *, const char *, const char *,
+ const char *);
+extern int zonecfg_delete_scratch(FILE *, const char *);
+extern boolean_t zonecfg_is_scratch(const char *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libzonecfg/Makefile.com b/usr/src/lib/libzonecfg/Makefile.com
index e01f34e45f..d38aa2bdc0 100644
--- a/usr/src/lib/libzonecfg/Makefile.com
+++ b/usr/src/lib/libzonecfg/Makefile.com
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -28,12 +28,12 @@
LIBRARY= libzonecfg.a
VERS= .1
-OBJECTS= libzonecfg.o getzoneent.o
+OBJECTS= libzonecfg.o getzoneent.o scratchops.o
include ../../Makefile.lib
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -lc -lsocket -lnsl
+LDLIBS += -lc -lsocket -lnsl -luuid
$(DYNLIB) := LDLIBS += -lxml2
CPPFLAGS += -I/usr/include/libxml2 -I$(SRCDIR) -D_REENTRANT
$(LINTLIB) := SRCS= $(SRCDIR)/$(LINTSRC)
diff --git a/usr/src/lib/libzonecfg/common/getzoneent.c b/usr/src/lib/libzonecfg/common/getzoneent.c
index 4a62bddaa9..2decb372a9 100644
--- a/usr/src/lib/libzonecfg/common/getzoneent.c
+++ b/usr/src/lib/libzonecfg/common/getzoneent.c
@@ -35,7 +35,6 @@
*/
#include <stdlib.h>
-#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <libzonecfg.h>
@@ -43,6 +42,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
+#include <uuid/uuid.h>
#include "zonecfg_impl.h"
@@ -56,6 +56,8 @@
* Same with double-quotes themselves: they are not allowed in zone names,
* and do not occur in zone states, and in theory should never occur in a
* zonepath since zonecfg does not support a method for escaping them.
+ *
+ * It never returns NULL.
*/
static char *
@@ -129,7 +131,7 @@ getzoneent_private(FILE *cookie)
continue;
}
p = gettok(&cp);
- if (p == NULL || *p == '\0' || strlen(p) > ZONENAME_MAX) {
+ if (*p == '\0' || strlen(p) >= ZONENAME_MAX) {
/*
* empty or very long zone names are not allowed
*/
@@ -138,7 +140,7 @@ getzoneent_private(FILE *cookie)
(void) strlcpy(ze->zone_name, p, ZONENAME_MAX);
p = gettok(&cp);
- if (p == NULL || *p == '\0') {
+ if (*p == '\0') {
/* state field should not be empty */
continue;
}
@@ -149,30 +151,44 @@ getzoneent_private(FILE *cookie)
ze->zone_state = ZONE_STATE_INCOMPLETE;
} else if (strcmp(p, ZONE_STATE_STR_INSTALLED) == 0) {
ze->zone_state = ZONE_STATE_INSTALLED;
- } else
+ } else {
continue;
+ }
p = gettok(&cp);
- if (strlen(p) > MAXPATHLEN) {
+ if (strlen(p) >= MAXPATHLEN) {
/* very long paths are not allowed */
continue;
}
- if (p == NULL) {
- /* empty paths accepted for backwards compatibility */
- p = "";
- }
(void) strlcpy(ze->zone_path, p, MAXPATHLEN);
+ p = gettok(&cp);
+ if (uuid_parse(p, ze->zone_uuid) == -1)
+ uuid_clear(ze->zone_uuid);
+
break;
}
return (ze);
}
+static boolean_t
+get_index_path(char *path)
+{
+ return (snprintf(path, MAXPATHLEN, "%s%s", zonecfg_root,
+ ZONE_INDEX_FILE) < MAXPATHLEN);
+}
+
FILE *
setzoneent(void)
{
- return (fopen(ZONE_INDEX_FILE, "r"));
+ char path[MAXPATHLEN];
+
+ if (!get_index_path(path)) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ return (fopen(path, "r"));
}
void
@@ -183,25 +199,35 @@ endzoneent(FILE *cookie)
}
static int
-lock_index_file(int *lock_fd)
+lock_index_file(void)
{
+ int lock_fd;
struct flock lock;
-
- if ((mkdir(ZONE_SNAPSHOT_ROOT, S_IRWXU) == -1) && errno != EEXIST)
- return (Z_LOCKING_FILE);
- *lock_fd = open(ZONE_INDEX_LOCK_FILE, O_CREAT|O_RDWR, 0644);
- if (*lock_fd < 0)
- return (Z_LOCKING_FILE);
+ char path[MAXPATHLEN];
+
+ if (snprintf(path, sizeof (path), "%s%s", zonecfg_root,
+ ZONE_INDEX_LOCK_DIR) >= sizeof (path))
+ return (-1);
+ if ((mkdir(path, S_IRWXU) == -1) && errno != EEXIST)
+ return (-1);
+ if (strlcat(path, ZONE_INDEX_LOCK_FILE, sizeof (path)) >=
+ sizeof (path))
+ return (-1);
+ lock_fd = open(path, O_CREAT|O_RDWR, 0644);
+ if (lock_fd == -1)
+ return (-1);
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
- if (fcntl(*lock_fd, F_SETLKW, &lock) == -1)
- return (Z_LOCKING_FILE);
+ if (fcntl(lock_fd, F_SETLKW, &lock) == -1) {
+ (void) close(lock_fd);
+ return (-1);
+ }
- return (Z_OK);
+ return (lock_fd);
}
static int
@@ -247,11 +273,14 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
{
FILE *index_file, *tmp_file;
char *tmp_file_name, buf[MAX_INDEX_LEN], orig_buf[MAX_INDEX_LEN];
- char zone[ZONENAME_MAX + 1]; /* name plus newline */
+ char zone[ZONENAME_MAX];
char line[MAX_INDEX_LEN];
int tmp_file_desc, lock_fd, err;
boolean_t exists = B_FALSE, need_quotes;
char *cp, *p;
+ char path[MAXPATHLEN];
+ char uuidstr[37]; /* hard-coded because of CR 6305641 */
+ size_t tlen;
assert(ze != NULL);
if (operation == PZE_ADD &&
@@ -261,13 +290,19 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
if (operation != PZE_MODIFY && strlen(ze->zone_newname) != 0)
return (Z_INVAL);
- if ((err = lock_index_file(&lock_fd)) != Z_OK)
- return (err);
- tmp_file_name = strdup(_PATH_TMPFILE);
+ if ((lock_fd = lock_index_file()) == -1)
+ return (Z_LOCKING_FILE);
+
+ /* using sizeof gives us room for the terminating NUL byte as well */
+ tlen = sizeof (_PATH_TMPFILE) + strlen(zonecfg_root);
+ tmp_file_name = malloc(tlen);
if (tmp_file_name == NULL) {
(void) unlock_index_file(lock_fd);
return (Z_NOMEM);
}
+ (void) snprintf(tmp_file_name, tlen, "%s%s", zonecfg_root,
+ _PATH_TMPFILE);
+
tmp_file_desc = mkstemp(tmp_file_name);
if (tmp_file_desc == -1) {
(void) unlink(tmp_file_name);
@@ -277,17 +312,16 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
}
if ((tmp_file = fdopen(tmp_file_desc, "w")) == NULL) {
(void) close(tmp_file_desc);
- (void) unlink(tmp_file_name);
- free(tmp_file_name);
- (void) unlock_index_file(lock_fd);
- return (Z_MISC_FS);
+ err = Z_MISC_FS;
+ goto error;
}
- if ((index_file = fopen(ZONE_INDEX_FILE, "r")) == NULL) {
- (void) fclose(tmp_file);
- (void) unlink(tmp_file_name);
- free(tmp_file_name);
- (void) unlock_index_file(lock_fd);
- return (Z_MISC_FS);
+ if (!get_index_path(path)) {
+ err = Z_MISC_FS;
+ goto error;
+ }
+ if ((index_file = fopen(path, "r")) == NULL) {
+ err = Z_MISC_FS;
+ goto error;
}
/*
@@ -300,9 +334,17 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
*/
need_quotes = (strchr(ze->zone_path, ':') != NULL);
- (void) snprintf(line, sizeof (line), "%s:%s:%s%s%s\n", ze->zone_name,
- zone_state_str(ze->zone_state), need_quotes ? "\"" : "",
- ze->zone_path, need_quotes ? "\"" : "");
+ /*
+ * If this zone doesn't yet have a unique identifier, then give it one.
+ */
+ if (uuid_is_null(ze->zone_uuid))
+ uuid_generate(ze->zone_uuid);
+ uuid_unparse(ze->zone_uuid, uuidstr);
+
+ (void) snprintf(line, sizeof (line), "%s:%s:%s%s%s:%s\n",
+ ze->zone_name, zone_state_str(ze->zone_state),
+ need_quotes ? "\"" : "", ze->zone_path, need_quotes ? "\"" : "",
+ uuidstr);
for (;;) {
if (fgets(buf, sizeof (buf), index_file) == NULL) {
if (operation == PZE_ADD && !exists)
@@ -323,7 +365,7 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
continue;
}
p = gettok(&cp);
- if (p == NULL || *p == '\0' || strlen(p) > ZONENAME_MAX) {
+ if (*p == '\0' || strlen(p) >= ZONENAME_MAX) {
/*
* empty or very long zone names are not allowed
*/
@@ -335,6 +377,7 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
exists = B_TRUE; /* already there */
if (operation == PZE_ADD) {
/* can't add same zone */
+ err = Z_UPDATING_INDEX;
goto error;
} else if (operation == PZE_MODIFY) {
char tmp_state[ZONE_STATE_MAXSTRLEN + 1];
@@ -348,8 +391,9 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
}
/* use existing value for state */
p = gettok(&cp);
- if (p == NULL || *p == '\0') {
+ if (*p == '\0') {
/* state field should not be empty */
+ err = Z_UPDATING_INDEX;
goto error;
}
(void) strlcpy(tmp_state,
@@ -367,11 +411,12 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
else
tmp_name = ze->zone_name;
- (void) fprintf(tmp_file, "%s:%s:%s%s%s\n",
+ (void) fprintf(tmp_file, "%s:%s:%s%s%s:%s\n",
tmp_name, tmp_state,
need_quotes ? "\"" : "",
(strlen(ze->zone_path) == 0) ? p :
- ze->zone_path, need_quotes ? "\"" : "");
+ ze->zone_path, need_quotes ? "\"" : "",
+ uuidstr);
}
/* else if (operation == PZE_REMOVE) { no-op } */
} else {
@@ -380,31 +425,30 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation)
}
(void) fclose(index_file);
+ index_file = NULL;
if (fclose(tmp_file) != 0) {
- (void) unlink(tmp_file_name);
- free(tmp_file_name);
- (void) unlock_index_file(lock_fd);
- return (Z_MISC_FS);
+ tmp_file = NULL;
+ err = Z_MISC_FS;
+ goto error;
}
+ tmp_file = NULL;
(void) chmod(tmp_file_name, 0644);
- if (rename(tmp_file_name, ZONE_INDEX_FILE) == -1) {
- (void) unlink(tmp_file_name);
- free(tmp_file_name);
- (void) unlock_index_file(lock_fd);
- if (errno == EACCES)
- return (Z_ACCES);
- return (Z_MISC_FS);
+ if (rename(tmp_file_name, path) == -1) {
+ err = errno == EACCES ? Z_ACCES : Z_MISC_FS;
+ goto error;
}
free(tmp_file_name);
if (unlock_index_file(lock_fd) != Z_OK)
return (Z_UNLOCKING_FILE);
return (Z_OK);
+
error:
- (void) fclose(index_file);
- (void) fclose(tmp_file);
+ if (index_file != NULL)
+ (void) fclose(index_file);
+ if (tmp_file != NULL)
+ (void) fclose(tmp_file);
(void) unlink(tmp_file_name);
free(tmp_file_name);
- if (unlock_index_file(lock_fd) != Z_OK)
- return (Z_UNLOCKING_FILE);
- return (Z_UPDATING_INDEX);
+ (void) unlock_index_file(lock_fd);
+ return (err);
}
diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c
index b9d80dbefa..b6a6a59cee 100644
--- a/usr/src/lib/libzonecfg/common/libzonecfg.c
+++ b/usr/src/lib/libzonecfg/common/libzonecfg.c
@@ -49,6 +49,7 @@
#include <libxml/parser.h>
#include <libdevinfo.h>
+#include <uuid/uuid.h>
#include <libzonecfg.h>
#include "zonecfg_impl.h"
@@ -105,6 +106,8 @@ struct zone_dochandle {
char zone_dh_delete_name[ZONENAME_MAX];
};
+char *zonecfg_root = "";
+
/*
* For functions which return int, which is most of the functions herein,
* the return values should be from the Z_foo set defined in <libzonecfg.h>.
@@ -113,22 +116,49 @@ struct zone_dochandle {
*/
/*
+ * Set the root (/) path for all zonecfg configuration files. This is a
+ * private interface used by Live Upgrade extensions to access zone
+ * configuration inside mounted alternate boot environments.
+ */
+void
+zonecfg_set_root(const char *rootpath)
+{
+ if (*zonecfg_root != '\0')
+ free(zonecfg_root);
+ if (rootpath == NULL || rootpath[0] == '\0' || rootpath[1] == '\0' ||
+ (zonecfg_root = strdup(rootpath)) == NULL)
+ zonecfg_root = "";
+}
+
+const char *
+zonecfg_get_root(void)
+{
+ return (zonecfg_root);
+}
+
+boolean_t
+zonecfg_in_alt_root(void)
+{
+ return (*zonecfg_root != '\0');
+}
+
+/*
* Callers of the _file_path() functions are expected to have the second
* parameter be a (char foo[MAXPATHLEN]).
*/
-static void
+static boolean_t
config_file_path(const char *zonename, char *answer)
{
- (void) snprintf(answer, MAXPATHLEN,
- "%s/%s.xml", ZONE_CONFIG_ROOT, zonename);
+ return (snprintf(answer, MAXPATHLEN, "%s%s/%s.xml", zonecfg_root,
+ ZONE_CONFIG_ROOT, zonename) < MAXPATHLEN);
}
-static void
-snap_file_path(char *zonename, char *answer)
+static boolean_t
+snap_file_path(const char *zonename, char *answer)
{
- (void) snprintf(answer, MAXPATHLEN,
- "%s/%s.snapshot.xml", ZONE_SNAPSHOT_ROOT, zonename);
+ return (snprintf(answer, MAXPATHLEN, "%s%s/%s.snapshot.xml",
+ zonecfg_root, ZONE_SNAPSHOT_ROOT, zonename) < MAXPATHLEN);
}
/*ARGSUSED*/
@@ -199,7 +229,8 @@ zonecfg_destroy(const char *zonename, boolean_t force)
int err, state_err;
zone_state_t state;
- config_file_path(zonename, path);
+ if (!config_file_path(zonename, path))
+ return (Z_MISC_FS);
state_err = zone_get_state((char *)zonename, &state);
err = access(path, W_OK);
@@ -251,11 +282,12 @@ zonecfg_destroy(const char *zonename, boolean_t force)
}
int
-zonecfg_destroy_snapshot(char *zonename)
+zonecfg_destroy_snapshot(const char *zonename)
{
char path[MAXPATHLEN];
- snap_file_path(zonename, path);
+ if (!snap_file_path(zonename, path))
+ return (Z_MISC_FS);
return (zonecfg_destroy_impl(path));
}
@@ -312,7 +344,8 @@ getrootattr(zone_dochandle_t handle, const xmlChar *propname,
}
static int
-setrootattr(zone_dochandle_t handle, const xmlChar *propname, char *propval)
+setrootattr(zone_dochandle_t handle, const xmlChar *propname,
+ const char *propval)
{
int err;
xmlNodePtr root;
@@ -358,7 +391,8 @@ stripcomments(zone_dochandle_t handle)
}
static int
-zonecfg_get_handle_impl(char *zonename, char *filename, zone_dochandle_t handle)
+zonecfg_get_handle_impl(const char *zonename, const char *filename,
+ zone_dochandle_t handle)
{
xmlValidCtxtPtr cvp;
struct stat statbuf;
@@ -387,34 +421,37 @@ zonecfg_get_handle_impl(char *zonename, char *filename, zone_dochandle_t handle)
}
int
-zonecfg_get_handle(char *zonename, zone_dochandle_t handle)
+zonecfg_get_handle(const char *zonename, zone_dochandle_t handle)
{
char path[MAXPATHLEN];
- config_file_path(zonename, path);
+ if (!config_file_path(zonename, path))
+ return (Z_MISC_FS);
handle->zone_dh_newzone = B_FALSE;
return (zonecfg_get_handle_impl(zonename, path, handle));
}
int
-zonecfg_get_snapshot_handle(char *zonename, zone_dochandle_t handle)
+zonecfg_get_snapshot_handle(const char *zonename, zone_dochandle_t handle)
{
char path[MAXPATHLEN];
- snap_file_path(zonename, path);
+ if (!snap_file_path(zonename, path))
+ return (Z_MISC_FS);
handle->zone_dh_newzone = B_FALSE;
return (zonecfg_get_handle_impl(zonename, path, handle));
}
int
-zonecfg_get_template_handle(char *template, char *zonename,
+zonecfg_get_template_handle(const char *template, const char *zonename,
zone_dochandle_t handle)
{
char path[MAXPATHLEN];
int err;
- config_file_path(template, path);
+ if (!config_file_path(template, path))
+ return (Z_MISC_FS);
if ((err = zonecfg_get_handle_impl(template, path, handle)) != Z_OK)
return (err);
@@ -450,7 +487,7 @@ is_snapshot(zone_dochandle_t handle)
* safety if this routine had to change the app locale on the fly.
*/
int
-zonecfg_validate_zonename(char *zone)
+zonecfg_validate_zonename(const char *zone)
{
int i;
@@ -573,7 +610,12 @@ zonecfg_set_name(zone_dochandle_t handle, char *name)
int
zonecfg_get_zonepath(zone_dochandle_t handle, char *path, size_t pathsize)
{
- return (getrootattr(handle, DTD_ATTR_ZONEPATH, path, pathsize));
+ size_t len;
+
+ if ((len = strlcpy(path, zonecfg_root, pathsize)) >= pathsize)
+ return (Z_TOO_BIG);
+ return (getrootattr(handle, DTD_ATTR_ZONEPATH, path + len,
+ pathsize - len));
}
int
@@ -841,7 +883,8 @@ zonecfg_save(zone_dochandle_t handle)
if ((err = zonecfg_get_name(handle, zname, sizeof (zname))) != Z_OK)
return (err);
- config_file_path(zname, path);
+ if (!config_file_path(zname, path))
+ return (Z_MISC_FS);
addcomment(handle, "\n DO NOT EDIT THIS "
"FILE. Use zonecfg(1M) instead.\n");
@@ -856,8 +899,8 @@ zonecfg_save(zone_dochandle_t handle)
handle->zone_dh_newzone = B_FALSE;
if (is_renaming(handle)) {
- config_file_path(handle->zone_dh_delete_name, delpath);
- (void) unlink(delpath);
+ if (config_file_path(handle->zone_dh_delete_name, delpath))
+ (void) unlink(delpath);
handle->zone_dh_delete_name[0] = '\0';
}
@@ -876,11 +919,17 @@ zonecfg_access(const char *zonename, int amode)
{
char path[MAXPATHLEN];
- config_file_path(zonename, path);
+ if (!config_file_path(zonename, path))
+ return (Z_INVAL);
if (access(path, amode) == 0)
return (Z_OK);
- if (errno == ENOENT && access(ZONE_CONFIG_ROOT, amode) == 0)
- return (Z_OK);
+ if (errno == ENOENT) {
+ if (snprintf(path, sizeof (path), "%s%s", zonecfg_root,
+ ZONE_CONFIG_ROOT) >= sizeof (path))
+ return (Z_INVAL);
+ if (access(path, amode) == 0)
+ return (Z_OK);
+ }
if (errno == EACCES)
return (Z_ACCES);
if (errno == EINVAL)
@@ -889,7 +938,7 @@ zonecfg_access(const char *zonename, int amode)
}
int
-zonecfg_create_snapshot(char *zonename)
+zonecfg_create_snapshot(const char *zonename)
{
zone_dochandle_t handle;
char path[MAXPATHLEN], zonepath[MAXPATHLEN], rpath[MAXPATHLEN];
@@ -925,12 +974,20 @@ zonecfg_create_snapshot(char *zonename)
if ((error = zonecfg_set_zonepath(handle, rpath)) != Z_OK)
goto out;
}
- if ((mkdir(ZONE_SNAPSHOT_ROOT, S_IRWXU) == -1) && (errno != EEXIST)) {
+ if (snprintf(path, sizeof (path), "%s%s", zonecfg_root,
+ ZONE_SNAPSHOT_ROOT) >= sizeof (path)) {
+ error = Z_MISC_FS;
+ goto out;
+ }
+ if ((mkdir(path, S_IRWXU) == -1) && (errno != EEXIST)) {
error = Z_MISC_FS;
goto out;
}
- snap_file_path(zonename, path);
+ if (!snap_file_path(zonename, path)) {
+ error = Z_MISC_FS;
+ goto out;
+ }
addcomment(handle, "\n DO NOT EDIT THIS FILE. "
"It is a snapshot of running zone state.\n");
@@ -2974,12 +3031,19 @@ zone_get_zonepath(char *zone_name, char *zonepath, size_t rp_sz)
struct zoneent *ze;
FILE *cookie;
int err;
+ char *cp;
if (zone_name == NULL)
return (Z_INVAL);
+ (void) strlcpy(zonepath, zonecfg_root, rp_sz);
+ cp = zonepath + strlen(zonepath);
+ while (cp > zonepath && cp[-1] == '/')
+ *--cp = '\0';
+
if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) {
- (void) strlcpy(zonepath, "/", rp_sz);
+ if (zonepath[0] == '\0')
+ (void) strlcpy(zonepath, "/", rp_sz);
return (Z_OK);
}
@@ -2988,20 +3052,20 @@ zone_get_zonepath(char *zone_name, char *zonepath, size_t rp_sz)
* a copy of the zone path, allow for it to be zero length, in which
* case we ignore this result and fall back to the XML files.
*/
- (void) strlcpy(zonepath, "", rp_sz);
cookie = setzoneent();
while ((ze = getzoneent_private(cookie)) != NULL) {
if (strcmp(ze->zone_name, zone_name) == 0) {
found = B_TRUE;
- if (strlen(ze->zone_path) > 0)
- (void) strlcpy(zonepath, ze->zone_path, rp_sz);
+ if (ze->zone_path[0] != '\0')
+ (void) strlcpy(cp, ze->zone_path,
+ rp_sz - (cp - zonepath));
}
free(ze);
if (found)
break;
}
endzoneent(cookie);
- if (found && strlen(zonepath) > 0)
+ if (found && *cp != '\0')
return (Z_OK);
/* Fall back to the XML files. */
@@ -3037,12 +3101,27 @@ zone_get_rootpath(char *zone_name, char *rootpath, size_t rp_sz)
}
static zone_state_t
-kernel_state_to_user_state(zone_status_t kernel_state)
+kernel_state_to_user_state(zoneid_t zoneid, zone_status_t kernel_state)
{
+ char zoneroot[MAXPATHLEN];
+ size_t zlen;
+
assert(kernel_state <= ZONE_MAX_STATE);
switch (kernel_state) {
case ZONE_IS_UNINITIALIZED:
+ return (ZONE_STATE_READY);
case ZONE_IS_READY:
+ /*
+ * If the zone's root is mounted on $ZONEPATH/lu, then
+ * it's a mounted scratch zone.
+ */
+ if (zone_getattr(zoneid, ZONE_ATTR_ROOT, zoneroot,
+ sizeof (zoneroot)) >= 0) {
+ zlen = strlen(zoneroot);
+ if (zlen > 3 &&
+ strcmp(zoneroot + zlen - 3, "/lu") == 0)
+ return (ZONE_STATE_MOUNTED);
+ }
return (ZONE_STATE_READY);
case ZONE_IS_BOOTING:
case ZONE_IS_RUNNING:
@@ -3067,15 +3146,33 @@ zone_get_state(char *zone_name, zone_state_t *state_num)
struct zoneent *ze;
boolean_t found = B_FALSE;
FILE *cookie;
+ char kernzone[ZONENAME_MAX];
+ FILE *fp;
if (zone_name == NULL)
return (Z_INVAL);
+ /*
+ * If we're looking at an alternate root, then we need to query the
+ * kernel using the scratch zone name.
+ */
+ zone_id = -1;
+ if (*zonecfg_root != '\0' && !zonecfg_is_scratch(zone_name)) {
+ if ((fp = zonecfg_open_scratch("", B_FALSE)) != NULL) {
+ if (zonecfg_find_scratch(fp, zone_name, zonecfg_root,
+ kernzone, sizeof (kernzone)) == 0)
+ zone_id = getzoneidbyname(kernzone);
+ zonecfg_close_scratch(fp);
+ }
+ } else {
+ zone_id = getzoneidbyname(zone_name);
+ }
+
/* check to see if zone is running */
- if ((zone_id = getzoneidbyname(zone_name)) != -1 &&
+ if (zone_id != -1 &&
zone_getattr(zone_id, ZONE_ATTR_STATUS, &status,
sizeof (status)) >= 0) {
- *state_num = kernel_state_to_user_state(status);
+ *state_num = kernel_state_to_user_state(zone_id, status);
return (Z_OK);
}
@@ -3152,7 +3249,7 @@ zone_get_id(const char *str, zoneid_t *zip)
(hdl = zonecfg_init_handle()) == NULL)
return (-1);
- if (zonecfg_get_handle((char *)str, hdl) == Z_OK) {
+ if (zonecfg_get_handle(str, hdl) == Z_OK) {
/* zone exists but isn't active */
*zip = ZONE_ID_UNDEFINED;
err = 0;
@@ -3176,6 +3273,8 @@ zone_state_str(zone_state_t state_num)
return (ZONE_STATE_STR_INSTALLED);
case ZONE_STATE_READY:
return (ZONE_STATE_STR_READY);
+ case ZONE_STATE_MOUNTED:
+ return (ZONE_STATE_STR_MOUNTED);
case ZONE_STATE_RUNNING:
return (ZONE_STATE_STR_RUNNING);
case ZONE_STATE_SHUTTING_DOWN:
@@ -3188,6 +3287,70 @@ zone_state_str(zone_state_t state_num)
}
/*
+ * Given a UUID value, find an associated zone name. This is intended to be
+ * used by callers who set up some 'default' name (corresponding to the
+ * expected name for the zone) in the zonename buffer, and thus the function
+ * doesn't touch this buffer on failure.
+ */
+int
+zonecfg_get_name_by_uuid(const uuid_t uuid, char *zonename, size_t namelen)
+{
+ FILE *fp;
+ struct zoneent *ze;
+
+ /*
+ * A small amount of subterfuge via casts is necessary here because
+ * libuuid doesn't use const correctly, but we don't want to export
+ * this brokenness to our clients.
+ */
+ if (uuid_is_null(*(uuid_t *)&uuid))
+ return (Z_NO_ZONE);
+ if ((fp = setzoneent()) == NULL)
+ return (Z_NO_ZONE);
+ while ((ze = getzoneent_private(fp)) != NULL) {
+ if (uuid_compare(*(uuid_t *)&uuid, ze->zone_uuid) == 0)
+ break;
+ free(ze);
+ }
+ endzoneent(fp);
+ if (ze != NULL) {
+ (void) strlcpy(zonename, ze->zone_name, namelen);
+ free(ze);
+ return (Z_OK);
+ } else {
+ return (Z_NO_ZONE);
+ }
+}
+
+/*
+ * Given a zone name, get its UUID. Returns a "NULL" UUID value if the zone
+ * exists but the file doesn't have a value set yet. Returns an error if the
+ * zone cannot be located.
+ */
+int
+zonecfg_get_uuid(const char *zonename, uuid_t uuid)
+{
+ FILE *fp;
+ struct zoneent *ze;
+
+ if ((fp = setzoneent()) == NULL)
+ return (Z_NO_ZONE);
+ while ((ze = getzoneent_private(fp)) != NULL) {
+ if (strcmp(ze->zone_name, zonename) == 0)
+ break;
+ free(ze);
+ }
+ endzoneent(fp);
+ if (ze != NULL) {
+ uuid_copy(uuid, ze->zone_uuid);
+ free(ze);
+ return (Z_OK);
+ } else {
+ return (Z_NO_ZONE);
+ }
+}
+
+/*
* File-system convenience functions.
*/
boolean_t
diff --git a/usr/src/lib/libzonecfg/common/scratchops.c b/usr/src/lib/libzonecfg/common/scratchops.c
new file mode 100644
index 0000000000..04e5724660
--- /dev/null
+++ b/usr/src/lib/libzonecfg/common/scratchops.c
@@ -0,0 +1,268 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This module contains functions used for reading and writing the scratch zone
+ * translation files. These files are used by Live Upgrade to keep track of
+ * mappings between actual kernel zone names and the zones in an alternate boot
+ * environment.
+ *
+ * The functions are MT-safe.
+ *
+ * The file format looks like this:
+ *
+ * <zonename> <kernel-zonename> <alt-root>
+ *
+ * The expected usage model is:
+ *
+ * fp = zonecfg_open_scratch("", B_TRUE);
+ * zonecfg_lock_scratch(fp);
+ * if (zonecfg_find_scratch(fp, zonename, altroot, NULL, 0) == 0) {
+ * handle error; zone already mounted
+ * }
+ * mount zone here
+ * zonecfg_add_scratch(fp, zonename, kernname, altroot);
+ * zonecfg_close_scratch(fp);
+ * fp = zonecfg_open_scratch(zoneroot, B_TRUE);
+ * ftruncate(fileno(fp), 0);
+ * zonecfg_add_scratch(fp, zonename, kernname, "/");
+ * zonecfg_close_scratch(fp);
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <libzonecfg.h>
+
+#define PATH_MAPFILE "tmp/.alt.lu-zone-map"
+
+static int
+lock_op(int fd, int type)
+{
+ struct flock lock;
+
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+
+ return (fcntl(fd, F_SETLKW, &lock));
+}
+
+FILE *
+zonecfg_open_scratch(const char *rootpath, boolean_t createfile)
+{
+ mode_t oldmask = umask(0);
+ struct stat lbuf, fbuf;
+ int fd, flags;
+ FILE *fp;
+ char mapfile[MAXPATHLEN];
+
+ (void) snprintf(mapfile, sizeof (mapfile), "%s/" PATH_MAPFILE,
+ rootpath);
+
+ flags = O_RDWR | O_NOFOLLOW | O_NOLINKS;
+ if (createfile)
+ flags |= O_EXCL | O_CREAT;
+ if ((fd = open(mapfile, flags, 0644)) == -1) {
+ if (!createfile) {
+ errno = ENOENT;
+ goto failure;
+ }
+ if (lstat(mapfile, &lbuf) == -1)
+ goto failure;
+ if (!S_ISREG(lbuf.st_mode) || lbuf.st_nlink != 1 ||
+ lbuf.st_uid != 0) {
+ errno = EINVAL;
+ goto failure;
+ }
+ fd = open(mapfile, O_RDWR);
+ if (fd == -1)
+ goto failure;
+ if (fstat(fd, &fbuf) == -1)
+ goto failure;
+ if (lbuf.st_ino != fbuf.st_ino || lbuf.st_dev != fbuf.st_dev) {
+ errno = EINVAL;
+ goto failure;
+ }
+ }
+ if (lock_op(fd, F_RDLCK) == -1)
+ goto failure;
+ (void) umask(oldmask);
+ if ((fp = fdopen(fd, "r+")) == NULL)
+ (void) close(fd);
+ return (fp);
+
+failure:
+ if (fd != -1)
+ (void) close(fd);
+ (void) umask(oldmask);
+ return (NULL);
+}
+
+int
+zonecfg_lock_scratch(FILE *fp)
+{
+ if (fflush(fp) != 0)
+ return (-1);
+ return (lock_op(fileno(fp), F_WRLCK));
+}
+
+void
+zonecfg_close_scratch(FILE *fp)
+{
+ (void) fclose(fp);
+}
+
+int
+zonecfg_get_scratch(FILE *fp, char *zonename, size_t namelen, char *kernname,
+ size_t kernlen, char *altroot, size_t altlen)
+{
+ char line[2 * ZONENAME_MAX + MAXPATHLEN + 2];
+ char *cp, *cp2;
+
+ /* We always hold at least a read lock on the file */
+ for (;;) {
+ if (fgets(line, sizeof (line), fp) == NULL)
+ return (-1);
+ if ((cp = strchr(line, '\n')) == NULL)
+ return (-1);
+ *cp = '\0';
+ if ((cp = strchr(line, ' ')) == NULL)
+ cp = line + strlen(line);
+ else
+ *cp++ = '\0';
+ if (zonename != NULL &&
+ strlcpy(zonename, line, namelen) >= namelen)
+ continue;
+ if ((cp2 = strchr(cp, ' ')) == NULL)
+ cp2 = cp + strlen(cp);
+ else
+ *cp2++ = '\0';
+ if (kernname != NULL &&
+ strlcpy(kernname, cp, kernlen) >= kernlen)
+ continue;
+ if (altroot != NULL && strlcpy(altroot, cp2, altlen) >= altlen)
+ continue;
+ break;
+ }
+ return (0);
+}
+
+int
+zonecfg_find_scratch(FILE *fp, const char *zonename, const char *altroot,
+ char *kernzone, size_t kernlen)
+{
+ char zone[ZONENAME_MAX];
+ char aroot[MAXPATHLEN];
+
+ rewind(fp);
+ while (zonecfg_get_scratch(fp, zone, sizeof (zone), kernzone, kernlen,
+ aroot, sizeof (aroot)) == 0) {
+ if (strcmp(zone, zonename) == 0 && strcmp(altroot, aroot) == 0)
+ return (0);
+ }
+ return (-1);
+}
+
+int
+zonecfg_reverse_scratch(FILE *fp, const char *kernzone, char *zonename,
+ size_t namelen, char *altroot, size_t altlen)
+{
+ char kzone[ZONENAME_MAX];
+
+ rewind(fp);
+ while (zonecfg_get_scratch(fp, zonename, namelen, kzone,
+ sizeof (kzone), altroot, altlen) == 0) {
+ if (strcmp(kzone, kernzone) == 0)
+ return (0);
+ }
+ return (-1);
+}
+
+int
+zonecfg_add_scratch(FILE *fp, const char *zonename, const char *kernzone,
+ const char *altroot)
+{
+ if (fseek(fp, 0, SEEK_END) == -1)
+ return (-1);
+ if (fprintf(fp, "%s %s %s\n", zonename, kernzone, altroot) == EOF)
+ return (-1);
+ if (fflush(fp) != 0)
+ return (-1);
+ return (0);
+}
+
+int
+zonecfg_delete_scratch(FILE *fp, const char *kernzone)
+{
+ char zone[ZONENAME_MAX];
+ char kzone[ZONENAME_MAX];
+ char aroot[MAXPATHLEN];
+ long roffs, woffs;
+
+ /*
+ * The implementation here is intentionally quite simple. We could
+ * allocate a buffer that's big enough to hold the data up to
+ * stat.st_size and then write back out the part we need to, but there
+ * seems to be little point.
+ */
+ rewind(fp);
+ roffs = 0;
+ do {
+ woffs = roffs;
+ if (zonecfg_get_scratch(fp, NULL, 0, kzone, sizeof (kzone),
+ NULL, 0) != 0)
+ return (-1);
+ roffs = ftell(fp);
+ } while (strcmp(kzone, kernzone) != 0);
+ while (zonecfg_get_scratch(fp, zone, sizeof (zone), kzone,
+ sizeof (kzone), aroot, sizeof aroot) == 0) {
+ roffs = ftell(fp);
+ if (fseek(fp, woffs, SEEK_SET) == -1)
+ break;
+ if (fprintf(fp, "%s %s %s\n", zone, kzone, aroot) == EOF)
+ break;
+ woffs = ftell(fp);
+ if (fseek(fp, roffs, SEEK_SET) == -1)
+ break;
+ }
+ (void) ftruncate(fileno(fp), woffs);
+ return (0);
+}
+
+boolean_t
+zonecfg_is_scratch(const char *kernzone)
+{
+ return (strncmp(kernzone, "SUNWlu", 6) == 0);
+}
diff --git a/usr/src/lib/libzonecfg/common/zonecfg_impl.h b/usr/src/lib/libzonecfg/common/zonecfg_impl.h
index 9700559820..b24f94ab1e 100644
--- a/usr/src/lib/libzonecfg/common/zonecfg_impl.h
+++ b/usr/src/lib/libzonecfg/common/zonecfg_impl.h
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,18 +49,31 @@ typedef enum {
#define ZONE_STATE_STR_INCOMPLETE "incomplete"
#define ZONE_STATE_STR_INSTALLED "installed"
#define ZONE_STATE_STR_READY "ready"
+#define ZONE_STATE_STR_MOUNTED "mounted"
#define ZONE_STATE_STR_RUNNING "running"
#define ZONE_STATE_STR_SHUTTING_DOWN "shutting_down"
#define ZONE_STATE_STR_DOWN "down"
-/* "::\n" => 3, no need to count '\0' as ZONENAME_MAX covers that */
-#define MAX_INDEX_LEN (ZONENAME_MAX + ZONE_STATE_MAXSTRLEN + MAXPATHLEN + 3)
+/*
+ * ":::\n" => 4, no need to count '\0' as ZONENAME_MAX covers that.
+ *
+ * Note that both ZONE_STATE_MAXSTRLEN and MAXPATHLEN include a NUL byte, and
+ * this extra count of 2 bytes covers the quotes that may be placed around the
+ * path.
+ *
+ * The swilly "36" constant here is to cover the fact that libuuid is broken;
+ * see CR 6305641.
+ */
+#define MAX_INDEX_LEN (ZONENAME_MAX + ZONE_STATE_MAXSTRLEN + MAXPATHLEN + \
+ 36 + 4)
-#define ZONE_INDEX_LOCK_FILE ZONE_SNAPSHOT_ROOT "/index.lock"
+#define ZONE_INDEX_LOCK_DIR ZONE_SNAPSHOT_ROOT
+#define ZONE_INDEX_LOCK_FILE "/index.lock"
#define ZONE_SNAPSHOT_ROOT ZONES_TMPDIR
extern int putzoneent(struct zoneent *, zoneent_op_t);
+extern char *zonecfg_root;
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libzonecfg/spec/libzonecfg.spec b/usr/src/lib/libzonecfg/spec/libzonecfg.spec
index 3d3a84a12f..dbc9f5da9a 100644
--- a/usr/src/lib/libzonecfg/spec/libzonecfg.spec
+++ b/usr/src/lib/libzonecfg/spec/libzonecfg.spec
@@ -26,6 +26,24 @@
#
# lib/libzonecfg/spec/libzonecfg.spec
+function zonecfg_set_root
+include <libzonecfg.h>
+declaration void zonecfg_set_root(const char *)
+version SUNWprivate_1.1
+end
+
+function zonecfg_get_root
+include <libzonecfg.h>
+declaration const char *zonecfg_get_root(void)
+version SUNWprivate_1.1
+end
+
+function zonecfg_in_alt_root
+include <libzonecfg.h>
+declaration boolean_t zonecfg_in_alt_root(void)
+version SUNWprivate_1.1
+end
+
function zonecfg_init_handle
include <libzonecfg.h>
declaration zone_dochandle_t zonecfg_init_handle(void)
@@ -34,19 +52,20 @@ end
function zonecfg_get_handle
include <libzonecfg.h>
-declaration int zonecfg_get_handle(char *, zone_dochandle_t)
+declaration int zonecfg_get_handle(const char *, zone_dochandle_t)
version SUNWprivate_1.1
end
function zonecfg_get_snapshot_handle
include <libzonecfg.h>
-declaration int zonecfg_get_snapshot_handle(char *, zone_dochandle_t)
+declaration int zonecfg_get_snapshot_handle(const char *, zone_dochandle_t)
version SUNWprivate_1.1
end
function zonecfg_get_template_handle
include <libzonecfg.h>
-declaration int zonecfg_get_template_handle(char *, char *, zone_dochandle_t)
+declaration int zonecfg_get_template_handle(const char *, const char *, \
+ zone_dochandle_t)
version SUNWprivate_1.1
end
@@ -448,13 +467,13 @@ end
function zonecfg_create_snapshot
include <libzonecfg.h>
-declaration int zonecfg_create_snapshot(char *)
+declaration int zonecfg_create_snapshot(const char *)
version SUNWprivate_1.1
end
function zonecfg_destroy_snapshot
include <libzonecfg.h>
-declaration int zonecfg_destroy_snapshot(char *)
+declaration int zonecfg_destroy_snapshot(const char *)
version SUNWprivate_1.1
end
@@ -543,6 +562,18 @@ declaration char *zone_state_str(zone_state_t);
version SUNWprivate_1.1
end
+function zonecfg_get_name_by_uuid
+include <libzonecfg.h>
+declaration int zonecfg_get_name_by_uuid(const uuid_t, char *, size_t)
+version SUNWprivate_1.1
+end
+
+function zonecfg_get_uuid
+include <libzonecfg.h>
+declaration int zonecfg_get_uuid(const char *, uuid_t)
+version SUNWprivate_1.1
+end
+
function zonecfg_same_net_address
include <libzonecfg.h>
declaration boolean_t zonecfg_same_net_address(char *, char *);
@@ -591,6 +622,64 @@ declaration int zonecfg_construct_rctlblk(const struct zone_rctlvaltab *, rctlbl
version SUNWprivate_1.1
end
+function zonecfg_open_scratch
+include <libzonecfg.h>
+declaration FILE *zonecfg_open_scratch(const char *, boolean_t)
+version SUNWprivate_1.1
+end
+
+function zonecfg_lock_scratch
+include <libzonecfg.h>
+declaration int zonecfg_lock_scratch(FILE *)
+version SUNWprivate_1.1
+end
+
+function zonecfg_close_scratch
+include <libzonecfg.h>
+declaration void zonecfg_close_scratch(FILE *)
+version SUNWprivate_1.1
+end
+
+function zonecfg_get_scratch
+include <libzonecfg.h>
+declaration int zonecfg_get_scratch(FILE *, char *, size_t, char *, \
+ size_t, char *, size_t)
+version SUNWprivate_1.1
+end
+
+function zonecfg_find_scratch
+include <libzonecfg.h>
+declaration int zonecfg_find_scratch(FILE *, const char *, const char *, \
+ char *, size_t)
+version SUNWprivate_1.1
+end
+
+function zonecfg_reverse_scratch
+include <libzonecfg.h>
+declaration int zonecfg_reverse_scratch(FILE *, const char *, char *, \
+ size_t, char *, size_t)
+version SUNWprivate_1.1
+end
+
+function zonecfg_add_scratch
+include <libzonecfg.h>
+declaration int zonecfg_add_scratch(FILE *, const char *, const char *, \
+ const char *)
+version SUNWprivate_1.1
+end
+
+function zonecfg_delete_scratch
+include <libzonecfg.h>
+declaration int zonecfg_delete_scratch(FILE *, const char *)
+version SUNWprivate_1.1
+end
+
+function zonecfg_is_scratch
+include <libzonecfg.h>
+declaration boolean_t zonecfg_is_scratch(const char *)
+version SUNWprivate_1.1
+end
+
function zonecfg_find_mounts
include <libzonecfg.h>
declaration int zonecfg_find_mounts(char * , int (*)(char *, void*), void*);
diff --git a/usr/src/uts/common/fs/nfs/nfs3_vfsops.c b/usr/src/uts/common/fs/nfs/nfs3_vfsops.c
index 6023abd955..a679103377 100644
--- a/usr/src/uts/common/fs/nfs/nfs3_vfsops.c
+++ b/usr/src/uts/common/fs/nfs/nfs3_vfsops.c
@@ -221,7 +221,7 @@ nfs3_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
STRUCT_DECL(netbuf, addr_tmp);
int flags, addr_type;
char *p, *pf;
- zone_t *zone = curproc->p_zone;
+ zone_t *zone = nfs_zone();
if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0)
return (EPERM);
@@ -695,7 +695,7 @@ more:
/*
* Stop the mount from going any further if the zone is going away.
*/
- if (zone_status_get(zone) >= ZONE_IS_SHUTTING_DOWN) {
+ if (zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN) {
error = EBUSY;
goto errout;
}
@@ -772,10 +772,10 @@ nfs3rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo *svp,
struct nfs_stats *nfsstatsp;
cred_t *lcr = NULL, *tcr = cr;
- nfsstatsp = zone_getspecific(nfsstat_zone_key, curproc->p_zone);
+ nfsstatsp = zone_getspecific(nfsstat_zone_key, nfs_zone());
ASSERT(nfsstatsp != NULL);
- ASSERT(curproc->p_zone == zone);
+ ASSERT(nfs_zone() == zone);
/*
* Create a mount record and link it to the vfs struct.
*/
@@ -1178,7 +1178,7 @@ nfs3_root(vfs_t *vfsp, vnode_t **vpp)
mi = VFTOMI(vfsp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EPERM);
svp = mi->mi_curr_serv;
@@ -1223,7 +1223,7 @@ nfs3_statvfs(vfs_t *vfsp, struct statvfs64 *sbp)
hrtime_t t;
mi = VFTOMI(vfsp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EPERM);
error = nfs3_root(vfsp, &vp);
if (error)
@@ -1332,7 +1332,7 @@ nfs3_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
return (ESTALE);
}
- if (curproc->p_zone != VFTOMI(vfsp)->mi_zone)
+ if (nfs_zone() != VFTOMI(vfsp)->mi_zone)
return (EPERM);
fh.fh3_length = fidp->fid_len;
bcopy(fidp->fid_data, fh.fh3_u.data, fh.fh3_length);
diff --git a/usr/src/uts/common/fs/nfs/nfs3_vnops.c b/usr/src/uts/common/fs/nfs/nfs3_vnops.c
index f93c4f80af..a53d2270b5 100644
--- a/usr/src/uts/common/fs/nfs/nfs3_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs3_vnops.c
@@ -278,7 +278,7 @@ nfs3_open(vnode_t **vpp, int flag, cred_t *cr)
vnode_t *vp;
vp = *vpp;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
mutex_enter(&rp->r_statelock);
@@ -331,7 +331,7 @@ nfs3_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr)
* open; if we happen to get here from the wrong zone we can't do
* anything over the wire.
*/
- if (VTOMI(vp)->mi_zone != curproc->p_zone) {
+ if (VTOMI(vp)->mi_zone != nfs_zone()) {
/*
* We could attempt to clean up locks, except we're sure
* that the current process didn't acquire any locks on
@@ -440,7 +440,7 @@ nfs3_directio_read(vnode_t *vp, struct uio *uiop, cred_t *cr)
char *sv_hostname;
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
sv_hostname = VTOR(vp)->r_server->sv_hostname;
douprintf = 1;
@@ -527,7 +527,7 @@ nfs3_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
ASSERT(nfs_rw_lock_held(&rp->r_rwlock, RW_READER));
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (vp->v_type != VREG)
@@ -616,7 +616,7 @@ nfs3_write(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
return (EISDIR);
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (uiop->uio_resid == 0)
return (0);
@@ -828,7 +828,7 @@ nfs3_rdwrlbn(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
uchar_t fsdata;
stable_how stab_comm;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
bp = pageio_setup(pp, len, vp, flags);
ASSERT(bp != NULL);
@@ -905,7 +905,7 @@ nfs3write(vnode_t *vp, caddr_t base, u_offset_t offset, int count, cred_t *cr,
rp = VTOR(vp);
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
args.file = *VTOFH3(vp);
args.stable = *stab_comm;
@@ -1033,7 +1033,7 @@ nfs3read(vnode_t *vp, caddr_t base, offset_t offset, int count,
rp = VTOR(vp);
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
douprintf = 1;
args.file = *VTOFH3(vp);
@@ -1125,7 +1125,7 @@ static int
nfs3_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
{
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
switch (cmd) {
case _FIODIRECTIO:
@@ -1141,7 +1141,7 @@ nfs3_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
int error;
rnode_t *rp;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
* If it has been specified that the return value will
@@ -1204,7 +1204,7 @@ nfs3_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
if (vap->va_mask & AT_NOSET)
return (EINVAL);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
va.va_mask = AT_UID | AT_MODE;
@@ -1234,7 +1234,7 @@ nfs3setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
vsecattr_t *vsp;
hrtime_t t;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
mask = vap->va_mask;
rp = VTOR(vp);
@@ -1407,7 +1407,7 @@ tryagain:
static int
nfs3_accessx(void *vp, int mode, cred_t *cr)
{
- ASSERT(curproc->p_zone == VTOMI((vnode_t *)vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI((vnode_t *)vp)->mi_zone);
return (nfs3_access(vp, mode, 0, cr));
}
@@ -1427,7 +1427,7 @@ nfs3_access(vnode_t *vp, int mode, int flags, cred_t *cr)
hrtime_t t;
acc = 0;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
if (mode & VREAD)
acc |= ACCESS3_READ;
@@ -1564,7 +1564,7 @@ nfs3_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr)
*/
if (vp->v_type != VLNK)
return (EINVAL);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
@@ -1662,7 +1662,7 @@ nfs3_fsync(vnode_t *vp, int syncflag, cred_t *cr)
if ((syncflag & FNODSYNC) || IS_SWAPVP(vp))
return (0);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
error = nfs3_putpage_commit(vp, (offset_t)0, 0, cr);
@@ -1690,7 +1690,7 @@ nfs3_inactive(vnode_t *vp, cred_t *cr)
* potentially turn into an expensive no-op if, for instance, v_count
* gets incremented in the meantime, but it's still correct.
*/
- if (curproc->p_zone != VTOMI(vp)->mi_zone) {
+ if (nfs_zone() != VTOMI(vp)->mi_zone) {
nfs_async_inactive(vp, cr, nfs3_inactive);
return;
}
@@ -1803,7 +1803,7 @@ nfs3_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
vnode_t *avp = NULL;
rnode_t *drp;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
drp = VTOR(dvp);
@@ -1885,7 +1885,7 @@ nfs3lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
int error;
rnode_t *drp;
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
/*
* If lookup is for "", just return dvp. Don't need
* to send it over the wire, look it up in the dnlc,
@@ -1955,7 +1955,7 @@ nfs3lookup_dnlc(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
vnode_t *vp;
ASSERT(*nm != '\0');
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
/*
* Lookup this name in the DNLC. If successful, then validate
* the caches and then recheck the DNLC. The DNLC is rechecked
@@ -2028,7 +2028,7 @@ nfs3lookup_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
ASSERT(*nm != '\0');
ASSERT(dvp->v_type == VDIR);
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
setdiropargs3(&args.what, nm, dvp);
@@ -2106,7 +2106,7 @@ nfs3_create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
vnode_t *tempvp;
drp = VTOR(dvp);
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR(dvp)))
return (EINTR);
@@ -2274,7 +2274,7 @@ nfs3create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
timestruc_t now;
hrtime_t t;
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
setdiropargs3(&args.where, nm, dvp);
if (exclusive == EXCL) {
args.how.mode = EXCLUSIVE;
@@ -2522,7 +2522,7 @@ nfs3excl_create_settimes(vnode_t *vp, struct vattr *vap, cred_t *cr)
rnode_t *rp;
hrtime_t t;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
/* save the caller's mask so that it can be reset later */
mask = vap->va_mask;
@@ -2589,7 +2589,7 @@ nfs3mknod(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
struct vattr vattr;
hrtime_t t;
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
switch (va->va_type) {
case VCHR:
case VBLK:
@@ -2707,7 +2707,7 @@ nfs3_remove(vnode_t *dvp, char *nm, cred_t *cr)
rnode_t *drp;
hrtime_t t;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
drp = VTOR(dvp);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR(dvp)))
@@ -2843,7 +2843,7 @@ nfs3_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr)
rnode_t *tdrp;
hrtime_t t;
- if (curproc->p_zone != VTOMI(tdvp)->mi_zone)
+ if (nfs_zone() != VTOMI(tdvp)->mi_zone)
return (EPERM);
if (VOP_REALVP(svp, &realvp) == 0)
svp = realvp;
@@ -2907,7 +2907,7 @@ nfs3_rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
{
vnode_t *realvp;
- if (curproc->p_zone != VTOMI(odvp)->mi_zone)
+ if (nfs_zone() != VTOMI(odvp)->mi_zone)
return (EPERM);
if (VOP_REALVP(ndvp, &realvp) == 0)
ndvp = realvp;
@@ -2933,7 +2933,7 @@ nfs3rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
rnode_t *ndrp;
hrtime_t t;
- ASSERT(curproc->p_zone == VTOMI(odvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(odvp)->mi_zone);
if (strcmp(onm, ".") == 0 || strcmp(onm, "..") == 0 ||
strcmp(nnm, ".") == 0 || strcmp(nnm, "..") == 0)
@@ -3215,7 +3215,7 @@ nfs3_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp, cred_t *cr)
rnode_t *drp;
hrtime_t t;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
setdiropargs3(&args.where, nm, dvp);
@@ -3317,7 +3317,7 @@ nfs3_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr)
rnode_t *drp;
hrtime_t t;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
drp = VTOR(dvp);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR(dvp)))
@@ -3422,7 +3422,7 @@ nfs3_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm, cred_t *cr)
mi = VTOMI(dvp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EPERM);
if (!(mi->mi_flags & MI_SYMLINK))
return (EOPNOTSUPP);
@@ -3551,7 +3551,7 @@ nfs3_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp)
rddir_cache srdc;
avl_index_t where;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
@@ -3841,7 +3841,7 @@ do_nfs3readdir(vnode_t *vp, rddir_cache *rdc, cred_t *cr)
rp = VTOR(vp);
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
/*
* Issue the proper request.
*
@@ -3897,7 +3897,7 @@ nfs3readdir(vnode_t *vp, rddir_cache *rdc, cred_t *cr)
rp = VTOR(vp);
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
args.dir = *RTOFH3(rp);
args.cookie = (cookie3)rdc->nfs3_cookie;
@@ -4006,7 +4006,7 @@ nfs3readdirplus(vnode_t *vp, rddir_cache *rdc, cred_t *cr)
rp = VTOR(vp);
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
args.dir = *RTOFH3(rp);
args.cookie = (cookie3)rdc->nfs3_cookie;
@@ -4113,7 +4113,7 @@ nfs3_bio(struct buf *bp, stable_how *stab_comm, cred_t *cr)
cred_t *cred;
offset_t offset;
- ASSERT(curproc->p_zone == VTOMI(bp->b_vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(bp->b_vp)->mi_zone);
offset = ldbtob(bp->b_lblkno);
DTRACE_IO1(start, struct buf *, bp);
@@ -4268,7 +4268,7 @@ nfs3_fid(vnode_t *vp, fid_t *fidp)
{
rnode_t *rp;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
@@ -4353,7 +4353,7 @@ nfs3_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
if (vp->v_flag & VNOMAP)
return (ENOSYS);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
if (protp != NULL)
*protp = PROT_ALL;
@@ -4444,7 +4444,7 @@ nfs3_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp,
page_t *pagefound;
page_t *savepp;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
@@ -4704,7 +4704,7 @@ nfs3_readahead(vnode_t *vp, u_offset_t blkoff, caddr_t addr, struct seg *seg,
rnode_t *rp = VTOR(vp);
page_t *savepp;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
mutex_enter(&rp->r_statelock);
@@ -4822,7 +4822,7 @@ nfs3_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr)
return (ENOSYS);
if (len == 0 && !(flags & B_INVAL) && vn_is_readonly(vp))
return (0);
- if (!(flags & B_ASYNC) && curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (!(flags & B_ASYNC) && nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
@@ -4856,7 +4856,7 @@ nfs3_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
ASSERT(!vn_is_readonly(vp));
ASSERT(pp != NULL);
ASSERT(cr != NULL);
- ASSERT((flags & B_ASYNC) || curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT((flags & B_ASYNC) || nfs_zone() == VTOMI(vp)->mi_zone);
rp = VTOR(vp);
ASSERT(rp->r_count > 0);
@@ -4969,7 +4969,7 @@ nfs3_sync_putapage(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
int error;
rnode_t *rp;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
flags |= B_WRITE;
@@ -5033,7 +5033,7 @@ nfs3_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
rnode_t *rp;
struct vattr va;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
if (vp->v_flag & VNOMAP)
@@ -5131,7 +5131,7 @@ nfs3_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
if (vp->v_flag & VNOMAP)
return (ENOSYS);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
@@ -5158,7 +5158,7 @@ nfs3_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
rnode_t *rp;
int error = 0, intr = INTR(vp);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/* check for valid cmd parameter */
if (cmd != F_GETLK && cmd != F_SETLK && cmd != F_SETLKW)
@@ -5305,7 +5305,7 @@ nfs3_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
ASSERT(vp->v_type == VREG);
if (cmd != F_FREESP)
return (EINVAL);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
error = convoff(vp, bfp, 0, offset);
@@ -5368,7 +5368,7 @@ nfs3_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
* A process may not change zones if it has NFS pages mmap'ed
* in, so we can't legitimately get here from the wrong zone.
*/
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
rp = VTOR(vp);
@@ -5482,7 +5482,7 @@ nfs3_delmap_callback(struct as *as, void *arg, uint_t event)
* dirty pages.
*/
if ((mi->mi_flags & MI_NOCTO) ||
- curproc->p_zone != mi->mi_zone)
+ nfs_zone() != mi->mi_zone)
error = nfs3_putpage(dmapp->vp, dmapp->off, dmapp->len,
B_ASYNC, dmapp->cr);
else
@@ -5524,7 +5524,7 @@ nfs3_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
rnode_t *rp;
hrtime_t t;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
* Large file spec - need to base answer on info stored
@@ -5714,7 +5714,7 @@ nfs3_sync_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
{
int error;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
error = nfs3_rdwrlbn(vp, pp, io_off, io_len, flags, cr);
if (flags & B_READ)
pvn_read_done(pp, (error ? B_ERROR : 0) | flags);
@@ -5732,7 +5732,7 @@ nfs3_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
if (pp == NULL)
return (EINVAL);
- if (!(flags & B_ASYNC) && curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (!(flags & B_ASYNC) && nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
@@ -5892,7 +5892,7 @@ nfs3_dispose(vnode_t *vp, page_t *pp, int fl, int dn, cred_t *cr)
mutex_exit(&rp->r_statelock);
if (curproc == proc_pageout || curproc == proc_fsflush ||
- curproc->p_zone != VTOMI(vp)->mi_zone) {
+ nfs_zone() != VTOMI(vp)->mi_zone) {
nfs_async_commit(vp, plist, offset, len, cr, nfs3_async_commit);
return;
}
@@ -5966,7 +5966,7 @@ nfs3_commit(vnode_t *vp, offset3 offset, count3 count, cred_t *cr)
cred_t *cred;
rp = VTOR(vp);
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
mutex_enter(&rp->r_statelock);
if (rp->r_cred != NULL) {
@@ -6054,7 +6054,7 @@ nfs3_set_mod(vnode_t *vp)
page_t *pp;
kmutex_t *vphm;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
vphm = page_vnode_mutex(vp);
mutex_enter(vphm);
if ((pp = vp->v_pages) != NULL) {
@@ -6184,7 +6184,7 @@ nfs3_get_commit_range(vnode_t *vp, u_offset_t soff, size_t len)
rp = VTOR(vp);
ASSERT(rp->r_flags & RCOMMIT);
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
/*
* If there are no pages associated with this vnode, then
@@ -6264,7 +6264,7 @@ nfs3_putpage_commit(vnode_t *vp, offset_t poff, size_t plen, cred_t *cr)
writeverf3 write_verf;
rnode_t *rp = VTOR(vp);
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
/*
* Flush the data portion of the file and then commit any
* portions which need to be committed. This may need to
@@ -6338,7 +6338,7 @@ nfs3_commit_vp(vnode_t *vp, u_offset_t poff, size_t plen, cred_t *cr)
rp = VTOR(vp);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
* Set the `commit inprogress' state bit. We must
@@ -6400,7 +6400,7 @@ nfs3_sync_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
int error;
page_t *pp;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
error = nfs3_commit(vp, offset, count, cr);
/*
@@ -6434,7 +6434,7 @@ static void
nfs3_async_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
cred_t *cr)
{
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
(void) nfs3_sync_commit(vp, plist, offset, count, cr);
}
@@ -6446,7 +6446,7 @@ nfs3_setsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (mi->mi_flags & MI_ACL) {
@@ -6466,7 +6466,7 @@ nfs3_getsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (mi->mi_flags & MI_ACL) {
@@ -6486,7 +6486,7 @@ nfs3_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr)
struct nfs_owner nfs_owner;
netobj lm_fh3;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
diff --git a/usr/src/uts/common/fs/nfs/nfs4_callback.c b/usr/src/uts/common/fs/nfs/nfs4_callback.c
index e586e33ed3..d80cde3182 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_callback.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_callback.c
@@ -721,7 +721,7 @@ cb_dispatch(struct svc_req *req, SVCXPRT *xprt)
struct nfs4_callback_globals *);
void (*freeproc)(CB_COMPOUND4res *);
- ncg = zone_getspecific(nfs4_callback_zone_key, curproc->p_zone);
+ ncg = zone_getspecific(nfs4_callback_zone_key, nfs_zone());
ASSERT(ncg != NULL);
ncg->nfs4_callback_stats.cb_dispatch.value.ui64++;
@@ -1058,7 +1058,7 @@ nfs4_svc(struct nfs4_svc_args *arg, model_t model)
return (error);
}
- ncg = zone_getspecific(nfs4_callback_zone_key, curproc->p_zone);
+ ncg = zone_getspecific(nfs4_callback_zone_key, nfs_zone());
ASSERT(ncg != NULL);
mutex_enter(&ncg->nfs4_cb_lock);
@@ -1083,7 +1083,7 @@ nfs4_svc(struct nfs4_svc_args *arg, model_t model)
struct nfs4_callback_globals *
nfs4_get_callback_globals(void)
{
- return (zone_getspecific(nfs4_callback_zone_key, curproc->p_zone));
+ return (zone_getspecific(nfs4_callback_zone_key, nfs_zone()));
}
static void *
@@ -1376,8 +1376,8 @@ nfs4delegreturn_cleanup(rnode4_t *rp, nfs4_server_t *np)
if (np != NULL) {
ncg = np->zone_globals;
- } else if (curproc->p_zone == VTOMI4(RTOV4(rp))->mi_zone) {
- ncg = zone_getspecific(nfs4_callback_zone_key, curproc->p_zone);
+ } else if (nfs_zone() == VTOMI4(RTOV4(rp))->mi_zone) {
+ ncg = zone_getspecific(nfs4_callback_zone_key, nfs_zone());
ASSERT(ncg != NULL);
} else {
/*
@@ -1722,7 +1722,7 @@ nfs4delegreturn(rnode4_t *rp, int flags)
{
struct nfs4_callback_globals *ncg;
- ncg = zone_getspecific(nfs4_callback_zone_key, curproc->p_zone);
+ ncg = zone_getspecific(nfs4_callback_zone_key, nfs_zone());
ASSERT(ncg != NULL);
return (nfs4delegreturn_impl(rp, flags, ncg));
@@ -2060,7 +2060,7 @@ nfs4delegreturn_thread(struct cb_recall_pass *args)
callb_cpr_t cpr_info;
struct nfs4_callback_globals *ncg;
- ncg = zone_getspecific(nfs4_callback_zone_key, curproc->p_zone);
+ ncg = zone_getspecific(nfs4_callback_zone_key, nfs_zone());
ASSERT(ncg != NULL);
mutex_init(&cpr_lock, NULL, MUTEX_DEFAULT, NULL);
@@ -2183,7 +2183,7 @@ nfs4_delegation_accept(rnode4_t *rp, open_claim_type4 claim, OPEN4res *res,
struct nfs4_callback_globals *ncg;
open_delegation_type4 odt;
- ncg = zone_getspecific(nfs4_callback_zone_key, curproc->p_zone);
+ ncg = zone_getspecific(nfs4_callback_zone_key, nfs_zone());
ASSERT(ncg != NULL);
mutex_enter(&rp->r_statev4_lock);
@@ -2598,7 +2598,7 @@ nfs4_dlistclean(void)
{
struct nfs4_callback_globals *ncg;
- ncg = zone_getspecific(nfs4_callback_zone_key, curproc->p_zone);
+ ncg = zone_getspecific(nfs4_callback_zone_key, nfs_zone());
ASSERT(ncg != NULL);
nfs4_dlistclean_impl(ncg, 0);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_client.c b/usr/src/uts/common/fs/nfs/nfs4_client.c
index 3a2bd2f846..df575206b7 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_client.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_client.c
@@ -1727,7 +1727,7 @@ nfs4_async_putapage(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
noasync:
if (curproc == proc_pageout || curproc == proc_fsflush ||
- curproc->p_zone == mi->mi_zone) {
+ nfs_zone() == mi->mi_zone) {
/*
* If we get here in the context of the pageout/fsflush,
* or we have run out of memory or we're attempting to
@@ -1748,7 +1748,7 @@ noasync:
}
/*
- * We'll get here only if (curproc->p_zone != mi->mi_zone)
+ * We'll get here only if (nfs_zone() != mi->mi_zone)
* which means that this was a cross-zone sync putpage.
*
* We pass in B_ERROR to pvn_write_done() to re-mark the pages
@@ -1877,7 +1877,7 @@ noasync:
return (0);
}
- if (curproc->p_zone != mi->mi_zone) {
+ if (nfs_zone() != mi->mi_zone) {
/*
* So this was a cross-zone sync pageio. We pass in B_ERROR
* to pvn_write_done() to re-mark the pages as dirty and unlock
@@ -2061,7 +2061,7 @@ nfs4_async_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
noasync:
if (curproc == proc_pageout || curproc == proc_fsflush ||
- curproc->p_zone != mi->mi_zone) {
+ nfs_zone() != mi->mi_zone) {
while (plist != NULL) {
pp = plist;
page_sub(&plist, pp);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_idmap.c b/usr/src/uts/common/fs/nfs/nfs4_idmap.c
index 6691416ac2..3af5d9689f 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_idmap.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_idmap.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -339,7 +339,7 @@ nfs_idmap_str_uid(utf8string *u8s, uid_t *uid, bool_t isserver)
door_arg_t door_args;
door_handle_t dh;
- nig = zone_getspecific(nfsidmap_zone_key, curproc->p_zone);
+ nig = zone_getspecific(nfsidmap_zone_key, nfs_zone());
ASSERT(nig != NULL);
if (!u8s || !u8s->utf8string_val || u8s->utf8string_len == 0 ||
@@ -552,7 +552,7 @@ nfs_idmap_uid_str(uid_t uid, utf8string *u8s, bool_t isserver)
door_arg_t door_args;
door_handle_t dh;
- nig = zone_getspecific(nfsidmap_zone_key, curproc->p_zone);
+ nig = zone_getspecific(nfsidmap_zone_key, nfs_zone());
ASSERT(nig != NULL);
/*
@@ -718,7 +718,7 @@ nfs_idmap_str_gid(utf8string *u8s, gid_t *gid, bool_t isserver)
door_arg_t door_args;
door_handle_t dh;
- nig = zone_getspecific(nfsidmap_zone_key, curproc->p_zone);
+ nig = zone_getspecific(nfsidmap_zone_key, nfs_zone());
ASSERT(nig != NULL);
if (!u8s || !u8s->utf8string_val || u8s->utf8string_len == 0 ||
@@ -932,7 +932,7 @@ nfs_idmap_gid_str(gid_t gid, utf8string *u8s, bool_t isserver)
door_arg_t door_args;
door_handle_t dh;
- nig = zone_getspecific(nfsidmap_zone_key, curproc->p_zone);
+ nig = zone_getspecific(nfsidmap_zone_key, nfs_zone());
ASSERT(nig != NULL);
/*
@@ -1138,7 +1138,7 @@ nfs_idmap_args(struct nfsidmap_args *idmp)
{
struct nfsidmap_globals *nig;
- nig = zone_getspecific(nfsidmap_zone_key, curproc->p_zone);
+ nig = zone_getspecific(nfsidmap_zone_key, nfs_zone());
ASSERT(nig != NULL);
nfs_idmap_cache_flush(&nig->u2s_ci);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_recovery.c b/usr/src/uts/common/fs/nfs/nfs4_recovery.c
index 7db8b999e8..45862d6eae 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_recovery.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_recovery.c
@@ -341,7 +341,7 @@ nfs4_start_recovery(nfs4_error_t *ep, mntinfo4_t *mi, vnode_t *vp1,
bool_t abort = FALSE;
bool_t gone = FALSE;
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
mutex_enter(&mi->mi_lock);
/*
* If there is lost state, we need to kick off recovery even if the
@@ -393,7 +393,7 @@ start_recovery_action(nfs4_recov_t what, bool_t reboot, mntinfo4_t *mi,
{
recov_info_t *recovp;
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
mutex_enter(&mi->mi_lock);
mi->mi_in_recovery++;
mutex_exit(&mi->mi_lock);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_rnode.c b/usr/src/uts/common/fs/nfs/nfs4_rnode.c
index 21a94a4a44..a105b0ba6c 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_rnode.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_rnode.c
@@ -815,7 +815,7 @@ again:
if (list_head(&rp->r_open_streams) != NULL) {
mutex_exit(&rp->r_os_lock);
rw_exit(&rp->r_hashq->r_lock);
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
nfs4_clear_open_streams(rp);
else
(void) nfs4close_all(vp, cr);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_subr.c b/usr/src/uts/common/fs/nfs/nfs4_subr.c
index 4cc714e3ea..5c6dd2d146 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_subr.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_subr.c
@@ -1548,8 +1548,8 @@ rfs4call(mntinfo4_t *mi, COMPOUND4args_clnt *argsp, COMPOUND4res_clnt *resp,
int num_resops;
struct nfs4_clnt *nfscl;
- ASSERT(curproc->p_zone == mi->mi_zone);
- nfscl = zone_getspecific(nfs4clnt_zone_key, curproc->p_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
+ nfscl = zone_getspecific(nfs4clnt_zone_key, nfs_zone());
ASSERT(nfscl != NULL);
nfscl->nfscl_stat.calls.value.ui64++;
@@ -2017,7 +2017,7 @@ nfs4_make_dotdot(nfs4_sharedfh_t *fhp, hrtime_t t, vnode_t *dvp,
((! need_start_op) && (no_need_start_op)));
}
#endif
- ASSERT(VTOMI4(dvp)->mi_zone == curproc->p_zone);
+ ASSERT(VTOMI4(dvp)->mi_zone == nfs_zone());
NFS4_DEBUG(nfs4_client_shadow_debug, (CE_NOTE,
"nfs4_make_dotdot: called with fhp %p, dvp %s", (void *)fhp,
diff --git a/usr/src/uts/common/fs/nfs/nfs4_vfsops.c b/usr/src/uts/common/fs/nfs/nfs4_vfsops.c
index 8475aaefd8..4c8be34d5d 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_vfsops.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_vfsops.c
@@ -331,7 +331,7 @@ nfs4_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
char *p, *pf;
struct pathname pn;
char *userbufptr;
- zone_t *zone = curproc->p_zone;
+ zone_t *zone = nfs_zone();
nfs4_error_t n4e;
if (secpolicy_fs_mount(cr, mvp, vfsp) != 0)
@@ -741,7 +741,7 @@ more:
/*
* Stop the mount from going any further if the zone is going away.
*/
- if (zone_status_get(zone) >= ZONE_IS_SHUTTING_DOWN) {
+ if (zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN) {
error = EBUSY;
goto errout;
}
@@ -1579,10 +1579,10 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head,
int orig_sv_pathlen, num_retry;
cred_t *lcr = NULL, *tcr = cr;
- nfsstatsp = zone_getspecific(nfsstat_zone_key, curproc->p_zone);
+ nfsstatsp = zone_getspecific(nfsstat_zone_key, nfs_zone());
ASSERT(nfsstatsp != NULL);
- ASSERT(curproc->p_zone == zone);
+ ASSERT(nfs_zone() == zone);
ASSERT(crgetref(cr));
/*
@@ -1955,7 +1955,7 @@ nfs4_unmount(vfs_t *vfsp, int flag, cred_t *cr)
if (flag & MS_FORCE) {
vfsp->vfs_flag |= VFS_UNMOUNTED;
- if (curproc->p_zone != mi->mi_zone) {
+ if (nfs_zone() != mi->mi_zone) {
/*
* If the request is coming from the wrong zone,
* we don't want to create any new threads, and
@@ -2038,7 +2038,7 @@ nfs4_root(vfs_t *vfsp, vnode_t **vpp)
mi = VFTOMI4(vfsp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EPERM);
svp = mi->mi_curr_serv;
@@ -3220,9 +3220,9 @@ nfs4_move_mi(mntinfo4_t *mi, servinfo4_t *old, servinfo4_t *new)
{
nfs4_server_t *p, *op = NULL, *np = NULL;
int num_open;
- zoneid_t zoneid = getzoneid();
+ zoneid_t zoneid = nfs_zoneid();
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
mutex_enter(&nfs4_server_lst_lock);
#ifdef DEBUG
@@ -3310,7 +3310,7 @@ nfs4_server_t *
servinfo4_to_nfs4_server(servinfo4_t *srv_p)
{
nfs4_server_t *np;
- zoneid_t zoneid = getzoneid();
+ zoneid_t zoneid = nfs_zoneid();
mutex_enter(&nfs4_server_lst_lock);
for (np = nfs4_server_lst.forw; np != &nfs4_server_lst; np = np->forw) {
@@ -3371,7 +3371,8 @@ find_nfs4_server_all(mntinfo4_t *mi, int all)
* another zone's server list, as long as it doesn't try to contact
* them.
*/
- ASSERT(zoneid == getzoneid() || getzoneid() == GLOBAL_ZONEID);
+ ASSERT(zoneid == getzoneid() || getzoneid() == GLOBAL_ZONEID ||
+ nfs_global_client_only != 0);
/*
* The nfs4_server_lst_lock global lock is held when we get a new
@@ -3539,7 +3540,7 @@ nfs4_free_mount(vfs_t *vfsp, cred_t *cr)
* We need to participate in the CPR framework if this is a kernel
* thread.
*/
- async_thread = (curproc == curproc->p_zone->zone_zsched);
+ async_thread = (curproc == nfs_zone()->zone_zsched);
if (async_thread) {
mutex_init(&cpr_lock, NULL, MUTEX_DEFAULT, NULL);
CALLB_CPR_INIT(&cpr_info, &cpr_lock, callb_generic_cpr,
diff --git a/usr/src/uts/common/fs/nfs/nfs4_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_vnops.c
index 0a6ad81bf4..d07cedb514 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c
@@ -586,7 +586,7 @@ nfs4_open(vnode_t **vpp, int flag, cred_t *cr)
char fn[MAXNAMELEN];
NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE, "nfs4_open: "));
- if (curproc->p_zone != VTOMI4(*vpp)->mi_zone)
+ if (nfs_zone() != VTOMI4(*vpp)->mi_zone)
return (EIO);
rp = VTOR4(*vpp);
@@ -820,7 +820,7 @@ nfs4open_otw(vnode_t *dvp, char *file_name, struct vattr *in_va,
"open %s open flag 0x%x cred %p", file_name, open_flag,
(void *)cr));
- ASSERT(curproc->p_zone == VTOMI4(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
if (create_flag) {
/*
* We are to create a file. Initialize the passed in vnode
@@ -1663,7 +1663,7 @@ nfs4_reopen(vnode_t *vp, nfs4_open_stream_t *osp, nfs4_error_t *ep,
nfs4_bseqid_entry_t *bsep = NULL;
ASSERT(nfs4_consistent_type(vp));
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
nfs4_error_zinit(ep);
@@ -2184,7 +2184,7 @@ nfs4_open_non_reg_file(vnode_t **vpp, int flag, cred_t *cr)
rnode4_t *rp;
nfs4_ga_res_t gar;
- ASSERT(curproc->p_zone == VTOMI4(*vpp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(*vpp)->mi_zone);
/*
* If close-to-open consistency checking is turned off or
@@ -2225,7 +2225,7 @@ nfs4_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr)
* open; if we happen to get here from the wrong zone we can't do
* anything over the wire.
*/
- if (VTOMI4(vp)->mi_zone != curproc->p_zone) {
+ if (VTOMI4(vp)->mi_zone != nfs_zone()) {
/*
* We could attempt to clean up locks, except we're sure
* that the current process didn't acquire any locks on
@@ -2368,7 +2368,7 @@ nfs4close_otw(rnode4_t *rp, cred_t *cred_otw, nfs4_open_owner_t *oop,
nfs4_lost_rqst_t lost_rqst;
hrtime_t t;
- ASSERT(curproc->p_zone == VTOMI4(RTOV4(rp))->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(RTOV4(rp))->mi_zone);
ASSERT(MUTEX_HELD(&osp->os_sync_lock));
@@ -2552,7 +2552,7 @@ nfs4_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
mi = VTOMI4(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (uiop->uio_resid == 0)
@@ -2655,7 +2655,7 @@ nfs4_write(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
mi = VTOMI4(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (uiop->uio_resid == 0)
@@ -2898,7 +2898,7 @@ nfs4_rdwrlbn(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
uchar_t fsdata;
stable_how4 stab_comm;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
bp = pageio_setup(pp, len, vp, flags);
ASSERT(bp != NULL);
@@ -2953,7 +2953,7 @@ nfs4rdwr_check_osid(vnode_t *vp, nfs4_error_t *ep, cred_t *cr)
mntinfo4_t *mi = VTOMI4(vp);
int reopen_needed;
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
oop = find_open_owner(cr, NFS4_PERM_CREATED, mi);
@@ -3028,7 +3028,7 @@ nfs4write(vnode_t *vp, caddr_t base, u_offset_t offset, int count, cred_t *cr,
rp = VTOR4(vp);
mi = VTOMI4(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
stable = *stab_comm;
*stab_comm = FILE_SYNC4;
@@ -3248,7 +3248,7 @@ nfs4read(vnode_t *vp, caddr_t base, offset_t offset, int count,
mi = VTOMI4(vp);
doqueue = 1;
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
args.ctag = async ? TAG_READAHEAD : TAG_READ;
@@ -3458,7 +3458,7 @@ recov_retry:
static int
nfs4_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
{
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
switch (cmd) {
case _FIODIRECTIO:
@@ -3474,7 +3474,7 @@ nfs4_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
int error;
rnode4_t *rp = VTOR4(vp);
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
/*
* If it has been specified that the return value will
@@ -3560,7 +3560,7 @@ nfs4_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
if (vap->va_mask & AT_NOSET)
return (EINVAL);
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
/*
@@ -3619,7 +3619,7 @@ nfs4setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
servinfo4_t *svp;
bitmap4 supp_attrs;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
rp = VTOR4(vp);
nfs4_init_stateid_types(&sid_types);
@@ -4106,7 +4106,7 @@ nfs4_access(vnode_t *vp, int mode, int flags, cred_t *cr)
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
mntinfo4_t *mi = VTOMI4(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
acc = 0;
@@ -4320,7 +4320,7 @@ nfs4_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr)
hrtime_t t;
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
/*
* Can't readlink anything other than a symbolic link.
@@ -4472,7 +4472,7 @@ nfs4_fsync(vnode_t *vp, int syncflag, cred_t *cr)
if ((syncflag & FNODSYNC) || IS_SWAPVP(vp))
return (0);
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
error = nfs4_putpage_commit(vp, (offset_t)0, 0, cr);
if (!error)
@@ -4506,7 +4506,7 @@ nfs4_inactive(vnode_t *vp, cred_t *cr)
* potentially turn into an expensive no-op if, for instance, v_count
* gets incremented in the meantime, but it's still correct.
*/
- if (curproc->p_zone != VTOMI4(vp)->mi_zone) {
+ if (nfs_zone() != VTOMI4(vp)->mi_zone) {
nfs4_async_inactive(vp, cr);
return;
}
@@ -4578,7 +4578,7 @@ nfs4_inactive_otw(vnode_t *vp, cred_t *cr)
char *name;
#endif
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
ASSERT(!IS_SHADOW(vp, rp));
#ifdef DEBUG
@@ -4778,7 +4778,7 @@ nfs4_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
rnode4_t *drp;
*vpp = NULL;
- if (curproc->p_zone != VTOMI4(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI4(dvp)->mi_zone)
return (EPERM);
/*
* if LOOKUP_XATTR, must replace dvp (object) with
@@ -4902,7 +4902,7 @@ nfs4lookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr, int skipdnlc)
int error;
rnode4_t *drp;
- ASSERT(curproc->p_zone == VTOMI4(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
/*
* If lookup is for "", just return dvp. Don't need
@@ -5069,7 +5069,7 @@ nfs4lookupvalidate_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
nfs4_ga_res_t *garp = NULL;
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
- ASSERT(curproc->p_zone == VTOMI4(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
ASSERT(nm != NULL);
ASSERT(nm[0] != '\0');
ASSERT(dvp->v_type == VDIR);
@@ -5498,7 +5498,7 @@ nfs4lookupnew_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
rnode4_t *drp = VTOR4(dvp);
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
- ASSERT(curproc->p_zone == VTOMI4(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
ASSERT(nm != NULL);
ASSERT(nm[0] != '\0');
ASSERT(dvp->v_type == VDIR);
@@ -6176,7 +6176,7 @@ nfs4openattr(vnode_t *dvp, vnode_t **avp, int cflag, cred_t *cr)
int needrecov = 0;
nfs4_recov_state_t recov_state;
- ASSERT(curproc->p_zone == VTOMI4(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
*avp = NULL;
recov_state.rs_flags = 0;
@@ -6339,7 +6339,7 @@ nfs4_create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
enum createmode4 createmode;
bool_t must_trunc = FALSE;
- if (curproc->p_zone != VTOMI4(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI4(dvp)->mi_zone)
return (EPERM);
if (exclusive == EXCL && (dvp->v_flag & V_XATTRDIR)) {
return (EINVAL);
@@ -6662,7 +6662,7 @@ call_nfs4_create_req(vnode_t *dvp, char *nm, void *data, struct vattr *va,
idx_fattr = 4;
}
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR4(dvp))) {
return (EINTR);
}
@@ -6941,7 +6941,7 @@ nfs4mknod(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
nfs_ftype4 type;
specdata4 spec, *specp = NULL;
- ASSERT(curproc->p_zone == VTOMI4(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
switch (va->va_type) {
case VCHR:
@@ -7020,7 +7020,7 @@ nfs4_remove(vnode_t *dvp, char *nm, cred_t *cr)
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
dirattr_info_t dinfo;
- if (curproc->p_zone != VTOMI4(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI4(dvp)->mi_zone)
return (EPERM);
drp = VTOR4(dvp);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR4(dvp)))
@@ -7248,7 +7248,7 @@ nfs4_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr)
ASSERT(nfs4_consistent_type(tdvp));
ASSERT(nfs4_consistent_type(svp));
- if (curproc->p_zone != VTOMI4(tdvp)->mi_zone)
+ if (nfs_zone() != VTOMI4(tdvp)->mi_zone)
return (EPERM);
if (VOP_REALVP(svp, &realvp) == 0) {
svp = realvp;
@@ -7438,7 +7438,7 @@ nfs4_rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
{
vnode_t *realvp;
- if (curproc->p_zone != VTOMI4(odvp)->mi_zone)
+ if (nfs_zone() != VTOMI4(odvp)->mi_zone)
return (EPERM);
if (VOP_REALVP(ndvp, &realvp) == 0)
ndvp = realvp;
@@ -7468,7 +7468,7 @@ nfs4rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
int do_link = 1;
nfsstat4 stat = NFS4_OK;
- ASSERT(curproc->p_zone == VTOMI4(odvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(odvp)->mi_zone);
ASSERT(nfs4_consistent_type(odvp));
ASSERT(nfs4_consistent_type(ndvp));
@@ -7842,7 +7842,7 @@ nfs4rename_persistent_fh(vnode_t *odvp, char *onm, vnode_t *renvp,
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
dirattr_info_t dinfo, *dinfop;
- ASSERT(curproc->p_zone == VTOMI4(odvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(odvp)->mi_zone);
recov_state.rs_flags = 0;
recov_state.rs_num_retry_despite_err = 0;
@@ -8034,7 +8034,7 @@ nfs4rename_volatile_fh(vnode_t *odvp, char *onm, vnode_t *ovp,
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
dirattr_info_t dinfo, *dinfop = &dinfo;
- ASSERT(curproc->p_zone == VTOMI4(odvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(odvp)->mi_zone);
recov_state.rs_flags = 0;
recov_state.rs_num_retry_despite_err = 0;
@@ -8293,7 +8293,7 @@ nfs4_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp, cred_t *cr)
int error;
vnode_t *vp;
- if (curproc->p_zone != VTOMI4(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI4(dvp)->mi_zone)
return (EPERM);
/*
* As ".." has special meaning and rather than send a mkdir
@@ -8342,7 +8342,7 @@ nfs4_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr)
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
dirattr_info_t dinfo, *dinfop;
- if (curproc->p_zone != VTOMI4(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI4(dvp)->mi_zone)
return (EPERM);
/*
* As ".." has special meaning and rather than send a rmdir
@@ -8526,7 +8526,7 @@ nfs4_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm, cred_t *cr)
char *contents;
mntinfo4_t *mi = VTOMI4(dvp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EPERM);
if (!(mi->mi_flags & MI4_SYMLINK))
return (EOPNOTSUPP);
@@ -8581,7 +8581,7 @@ nfs4_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp)
rddir4_cache *rdc;
rddir4_cache *rrdc;
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
rp = VTOR4(vp);
@@ -8771,7 +8771,7 @@ do_nfs4readdir(vnode_t *vp, rddir4_cache *rdc, cred_t *cr)
int error;
rnode4_t *rp;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
rp = VTOR4(vp);
@@ -8887,7 +8887,7 @@ nfs4readdir(vnode_t *vp, rddir4_cache *rdc, cred_t *cr)
hrtime_t t;
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
ASSERT(rdc->flags & RDDIR);
ASSERT(rdc->entries == NULL);
@@ -9246,7 +9246,7 @@ nfs4_bio(struct buf *bp, stable_how4 *stab_comm, cred_t *cr, bool_t readahead)
bool_t first_time = TRUE; /* first time getting otw cred */
bool_t last_time = FALSE; /* last time getting otw cred */
- ASSERT(curproc->p_zone == VTOMI4(bp->b_vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(bp->b_vp)->mi_zone);
DTRACE_IO1(start, struct buf *, bp);
offset = ldbtob(bp->b_lblkno);
@@ -9421,7 +9421,7 @@ nfs4_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
static int
nfs4_seek(vnode_t *vp, offset_t ooff, offset_t *noffp)
{
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
/*
@@ -9449,7 +9449,7 @@ nfs4_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
int error;
mntinfo4_t *mi;
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
rp = VTOR4(vp);
if (IS_SHADOW(vp, rp))
@@ -9555,7 +9555,7 @@ nfs4_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp,
page_t *pagefound;
page_t *savepp;
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
rp = VTOR4(vp);
@@ -9815,7 +9815,7 @@ nfs4_readahead(vnode_t *vp, u_offset_t blkoff, caddr_t addr, struct seg *seg,
rnode4_t *rp = VTOR4(vp);
page_t *savepp;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
@@ -9927,7 +9927,7 @@ nfs4_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr)
ASSERT(cr != NULL);
- if (!(flags & B_ASYNC) && curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (!(flags & B_ASYNC) && nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
rp = VTOR4(vp);
@@ -9974,7 +9974,7 @@ nfs4_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
ASSERT(!(vp->v_vfsp->vfs_flag & VFS_RDONLY));
ASSERT(pp != NULL);
ASSERT(cr != NULL);
- ASSERT((flags & B_ASYNC) || curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT((flags & B_ASYNC) || nfs_zone() == VTOMI4(vp)->mi_zone);
rp = VTOR4(vp);
ASSERT(rp->r_count > 0);
@@ -10088,7 +10088,7 @@ nfs4_sync_putapage(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
int error;
rnode4_t *rp;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
flags |= B_WRITE;
@@ -10157,7 +10157,7 @@ nfs4_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
rnode4_t *rp = VTOR4(vp);
mntinfo4_t *mi = VTOMI4(vp);
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
if (vp->v_flag & VNOMAP)
@@ -10426,7 +10426,7 @@ nfs4_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
mi = VTOMI4(vp);
rp = VTOR4(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (vp->v_flag & VNOMAP)
return (ENOSYS);
@@ -10538,7 +10538,7 @@ nfs4_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
int error = 0, intr = INTR4(vp);
nfs4_error_t e;
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
/* check for valid cmd parameter */
@@ -10684,7 +10684,7 @@ nfs4_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
{
int error;
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
ASSERT(vp->v_type == VREG);
if (cmd != F_FREESP)
@@ -10741,7 +10741,7 @@ nfs4_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
* A process may not change zones if it has NFS pages mmap'ed
* in, so we can't legitimately get here from the wrong zone.
*/
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
rp = VTOR4(vp);
@@ -11003,7 +11003,7 @@ nfs4_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
gar.n4g_ext_res = &ger;
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
if (cmd == _PC_PATH_MAX || cmd == _PC_SYMLINK_MAX) {
*valp = MAXPATHLEN;
@@ -11133,7 +11133,7 @@ nfs4_sync_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
{
int error;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
error = nfs4_rdwrlbn(vp, pp, io_off, io_len, flags, cr);
if (flags & B_READ)
@@ -11150,7 +11150,7 @@ nfs4_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
int error;
rnode4_t *rp;
- if (!(flags & B_ASYNC) && curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (!(flags & B_ASYNC) && nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
if (pp == NULL)
@@ -11314,7 +11314,7 @@ nfs4_dispose(vnode_t *vp, page_t *pp, int fl, int dn, cred_t *cr)
mutex_exit(&rp->r_statelock);
if (curproc == proc_pageout || curproc == proc_fsflush ||
- curproc->p_zone != VTOMI4(vp)->mi_zone) {
+ nfs_zone() != VTOMI4(vp)->mi_zone) {
nfs4_async_commit(vp, plist, offset, len,
cr, do_nfs4_async_commit);
return;
@@ -11402,7 +11402,7 @@ nfs4_commit(vnode_t *vp, offset4 offset, count4 count, cred_t *cr)
bool_t last_time = FALSE; /* last time getting OTW cred */
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
rp = VTOR4(vp);
@@ -11544,7 +11544,7 @@ nfs4_set_mod(vnode_t *vp)
kmutex_t *vphm;
rnode4_t *rp;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
/* make sure we're looking at the master vnode, not a shadow */
@@ -11693,7 +11693,7 @@ nfs4_get_commit_range(vnode_t *vp, u_offset_t soff, size_t len)
rp = VTOR4(vp);
ASSERT(rp->r_flags & R4COMMIT);
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
/* make sure we're looking at the master vnode, not a shadow */
@@ -11753,7 +11753,7 @@ nfs4_putpage_commit(vnode_t *vp, offset_t poff, size_t plen, cred_t *cr)
verifier4 write_verf;
rnode4_t *rp = VTOR4(vp);
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
/*
* Flush the data portion of the file and then commit any
@@ -11831,7 +11831,7 @@ nfs4_commit_vp(vnode_t *vp, u_offset_t poff, size_t plen,
offset3 offset;
count3 len;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
rp = VTOR4(vp);
@@ -11907,7 +11907,7 @@ nfs4_sync_commit(vnode_t *vp, page_t *plist, offset3 offset, count3 count,
int error;
page_t *pp;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
error = nfs4_commit(vp, (offset4)offset, (count3)count, cr);
@@ -11956,7 +11956,7 @@ nfs4_setsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
vsecattr_t nfsace4_vsap;
mi = VTOMI4(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (mi->mi_flags & MI4_ACL) {
/* if we have a delegation, return it */
@@ -12003,7 +12003,7 @@ nfs4_getsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
rnode4_t *rp = VTOR4(vp);
mi = VTOMI4(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
bzero(&gar, sizeof (gar));
@@ -12208,7 +12208,7 @@ nfs4_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr)
{
int error;
- if (curproc->p_zone != VTOMI4(vp)->mi_zone)
+ if (nfs_zone() != VTOMI4(vp)->mi_zone)
return (EIO);
/*
* check for valid cmd parameter
@@ -12266,7 +12266,7 @@ nfs4_update_attrcache(nfsstat4 status, nfs4_ga_res_t *garp,
{
int error = 0;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
if (status != NFS4_OK) {
/* getattr not done or failed */
@@ -12292,7 +12292,7 @@ nfs4_update_dircaches(change_info4 *cinfo, vnode_t *dvp, vnode_t *vp, char *nm,
{
rnode4_t *drp = VTOR4(dvp);
- ASSERT(curproc->p_zone == VTOMI4(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(dvp)->mi_zone);
/* Purge rddir cache for dir since it changed */
if (drp->r_dir != NULL)
@@ -12397,7 +12397,7 @@ nfs4open_confirm(vnode_t *vp, seqid4 *seqid, stateid4 *stateid, cred_t *cr,
OPEN_CONFIRM4args *open_confirm_args;
int needrecov;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
#if DEBUG
mutex_enter(&oop->oo_lock);
ASSERT(oop->oo_seqid_inuse);
@@ -12520,7 +12520,7 @@ state_to_cred(nfs4_open_stream_t *osp)
static struct lm_sysid *
nfs4_find_sysid(mntinfo4_t *mi)
{
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
/*
* Switch from RDMA knconf to original mount knconf
@@ -12622,7 +12622,7 @@ nfs4frlock_validate_args(int cmd, flock64_t *flk, int flag, vnode_t *vp,
static int
nfs4frlock_get_sysid(struct lm_sysid **lspp, vnode_t *vp, flock64_t *flk)
{
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
/* Find the lm_sysid */
*lspp = nfs4_find_sysid(VTOMI4(vp));
@@ -12718,7 +12718,7 @@ nfs4frlock_start_call(nfs4_lock_call_type_t ctype, vnode_t *vp,
int error = 0;
rnode4_t *rp;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
if (ctype == NFS4_LCK_CTYPE_NORM) {
error = nfs4_start_fop(VTOMI4(vp), vp, NULL, op_hint,
@@ -12853,7 +12853,7 @@ nfs4frlock_setup_lockt_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop,
{
LOCKT4args *lockt_args;
- ASSERT(curproc->p_zone == VTOMI4(RTOV4(rp))->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(RTOV4(rp))->mi_zone);
ASSERT(ctype == NFS4_LCK_CTYPE_NORM);
argop->argop = OP_LOCKT;
argsp->ctag = TAG_LOCKT;
@@ -12901,7 +12901,7 @@ nfs4frlock_check_deleg(vnode_t *vp, nfs4_error_t *ep, cred_t *cr, int lt)
rnode4_t *rp = VTOR4(vp);
mntinfo4_t *mi = VTOMI4(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
nfs4_error_zinit(ep);
@@ -13005,7 +13005,7 @@ nfs4frlock_setup_locku_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop,
bool_t is_spec = FALSE;
rnode4_t *rp = VTOR4(vp);
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
ASSERT(ctype == NFS4_LCK_CTYPE_NORM);
nfs4frlock_check_deleg(vp, ep, cr, F_UNLCK);
@@ -13116,7 +13116,7 @@ nfs4frlock_setup_lock_args(nfs4_lock_call_type_t ctype, LOCK4args **lock_argsp,
pid_t pid;
rnode4_t *rp = VTOR4(vp);
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
nfs4frlock_check_deleg(vp, ep, cr, flk->l_type);
if (ep->error || ep->stat != NFS4_OK)
@@ -13174,7 +13174,7 @@ nfs4frlock_save_lost_rqst(nfs4_lock_call_type_t ctype, int error,
{
bool_t unlock = (flk->l_type == F_UNLCK);
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
ASSERT(ctype == NFS4_LCK_CTYPE_NORM ||
ctype == NFS4_LCK_CTYPE_REINSTATE);
@@ -13344,7 +13344,7 @@ nfs4frlock_recovery(int needrecov, nfs4_error_t *ep,
bool_t abort, retry;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
ASSERT((*argspp) != NULL);
ASSERT((*respp) != NULL);
if (lock_args || locku_args)
@@ -13456,7 +13456,7 @@ nfs4frlock_results_ok(nfs4_lock_call_type_t ctype, int cmd, flock64_t *flk,
vnode_t *vp, int flag, u_offset_t offset,
nfs4_lost_rqst_t *resend_rqstp)
{
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
if ((cmd == F_SETLK || cmd == F_SETLKW) &&
(flk->l_type == F_RDLCK || flk->l_type == F_WRLCK)) {
if (ctype == NFS4_LCK_CTYPE_NORM) {
@@ -13491,7 +13491,7 @@ nfs4frlock_results_denied(nfs4_lock_call_type_t ctype, LOCK4args *lock_args,
nfs_resop4 *resop, cred_t *cr, bool_t *did_start_fop,
bool_t *skip_get_err)
{
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
if (lock_args) {
nfs4_open_owner_t *oop = *oopp;
@@ -13641,7 +13641,7 @@ nfs4frlock_update_state(LOCK4args *lock_args, LOCKU4args *locku_args,
vnode_t *vp, flock64_t *flk, cred_t *cr,
nfs4_lost_rqst_t *resend_rqstp)
{
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
if (lock_args) {
LOCK4res *lock_res;
@@ -13708,7 +13708,7 @@ nfs4frlock_final_cleanup(nfs4_lock_call_type_t ctype, COMPOUND4args_clnt *argsp,
int error = *errorp;
nfs_argop4 *argop;
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
/*
* The client recovery code wants the raw status information,
* so don't map the NFS status code to an errno value for
@@ -13867,7 +13867,7 @@ nfs4frlock(nfs4_lock_call_type_t ctype, vnode_t *vp, int cmd, flock64_t *flk,
char *name;
#endif
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
#ifdef DEBUG
name = fn_name(VTOSV(vp)->sv_name);
@@ -14185,7 +14185,7 @@ nfs4_safelock(vnode_t *vp, const struct flock64 *bfp, cred_t *cr)
struct vattr va;
int error;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
ASSERT(rp->r_mapcnt >= 0);
NFS4_DEBUG(nfs4_client_lock_debug, (CE_NOTE, "nfs4_safelock %s: "
"(%"PRIx64", %"PRIx64"); mapcnt = %ld", bfp->l_type == F_WRLCK ?
@@ -14246,7 +14246,7 @@ nfs4_register_lock_locally(vnode_t *vp, struct flock64 *flk, int flag,
char *name;
#endif
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
#ifdef DEBUG
name = fn_name(VTOSV(vp)->sv_name);
@@ -14304,7 +14304,7 @@ nfs4_lockrelease(vnode_t *vp, int flag, offset_t offset, cred_t *cr)
bool_t recovonly;
ASSERT((uintptr_t)vp > KERNELBASE);
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
rp = VTOR4(vp);
mi = VTOMI4(vp);
@@ -14474,7 +14474,7 @@ vtodv(vnode_t *vp, vnode_t **dvpp, cred_t *cr, bool_t need_start_op)
nfs4_fname_t *mfname;
int error;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
if (vp->v_flag & VROOT) {
nfs4_sharedfh_t *sfh;
@@ -14639,7 +14639,7 @@ nfs4close_notw(vnode_t *vp, nfs4_open_stream_t *osp, int *have_lockp)
NFS4_DEBUG(nfs4close_notw_debug, (CE_NOTE, "nfs4close_notw: "
"rp=%p osp=%p", (void *)rp, (void *)osp));
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
ASSERT(mutex_owned(&osp->os_sync_lock));
ASSERT(*have_lockp);
@@ -14681,7 +14681,7 @@ nfs4close_all(vnode_t *vp, cred_t *cr)
nfs4_error_t e = { 0, NFS4_OK, RPC_SUCCESS };
rnode4_t *rp;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
error = 0;
rp = VTOR4(vp);
@@ -14823,7 +14823,7 @@ nfs4close_one(vnode_t *vp, nfs4_open_stream_t *provided_osp, cred_t *cr,
int did_start_seqid_sync = 0;
int have_sync_lock = 0;
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
NFS4_DEBUG(nfs4close_one_debug, (CE_NOTE, "closing vp %p osp %p, "
"lrp %p, close type %d len %ld prot %x mmap flags %x bits %x",
@@ -15567,7 +15567,7 @@ nfs4_reinstitute_local_lock_state(vnode_t *vp, flock64_t *lost_flp, cred_t *cr,
* as that found in the active lock list, "list". The intersecting
* region locks are added to ri_llp in increasing l_start order.
*/
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
locks = flk_active_locks_for_vp(vp);
ri_llp = NULL;
@@ -15696,7 +15696,7 @@ push_reinstate(vnode_t *vp, int cmd, flock64_t *flk, cred_t *cr,
nfs_lock_type4 locktype;
nfs4_error_t e = { EINTR, NFS4_OK, RPC_SUCCESS };
- ASSERT(curproc->p_zone == VTOMI4(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI4(vp)->mi_zone);
locktype = flk_to_locktype(cmd, flk->l_type);
nfs4frlock_save_lost_rqst(NFS4_LCK_CTYPE_REINSTATE, EINTR, locktype,
diff --git a/usr/src/uts/common/fs/nfs/nfs_client.c b/usr/src/uts/common/fs/nfs/nfs_client.c
index ebc430d4c4..5bc488a65c 100644
--- a/usr/src/uts/common/fs/nfs/nfs_client.c
+++ b/usr/src/uts/common/fs/nfs/nfs_client.c
@@ -1461,7 +1461,7 @@ noasync:
pvn_write_done(pp, flags | B_ERROR);
return (0);
}
- if (curproc->p_zone != mi->mi_zone) {
+ if (nfs_zone() != mi->mi_zone) {
/*
* So this was a cross-zone sync putpage. We pass in B_ERROR
* to pvn_write_done() to re-mark the pages as dirty and unlock
@@ -1594,7 +1594,7 @@ noasync:
return (0);
}
- if (curproc->p_zone != mi->mi_zone) {
+ if (nfs_zone() != mi->mi_zone) {
/*
* So this was a cross-zone sync pageio. We pass in B_ERROR
* to pvn_write_done() to re-mark the pages as dirty and unlock
@@ -1790,7 +1790,7 @@ noasync:
}
if (curproc == proc_pageout || curproc == proc_fsflush ||
- curproc->p_zone != mi->mi_zone) {
+ nfs_zone() != mi->mi_zone) {
while (plist != NULL) {
pp = plist;
page_sub(&plist, pp);
diff --git a/usr/src/uts/common/fs/nfs/nfs_subr.c b/usr/src/uts/common/fs/nfs/nfs_subr.c
index bef0e6bb16..1451e791c9 100644
--- a/usr/src/uts/common/fs/nfs/nfs_subr.c
+++ b/usr/src/uts/common/fs/nfs/nfs_subr.c
@@ -454,7 +454,7 @@ clget(clinfo_t *ci, servinfo_t *svp, cred_t *cr, CLIENT **newcl,
{
struct nfs_clnt *nfscl;
- nfscl = zone_getspecific(nfsclnt_zone_key, curproc->p_zone);
+ nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
ASSERT(nfscl != NULL);
return (clget_impl(ci, svp, cr, newcl, chp, nfscl));
@@ -612,7 +612,7 @@ clfree(CLIENT *cl, struct chtab *cp)
{
struct nfs_clnt *nfscl;
- nfscl = zone_getspecific(nfsclnt_zone_key, curproc->p_zone);
+ nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
ASSERT(nfscl != NULL);
clfree_impl(cl, cp, nfscl);
@@ -937,7 +937,7 @@ rfscall(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
TRACE_2(TR_FAC_NFS, TR_RFSCALL_START,
"rfscall_start:which %d mi %p", which, mi);
- nfscl = zone_getspecific(nfsclnt_zone_key, curproc->p_zone);
+ nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
ASSERT(nfscl != NULL);
nfscl->nfscl_stat.calls.value.ui64++;
@@ -1475,7 +1475,7 @@ aclcall(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
"rfscall_start:which %d mi %p", which, mi);
#endif
- nfscl = zone_getspecific(nfsclnt_zone_key, curproc->p_zone);
+ nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
ASSERT(nfscl != NULL);
nfscl->nfscl_stat.calls.value.ui64++;
@@ -4208,7 +4208,7 @@ failover_thread(mntinfo_t *mi)
* DEBUG kernels, hence we don't want to pay the penalty of the lookup
* on non-DEBUG kernels.
*/
- nfscl = zone_getspecific(nfsclnt_zone_key, curproc->p_zone);
+ nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
ASSERT(nfscl != NULL);
#endif
@@ -4431,7 +4431,7 @@ failover_remap(failinfo_t *fi)
#ifdef DEBUG
struct nfs_clnt *nfscl;
- nfscl = zone_getspecific(nfsclnt_zone_key, curproc->p_zone);
+ nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
ASSERT(nfscl != NULL);
#endif
/*
@@ -4934,3 +4934,28 @@ nfs_getsrvnames(mntinfo_t *mi, size_t *len)
return (srvnames);
}
+
+/*
+ * These two functions are temporary and designed for the upgrade-workaround
+ * only. They cannot be used for general zone-crossing NFS client support, and
+ * will be removed shortly.
+ *
+ * When the workaround is enabled, all NFS traffic is forced into the global
+ * zone. These functions are called when the code needs to refer to the state
+ * of the underlying network connection. They're not called when the function
+ * needs to refer to the state of the process that invoked the system call.
+ * (E.g., when checking whether the zone is shutting down during the mount()
+ * call.)
+ */
+
+struct zone *
+nfs_zone(void)
+{
+ return (nfs_global_client_only != 0 ? global_zone : curproc->p_zone);
+}
+
+zoneid_t
+nfs_zoneid(void)
+{
+ return (nfs_global_client_only != 0 ? GLOBAL_ZONEID : getzoneid());
+}
diff --git a/usr/src/uts/common/fs/nfs/nfs_vfsops.c b/usr/src/uts/common/fs/nfs/nfs_vfsops.c
index 5d5a65008b..ff4b5ecd6f 100644
--- a/usr/src/uts/common/fs/nfs/nfs_vfsops.c
+++ b/usr/src/uts/common/fs/nfs/nfs_vfsops.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
@@ -222,7 +222,7 @@ nfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
STRUCT_DECL(netbuf, addr_tmp);
int flags, addr_type;
char *p, *pf;
- zone_t *zone = curproc->p_zone;
+ zone_t *zone = nfs_zone();
if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0)
return (error);
@@ -685,7 +685,7 @@ more:
/*
* Stop the mount from going any further if the zone is going away.
*/
- if (zone_status_get(zone) >= ZONE_IS_SHUTTING_DOWN) {
+ if (zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN) {
error = EBUSY;
goto errout;
}
@@ -856,7 +856,7 @@ nfsrootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo *svp,
struct nfs_stats *nfsstatsp;
cred_t *lcr = NULL, *tcr = cr;
- nfsstatsp = zone_getspecific(nfsstat_zone_key, curproc->p_zone);
+ nfsstatsp = zone_getspecific(nfsstat_zone_key, nfs_zone());
ASSERT(nfsstatsp != NULL);
/*
@@ -1130,7 +1130,7 @@ nfs_root(vfs_t *vfsp, vnode_t **vpp)
mi = VFTOMI(vfsp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EPERM);
svp = mi->mi_curr_serv;
@@ -1287,7 +1287,7 @@ nfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
struct nfs_fid *nfsfidp = (struct nfs_fid *)fidp;
zoneid_t zoneid = VFTOMI(vfsp)->mi_zone->zone_id;
- if (curproc->p_zone != VFTOMI(vfsp)->mi_zone)
+ if (nfs_zone() != VFTOMI(vfsp)->mi_zone)
return (EPERM);
if (fidp->fid_len != (sizeof (*nfsfidp) - sizeof (short))) {
#ifdef DEBUG
diff --git a/usr/src/uts/common/fs/nfs/nfs_vnops.c b/usr/src/uts/common/fs/nfs/nfs_vnops.c
index 99baf1312f..b98b3d280e 100644
--- a/usr/src/uts/common/fs/nfs/nfs_vnops.c
+++ b/usr/src/uts/common/fs/nfs/nfs_vnops.c
@@ -241,7 +241,7 @@ nfs_open(vnode_t **vpp, int flag, cred_t *cr)
vp = *vpp;
rp = VTOR(vp);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
mutex_enter(&rp->r_statelock);
if (rp->r_cred == NULL) {
@@ -293,7 +293,7 @@ nfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr)
* open; if we happen to get here from the wrong zone we can't do
* anything over the wire.
*/
- if (VTOMI(vp)->mi_zone != curproc->p_zone) {
+ if (VTOMI(vp)->mi_zone != nfs_zone()) {
/*
* We could attempt to clean up locks, except we're sure
* that the current process didn't acquire any locks on
@@ -404,7 +404,7 @@ nfs_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
rp = VTOR(vp);
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
ASSERT(nfs_rw_lock_held(&rp->r_rwlock, RW_READER));
@@ -517,7 +517,7 @@ nfs_write(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
rp = VTOR(vp);
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (vp->v_type != VREG)
return (EISDIR);
@@ -726,7 +726,7 @@ nfs_rdwrlbn(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
struct buf *bp;
int error;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
bp = pageio_setup(pp, len, vp, flags);
ASSERT(bp != NULL);
@@ -774,7 +774,7 @@ nfswrite(vnode_t *vp, caddr_t base, uint_t offset, int count, cred_t *cr)
rp = VTOR(vp);
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
wa.wa_args = &wa.wa_args_buf;
wa.wa_fhandle = *VTOFH(vp);
@@ -858,7 +858,7 @@ nfsread(vnode_t *vp, caddr_t base, uint_t offset, int count, size_t *residp,
rp = VTOR(vp);
mi = VTOMI(vp);
- ASSERT(curproc->p_zone == mi->mi_zone);
+ ASSERT(nfs_zone() == mi->mi_zone);
douprintf = 1;
@@ -962,7 +962,7 @@ static int
nfs_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
{
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
switch (cmd) {
case _FIODIRECTIO:
@@ -978,7 +978,7 @@ nfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
int error;
rnode_t *rp;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
* If it has been specified that the return value will
@@ -1050,7 +1050,7 @@ nfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
vap->va_size > MAXOFF32_T)
return (EFBIG);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
va.va_mask = AT_UID | AT_MODE;
@@ -1085,7 +1085,7 @@ nfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
mask = vap->va_mask;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
rp = VTOR(vp);
@@ -1287,7 +1287,7 @@ nfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
static int
nfs_accessx(void *vp, int mode, cred_t *cr)
{
- ASSERT(curproc->p_zone == VTOMI((vnode_t *)vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI((vnode_t *)vp)->mi_zone);
return (nfs_access(vp, mode, 0, cr));
}
@@ -1301,7 +1301,7 @@ nfs_access(vnode_t *vp, int mode, int flags, cred_t *cr)
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (mi->mi_flags & MI_ACL) {
error = acl_access2(vp, mode, flags, cr);
@@ -1368,7 +1368,7 @@ nfs_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr)
if (vp->v_type != VLNK)
return (EINVAL);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
@@ -1455,7 +1455,7 @@ nfs_fsync(vnode_t *vp, int syncflag, cred_t *cr)
if ((syncflag & FNODSYNC) || IS_SWAPVP(vp))
return (0);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
error = nfs_putpage(vp, (offset_t)0, 0, 0, cr);
@@ -1484,7 +1484,7 @@ nfs_inactive(vnode_t *vp, cred_t *cr)
* potentially turn into an expensive no-op if, for instance, v_count
* gets incremented in the meantime, but it's still correct.
*/
- if (curproc->p_zone != VTOMI(vp)->mi_zone) {
+ if (nfs_zone() != VTOMI(vp)->mi_zone) {
nfs_async_inactive(vp, cr, nfs_inactive);
return;
}
@@ -1582,7 +1582,7 @@ nfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
vnode_t *avp = NULL;
rnode_t *drp;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
drp = VTOR(dvp);
@@ -1663,7 +1663,7 @@ nfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
{
int error;
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
/*
* If lookup is for "", just return dvp. Don't need
@@ -1727,7 +1727,7 @@ nfslookup_dnlc(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr)
vnode_t *vp;
ASSERT(*nm != '\0');
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
/*
* Lookup this name in the DNLC. If successful, then validate
@@ -1798,7 +1798,7 @@ nfslookup_otw(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
ASSERT(*nm != '\0');
ASSERT(dvp->v_type == VDIR);
- ASSERT(curproc->p_zone == VTOMI(dvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
setdiropargs(&da, nm, dvp);
@@ -1863,7 +1863,7 @@ nfs_create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
drp = VTOR(dvp);
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR(dvp)))
return (EINTR);
@@ -2101,7 +2101,7 @@ nfs_remove(vnode_t *dvp, char *nm, cred_t *cr)
rnode_t *rp;
rnode_t *drp;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
drp = VTOR(dvp);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR(dvp)))
@@ -2228,7 +2228,7 @@ nfs_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr)
int douprintf;
rnode_t *tdrp;
- if (curproc->p_zone != VTOMI(tdvp)->mi_zone)
+ if (nfs_zone() != VTOMI(tdvp)->mi_zone)
return (EPERM);
if (VOP_REALVP(svp, &realvp) == 0)
svp = realvp;
@@ -2270,7 +2270,7 @@ nfs_rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
{
vnode_t *realvp;
- if (curproc->p_zone != VTOMI(odvp)->mi_zone)
+ if (nfs_zone() != VTOMI(odvp)->mi_zone)
return (EPERM);
if (VOP_REALVP(ndvp, &realvp) == 0)
ndvp = realvp;
@@ -2295,7 +2295,7 @@ nfsrename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
rnode_t *odrp;
rnode_t *ndrp;
- ASSERT(curproc->p_zone == VTOMI(odvp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(odvp)->mi_zone);
if (strcmp(onm, ".") == 0 || strcmp(onm, "..") == 0 ||
strcmp(nnm, ".") == 0 || strcmp(nnm, "..") == 0)
return (EINVAL);
@@ -2560,7 +2560,7 @@ nfs_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp, cred_t *cr)
rnode_t *drp;
hrtime_t t;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
setdiropargs(&args.ca_da, nm, dvp);
@@ -2646,7 +2646,7 @@ nfs_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr)
int douprintf;
rnode_t *drp;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
drp = VTOR(dvp);
if (nfs_rw_enter_sig(&drp->r_rwlock, RW_WRITER, INTR(dvp)))
@@ -2739,7 +2739,7 @@ nfs_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm, cred_t *cr)
int douprintf;
rnode_t *drp;
- if (curproc->p_zone != VTOMI(dvp)->mi_zone)
+ if (nfs_zone() != VTOMI(dvp)->mi_zone)
return (EPERM);
setdiropargs(&args.sla_from, lnm, dvp);
args.sla_sa = &args.sla_sa_buf;
@@ -2818,7 +2818,7 @@ nfs_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp)
rp = VTOR(vp);
ASSERT(nfs_rw_lock_held(&rp->r_rwlock, RW_READER));
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
* Make sure that the directory cache is valid.
@@ -3095,7 +3095,7 @@ nfsreaddir(vnode_t *vp, rddir_cache *rdc, cred_t *cr)
int douprintf;
failinfo_t fi, *fip;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
count = rdc->buflen;
rp = VTOR(vp);
@@ -3218,7 +3218,7 @@ nfs_bio(struct buf *bp, cred_t *cr)
DTRACE_IO1(start, struct buf *, bp);
- ASSERT(curproc->p_zone == VTOMI(bp->b_vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(bp->b_vp)->mi_zone);
offset = dbtob(bp->b_blkno);
if (bp->b_flags & B_READ) {
@@ -3459,7 +3459,7 @@ nfs_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
return (ENOSYS);
ASSERT(off <= MAXOFF32_T);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
if (protp != NULL)
*protp = PROT_ALL;
@@ -3549,7 +3549,7 @@ nfs_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp,
int ra_window; /* readahead window */
page_t *pagefound;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
@@ -3803,7 +3803,7 @@ nfs_readahead(vnode_t *vp, u_offset_t blkoff, caddr_t addr, struct seg *seg,
uint_t bsize, blksize;
rnode_t *rp = VTOR(vp);
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
@@ -3919,7 +3919,7 @@ nfs_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr)
if (len == 0 && !(flags & B_INVAL) && vn_is_readonly(vp))
return (0);
- if (!(flags & B_ASYNC) && curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (!(flags & B_ASYNC) && nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
ASSERT(off <= MAXOFF32_T);
@@ -3954,7 +3954,7 @@ nfs_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
ASSERT(!vn_is_readonly(vp));
ASSERT(pp != NULL);
ASSERT(cr != NULL);
- ASSERT((flags & B_ASYNC) || curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT((flags & B_ASYNC) || nfs_zone() == VTOMI(vp)->mi_zone);
rp = VTOR(vp);
ASSERT(rp->r_count > 0);
@@ -4071,7 +4071,7 @@ nfs_sync_putapage(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
flags |= B_WRITE;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
error = nfs_rdwrlbn(vp, pp, io_off, io_len, flags, cr);
rp = VTOR(vp);
@@ -4129,7 +4129,7 @@ nfs_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
rnode_t *rp;
struct vattr va;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
if (vp->v_flag & VNOMAP)
@@ -4230,7 +4230,7 @@ nfs_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
if (vp->v_flag & VNOMAP)
return (ENOSYS);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
@@ -4260,7 +4260,7 @@ nfs_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
/* check for valid cmd parameter */
if (cmd != F_GETLK && cmd != F_SETLK && cmd != F_SETLKW)
return (EINVAL);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/* Verify l_type. */
@@ -4414,7 +4414,7 @@ nfs_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
(bfp->l_len > MAXOFF32_T))
return (EFBIG);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
error = convoff(vp, bfp, 0, offset);
@@ -4477,7 +4477,7 @@ nfs_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
* A process may not change zones if it has NFS pages mmap'ed
* in, so we can't legitimately get here from the wrong zone.
*/
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
rp = VTOR(vp);
@@ -4591,7 +4591,7 @@ nfs_delmap_callback(struct as *as, void *arg, uint_t event)
* dirty pages.
*/
if ((mi->mi_flags & MI_NOCTO) ||
- curproc->p_zone != mi->mi_zone)
+ nfs_zone() != mi->mi_zone)
error = nfs_putpage(dmapp->vp, dmapp->off, dmapp->len,
B_ASYNC, dmapp->cr);
else
@@ -4621,7 +4621,7 @@ nfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
{
int error = 0;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
* This looks a little weird because it's written in a general
@@ -4729,7 +4729,7 @@ nfs_sync_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
{
int error;
- ASSERT(curproc->p_zone == VTOMI(vp)->mi_zone);
+ ASSERT(nfs_zone() == VTOMI(vp)->mi_zone);
error = nfs_rdwrlbn(vp, pp, io_off, io_len, flags, cr);
if (flags & B_READ)
pvn_read_done(pp, (error ? B_ERROR : 0) | flags);
@@ -4750,7 +4750,7 @@ nfs_pageio(vnode_t *vp, page_t *pp, u_offset_t io_off, size_t io_len,
if (io_off > MAXOFF32_T)
return (EFBIG);
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
rp = VTOR(vp);
mutex_enter(&rp->r_statelock);
@@ -4777,7 +4777,7 @@ nfs_setsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (mi->mi_flags & MI_ACL) {
error = acl_setacl2(vp, vsecattr, flag, cr);
@@ -4796,7 +4796,7 @@ nfs_getsecattr(vnode_t *vp, vsecattr_t *vsecattr, int flag, cred_t *cr)
mi = VTOMI(vp);
- if (curproc->p_zone != mi->mi_zone)
+ if (nfs_zone() != mi->mi_zone)
return (EIO);
if (mi->mi_flags & MI_ACL) {
error = acl_getacl2(vp, vsecattr, flag, cr);
@@ -4815,7 +4815,7 @@ nfs_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr)
struct nfs_owner nfs_owner;
netobj lm_fh;
- if (curproc->p_zone != VTOMI(vp)->mi_zone)
+ if (nfs_zone() != VTOMI(vp)->mi_zone)
return (EIO);
/*
diff --git a/usr/src/uts/common/fs/vnode.c b/usr/src/uts/common/fs/vnode.c
index 74dfbc8205..1e7793ba39 100644
--- a/usr/src/uts/common/fs/vnode.c
+++ b/usr/src/uts/common/fs/vnode.c
@@ -72,6 +72,9 @@
((vp)->v_type != VCHR && (vp)->v_type != VBLK && \
(vp)->v_type != VFIFO && vn_is_readonly(vp))
+/* Tunable via /etc/system; used only by admin/install */
+int nfs_global_client_only;
+
/*
* Convert stat(2) formats to vnode types and vice versa. (Knows about
* numerical order of S_IFMT and vnode types.)
@@ -1843,6 +1846,9 @@ vn_can_change_zones(vnode_t *vp)
int allow = 1;
vnode_t *rvp;
+ if (nfs_global_client_only != 0)
+ return (1);
+
/*
* We always want to look at the underlying vnode if there is one.
*/
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index 9b995cd7df..e89068125f 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -8912,6 +8912,13 @@ tcp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
dev_t conn_dev;
zoneid_t zoneid = getzoneid();
+ /*
+ * Special case for install: miniroot needs to be able to access files
+ * via NFS as though it were always in the global zone.
+ */
+ if (credp == kcred && nfs_global_client_only != 0)
+ zoneid = GLOBAL_ZONEID;
+
if (q->q_ptr != NULL)
return (0);
diff --git a/usr/src/uts/common/ktli/t_kopen.c b/usr/src/uts/common/ktli/t_kopen.c
index f05a9cbdb5..c49b03b610 100644
--- a/usr/src/uts/common/ktli/t_kopen.c
+++ b/usr/src/uts/common/ktli/t_kopen.c
@@ -80,6 +80,13 @@ t_kopen(file_t *fp, dev_t rdev, int flags, TIUSER **tiptr, cred_t *cr)
TIUSER *ntiptr;
int rtries = 0;
+ /*
+ * Special case for install: miniroot needs to be able to access files
+ * via NFS as though it were always in the global zone.
+ */
+ if (nfs_global_client_only != 0)
+ cr = kcred;
+
KTLILOG(2, "t_kopen: fp %x, ", fp);
KTLILOG(2, "rdev %x, ", rdev);
KTLILOG(2, "flags %x\n", flags);
diff --git a/usr/src/uts/common/nfs/rnode.h b/usr/src/uts/common/nfs/rnode.h
index ef1aa644c4..11520dd356 100644
--- a/usr/src/uts/common/nfs/rnode.h
+++ b/usr/src/uts/common/nfs/rnode.h
@@ -382,6 +382,8 @@ extern void nfs_rw_destroy(nfs_rwlock_t *);
extern int nfs_directio(vnode_t *, int, cred_t *);
extern int nfs3_rddir_compar(const void *, const void *);
extern int nfs_rddir_compar(const void *, const void *);
+extern struct zone *nfs_zone(void);
+extern zoneid_t nfs_zoneid(void);
#endif
diff --git a/usr/src/uts/common/os/zone.c b/usr/src/uts/common/os/zone.c
index e7b929c406..b4abecaadf 100644
--- a/usr/src/uts/common/os/zone.c
+++ b/usr/src/uts/common/os/zone.c
@@ -3090,6 +3090,15 @@ zone_destroy(zoneid_t zoneid)
(mod_hash_key_t)(uintptr_t)zone->zone_id);
mutex_exit(&zonehash_lock);
+ /*
+ * Release the root vnode; we're not using it anymore. Nor should any
+ * other thread that might access it exist.
+ */
+ if (zone->zone_rootvp != NULL) {
+ VN_RELE(zone->zone_rootvp);
+ zone->zone_rootvp = NULL;
+ }
+
/* add to deathrow list */
mutex_enter(&zone_deathrow_lock);
list_insert_tail(&zone_deathrow, zone);
diff --git a/usr/src/uts/common/rpc/clnt.h b/usr/src/uts/common/rpc/clnt.h
index 1600176aa0..f422f039d6 100644
--- a/usr/src/uts/common/rpc/clnt.h
+++ b/usr/src/uts/common/rpc/clnt.h
@@ -340,6 +340,9 @@ typedef struct calllist_s {
*/
extern uint32_t alloc_xid(void);
+extern struct zone *rpc_zone(void);
+extern zoneid_t rpc_zoneid(void);
+
extern int clnt_tli_kcreate(struct knetconfig *config, struct netbuf *svcaddr,
rpcprog_t, rpcvers_t, uint_t max_msgsize, int retrys,
struct cred *cred, CLIENT **ncl);
diff --git a/usr/src/uts/common/rpc/clnt_clts.c b/usr/src/uts/common/rpc/clnt_clts.c
index a694a0351d..affd816ae7 100644
--- a/usr/src/uts/common/rpc/clnt_clts.c
+++ b/usr/src/uts/common/rpc/clnt_clts.c
@@ -374,7 +374,7 @@ clnt_clts_kinit(CLIENT *h, struct netbuf *addr, int retrys, cred_t *cred)
struct cku_private *p = htop(h);
struct rpcstat *rsp;
- rsp = zone_getspecific(rpcstat_zone_key, curproc->p_zone);
+ rsp = zone_getspecific(rpcstat_zone_key, rpc_zone());
ASSERT(rsp != NULL);
p->cku_retrys = retrys;
@@ -1296,7 +1296,7 @@ endpnt_type_create(struct knetconfig *config)
mutex_init(&etype->e_plock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&etype->e_ilock, NULL, MUTEX_DEFAULT, NULL);
etype->e_rdev = config->knc_rdev;
- etype->e_zoneid = getzoneid();
+ etype->e_zoneid = rpc_zoneid();
etype->e_async_count = 0;
cv_init(&etype->e_async_cv, NULL, CV_DEFAULT, NULL);
@@ -1427,7 +1427,7 @@ endpnt_get(struct knetconfig *config, int useresvport)
int i = 0;
int error;
int retval;
- zoneid_t zoneid = getzoneid();
+ zoneid_t zoneid = rpc_zoneid();
RPCLOG(1, "endpnt_get: protofmly %s, ", config->knc_protofmly);
RPCLOG(1, "rdev %ld\n", config->knc_rdev);
diff --git a/usr/src/uts/common/rpc/clnt_cots.c b/usr/src/uts/common/rpc/clnt_cots.c
index 965fb3056f..e5a7e5b3d7 100644
--- a/usr/src/uts/common/rpc/clnt_cots.c
+++ b/usr/src/uts/common/rpc/clnt_cots.c
@@ -543,7 +543,7 @@ clnt_cots_kcreate(dev_t dev, struct netbuf *addr, int family, rpcprog_t prog,
RPCLOG(8, "clnt_cots_kcreate: prog %u\n", prog);
- rpcstat = zone_getspecific(rpcstat_zone_key, curproc->p_zone);
+ rpcstat = zone_getspecific(rpcstat_zone_key, rpc_zone());
ASSERT(rpcstat != NULL);
/* Allocate and intialize the client handle. */
@@ -1737,7 +1737,7 @@ connmgr_get(
clock_t prev_time;
int tidu_size;
bool_t connected;
- zoneid_t zoneid = getzoneid();
+ zoneid_t zoneid = rpc_zoneid();
/*
* If the call is not a retry, look for a transport entry that
@@ -2459,7 +2459,7 @@ connmgr_connect(
*/
struct rpcstat *rpcstat;
- rpcstat = zone_getspecific(rpcstat_zone_key, curproc->p_zone);
+ rpcstat = zone_getspecific(rpcstat_zone_key, rpc_zone());
ASSERT(rpcstat != NULL);
RPCLOG0(1, "connmgr_connect: cannot alloc mp for "
diff --git a/usr/src/uts/common/rpc/mt_rpcinit.c b/usr/src/uts/common/rpc/mt_rpcinit.c
index 630345e5f5..65cfc46b34 100644
--- a/usr/src/uts/common/rpc/mt_rpcinit.c
+++ b/usr/src/uts/common/rpc/mt_rpcinit.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -167,3 +167,20 @@ alloc_xid(void)
mutex_exit(&xid_lock);
return (xid);
}
+
+/*
+ * These functions are temporary and designed for the upgrade-workaround only.
+ * They cannot be used for general zone-crossing RPC client support, and will
+ * be removed shortly.
+ */
+struct zone *
+rpc_zone(void)
+{
+ return (nfs_global_client_only != 0 ? global_zone : curproc->p_zone);
+}
+
+zoneid_t
+rpc_zoneid(void)
+{
+ return (nfs_global_client_only != 0 ? GLOBAL_ZONEID : getzoneid());
+}
diff --git a/usr/src/uts/common/rpc/rpcmod.c b/usr/src/uts/common/rpc/rpcmod.c
index be8a2c341f..2f1d601a5a 100644
--- a/usr/src/uts/common/rpc/rpcmod.c
+++ b/usr/src/uts/common/rpc/rpcmod.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -496,7 +496,7 @@ rpcmodopen(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp)
mutex_init(&rmp->rm_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&rmp->rm_cwait, NULL, CV_DEFAULT, NULL);
- rmp->rm_zoneid = getzoneid();
+ rmp->rm_zoneid = rpc_zoneid();
/*
* slot type will be set by kRPC client and server ioctl's
*/
@@ -1380,7 +1380,7 @@ mir_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
mir->mir_frag_len = -(int32_t)sizeof (uint32_t);
- mir->mir_zoneid = getzoneid();
+ mir->mir_zoneid = rpc_zoneid();
mutex_init(&mir->mir_mutex, NULL, MUTEX_DEFAULT, NULL);
cv_init(&mir->mir_condvar, NULL, CV_DRIVER, NULL);
cv_init(&mir->mir_timer_cv, NULL, CV_DRIVER, NULL);
diff --git a/usr/src/uts/common/sys/systm.h b/usr/src/uts/common/sys/systm.h
index 36ef678d4a..1015641e7f 100644
--- a/usr/src/uts/common/sys/systm.h
+++ b/usr/src/uts/common/sys/systm.h
@@ -110,6 +110,12 @@ extern char *isa_list; /* For sysinfo's isalist option */
extern int noexec_user_stack; /* patchable via /etc/system */
extern int noexec_user_stack_log; /* patchable via /etc/system */
+/*
+ * Use NFS client operations in the global zone only. Under contract with
+ * admin/install; do not change without coordinating with that consolidation.
+ */
+extern int nfs_global_client_only;
+
extern void report_stack_exec(proc_t *, caddr_t);
extern void startup(void);
diff --git a/usr/src/uts/common/sys/zone.h b/usr/src/uts/common/sys/zone.h
index 867e531c85..0bc997a57b 100644
--- a/usr/src/uts/common/sys/zone.h
+++ b/usr/src/uts/common/sys/zone.h
@@ -120,7 +120,8 @@ typedef enum {
* communicates with zoneadmd, but only uses Z_REBOOT and Z_HALT.
*/
typedef enum zone_cmd {
- Z_READY, Z_BOOT, Z_REBOOT, Z_HALT, Z_NOTE_UNINSTALLING
+ Z_READY, Z_BOOT, Z_REBOOT, Z_HALT, Z_NOTE_UNINSTALLING,
+ Z_MOUNT, Z_UNMOUNT
} zone_cmd_t;
#define ZONEBOOTARGS_MAX 257 /* uadmin()'s buffer is 257 bytes. */