summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2011-01-31 16:51:07 -0700
committerJerry Jelinek <jerry.jelinek@joyent.com>2011-01-31 16:51:07 -0700
commitc2a4113fafb4afdd766fbbf0fd0bcb9aa1eed84c (patch)
treec86ebf0cc453056616acca555c20da7f8b9f5e78
parent180efeda14b4d453183ef3b7e53168ce36d467a6 (diff)
downloadillumos-joyent-c2a4113fafb4afdd766fbbf0fd0bcb9aa1eed84c.tar.gz
OS-180 need zoneid to be persistent across zone reboot
-rw-r--r--usr/src/cmd/zoneadmd/vplat.c12
-rw-r--r--usr/src/cmd/zoneadmd/zoneadmd.c24
-rw-r--r--usr/src/cmd/zoneadmd/zoneadmd.h3
-rw-r--r--usr/src/head/zone.h3
-rw-r--r--usr/src/lib/libc/port/sys/zone.c5
-rw-r--r--usr/src/uts/common/os/zone.c25
-rw-r--r--usr/src/uts/common/sys/zone.h2
7 files changed, 54 insertions, 20 deletions
diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c
index 9e4dca604d..608b8ef5cc 100644
--- a/usr/src/cmd/zoneadmd/vplat.c
+++ b/usr/src/cmd/zoneadmd/vplat.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
*/
/*
@@ -4632,8 +4633,15 @@ out:
return (res);
}
+/*
+ * The requested zoneid (req_zoneid) is advisory to the kernel and will be
+ * -1 if this is a new instance of a zone without a pre-existing zoneid.
+ * If this zone already exists (i.e. we're rebooting it) then the kernel will
+ * try to reassign the same zoneid, however there is no guarantee that this
+ * will occur. In practice it should always occur.
+ */
zoneid_t
-vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd)
+vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t req_zoneid)
{
zoneid_t rval = -1;
priv_set_t *privs;
@@ -4774,7 +4782,7 @@ vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd)
xerr = 0;
if ((zoneid = zone_create(kzone, rootpath, privs, rctlbuf,
rctlbufsz, zfsbuf, zfsbufsz, &xerr, match, doi, zlabel,
- flags)) == -1) {
+ flags, req_zoneid)) == -1) {
if (xerr == ZE_AREMOUNTS) {
if (zonecfg_find_mounts(rootpath, NULL, NULL) < 1) {
zerror(zlogp, B_FALSE,
diff --git a/usr/src/cmd/zoneadmd/zoneadmd.c b/usr/src/cmd/zoneadmd/zoneadmd.c
index 94ab464193..9ec94eaf58 100644
--- a/usr/src/cmd/zoneadmd/zoneadmd.c
+++ b/usr/src/cmd/zoneadmd/zoneadmd.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
*/
/*
@@ -529,7 +530,7 @@ notify_zonestatd(zoneid_t zoneid)
* subcommand.
*/
static int
-zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate)
+zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate, zoneid_t req_zoneid)
{
int err;
@@ -542,7 +543,7 @@ zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate)
goto bad;
}
- if ((zone_id = vplat_create(zlogp, mount_cmd)) == -1) {
+ if ((zone_id = vplat_create(zlogp, mount_cmd, req_zoneid)) == -1) {
if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
zerror(zlogp, B_FALSE, "destroying snapshot: %s",
zonecfg_strerror(err));
@@ -1163,12 +1164,14 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
goto out;
}
+ zoneid = getzoneidbyname(zone_name);
+
if (kernelcall) {
/*
* Kernel-initiated requests may lose their validity if the
* zone_t the kernel was referring to has gone away.
*/
- if ((zoneid = getzoneidbyname(zone_name)) == -1 ||
+ if (zoneid == -1 ||
zone_getattr(zoneid, ZONE_ATTR_UNIQID, &uniqid,
sizeof (uniqid)) == -1 || uniqid != zargp->uniqid) {
/*
@@ -1204,15 +1207,15 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
case ZONE_STATE_INSTALLED:
switch (cmd) {
case Z_READY:
- rval = zone_ready(zlogp, Z_MNT_BOOT, zstate);
+ rval = zone_ready(zlogp, Z_MNT_BOOT, zstate, zoneid);
if (rval == 0)
eventstream_write(Z_EVT_ZONE_READIED);
break;
case Z_BOOT:
case Z_FORCEBOOT:
eventstream_write(Z_EVT_ZONE_BOOTING);
- if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
- == 0) {
+ if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate,
+ zoneid)) == 0) {
rval = zone_bootup(zlogp, zargp->bootbuf,
zstate);
}
@@ -1271,7 +1274,7 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
rval = zone_ready(zlogp,
strcmp(zargp->bootbuf, "-U") == 0 ?
- Z_MNT_UPDATE : Z_MNT_SCRATCH, zstate);
+ Z_MNT_UPDATE : Z_MNT_SCRATCH, zstate, zoneid);
if (rval != 0)
break;
@@ -1398,7 +1401,8 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
!= 0)
break;
- if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) == 0)
+ if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate,
+ zoneid)) == 0)
eventstream_write(Z_EVT_ZONE_READIED);
else
eventstream_write(Z_EVT_ZONE_HALTED);
@@ -1429,8 +1433,8 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp,
boot_args[0] = '\0';
break;
}
- if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
- != 0) {
+ if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate,
+ zoneid)) != 0) {
eventstream_write(Z_EVT_ZONE_BOOTFAILED);
boot_args[0] = '\0';
break;
diff --git a/usr/src/cmd/zoneadmd/zoneadmd.h b/usr/src/cmd/zoneadmd/zoneadmd.h
index 63b23481d2..4c348c1100 100644
--- a/usr/src/cmd/zoneadmd/zoneadmd.h
+++ b/usr/src/cmd/zoneadmd/zoneadmd.h
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
*/
#ifndef _ZONEADMD_H
@@ -130,7 +131,7 @@ typedef enum {
/*
* Virtual platform interfaces.
*/
-extern zoneid_t vplat_create(zlog_t *, zone_mnt_t);
+extern zoneid_t vplat_create(zlog_t *, zone_mnt_t, zoneid_t);
extern int vplat_bringup(zlog_t *, zone_mnt_t, zoneid_t);
extern int vplat_teardown(zlog_t *, boolean_t, boolean_t);
extern int vplat_get_iptype(zlog_t *, zone_iptype_t *);
diff --git a/usr/src/head/zone.h b/usr/src/head/zone.h
index 34528a27f5..ae03d2453c 100644
--- a/usr/src/head/zone.h
+++ b/usr/src/head/zone.h
@@ -21,6 +21,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2011 Joyent Inc. All rights reserved.
*/
#ifndef _ZONE_H
@@ -56,7 +57,7 @@ extern int zone_get_id(const char *, zoneid_t *);
/* System call API */
extern zoneid_t zone_create(const char *, const char *,
const struct priv_set *, const char *, size_t, const char *, size_t, int *,
- int, int, const bslabel_t *, int);
+ int, int, const bslabel_t *, int, zoneid_t);
extern int zone_boot(zoneid_t);
extern int zone_destroy(zoneid_t);
extern ssize_t zone_getattr(zoneid_t, int, void *, size_t);
diff --git a/usr/src/lib/libc/port/sys/zone.c b/usr/src/lib/libc/port/sys/zone.c
index 4a4c70043d..182a7f22f7 100644
--- a/usr/src/lib/libc/port/sys/zone.c
+++ b/usr/src/lib/libc/port/sys/zone.c
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2011 Joyent Inc. All rights reserved.
*/
#include "lint.h"
@@ -39,7 +40,8 @@
zoneid_t
zone_create(const char *name, const char *root, const struct priv_set *privs,
const char *rctls, size_t rctlsz, const char *zfs, size_t zfssz,
- int *extended_error, int match, int doi, const bslabel_t *label, int flags)
+ int *extended_error, int match, int doi, const bslabel_t *label, int flags,
+ zoneid_t req_zoneid)
{
zone_def zd;
priv_data_t *d;
@@ -59,6 +61,7 @@ zone_create(const char *name, const char *root, const struct priv_set *privs,
zd.doi = doi;
zd.label = label;
zd.flags = flags;
+ zd.zoneid = req_zoneid;
return ((zoneid_t)syscall(SYS_zone, ZONE_CREATE, &zd));
}
diff --git a/usr/src/uts/common/os/zone.c b/usr/src/uts/common/os/zone.c
index 55dff6e756..0627434427 100644
--- a/usr/src/uts/common/os/zone.c
+++ b/usr/src/uts/common/os/zone.c
@@ -425,8 +425,9 @@ static boolean_t zsd_wait_for_inprogress(zone_t *, struct zsd_entry *,
* Version 5 alters the zone_boot system call, and converts its old
* bootargs parameter to be set by the zone_setattr API instead.
* Version 6 adds the flag argument to zone_create.
+ * Version 7 adds the requested zoneid to zone_create.
*/
-static const int ZONE_SYSCALL_API_VERSION = 6;
+static const int ZONE_SYSCALL_API_VERSION = 7;
/*
* Certain filesystems (such as NFS and autofs) need to know which zone
@@ -4185,13 +4186,13 @@ zone_create(const char *zone_name, const char *zone_root,
caddr_t rctlbuf, size_t rctlbufsz,
caddr_t zfsbuf, size_t zfsbufsz, int *extended_error,
int match, uint32_t doi, const bslabel_t *label,
- int flags)
+ int flags, zoneid_t req_zoneid)
{
struct zsched_arg zarg;
nvlist_t *rctls = NULL;
proc_t *pp = curproc;
zone_t *zone, *ztmp;
- zoneid_t zoneid;
+ zoneid_t zoneid = -1;
int error;
int error2 = 0;
char *str;
@@ -4207,7 +4208,20 @@ zone_create(const char *zone_name, const char *zone_root,
extended_error));
zone = kmem_zalloc(sizeof (zone_t), KM_SLEEP);
- zoneid = zone->zone_id = id_alloc(zoneid_space);
+ /*
+ * If zoneadmd is asking for a specific zoneid, see if we can grant
+ * the request, but allocate a new id if that fails for any reason.
+ */
+ if (req_zoneid != -1) {
+ zoneid = id_alloc_specific_nosleep(zoneid_space, req_zoneid);
+ if (zoneid == -1)
+ cmn_err(CE_WARN,
+ "zone_create: re-use zoneid %d failed\n",
+ req_zoneid);
+ }
+ if (zoneid == -1)
+ zoneid = id_alloc(zoneid_space);
+ zone->zone_id = zoneid;
zone->zone_status = ZONE_IS_UNINITIALIZED;
zone->zone_pool = pool_default;
zone->zone_pool_mod = gethrtime();
@@ -6180,6 +6194,7 @@ zone(int cmd, void *arg1, void *arg2, void *arg3, void *arg4)
zs.doi = zs32.doi;
zs.label = (const bslabel_t *)(uintptr_t)zs32.label;
zs.flags = zs32.flags;
+ zs.zoneid = zs32.zoneid;
#else
panic("get_udatamodel() returned bogus result\n");
#endif
@@ -6190,7 +6205,7 @@ zone(int cmd, void *arg1, void *arg2, void *arg3, void *arg4)
(caddr_t)zs.rctlbuf, zs.rctlbufsz,
(caddr_t)zs.zfsbuf, zs.zfsbufsz,
zs.extended_error, zs.match, zs.doi,
- zs.label, zs.flags));
+ zs.label, zs.flags, zs.zoneid));
case ZONE_BOOT:
return (zone_boot((zoneid_t)(uintptr_t)arg1));
case ZONE_DESTROY:
diff --git a/usr/src/uts/common/sys/zone.h b/usr/src/uts/common/sys/zone.h
index 1d4f8b0ed8..3b82c8adf3 100644
--- a/usr/src/uts/common/sys/zone.h
+++ b/usr/src/uts/common/sys/zone.h
@@ -181,6 +181,7 @@ typedef struct {
uint32_t doi; /* DOI for label */
caddr32_t label; /* label associated with zone */
int flags;
+ zoneid_t zoneid; /* requested zoneid */
} zone_def32;
#endif
typedef struct {
@@ -197,6 +198,7 @@ typedef struct {
uint32_t doi; /* DOI for label */
const bslabel_t *label; /* label associated with zone */
int flags;
+ zoneid_t zoneid; /* requested zoneid */
} zone_def;
/* extended error information */