summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sbdadm
diff options
context:
space:
mode:
authortim szeto <Tim.Szeto@Sun.COM>2009-05-08 16:22:42 -0600
committertim szeto <Tim.Szeto@Sun.COM>2009-05-08 16:22:42 -0600
commit8fe960854f0d52e2e8a80ba68e8621a5ac6a866d (patch)
tree84808627bb61eb33774fed65dcec310651e857fd /usr/src/cmd/sbdadm
parenta988fde5d885d3c96b92999f2de6395620472649 (diff)
downloadillumos-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/Makefile4
-rw-r--r--usr/src/cmd/sbdadm/sbdadm.c1179
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 */