diff options
| author | carlsonj <none@none> | 2005-10-27 04:35:13 -0700 |
|---|---|---|
| committer | carlsonj <none@none> | 2005-10-27 04:35:13 -0700 |
| commit | 108322fb1c3ed341aba9c80c9774df0ed9e35768 (patch) | |
| tree | 61abe7b187db6042e0a010756a82a6c7d9d9c5ad /usr/src/lib/libzonecfg/common/getzoneent.c | |
| parent | ed9df62ee8252b9df6f24409276deabf199dcd40 (diff) | |
| download | illumos-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/lib/libzonecfg/common/getzoneent.c')
| -rw-r--r-- | usr/src/lib/libzonecfg/common/getzoneent.c | 158 |
1 files changed, 101 insertions, 57 deletions
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); } |
