diff options
author | carlsonj <none@none> | 2006-06-29 12:12:49 -0700 |
---|---|---|
committer | carlsonj <none@none> | 2006-06-29 12:12:49 -0700 |
commit | 555afedfc38adf0cc5fbc1de696dc811973eaaca (patch) | |
tree | 5900355bf83e141f219bd32bf2fe74ef4e19b5a2 | |
parent | 368eb9166ea32e85e3565e5902f9fa4bafe50220 (diff) | |
download | illumos-joyent-555afedfc38adf0cc5fbc1de696dc811973eaaca.tar.gz |
PSARC 2006/387 Zones Features For Zulu
6365741 RFE: add unique identifier to facilitate asset tracking (similar to hostid)
6384962 libzonecfg doesn't preserve owner/mode on changes
6394273 fix for CR 6305641 missed one of the hard-coded constants
6431731 zoneadm list -p (parseable) output isn't
6436841 Zonecfg needs to address alternate roots to adjust file paths
6436853 Zoneadm should allow zones to be marked as incomplete
-rw-r--r-- | usr/src/cmd/zoneadm/Makefile | 2 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/zoneadm.c | 126 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/zoneadm.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/Makefile | 2 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/vplat.c | 85 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/zoneadmd.c | 6 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/zoneadmd.h | 7 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg.c | 52 | ||||
-rw-r--r-- | usr/src/cmd/zonecfg/zonecfg_grammar.y | 13 | ||||
-rw-r--r-- | usr/src/head/libzonecfg.h | 10 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/common/getzoneent.c | 3 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/common/libzonecfg.c | 22 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/common/zonecfg_impl.h | 19 |
13 files changed, 302 insertions, 48 deletions
diff --git a/usr/src/cmd/zoneadm/Makefile b/usr/src/cmd/zoneadm/Makefile index 6ff4eab038..bf4e21d47e 100644 --- a/usr/src/cmd/zoneadm/Makefile +++ b/usr/src/cmd/zoneadm/Makefile @@ -43,7 +43,7 @@ SRCS = $(OBJS:.o=.c) POFILE=zoneadm_all.po POFILES= $(OBJS:%.o=%.po) -LDLIBS += -lzonecfg -lsocket -lgen -lpool -lbsm -lzfs +LDLIBS += -lzonecfg -lsocket -lgen -lpool -lbsm -lzfs -luuid .KEEP_STATE: diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c index 891f9e80e8..6e39d48d36 100644 --- a/usr/src/cmd/zoneadm/zoneadm.c +++ b/usr/src/cmd/zoneadm/zoneadm.c @@ -64,6 +64,7 @@ #include <sys/mntent.h> #include <limits.h> #include <dirent.h> +#include <uuid/uuid.h> #include <fcntl.h> #include <door.h> @@ -86,6 +87,7 @@ typedef struct zone_entry { char *zstate_str; zone_state_t zstate_num; char zroot[MAXPATHLEN]; + char zuuid[UUID_PRINTABLE_STRING_LENGTH]; } zone_entry_t; static zone_entry_t *zents; @@ -124,6 +126,7 @@ struct cmd { #define SHELP_MOVE "move zonepath" #define SHELP_DETACH "detach [-n]" #define SHELP_ATTACH "attach [-F] [-n <path>]" +#define SHELP_MARK "mark incomplete" static int help_func(int argc, char *argv[]); static int ready_func(int argc, char *argv[]); @@ -140,6 +143,7 @@ static int clone_func(int argc, char *argv[]); static int move_func(int argc, char *argv[]); static int detach_func(int argc, char *argv[]); static int attach_func(int argc, char *argv[]); +static int mark_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); @@ -162,7 +166,8 @@ static struct cmd cmdtab[] = { { CMD_CLONE, "clone", SHELP_CLONE, clone_func }, { CMD_MOVE, "move", SHELP_MOVE, move_func }, { CMD_DETACH, "detach", SHELP_DETACH, detach_func }, - { CMD_ATTACH, "attach", SHELP_ATTACH, attach_func } + { CMD_ATTACH, "attach", SHELP_ATTACH, attach_func }, + { CMD_MARK, "mark", SHELP_MARK, mark_func } }; /* global variables */ @@ -171,6 +176,7 @@ static struct cmd cmdtab[] = { static char *execname; static char *locale; char *target_zone; +static char *target_uuid; /* used in do_subproc() and signal handler */ static volatile boolean_t child_killed; @@ -209,16 +215,16 @@ long_help(int cmd_num) "running zones are listed, though this can be " "expanded to all\n\tinstalled zones with the -i " "option or all configured zones with the\n\t-c " - "option. When used with the general -z <zone> " - "option, lists only the\n\tspecified zone, but " - "lists it regardless of its state, and the -i " - "and -c\n\toptions are disallowed. The -v option " - "can be used to display verbose\n\tinformation: " - "zone name, id, current state, root directory and " - "options.\n\tThe -p option can be used to request " - "machine-parsable output. The -v\n\tand -p " - "options are mutually exclusive. If neither -v " - "nor -p is used,\n\tjust the zone name is listed.")); + "option. When used with the general -z <zone> and/or -u " + "<uuid-match>\n\toptions, lists only the specified " + "matching zone, but lists it\n\tregardless of its state, " + "and the -i and -c options are disallowed. The\n\t-v " + "option can be used to display verbose information: zone " + "name, id,\n\tcurrent state, root directory and options. " + "The -p option can be used\n\tto request machine-parsable " + "output. The -v and -p options are mutually\n\texclusive." + " If neither -v nor -p is used, just the zone name is " + "listed.")); case CMD_VERIFY: return (gettext("Check to make sure the configuration " "can safely be instantiated\n\ton the machine: " @@ -263,6 +269,12 @@ long_help(int cmd_num) "from the\n\tspecified path and the configuration is only " "validated. The path can\n\tbe '-' to specify standard " "input.")); + case CMD_MARK: + return (gettext("Set the state of the zone. This can be used " + "to force the zone\n\tstate to 'incomplete' " + "administratively if some activity has rendered\n\tthe " + "zone permanently unusable. The only valid state that " + "may be\n\tspecified is 'incomplete'.")); default: return (""); } @@ -282,8 +294,9 @@ usage(boolean_t explicit) FILE *fd = explicit ? stdout : stderr; (void) fprintf(fd, "%s:\t%s help\n", gettext("usage"), execname); - (void) fprintf(fd, "\t%s [-z <zone>] list\n", execname); - (void) fprintf(fd, "\t%s -z <zone> <%s>\n", execname, + (void) fprintf(fd, "\t%s [-z <zone>] [-u <uuid-match>] list\n", + execname); + (void) fprintf(fd, "\t%s {-z <zone>|-u <uuid-match>} <%s>\n", execname, gettext("subcommand")); (void) fprintf(fd, "\n%s:\n\n", gettext("Subcommands")); for (i = CMD_MIN; i <= CMD_MAX; i++) { @@ -374,6 +387,8 @@ zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) "NAME", "STATUS", "PATH"); } if (!verbose) { + char *cp, *clim; + if (!parsable) { (void) printf("%s\n", zent->zname); return; @@ -382,8 +397,13 @@ zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) (void) printf("-"); else (void) printf("%lu", zent->zid); - (void) printf(":%s:%s:%s\n", zent->zname, zent->zstate_str, - zent->zroot); + (void) printf(":%s:%s:", zent->zname, zent->zstate_str); + cp = zent->zroot; + while ((clim = strchr(cp, ':')) != NULL) { + (void) printf("%.*s\\:", clim - cp, cp); + cp = clim + 1; + } + (void) printf("%s:%s\n", cp, zent->zuuid); return; } if (zent->zstate_str != NULL) { @@ -401,6 +421,7 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) { char root[MAXPATHLEN], *cp; int err; + uuid_t uuid; (void) strlcpy(zent->zname, zone_name, sizeof (zent->zname)); (void) strlcpy(zent->zroot, "???", sizeof (zent->zroot)); @@ -408,6 +429,12 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) zent->zid = zid; + if (zonecfg_get_uuid(zone_name, uuid) == Z_OK && + !uuid_is_null(uuid)) + uuid_unparse(uuid, zent->zuuid); + else + zent->zuuid[0] = '\0'; + /* * For labeled zones which query the zone path of lower-level * zones, the path needs to be adjusted to drop the final @@ -1374,21 +1401,38 @@ static void fake_up_local_zone(zoneid_t zid, zone_entry_t *zeptr) { ssize_t result; + uuid_t uuid; + FILE *fp; + + (void) memset(zeptr, 0, sizeof (*zeptr)); zeptr->zid = zid; + /* * Since we're looking up our own (non-global) zone name, * we can be assured that it will succeed. */ result = getzonenamebyid(zid, zeptr->zname, sizeof (zeptr->zname)); assert(result >= 0); - if (!is_system_labeled()) { - (void) strlcpy(zeptr->zroot, "/", sizeof (zeptr->zroot)); - } else { + if (zonecfg_is_scratch(zeptr->zname) && + (fp = zonecfg_open_scratch("", B_FALSE)) != NULL) { + (void) zonecfg_reverse_scratch(fp, zeptr->zname, zeptr->zname, + sizeof (zeptr->zname), NULL, 0); + zonecfg_close_scratch(fp); + } + + if (is_system_labeled()) { (void) zone_getattr(zid, ZONE_ATTR_ROOT, zeptr->zroot, sizeof (zeptr->zroot)); + } else { + (void) strlcpy(zeptr->zroot, "/", sizeof (zeptr->zroot)); } + zeptr->zstate_str = "running"; + + if (zonecfg_get_uuid(zeptr->zname, uuid) == Z_OK && + !uuid_is_null(uuid)) + uuid_unparse(uuid, zeptr->zuuid); } static int @@ -1720,6 +1764,7 @@ sanity_check(char *zone, int cmd_num, boolean_t running, case CMD_READY: case CMD_BOOT: case CMD_MOUNT: + case CMD_MARK: if (state < ZONE_STATE_INSTALLED) { zerror(gettext("must be %s before %s."), zone_state_str(ZONE_STATE_INSTALLED), @@ -4364,6 +4409,32 @@ unmount_func(int argc, char *argv[]) } static int +mark_func(int argc, char *argv[]) +{ + int err, lockfd; + + if (argc != 1 || strcmp(argv[0], "incomplete") != 0) + return (Z_USAGE); + if (sanity_check(target_zone, CMD_MARK, B_FALSE, B_FALSE) != Z_OK) + return (Z_ERR); + + if (grab_lock_file(target_zone, &lockfd) != Z_OK) { + zerror(gettext("another %s may have an operation in progress."), + "zoneadm"); + return (Z_ERR); + } + + err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); + if (err != Z_OK) { + errno = err; + zperror2(target_zone, gettext("could not set state")); + } + release_lock_file(lockfd); + + return (err); +} + +static int help_func(int argc, char *argv[]) { int arg, cmd_num; @@ -4468,10 +4539,13 @@ main(int argc, char **argv) if (init_zfs() != Z_OK) exit(Z_ERR); - while ((arg = getopt(argc, argv, "?z:R:")) != EOF) { + while ((arg = getopt(argc, argv, "?u:z:R:")) != EOF) { switch (arg) { case '?': return (usage(B_TRUE)); + case 'u': + target_uuid = optarg; + break; case 'z': target_zone = optarg; break; @@ -4494,6 +4568,20 @@ main(int argc, char **argv) if (optind >= argc) return (usage(B_FALSE)); + + if (target_uuid != NULL && *target_uuid != '\0') { + uuid_t uuid; + static char newtarget[ZONENAME_MAX]; + + if (uuid_parse(target_uuid, uuid) == -1) { + zerror(gettext("illegal UUID value specified")); + exit(Z_ERR); + } + if (zonecfg_get_name_by_uuid(uuid, newtarget, + sizeof (newtarget)) == Z_OK) + target_zone = newtarget; + } + if (target_zone != NULL && zone_get_id(target_zone, &zid) != 0) { errno = Z_NO_ZONE; zperror(target_zone, B_TRUE); diff --git a/usr/src/cmd/zoneadm/zoneadm.h b/usr/src/cmd/zoneadm/zoneadm.h index d6aa67798d..a94053e258 100644 --- a/usr/src/cmd/zoneadm/zoneadm.h +++ b/usr/src/cmd/zoneadm/zoneadm.h @@ -44,9 +44,10 @@ #define CMD_MOVE 12 #define CMD_DETACH 13 #define CMD_ATTACH 14 +#define CMD_MARK 15 #define CMD_MIN CMD_HELP -#define CMD_MAX CMD_ATTACH +#define CMD_MAX CMD_MARK #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ diff --git a/usr/src/cmd/zoneadmd/Makefile b/usr/src/cmd/zoneadmd/Makefile index 33c89cd085..2d9082894a 100644 --- a/usr/src/cmd/zoneadmd/Makefile +++ b/usr/src/cmd/zoneadmd/Makefile @@ -43,7 +43,7 @@ CFLAGS += $(CCVERBOSE) LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD) lint := LAZYLIBS = -ltsol LDLIBS += -lsocket -lzonecfg -lnsl -ldevinfo -ldevice -lnvpair -lpool \ - -lgen -lbsm -lcontract -lzfs -ltsnet $(LAZYLIBS) + -lgen -lbsm -lcontract -lzfs -ltsnet -luuid $(LAZYLIBS) XGETFLAGS += -a -x zoneadmd.xcl .KEEP_STATE: diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c index f018c4436c..16d79f91fa 100644 --- a/usr/src/cmd/zoneadmd/vplat.c +++ b/usr/src/cmd/zoneadmd/vplat.c @@ -78,7 +78,6 @@ #include <arpa/inet.h> #include <netinet/in.h> #include <net/route.h> -#include <netdb.h> #include <stdio.h> #include <errno.h> @@ -94,6 +93,9 @@ #include <libzfs.h> #include <zone.h> #include <assert.h> +#include <libcontract.h> +#include <libcontract_priv.h> +#include <uuid/uuid.h> #include <sys/mntio.h> #include <sys/mnttab.h> @@ -3542,8 +3544,84 @@ error: return (rval); } +/* + * Enter the zone and write a /etc/zones/index file there. This allows + * libzonecfg (and thus zoneadm) to report the UUID and potentially other zone + * details from inside the zone. + */ +static void +write_index_file(zoneid_t zoneid) +{ + FILE *zef; + FILE *zet; + struct zoneent *zep; + pid_t child; + int tmpl_fd; + ctid_t ct; + int fd; + char uuidstr[UUID_PRINTABLE_STRING_LENGTH]; + + /* Locate the zone entry in the global zone's index file */ + if ((zef = setzoneent()) == NULL) + return; + while ((zep = getzoneent_private(zef)) != NULL) { + if (strcmp(zep->zone_name, zone_name) == 0) + break; + free(zep); + } + endzoneent(zef); + if (zep == NULL) + return; + + if ((tmpl_fd = init_template()) == -1) { + free(zep); + return; + } + + if ((child = fork()) == -1) { + (void) ct_tmpl_clear(tmpl_fd); + (void) close(tmpl_fd); + free(zep); + return; + } + + /* parent waits for child to finish */ + if (child != 0) { + free(zep); + if (contract_latest(&ct) == -1) + ct = -1; + (void) ct_tmpl_clear(tmpl_fd); + (void) close(tmpl_fd); + (void) waitpid(child, NULL, 0); + (void) contract_abandon_id(ct); + return; + } + + /* child enters zone and sets up index file */ + (void) ct_tmpl_clear(tmpl_fd); + if (zone_enter(zoneid) != -1) { + (void) mkdir(ZONE_CONFIG_ROOT, ZONE_CONFIG_MODE); + (void) chown(ZONE_CONFIG_ROOT, ZONE_CONFIG_UID, + ZONE_CONFIG_GID); + fd = open(ZONE_INDEX_FILE, O_WRONLY|O_CREAT|O_TRUNC, + ZONE_INDEX_MODE); + if (fd != -1 && (zet = fdopen(fd, "w")) != NULL) { + (void) fchown(fd, ZONE_INDEX_UID, ZONE_INDEX_GID); + if (uuid_is_null(zep->zone_uuid)) + uuidstr[0] = '\0'; + else + uuid_unparse(zep->zone_uuid, uuidstr); + (void) fprintf(zet, "%s:%s:/:%s\n", zep->zone_name, + zone_state_str(zep->zone_state), + uuidstr); + (void) fclose(zet); + } + } + _exit(0); +} + int -vplat_bringup(zlog_t *zlogp, boolean_t mount_cmd) +vplat_bringup(zlog_t *zlogp, boolean_t mount_cmd, zoneid_t zoneid) { if (!mount_cmd && validate_datasets(zlogp) != 0) { lofs_discard_mnttab(); @@ -3560,6 +3638,9 @@ vplat_bringup(zlog_t *zlogp, boolean_t mount_cmd) lofs_discard_mnttab(); return (-1); } + + write_index_file(zoneid); + lofs_discard_mnttab(); return (0); } diff --git a/usr/src/cmd/zoneadmd/zoneadmd.c b/usr/src/cmd/zoneadmd/zoneadmd.c index 050e5f1480..ca6e04e50f 100644 --- a/usr/src/cmd/zoneadmd/zoneadmd.c +++ b/usr/src/cmd/zoneadmd/zoneadmd.c @@ -459,7 +459,7 @@ zone_ready(zlog_t *zlogp, boolean_t mount_cmd) zonecfg_strerror(err)); return (-1); } - if (vplat_bringup(zlogp, mount_cmd) != 0) { + if (vplat_bringup(zlogp, mount_cmd, zone_id) != 0) { bringup_failure_recovery = B_TRUE; (void) vplat_teardown(NULL, mount_cmd); if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) @@ -471,8 +471,8 @@ zone_ready(zlog_t *zlogp, boolean_t mount_cmd) return (0); } -static int -init_template() +int +init_template(void) { int fd; int err = 0; diff --git a/usr/src/cmd/zoneadmd/zoneadmd.h b/usr/src/cmd/zoneadmd/zoneadmd.h index 591a75fd77..a048d5dd25 100644 --- a/usr/src/cmd/zoneadmd/zoneadmd.h +++ b/usr/src/cmd/zoneadmd/zoneadmd.h @@ -99,7 +99,7 @@ extern void eventstream_write(zone_evt_t evt); * Virtual platform interfaces. */ extern zoneid_t vplat_create(zlog_t *, boolean_t); -extern int vplat_bringup(zlog_t *, boolean_t); +extern int vplat_bringup(zlog_t *, boolean_t, zoneid_t); extern int vplat_teardown(zlog_t *, boolean_t); @@ -112,6 +112,11 @@ extern void reset_slave_terminal(zlog_t *); extern int init_console(zlog_t *); extern void serve_console(zlog_t *); +/* + * Contract handling. + */ +extern int init_template(void); + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c index e5882454dc..1c4b512273 100644 --- a/usr/src/cmd/zonecfg/zonecfg.c +++ b/usr/src/cmd/zonecfg/zonecfg.c @@ -68,7 +68,6 @@ #include <locale.h> #include <libintl.h> #include <alloca.h> -#include <regex.h> #include <signal.h> #include <libtecla.h> #include <libzfs.h> @@ -2668,15 +2667,31 @@ void set_func(cmd_t *cmd) { char *prop_id; - int err, res_type, prop_type; + int arg, err, res_type, prop_type; property_value_ptr_t pp; boolean_t autoboot; + boolean_t force_set = FALSE; if (zone_is_read_only(CMD_SET)) return; assert(cmd != NULL); + optind = opterr = 0; + while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) { + switch (arg) { + case 'F': + force_set = TRUE; + break; + default: + if (optopt == '?') + longer_usage(CMD_SET); + else + short_usage(CMD_SET); + return; + } + } + prop_type = cmd->cmd_prop_name[0]; if (global_scope) { if (prop_type == PT_ZONENAME) { @@ -2701,6 +2716,20 @@ set_func(cmd_t *cmd) res_type = resource_scope; } + if (force_set) { + if (res_type != RT_ZONEPATH) { + zerr(gettext("Only zonepath setting can be forced.")); + saw_error = TRUE; + return; + } + if (!zonecfg_in_alt_root()) { + zerr(gettext("Zonepath is changeable only in an " + "alternate root.")); + saw_error = TRUE; + return; + } + } + pp = cmd->cmd_property_ptr[0]; /* * A nasty expression but not that complicated: @@ -2756,7 +2785,7 @@ set_func(cmd_t *cmd) } return; case RT_ZONEPATH: - if (state_atleast(ZONE_STATE_INSTALLED)) { + if (!force_set && state_atleast(ZONE_STATE_INSTALLED)) { zerr(gettext("Zone %s already installed; %s %s not " "allowed."), zone, cmd_to_str(CMD_SET), rt_to_str(RT_ZONEPATH)); @@ -4603,6 +4632,7 @@ int main(int argc, char *argv[]) { int err, arg; + struct stat st; /* This must be before anything goes to stdout. */ setbuf(stdout, NULL); @@ -4629,7 +4659,7 @@ main(int argc, char *argv[]) exit(Z_OK); } - while ((arg = getopt(argc, argv, "?f:z:")) != EOF) { + while ((arg = getopt(argc, argv, "?f:R:z:")) != EOF) { switch (arg) { case '?': if (optopt == '?') @@ -4642,6 +4672,20 @@ main(int argc, char *argv[]) cmd_file_name = optarg; cmd_file_mode = TRUE; break; + case 'R': + if (*optarg != '/') { + zerr(gettext("root path must be absolute: %s"), + optarg); + exit(Z_USAGE); + } + if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { + zerr(gettext( + "root path must be a directory: %s"), + optarg); + exit(Z_USAGE); + } + zonecfg_set_root(optarg); + break; case 'z': if (zonecfg_validate_zonename(optarg) != Z_OK) { zone_perror(optarg, Z_BOGUS_ZONE_NAME, TRUE); diff --git a/usr/src/cmd/zonecfg/zonecfg_grammar.y b/usr/src/cmd/zonecfg/zonecfg_grammar.y index b9a8d744e2..d47aac79ae 100644 --- a/usr/src/cmd/zonecfg/zonecfg_grammar.y +++ b/usr/src/cmd/zonecfg/zonecfg_grammar.y @@ -659,6 +659,19 @@ set_command: SET $$->cmd_prop_name[0] = $2; $$->cmd_property_ptr[0] = &property[0]; } + | SET TOKEN ZONEPATH EQUAL property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_argc = 1; + $$->cmd_argv[0] = $2; + $$->cmd_argv[1] = NULL; + $$->cmd_handler = &set_func; + $$->cmd_prop_nv_pairs = 1; + $$->cmd_prop_name[0] = PT_ZONEPATH; + $$->cmd_property_ptr[0] = &property[0]; + } verify_command: VERIFY { diff --git a/usr/src/head/libzonecfg.h b/usr/src/head/libzonecfg.h index 056600e20d..3030bb42e8 100644 --- a/usr/src/head/libzonecfg.h +++ b/usr/src/head/libzonecfg.h @@ -110,6 +110,16 @@ extern "C" { #define ZONE_CONFIG_ROOT "/etc/zones" #define ZONE_INDEX_FILE ZONE_CONFIG_ROOT "/index" +/* Owner, group, and mode (defined by packaging) for the config directory */ +#define ZONE_CONFIG_UID 0 /* root */ +#define ZONE_CONFIG_GID 3 /* sys */ +#define ZONE_CONFIG_MODE 0755 + +/* Owner, group, and mode (defined by packaging) for the index file */ +#define ZONE_INDEX_UID 0 /* root */ +#define ZONE_INDEX_GID 3 /* sys */ +#define ZONE_INDEX_MODE 0644 + /* The maximum length of the VERSION string in the pkginfo(4) file. */ #define ZONE_PKG_VERSMAX 256 diff --git a/usr/src/lib/libzonecfg/common/getzoneent.c b/usr/src/lib/libzonecfg/common/getzoneent.c index c75ce2f096..c623152933 100644 --- a/usr/src/lib/libzonecfg/common/getzoneent.c +++ b/usr/src/lib/libzonecfg/common/getzoneent.c @@ -308,6 +308,8 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation) (void) unlock_index_file(lock_fd); return (Z_TEMP_FILE); } + (void) fchmod(tmp_file_desc, ZONE_INDEX_MODE); + (void) fchown(tmp_file_desc, ZONE_INDEX_UID, ZONE_INDEX_GID); if ((tmp_file = fdopen(tmp_file_desc, "w")) == NULL) { (void) close(tmp_file_desc); err = Z_MISC_FS; @@ -454,7 +456,6 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation) goto error; } tmp_file = NULL; - (void) chmod(tmp_file_name, 0644); if (rename(tmp_file_name, path) == -1) { err = errno == EACCES ? Z_ACCES : Z_MISC_FS; goto error; diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c index 023a96888f..19ca573b0c 100644 --- a/usr/src/lib/libzonecfg/common/libzonecfg.c +++ b/usr/src/lib/libzonecfg/common/libzonecfg.c @@ -828,6 +828,17 @@ zonecfg_get_zonepath(zone_dochandle_t handle, char *path, size_t pathsize) int zonecfg_set_zonepath(zone_dochandle_t handle, char *zonepath) { + size_t len; + + /* + * The user deals in absolute paths in the running global zone, but the + * internal configuration files deal with boot environment relative + * paths. Strip out the alternate root when specified. + */ + len = strlen(zonecfg_root); + if (strncmp(zonepath, zonecfg_root, len) != 0 || zonepath[len] != '/') + return (Z_BAD_PROPERTY); + zonepath += len; return (setrootattr(handle, DTD_ATTR_ZONEPATH, zonepath)); } @@ -923,7 +934,8 @@ zonecfg_refresh_index_file(zone_dochandle_t handle) if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) != Z_OK) return (err); - (void) strlcpy(ze.zone_path, zonepath, sizeof (ze.zone_path)); + (void) strlcpy(ze.zone_path, zonepath + strlen(zonecfg_root), + sizeof (ze.zone_path)); if (is_renaming(handle)) { opcode = PZE_MODIFY; @@ -4012,22 +4024,24 @@ zone_state_str(zone_state_t state_num) * doesn't touch this buffer on failure. */ int -zonecfg_get_name_by_uuid(const uuid_t uuid, char *zonename, size_t namelen) +zonecfg_get_name_by_uuid(const uuid_t uuidin, char *zonename, size_t namelen) { FILE *fp; struct zoneent *ze; + uchar_t *uuid; /* * 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)) + uuid = (uchar_t *)uuidin; + if (uuid_is_null(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) + if (uuid_compare(uuid, ze->zone_uuid) == 0) break; free(ze); } diff --git a/usr/src/lib/libzonecfg/common/zonecfg_impl.h b/usr/src/lib/libzonecfg/common/zonecfg_impl.h index b24f94ab1e..d6be1387e4 100644 --- a/usr/src/lib/libzonecfg/common/zonecfg_impl.h +++ b/usr/src/lib/libzonecfg/common/zonecfg_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,6 +33,7 @@ extern "C" { #endif #include <zone.h> +#include <sys/uuid.h> #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ @@ -57,15 +57,12 @@ typedef enum { /* * ":::\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. + * Note that ZONE_STATE_MAXSTRLEN, MAXPATHLEN, and UUID_PRINTABLE_STRING_LENGTH + * all include a NUL byte, and this extra count of 2 bytes covers the quotes + * that may be placed around the path plus one more. */ #define MAX_INDEX_LEN (ZONENAME_MAX + ZONE_STATE_MAXSTRLEN + MAXPATHLEN + \ - 36 + 4) + UUID_PRINTABLE_STRING_LENGTH + 3) #define ZONE_INDEX_LOCK_DIR ZONE_SNAPSHOT_ROOT #define ZONE_INDEX_LOCK_FILE "/index.lock" |