diff options
| author | tim szeto <Tim.Szeto@Sun.COM> | 2009-05-08 16:22:42 -0600 |
|---|---|---|
| committer | tim szeto <Tim.Szeto@Sun.COM> | 2009-05-08 16:22:42 -0600 |
| commit | 8fe960854f0d52e2e8a80ba68e8621a5ac6a866d (patch) | |
| tree | 84808627bb61eb33774fed65dcec310651e857fd /usr/src/cmd/sbdadm | |
| parent | a988fde5d885d3c96b92999f2de6395620472649 (diff) | |
| download | illumos-joyent-8fe960854f0d52e2e8a80ba68e8621a5ac6a866d.tar.gz | |
6795089 COMSTAR sbd lun provider should support PGR
6808269 Add interfaces for support of create/delete/modify logical unit
6824910 Allow persistence of configuration data to be optional
6794362 Add support for the SCSI direct-access block device Caching mode page
6749644 stmf/sbd getinfo(9E) entry point needs to be fixed
PSARC 2009/251 libstmf/stmfadm enhancements for COMSTAR
Diffstat (limited to 'usr/src/cmd/sbdadm')
| -rw-r--r-- | usr/src/cmd/sbdadm/Makefile | 4 | ||||
| -rw-r--r-- | usr/src/cmd/sbdadm/sbdadm.c | 1179 |
2 files changed, 541 insertions, 642 deletions
diff --git a/usr/src/cmd/sbdadm/Makefile b/usr/src/cmd/sbdadm/Makefile index ff11610b64..9c4479d06e 100644 --- a/usr/src/cmd/sbdadm/Makefile +++ b/usr/src/cmd/sbdadm/Makefile @@ -20,7 +20,7 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -41,7 +41,7 @@ POFILE = sbdadm_all.po POFILES = $(LOCAL_OBJS:%.o=%.po) CPPFLAGS += -I. -I$(COMMONBASE)/cmdparse -LDLIBS += -lstmf -lnvpair +LDLIBS += -lstmf LINTFLAGS += -xerroff=E_BAD_PTR_CAST_ALIGN .KEEP_STATE: diff --git a/usr/src/cmd/sbdadm/sbdadm.c b/usr/src/cmd/sbdadm/sbdadm.c index 1481e44833..41229169e9 100644 --- a/usr/src/cmd/sbdadm/sbdadm.c +++ b/usr/src/cmd/sbdadm/sbdadm.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include <stdlib.h> @@ -36,49 +36,36 @@ #include <strings.h> #include <ctype.h> #include <libnvpair.h> +#include <locale.h> #include <cmdparse.h> #include <sys/stmf_defines.h> #include <libstmf.h> #include <sys/stmf_sbd_ioctl.h> -#define BIG_BUF_SIZE 512 #define MAX_LU_LIST 8192 #define LU_LIST_MAX_RETRIES 3 +#define GUID_INPUT 32 -uint8_t big_buf[BIG_BUF_SIZE]; +#define VERSION_STRING_MAJOR "1" +#define VERSION_STRING_MINOR "0" +#define VERSION_STRING_MAX_LEN 10 + +char *cmdName; + +static char *getExecBasename(char *); int delete_lu(int argc, char *argv[], cmdOptions_t *options, void *callData); int create_lu(int argc, char *argv[], cmdOptions_t *options, void *callData); -int import_lu(int argc, char *argv[], cmdOptions_t *options, void *callData); int list_lus(int argc, char *argv[], cmdOptions_t *options, void *callData); int modify_lu(int argc, char *argv[], cmdOptions_t *options, void *callData); -static int persist_lu_register(char *, char *); -int print_lu_attr(uint64_t handle, char **s); +int import_lu(int argc, char *argv[], cmdOptions_t *options, void *callData); +static int callModify(char *, stmfGuid *, uint32_t, const char *, const char *); +int print_lu_attr(stmfGuid *); void print_guid(uint8_t *g, FILE *f); void print_attr_header(); -char *rlc_ret[] = { "", "Metadata creation failed", - "LU is not initialized", - "File is already loaded", - "GUID in the file is already registered", - "Registration with framework failed", - "Deregistration with stmf failed", - "Unable to lookup file", - "Incorrect file type to export as LU. Only regular \n" - "files and raw storage devices (disks/volumes) can be exported " - "as LUs", - "Unable to open file", - "Unable to get file attributes", - "File size has to be at least 1M", - "File size is not a multiple of blocksize", - "LU size is out of range", - "LU size is not supported by underlying Filesystem" -}; - -char sbdadm_ver[] = "sbdadm version 1.0"; - optionTbl_t options[] = { { "disk-size", required_argument, 's', "Size with <none>/k/m/g/t/p/e modifier" }, @@ -103,590 +90,445 @@ subCommandProps_t subCommands[] = { { NULL, 0, 0, NULL, 0, NULL} }; -int sbd_fd; - +/*ARGSUSED*/ int -main(int argc, char *argv[]) +create_lu(int argc, char *operands[], cmdOptions_t *options, void *callData) { - int ret, func_ret; - synTables_t sbdt = { sbdadm_ver, options, subCommands }; - - sbd_fd = open("/devices/pseudo/stmf_sbd@0:admin", O_RDONLY); - if (sbd_fd < 0) { - if (errno == EPERM) { - (void) fprintf(stderr, "Not enough permissions to open " - "device\n"); - } else { - (void) fprintf(stderr, - "Unable to open device. Is the driver " - "attached ?\n"); - } - exit(1); - } - ret = cmdParse(argc, argv, sbdt, NULL, &func_ret); - - if (ret) - return (ret); - return (func_ret); -} + luResource hdl = NULL; + int ret = 0; + stmfGuid createdGuid; -/* - * Supports upto 8 Exabytes. - * - * Returns zero upon success and the size in sizep. - * returns 2 if the string format is invalid. - * returns 1 if the specified size is out of range. - */ -int -str_to_size(char *str, uint64_t *sizep) -{ - uint64_t cur_size, m; - uint64_t new_cur_size; - int i; - char c; + ret = stmfCreateLuResource(STMF_DISK, &hdl); - m = 1; - cur_size = 0; + if (ret != STMF_STATUS_SUCCESS) { + (void) fprintf(stderr, "%s: %s\n", + cmdName, gettext("Failure to create lu resource\n")); + return (1); + } - for (i = 0; str[i] != NULL; i++) { - if (m != 1) { - /* We should have been done after the modifier */ - return (2); - } - c = str[i]; - if (isdigit(c)) { - new_cur_size = (cur_size * 10) + - (((uint64_t)c) - '0'); - if (new_cur_size < cur_size) { - /* Overflow */ + for (; options->optval; options++) { + switch (options->optval) { + case 's': + ret = stmfSetLuProp(hdl, STMF_LU_PROP_SIZE, + options->optarg); + if (ret != STMF_STATUS_SUCCESS) { + (void) fprintf(stderr, "%s: %c: %s\n", + cmdName, options->optval, + gettext("size param invalid")); + (void) stmfFreeLuResource(hdl); + return (1); + } + break; + default: + (void) fprintf(stderr, "%s: %c: %s\n", + cmdName, options->optval, + gettext("unknown option")); return (1); - } - cur_size = new_cur_size; - continue; - } - if (cur_size == 0) { - /* Direct format modifier ?? */ - return (2); - } - c = toupper(c); - if (c == 'K') { - m = 1024; - } else if (c == 'M') { - m = 1024 * 1024; - } else if (c == 'G') { - m = 1024 * 1024 * 1024; - } else if (c == 'T') { - m = 1024ll * 1024 * 1024 * 1024; - } else if (c == 'P') { - m = 1024ll * 1024 * 1024 * 1024 * 1024; - } else if (c == 'E') { - m = 1024ll * 1024 * 1024 * 1024 * 1024 * 1024; - } else { - return (2); } } - while (m > 1) { - if (cur_size & 0x8000000000000000ull) { - /* Overflow */ - return (1); - } - cur_size <<= 1; - m >>= 1; - } + ret = stmfSetLuProp(hdl, STMF_LU_PROP_FILENAME, operands[0]); - if (cur_size > 0x8000000000000000ull) { - /* We cannot allow more than 8 Exabytes */ + if (ret != STMF_STATUS_SUCCESS) { + (void) fprintf(stderr, "%s: %s\n", + cmdName, gettext("could not set filename")); return (1); } - *sizep = cur_size; - - return (0); -} - -static int -persist_lu_register(char *guid, char *filename) -{ - int ret = 0; - nvlist_t *nvl = NULL; - uint64_t setToken; - boolean_t retryGetProviderData; - - do { - retryGetProviderData = B_FALSE; - ret = stmfGetProviderDataProt("sbd", &nvl, - STMF_LU_PROVIDER_TYPE, &setToken); - if (ret != STMF_STATUS_SUCCESS) { - if (ret == STMF_ERROR_NOT_FOUND) { - (void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); - } else { - (void) fprintf(stderr, - "could not access persistent store\n"); - ret = 1; - goto out; - } - } - - ret = nvlist_add_string(nvl, guid, filename); - if (ret != 0) { - (void) fprintf(stderr, - "could not add data to nvlist\n"); - ret = 1; - goto out; - } - - ret = stmfSetProviderDataProt("sbd", nvl, STMF_LU_PROVIDER_TYPE, - &setToken); - if (ret != STMF_STATUS_SUCCESS) { - if (ret == STMF_ERROR_BUSY) { - (void) fprintf(stderr, - "stmf framework resource busy\n"); - } else if (ret == STMF_ERROR_PROV_DATA_STALE) { - nvlist_free(nvl); - nvl = NULL; - retryGetProviderData = B_TRUE; - continue; - } else { - (void) fprintf(stderr, - "unable to set persistent store data\n"); - } - ret = 1; - goto out; - } - } while (retryGetProviderData); -out: - nvlist_free(nvl); - return (ret); -} - -/*ARGSUSED*/ -int -create_lu(int argc, char *argv[], cmdOptions_t *options, void *callData) -{ - register_lu_cmd_t *rlc; - uint32_t fl; - int ret = 0, err; - uint64_t size; - char guidAsciiBuf[33]; - - /* Check whether this file path is absolute path */ - if (argv[argc - 1][0] != '/') { - (void) fprintf(stderr, "File name should be an absolute path" - " i.e. it should start with a /\n"); - return (1); + ret = stmfCreateLu(hdl, &createdGuid); + switch (ret) { + case STMF_STATUS_SUCCESS: + break; + case STMF_ERROR_BUSY: + case STMF_ERROR_LU_BUSY: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("resource busy")); + ret++; + break; + case STMF_ERROR_PERM: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("permission denied")); + ret++; + break; + case STMF_ERROR_FILE_IN_USE: + (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName, + operands[0], gettext("in use")); + ret++; + break; + case STMF_ERROR_INVALID_BLKSIZE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("invalid block size")); + ret++; + break; + case STMF_ERROR_GUID_IN_USE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("guid in use")); + ret++; + break; + case STMF_ERROR_META_FILE_NAME: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("meta file error")); + ret++; + break; + case STMF_ERROR_DATA_FILE_NAME: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("data file error")); + ret++; + break; + case STMF_ERROR_SIZE_OUT_OF_RANGE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("invalid size")); + ret++; + break; + case STMF_ERROR_META_CREATION: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("could not create meta file")); + ret++; + break; + default: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("unknown error")); + ret++; + break; } - fl = strlen(argv[argc - 1]) + 1; - rlc = (register_lu_cmd_t *)malloc(sizeof (register_lu_cmd_t) + fl - 8); - if (rlc == NULL) { - (void) fprintf(stderr, "Unable to allocate memory\n"); - return (1); + if (ret != STMF_STATUS_SUCCESS) { + goto done; } - bzero(rlc, sizeof (register_lu_cmd_t)); - rlc->total_struct_size = sizeof (register_lu_cmd_t) + fl - 8; - rlc->flags = RLC_LU_TYPE_FILEDISK | RLC_CREATE_LU | RLC_REGISTER_LU; - for (; options->optval; options++) { - if (options->optval == 's') { - err = str_to_size(options->optarg, &size); - if (err == 1) { - (void) fprintf(stderr, - "Size out of range: maximum" - " supported size is 9223372036854710272" - " (8 Exabytes - 64 Kilobytes)\n"); - ret = 1; - goto create_lu_done; - } else if (err == 2) { - (void) fprintf(stderr, - "Invalid size specified\n"); - ret = 1; - goto create_lu_done; - } - rlc->lu_size = size; - } - } - (void) strcpy(rlc->name, argv[argc-1]); - if ((ioctl(sbd_fd, SBD_REGISTER_LU, rlc) < 0) || - (rlc->return_code != 0) || (rlc->op_ret != STMF_SUCCESS)) { - if (rlc->return_code && (rlc->return_code < RLC_RET_MAX_VAL)) { - (void) fprintf(stderr, "LU Create failed : %s.\n", - rlc_ret[rlc->return_code]); - if (rlc->return_code == - RLC_RET_SIZE_NOT_SUPPORTED_BY_FS) { - (void) fprintf(stderr, "Maximum LU size on " - "the underlying filesystem can be %llu " - "bytes.\n", - ((((uint64_t)1) << rlc->filesize_nbits) - - 1 - 64 * 1024) & 0xfffffffffffffe00ull); - } - if (rlc->return_code == - RLC_RET_GUID_ALREADY_REGISTERED) { - (void) fprintf(stderr, "Registered GUID is "); - print_guid(rlc->guid, stderr); - (void) fprintf(stderr, "\n"); - } - } else { - (void) fprintf(stderr, "LU Create failed(%llx) : %s.\n", - rlc->op_ret, strerror(errno)); - } - ret = 1; - } else { - if (rlc->flags & RLC_REGISTER_LU) { - (void) printf("\nCreated the following LU:\n"); - print_attr_header(); - (void) print_lu_attr(rlc->lu_handle, NULL); - (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" - "%02x%02x%02x%02x%02x%02x", - rlc->guid[0], rlc->guid[1], rlc->guid[2], - rlc->guid[3], rlc->guid[4], rlc->guid[5], - rlc->guid[6], rlc->guid[7], rlc->guid[8], - rlc->guid[9], rlc->guid[10], rlc->guid[11], - rlc->guid[12], rlc->guid[13], rlc->guid[14], - rlc->guid[15]); - - ret = persist_lu_register(guidAsciiBuf, argv[argc - 1]); - } - } + (void) printf("Created the following LU:\n"); + print_attr_header(); + ret = print_lu_attr(&createdGuid); -create_lu_done:; - free(rlc); +done: + (void) stmfFreeLuResource(hdl); return (ret); } /*ARGSUSED*/ int -import_lu(int argc, char *argv[], cmdOptions_t *options, void *callData) +import_lu(int argc, char *operands[], cmdOptions_t *options, void *callData) { - register_lu_cmd_t *rlc; - uint32_t fl; int ret = 0; - char guidAsciiBuf[33]; + stmfGuid createdGuid; - /* Check whether this file path is absolute path */ - if (argv[argc - 1][0] != '/') { - (void) fprintf(stderr, "File name should be an absolute path" - " i.e. it should start with a /\n"); - return (1); + ret = stmfImportLu(STMF_DISK, operands[0], &createdGuid); + switch (ret) { + case STMF_STATUS_SUCCESS: + break; + case STMF_ERROR_BUSY: + case STMF_ERROR_LU_BUSY: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("resource busy")); + ret++; + break; + case STMF_ERROR_PERM: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("permission denied")); + ret++; + break; + case STMF_ERROR_FILE_IN_USE: + (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName, + operands[0], gettext("in use")); + ret++; + break; + case STMF_ERROR_GUID_IN_USE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("guid in use")); + ret++; + break; + case STMF_ERROR_META_FILE_NAME: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("meta file error")); + ret++; + break; + case STMF_ERROR_DATA_FILE_NAME: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("data file error")); + ret++; + break; + case STMF_ERROR_SIZE_OUT_OF_RANGE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("invalid size")); + ret++; + break; + case STMF_ERROR_META_CREATION: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("could not create meta file")); + ret++; + break; + default: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("unknown error")); + ret++; + break; } - fl = strlen(argv[argc - 1]) + 1; - rlc = (register_lu_cmd_t *)malloc(sizeof (register_lu_cmd_t) + fl - 8); - if (rlc == NULL) { - (void) fprintf(stderr, "Unable to allocate memory\n"); - return (1); - } - bzero(rlc, sizeof (register_lu_cmd_t)); - rlc->total_struct_size = sizeof (register_lu_cmd_t) + fl - 8; - - rlc->flags = RLC_LU_TYPE_FILEDISK | RLC_REGISTER_LU; - (void) strcpy(rlc->name, argv[argc-1]); - if ((ioctl(sbd_fd, SBD_REGISTER_LU, rlc) < 0) || - (rlc->return_code != 0) || (rlc->op_ret != STMF_SUCCESS)) { - if (rlc->return_code && (rlc->return_code < RLC_RET_MAX_VAL)) { - (void) fprintf(stderr, "LU import failed : %s.\n", - rlc_ret[rlc->return_code]); - if (rlc->return_code == - RLC_RET_SIZE_NOT_SUPPORTED_BY_FS) { - (void) fprintf(stderr, "Maximum LU size on " - "the underlying filesystem can be %llu " - "bytes.\n", - ((((uint64_t)1) << rlc->filesize_nbits) - - 1 - 64 * 1024) & 0xfffffffffffffe00ull); - } - if (rlc->return_code == - RLC_RET_GUID_ALREADY_REGISTERED) { - (void) fprintf(stderr, "Registered GUID is "); - print_guid(rlc->guid, stderr); - (void) fprintf(stderr, "\n"); - } - } else { - (void) fprintf(stderr, "LU import failed(%llx) : %s.\n", - rlc->op_ret, strerror(errno)); - } - ret = 1; - } else { - if (rlc->flags & RLC_REGISTER_LU) { - (void) printf("\nImported the following LU:\n"); - print_attr_header(); - (void) print_lu_attr(rlc->lu_handle, NULL); - (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" - "%02x%02x%02x%02x%02x%02x", - rlc->guid[0], rlc->guid[1], rlc->guid[2], - rlc->guid[3], rlc->guid[4], rlc->guid[5], - rlc->guid[6], rlc->guid[7], rlc->guid[8], - rlc->guid[9], rlc->guid[10], rlc->guid[11], - rlc->guid[12], rlc->guid[13], rlc->guid[14], - rlc->guid[15]); - - ret = persist_lu_register(guidAsciiBuf, argv[argc - 1]); - } + if (ret != STMF_STATUS_SUCCESS) { + goto done; } -import_lu_done:; - free(rlc); + (void) printf("Imported the following LU:\n"); + print_attr_header(); + ret = print_lu_attr(&createdGuid); + +done: return (ret); } /*ARGSUSED*/ int -delete_lu(int argc, char *argv[], cmdOptions_t *options, void *callData) +delete_lu(int operandLen, char *operands[], cmdOptions_t *options, + void *callData) { - deregister_lu_cmd_t drlc; - int ret = 0, i; - char chstr[3], *pend = NULL; - uint32_t ch, off = 0; - int exists = 0; - char guidAsciiBuf[33]; - nvlist_t *nvl = NULL; - - int stmf_ret; - int keep_view = 0; - uint64_t setToken; - stmfGuid inGuid; - stmfViewEntryList *viewEntryList; - boolean_t retryGetProviderData; + int i, j; + int ret = 0; + int stmfRet; + unsigned int inGuid[sizeof (stmfGuid)]; + stmfGuid delGuid; + boolean_t keepViews = B_FALSE; + boolean_t viewEntriesRemoved = B_FALSE; + boolean_t noLunFound = B_FALSE; + boolean_t views = B_FALSE; + char sGuid[GUID_INPUT + 1]; + stmfViewEntryList *viewEntryList = NULL; for (; options->optval; options++) { switch (options->optval) { - case 'k': - keep_view = 1; - break; + /* Keep views for logical unit */ + case 'k': + keepViews = B_TRUE; + break; + default: + (void) fprintf(stderr, "%s: %c: %s\n", + cmdName, options->optval, + gettext("unknown option")); + return (1); } } - if (strlen(argv[argc - 1]) != 32) { - (void) fprintf(stderr, "GUID must be 32 characters\n"); - ret = 1; - goto delete_lu_done; - } - - for (i = 0; i < 32; i++) { - guidAsciiBuf[i] = tolower(argv[argc - 1][i]); - } - guidAsciiBuf[i] = 0; - - do { - retryGetProviderData = B_FALSE; - stmf_ret = stmfGetProviderDataProt("sbd", &nvl, - STMF_LU_PROVIDER_TYPE, &setToken); - if (stmf_ret != STMF_STATUS_SUCCESS) { - (void) fprintf(stderr, - "Could not access persistent store\n"); - ret = 1; - goto delete_lu_done; - } - ret = nvlist_remove(nvl, guidAsciiBuf, DATA_TYPE_STRING); - if (ret == 0) { - exists = 1; - stmf_ret = stmfSetProviderDataProt("sbd", nvl, - STMF_LU_PROVIDER_TYPE, &setToken); - if (stmf_ret != STMF_STATUS_SUCCESS) { - if (stmf_ret == STMF_ERROR_BUSY) { - (void) fprintf(stderr, - "stmf framework resource busy\n"); - } else if (stmf_ret == - STMF_ERROR_PROV_DATA_STALE) { - /* - * update failed, try again - */ - nvlist_free(nvl); - nvl = NULL; - retryGetProviderData = B_TRUE; - continue; - } else { - (void) fprintf(stderr, - "unable to set persistent store " - "data\n"); - } - ret = 1; - goto delete_lu_done; + for (i = 0; i < operandLen; i++) { + for (j = 0; j < GUID_INPUT; j++) { + if (!isxdigit(operands[i][j])) { + break; } + sGuid[j] = tolower(operands[i][j]); } - } while (retryGetProviderData); - - bzero(&drlc, sizeof (drlc)); - drlc.total_struct_size = sizeof (drlc); - drlc.flags = RLC_DEREGISTER_LU; - - chstr[2] = 0; - i = 0; - while ((off + 2) <= strlen(argv[argc - 1])) { - bcopy(argv[argc -1] + off, chstr, 2); - off += 2; - - if (!isxdigit(chstr[0]) || !isxdigit(chstr[1])) { - (void) fprintf(stderr, "Invalid LU GUID specified.\n"); - ret = 1; - goto delete_lu_done; - } - errno = 0; - ch = strtoul(chstr, &pend, 16); - if (errno != 0) { - (void) fprintf(stderr, "Invalid LU GUID specified.\n"); - ret = 1; - goto delete_lu_done; + if (j != GUID_INPUT) { + (void) fprintf(stderr, "%s: %s: %s%d%s\n", + cmdName, operands[i], gettext("must be "), + GUID_INPUT, + gettext(" hexadecimal digits long")); + ret++; + continue; } - drlc.guid[i++] = ch; - } + sGuid[j] = 0; - if (ioctl(sbd_fd, SBD_DEREGISTER_LU, &drlc) < 0) { - if (errno != ENODEV) { - (void) fprintf(stderr, - "Request to delete LU failed: %s\n", - strerror(errno)); - ret = 1; - goto delete_lu_done; + (void) sscanf(sGuid, + "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", + &inGuid[0], &inGuid[1], &inGuid[2], &inGuid[3], + &inGuid[4], &inGuid[5], &inGuid[6], &inGuid[7], + &inGuid[8], &inGuid[9], &inGuid[10], &inGuid[11], + &inGuid[12], &inGuid[13], &inGuid[14], &inGuid[15]); + + for (j = 0; j < sizeof (stmfGuid); j++) { + delGuid.guid[j] = inGuid[j]; } - } else if (drlc.return_code != 0) { - (void) fprintf(stderr, "LU deregister failed: ret_code-%x", - drlc.return_code); - ret = 1; - goto delete_lu_done; - } else { - exists = 1; - } - if (!keep_view) { - for (i = 0; i < 16; i++) - inGuid.guid[i] = drlc.guid[i]; + stmfRet = stmfDeleteLu(&delGuid); + switch (stmfRet) { + case STMF_STATUS_SUCCESS: + break; + case STMF_ERROR_NOT_FOUND: + noLunFound = B_TRUE; + break; + case STMF_ERROR_BUSY: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("resource busy")); + ret++; + break; + case STMF_ERROR_PERM: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("permission denied")); + ret++; + break; + default: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("unknown error")); + ret++; + break; + } - if ((stmf_ret = stmfGetViewEntryList(&inGuid, - &viewEntryList)) == STMF_STATUS_SUCCESS) { - for (i = 0; i < viewEntryList->cnt; i++) { - (void) stmfRemoveViewEntry(&inGuid, - viewEntryList->ve[i].veIndex); + if (!keepViews) { + stmfRet = stmfGetViewEntryList(&delGuid, + &viewEntryList); + if (stmfRet == STMF_STATUS_SUCCESS) { + for (j = 0; j < viewEntryList->cnt; j++) { + (void) stmfRemoveViewEntry(&delGuid, + viewEntryList->ve[j].veIndex); + } + viewEntriesRemoved = B_TRUE; + stmfFreeMemory(viewEntryList); + } else if (stmfRet != STMF_ERROR_NOT_FOUND) { + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("unable to remove view entries\n")); + ret++; + } /* No view entries to remove */ + } + if (keepViews) { + stmfRet = stmfGetViewEntryList(&delGuid, + &viewEntryList); + if (stmfRet == STMF_STATUS_SUCCESS) { + views = B_TRUE; + stmfFreeMemory(viewEntryList); } - } else if (stmf_ret != STMF_ERROR_NOT_FOUND) { - (void) fprintf(stderr, - "unable to remove view entries\n"); - ret = 1; } - } - if (!exists) { - (void) fprintf(stderr, "GUID not found.\n"); - ret = 1; - goto delete_lu_done; + if ((!viewEntriesRemoved && noLunFound && !views) || + (!views && keepViews && noLunFound)) { + (void) fprintf(stderr, "%s: %s: %s\n", + cmdName, sGuid, + gettext("not found")); + ret++; + } + noLunFound = viewEntriesRemoved = views = B_FALSE; } - -delete_lu_done:; return (ret); } /*ARGSUSED*/ int -modify_lu(int argc, char *argv[], cmdOptions_t *options, void *callData) +modify_lu(int operandLen, char *operands[], cmdOptions_t *options, + void *callData) { - modify_lu_cmd_t *mlc; - uint32_t fl = 0, struct_size; - int ret = 0, err; - int i = 0; - uint64_t size; - int is_filename = 0; - char chstr[3], *pend = NULL; - uint32_t ch; - uint32_t off = 0; - - if (argv[argc - 1][0] == '/') { - is_filename = 1; - fl = strlen(argv[argc - 1]) + 1; - struct_size = sizeof (modify_lu_cmd_t) + fl - 8; - } else { - struct_size = sizeof (modify_lu_cmd_t); + stmfGuid inGuid; + unsigned int guid[sizeof (stmfGuid)]; + int ret = 0; + int i; + char *fname = NULL; + char sGuid[GUID_INPUT + 1]; + boolean_t fnameUsed = B_FALSE; + + if (operands[0][0] == '/') { + fnameUsed = B_TRUE; + fname = operands[0]; } - mlc = (modify_lu_cmd_t *)malloc(struct_size); - if (mlc == NULL) { - (void) fprintf(stderr, "Unable to allocate memory\n"); + + /* check input length */ + if (!fnameUsed && strlen(operands[0]) != GUID_INPUT) { + (void) fprintf(stderr, "%s: %s: %s%d%s\n", cmdName, operands[0], + gettext("must be "), GUID_INPUT, + gettext(" hexadecimal digits")); return (1); } - bzero(mlc, sizeof (modify_lu_cmd_t)); - mlc->total_struct_size = struct_size; - mlc->flags = RLC_LU_TYPE_FILEDISK | RLC_CREATE_LU; - for (; options->optval; options++) { - if (options->optval == 's') { - err = str_to_size(options->optarg, &size); - if (err == 1) { - (void) fprintf(stderr, - "Size out of range: maximum" - " supported size is 9223372036854775808" - " (8 Exabytes)\n"); - ret = 1; - goto modify_lu_done; - } else if (err == 2) { - (void) fprintf(stderr, - "Invalid size specified\n"); - ret = 1; - goto modify_lu_done; - } - mlc->lu_size = size; + if (!fnameUsed) { + /* convert to lower case for scan */ + for (i = 0; i < 32; i++) + sGuid[i] = tolower(operands[0][i]); + sGuid[i] = 0; + (void) sscanf(sGuid, + "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", + &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5], + &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], + &guid[11], &guid[12], &guid[13], &guid[14], &guid[15]); + + for (i = 0; i < sizeof (stmfGuid); i++) { + inGuid.guid[i] = guid[i]; } } - if (is_filename) { - (void) strcpy(mlc->name, argv[argc-1]); - (void) memset(mlc->guid, 0, 16); - } else { - if (strlen(argv[argc - 1]) != 32) { - (void) fprintf(stderr, - "Invalid device identifier or filename" - " specified.\nIf it is a filename, it should be an" - " absolute path i.e. it should start with a /\n"); - goto modify_lu_done; - } - chstr[2] = 0; - i = 0; - while ((off + 2) <= strlen(argv[argc - 1])) { - bcopy(argv[argc -1] + off, chstr, 2); - off += 2; - - ch = strtoul(chstr, &pend, 16); - if (errno != 0) { - (void) fprintf(stderr, - "Invalid device identifier or" - " filename specified.\nIf it is a" - " filename, it should be an absolute path" - " i.e. it should start with a /\n"); - ret = 1; - goto modify_lu_done; - } - mlc->guid[i++] = ch; + for (; options->optval; options++) { + switch (options->optval) { + case 's': + if (callModify(fname, &inGuid, + STMF_LU_PROP_SIZE, options->optarg, + "size") != 0) { + return (1); + } + break; + default: + (void) fprintf(stderr, "%s: %c: %s\n", + cmdName, options->optval, + gettext("unknown option")); + return (1); } - mlc->name[0] = '\0'; } - if ((ioctl(sbd_fd, SBD_MODIFY_LU, mlc) < 0) || - (mlc->return_code != 0) || (mlc->op_ret |= STMF_SUCCESS)) { - if (mlc->return_code && (mlc->return_code < RLC_RET_MAX_VAL)) { - (void) fprintf(stderr, "LU modify failed : %s.\n", - rlc_ret[mlc->return_code]); - if (mlc->return_code == - RLC_RET_SIZE_NOT_SUPPORTED_BY_FS) { - (void) fprintf(stderr, "Maximum LU size on " - "the underlying filesystem can be %llu " - "bytes.\n", - ((((uint64_t)1) << mlc->filesize_nbits) - - 1) & 0xfffffffffffffe00ull); - } else if (mlc->return_code == - RLC_RET_LU_NOT_INITIALIZED) { - (void) fprintf(stderr, "Use 'sbdadm lu-create' " - "to initialize the LU.\n"); - } - } else { - (void) fprintf(stderr, "LU modify failed(%llx) : %s.\n", - mlc->op_ret, strerror(errno)); - } - ret = 1; + return (ret); +} + +static int +callModify(char *fname, stmfGuid *luGuid, uint32_t prop, const char *propVal, + const char *propString) +{ + int ret = 0; + int stmfRet = 0; + + if (!fname) { + stmfRet = stmfModifyLu(luGuid, prop, propVal); } else { - (void) printf("LU modified Successfully.\n"); + stmfRet = stmfModifyLuByFname(STMF_DISK, fname, prop, + propVal); + } + switch (stmfRet) { + case STMF_STATUS_SUCCESS: + break; + case STMF_ERROR_BUSY: + case STMF_ERROR_LU_BUSY: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("resource busy")); + ret++; + break; + case STMF_ERROR_PERM: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("permission denied")); + ret++; + break; + case STMF_ERROR_INVALID_BLKSIZE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("invalid block size")); + ret++; + break; + case STMF_ERROR_GUID_IN_USE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("guid in use")); + ret++; + break; + case STMF_ERROR_META_FILE_NAME: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("meta file error")); + ret++; + break; + case STMF_ERROR_DATA_FILE_NAME: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("data file error")); + ret++; + break; + case STMF_ERROR_FILE_SIZE_INVALID: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("file size invalid")); + ret++; + break; + case STMF_ERROR_SIZE_OUT_OF_RANGE: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("invalid size")); + ret++; + break; + case STMF_ERROR_META_CREATION: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("could not create meta file")); + ret++; + break; + default: + (void) fprintf(stderr, "%s: %s: %s: %d\n", cmdName, + gettext("could not set property"), propString, + stmfRet); + ret++; + break; } -modify_lu_done:; - free(mlc); return (ret); } @@ -695,88 +537,71 @@ modify_lu_done:; int list_lus(int argc, char *argv[], cmdOptions_t *options, void *callData) { - sbd_lu_list_t *sll; - uint32_t i; - ssize_t list_size; - int retry_count = 0; - uint32_t lu_count_in = MAX_LU_LIST; - int ret; - nvlist_t *nvl = NULL; - nvpair_t *np; - char *s; + int stmfRet; + stmfGuidList *luList; + stmfLogicalUnitProperties luProps; + int sbdLuCnt = 0; + int i; - ret = stmfGetProviderDataProt("sbd", &nvl, STMF_LU_PROVIDER_TYPE, - NULL); - if (ret != STMF_STATUS_SUCCESS) { - if (ret == STMF_ERROR_NOT_FOUND) { - (void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); - } else { - (void) fprintf(stderr, - "Could not access persistent store\n"); - return (1); + if ((stmfRet = stmfGetLogicalUnitList(&luList)) + != STMF_STATUS_SUCCESS) { + switch (stmfRet) { + case STMF_ERROR_SERVICE_NOT_FOUND: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("STMF service not found")); + break; + case STMF_ERROR_BUSY: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("resource busy")); + break; + case STMF_ERROR_PERM: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("permission denied")); + break; + case STMF_ERROR_SERVICE_DATA_VERSION: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("STMF service version incorrect")); + break; + default: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("list failed")); + break; } - } - -retry_get_lu_list: - list_size = (lu_count_in * 8) + sizeof (sbd_lu_list_t) - 8; - sll = (sbd_lu_list_t *)calloc(1, list_size); - if (sll == NULL) { - (void) fprintf(stderr, "Memory allocation failure\n"); - nvlist_free(nvl); return (1); } - sll->total_struct_size = list_size; - - sll->count_in = lu_count_in; - if (ioctl(sbd_fd, SBD_GET_LU_LIST, sll) < 0) { - (void) fprintf(stderr, "Unable to get LU list : %s\n", - strerror(errno)); - free(sll); - nvlist_free(nvl); - return (1); - } - if (sll->count_out > sll->count_in) { - lu_count_in = sll->count_out; - free(sll); - if (retry_count < LU_LIST_MAX_RETRIES) { - retry_count++; - goto retry_get_lu_list; - } else { - (void) fprintf(stderr, "Unable to get LU list after %d" - " retries\n", retry_count); - nvlist_free(nvl); + for (i = 0; i < luList->cnt; i++) { + stmfRet = stmfGetLogicalUnitProperties(&luList->guid[i], + &luProps); + if (stmfRet != STMF_STATUS_SUCCESS) { + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("list failed")); return (1); } + if (strcmp(luProps.providerName, "sbd") == 0) { + sbdLuCnt++; + } } - (void) printf("\nFound %d LU(s)\n", sll->count_out); - if (sll->count_out == 0) - goto over_print_attr; + if (sbdLuCnt == 0) + return (0); + + (void) printf("\nFound %d LU(s)\n", sbdLuCnt); print_attr_header(); - for (i = 0; i < sll->count_out; i++) { - if (!print_lu_attr(sll->handles[i], &s)) - continue; - if (nvlist_remove(nvl, s, DATA_TYPE_STRING) != 0) { - (void) fprintf(stderr, - "Error: GUID %s does not exist in " - "persistent store\n", s); - } - } -over_print_attr: - free(sll); - np = NULL; - while ((np = nvlist_next_nvpair(nvl, np)) != NULL) { - if (nvpair_type(np) != DATA_TYPE_STRING) - continue; - if (nvpair_value_string(np, &s) != 0) - continue; - (void) fprintf(stderr, "%s <Failed to load> %s\n", - nvpair_name(np), s); + for (i = 0; i < luList->cnt; i++) { + stmfRet = stmfGetLogicalUnitProperties(&luList->guid[i], + &luProps); + if (stmfRet != STMF_STATUS_SUCCESS) { + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("list failed")); + return (1); + } + if (strcmp(luProps.providerName, "sbd") == 0) { + (void) print_lu_attr(&luList->guid[i]); + } } - nvlist_free(nvl); return (0); } @@ -801,47 +626,121 @@ print_guid(uint8_t *g, FILE *f) } int -print_lu_attr(uint64_t handle, char **s) +print_lu_attr(stmfGuid *guid) { - sbd_lu_attr_t *sla; - - sla = (sbd_lu_attr_t *)big_buf; + luResource hdl = NULL; + int stmfRet = 0; + int ret = 0; + char propVal[MAXPATHLEN]; + size_t propValSize = sizeof (propVal); + + if ((stmfRet = stmfGetLuResource(guid, &hdl)) != STMF_STATUS_SUCCESS) { + switch (stmfRet) { + case STMF_ERROR_BUSY: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("resource busy")); + break; + case STMF_ERROR_PERM: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("permission denied")); + break; + case STMF_ERROR_NOT_FOUND: + /* No error here */ + return (0); + break; + default: + (void) fprintf(stderr, "%s: %s\n", cmdName, + gettext("get extended properties failed")); + break; + } + return (1); + } - bzero(sla, BIG_BUF_SIZE); + print_guid((uint8_t *)guid, stdout); - sla->lu_handle = handle; - sla->total_struct_size = BIG_BUF_SIZE; - sla->max_name_length = BIG_BUF_SIZE - sizeof (*sla) + 7; + stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_SIZE, propVal, + &propValSize); + if (stmfRet == STMF_STATUS_SUCCESS) { + (void) printf(" %-19s ", propVal); + } else if (stmfRet == STMF_ERROR_NO_PROP) { + (void) printf("not set\n"); + } else { + (void) printf("<error retrieving property>"); + ret++; + } - if (ioctl(sbd_fd, SBD_GET_LU_ATTR, sla) < 0) { - (void) fprintf(stderr, "Request to get LU attr failed: %s\n", - strerror(errno)); - return (0); + stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_FILENAME, propVal, + &propValSize); + if (stmfRet == STMF_STATUS_SUCCESS) { + (void) printf("%s\n", propVal); + } else if (stmfRet == STMF_ERROR_NO_PROP) { + (void) printf("not set\n"); + } else { + (void) printf("<error retrieving property>"); + ret++; } - print_guid(sla->guid, stdout); - if (sla->data_size > 9999999999999ull) - (void) printf(" %-19llu ", sla->data_size); - else - (void) printf(" %-13llu ", sla->data_size); + (void) stmfFreeLuResource(hdl); + return (ret); +} - if (sla->flags & RLC_LU_TYPE_MEMDISK) { - (void) printf("<RAM : %llu bytes>\n", sla->total_size); - } else { - (void) printf("%s\n", sla->name); - } - if (s != NULL) { - (void) snprintf((char *)big_buf, sizeof (big_buf), - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" - "%02x%02x%02x%02x%02x%02x", - sla->guid[0], sla->guid[1], sla->guid[2], - sla->guid[3], sla->guid[4], sla->guid[5], - sla->guid[6], sla->guid[7], sla->guid[8], - sla->guid[9], sla->guid[10], sla->guid[11], - sla->guid[12], sla->guid[13], sla->guid[14], - sla->guid[15]); - *s = (char *)big_buf; +/* + * input: + * execFullName - exec name of program (argv[0]) + * + * copied from usr/src/cmd/zoneadm/zoneadm.c in OS/Net + * (changed name to lowerCamelCase to keep consistent with this file) + * + * Returns: + * command name portion of execFullName + */ +static char * +getExecBasename(char *execFullname) +{ + char *lastSlash, *execBasename; + + /* guard against '/' at end of command invocation */ + for (;;) { + lastSlash = strrchr(execFullname, '/'); + if (lastSlash == NULL) { + execBasename = execFullname; + break; + } else { + execBasename = lastSlash + 1; + if (*execBasename == '\0') { + *lastSlash = '\0'; + continue; + } + break; + } } - return (1); + return (execBasename); } +int +main(int argc, char *argv[]) +{ + synTables_t synTables; + char versionString[VERSION_STRING_MAX_LEN]; + int ret; + int funcRet; + void *subcommandArgs = NULL; + + (void) setlocale(LC_ALL, ""); + (void) textdomain(TEXT_DOMAIN); + /* set global command name */ + cmdName = getExecBasename(argv[0]); + + (void) snprintf(versionString, VERSION_STRING_MAX_LEN, "%s.%s", + VERSION_STRING_MAJOR, VERSION_STRING_MINOR); + synTables.versionString = versionString; + synTables.longOptionTbl = options; + synTables.subCommandPropsTbl = subCommands; + + ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet); + if (ret != 0) { + return (ret); + } + + return (funcRet); +} /* end main */ |
