diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2011-01-31 16:51:07 -0700 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2011-01-31 16:51:07 -0700 |
commit | c2a4113fafb4afdd766fbbf0fd0bcb9aa1eed84c (patch) | |
tree | c86ebf0cc453056616acca555c20da7f8b9f5e78 | |
parent | 180efeda14b4d453183ef3b7e53168ce36d467a6 (diff) | |
download | illumos-joyent-c2a4113fafb4afdd766fbbf0fd0bcb9aa1eed84c.tar.gz |
OS-180 need zoneid to be persistent across zone reboot
-rw-r--r-- | usr/src/cmd/zoneadmd/vplat.c | 12 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/zoneadmd.c | 24 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/zoneadmd.h | 3 | ||||
-rw-r--r-- | usr/src/head/zone.h | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/zone.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/os/zone.c | 25 | ||||
-rw-r--r-- | usr/src/uts/common/sys/zone.h | 2 |
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 */ |