summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authoryw161884 <none@none>2008-07-30 18:54:10 -0700
committeryw161884 <none@none>2008-07-30 18:54:10 -0700
commitb449fa8aa1f53939091aeb3a5af8a8f3ba9d33dc (patch)
treebc24f22b5aa62a98ccadc16a7a046ad73fdf07f5 /usr/src
parent61b2e298a43ac1155abb6369dd7c6a117fbeb473 (diff)
downloadillumos-joyent-b449fa8aa1f53939091aeb3a5af8a8f3ba9d33dc.tar.gz
PSARC 2008/458 RaidCfg GUID and volume activation support
6523832 raidctl cannot support mpxio-capable disks when mpxio enabled on the hba controller. 6692827 raidctl not capable of hot-spare setting/un-setting actions 6695619 raidctl should allow activation of RAID volumes 6724263 raidctl volume limitation 6729161 raidctl -l <volume> truncates volume name
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/raidctl/raidctl.c118
-rw-r--r--usr/src/lib/libraidcfg/common/raidcfg.c161
-rw-r--r--usr/src/lib/libraidcfg/common/raidcfg.h3
-rw-r--r--usr/src/lib/libraidcfg/common/raidcfg_spi.h26
-rw-r--r--usr/src/uts/common/sys/mpt/mpi_raid.h4
5 files changed, 275 insertions, 37 deletions
diff --git a/usr/src/cmd/raidctl/raidctl.c b/usr/src/cmd/raidctl/raidctl.c
index ef206c590b..8c7f995272 100644
--- a/usr/src/cmd/raidctl/raidctl.c
+++ b/usr/src/cmd/raidctl/raidctl.c
@@ -1361,19 +1361,25 @@ do_set_array_attr(uint32_t f_flag, char *p_argp, char **argv, uint32_t optind)
param = strtok(p_argp, op);
if (strcmp(param, "wp") == 0) {
type = SET_CACHE_WR_PLY;
+ param = strtok(NULL, op);
+ if (strcmp(param, "on") == 0) {
+ value = CACHE_WR_ON;
+ } else if (strcmp(param, "off") == 0) {
+ value = CACHE_WR_OFF;
+ } else {
+ return (INVALID_ARG);
+ }
+ } else if (strcmp(param, "state") == 0) {
+ type = SET_ACTIVATION_PLY;
+ param = strtok(NULL, op);
+ if (strcmp(param, "activate") == 0) {
+ value = ARRAY_ACT_ACTIVATE;
+ } else {
+ return (INVALID_ARG);
+ }
} else {
return (INVALID_ARG);
}
-
- param = strtok(NULL, op);
- if (strcmp(param, "on") == 0) {
- value = CACHE_WR_ON;
- } else if (strcmp(param, "off") == 0) {
- value = CACHE_WR_OFF;
- } else {
- return (INVALID_ARG);
- }
-
} else {
return (INVALID_ARG);
}
@@ -1836,7 +1842,7 @@ print_array_table(raid_obj_handle_t ctl_handle, raid_obj_handle_t array_handle)
raid_obj_handle_t arraypart_handle;
raid_obj_handle_t task_handle;
- char array[8];
+ char array[16];
char arraypart[8];
int ret;
int i;
@@ -1869,7 +1875,10 @@ print_array_table(raid_obj_handle_t ctl_handle, raid_obj_handle_t array_handle)
(void) snprintf(array, sizeof (array), "c%ut%llud%llu",
ctl_attr.controller_id, array_attr.tag.idl.target_id,
array_attr.tag.idl.lun);
- (void) fprintf(stdout, "%s\t\t\t", array);
+ (void) fprintf(stdout, "%s\t\t", array);
+ if (strlen(array) < 8)
+ (void) fprintf(stdout, "\t");
+
/* check if array is in sync state */
task_handle = raidcfg_list_head(array_handle, OBJ_TYPE_TASK);
@@ -1990,6 +1999,8 @@ print_disk_table(raid_obj_handle_t ctl_handle, raid_obj_handle_t disk_handle)
{
raidcfg_controller_t ctl_attr;
raidcfg_disk_t disk_attr;
+ raidcfg_prop_t *prop_attr, *prop_attr2;
+ raid_obj_handle_t prop_handle;
char disk[8];
int ret;
@@ -2020,8 +2031,47 @@ print_disk_table(raid_obj_handle_t ctl_handle, raid_obj_handle_t disk_handle)
(void) fprintf(stdout, "%s\t", disk);
(void) print_disk_attr(ctl_handle, disk_handle, &disk_attr);
- (void) fprintf(stdout, "\n");
+ prop_attr = calloc(1, sizeof (raidcfg_prop_t));
+ if (prop_attr == NULL) {
+ (void) fprintf(stderr, "%s\n", raidcfg_errstr(ERR_NOMEM));
+ return (FAILURE);
+ }
+
+ prop_handle = raidcfg_list_head(disk_handle, OBJ_TYPE_PROP);
+ if (prop_handle == 0) {
+ free(prop_attr);
+ return (SUCCESS);
+ }
+
+ do {
+ prop_attr->prop_size = 0;
+ if ((ret = raidcfg_get_attr(prop_handle, prop_attr)) < 0) {
+ free(prop_attr);
+ (void) fprintf(stderr, "%s\n", raidcfg_errstr(ret));
+ return (FAILURE);
+ }
+ if (prop_attr->prop_type == PROP_GUID)
+ break;
+ } while (prop_handle != 0);
+
+ prop_attr2 = realloc(prop_attr,
+ sizeof (raidcfg_prop_t) + prop_attr->prop_size);
+ free(prop_attr);
+ if (prop_attr2 == NULL) {
+ (void) fprintf(stderr, "%s\n", raidcfg_errstr(ERR_NOMEM));
+ return (FAILURE);
+ }
+
+ if ((ret = raidcfg_get_attr(prop_handle, prop_attr2)) < 0) {
+ free(prop_attr2);
+ (void) fprintf(stderr, "%s\n", raidcfg_errstr(ret));
+ return (FAILURE);
+ }
+
+ (void) fprintf(stdout, "GUID:%s\n", prop_attr2->prop);
+
+ free(prop_attr2);
return (SUCCESS);
}
@@ -2082,25 +2132,29 @@ print_array_attr(raidcfg_array_t *attrp)
(void) printf(gettext("N/A\t"));
}
- switch (attrp->state) {
- case ARRAY_STATE_OPTIMAL:
- (void) printf("%-8s", gettext("OPTIMAL"));
- break;
- case ARRAY_STATE_DEGRADED:
- (void) printf("%-8s", gettext("DEGRADED"));
- break;
- case ARRAY_STATE_FAILED:
- (void) printf("%-8s", gettext("FAILED"));
- break;
- case ARRAY_STATE_SYNC:
- (void) printf("%-8s", gettext("SYNC"));
- break;
- case ARRAY_STATE_MISSING:
- (void) printf("%-8s", gettext("MISSING"));
- break;
- default:
- (void) printf("%-8s", gettext("N/A"));
- break;
+ if (attrp->state & ARRAY_STATE_INACTIVATE)
+ (void) printf("%-8s", gettext("INACTIVE"));
+ else {
+ switch (attrp->state) {
+ case ARRAY_STATE_OPTIMAL:
+ (void) printf("%-8s", gettext("OPTIMAL"));
+ break;
+ case ARRAY_STATE_DEGRADED:
+ (void) printf("%-8s", gettext("DEGRADED"));
+ break;
+ case ARRAY_STATE_FAILED:
+ (void) printf("%-8s", gettext("FAILED"));
+ break;
+ case ARRAY_STATE_SYNC:
+ (void) printf("%-8s", gettext("SYNC"));
+ break;
+ case ARRAY_STATE_MISSING:
+ (void) printf("%-8s", gettext("MISSING"));
+ break;
+ default:
+ (void) printf("%-8s", gettext("N/A"));
+ break;
+ }
}
(void) printf(" ");
diff --git a/usr/src/lib/libraidcfg/common/raidcfg.c b/usr/src/lib/libraidcfg/common/raidcfg.c
index 23787210e5..99a6d2e386 100644
--- a/usr/src/lib/libraidcfg/common/raidcfg.c
+++ b/usr/src/lib/libraidcfg/common/raidcfg.c
@@ -142,6 +142,7 @@ typedef struct {
uint32_t disk_id;
uint64_t seq_id;
uint32_t task_id;
+ uint32_t prop_id;
uint32_t fd; /* Only for controller */
raid_lib_t *raid_lib; /* Only for controller */
} handle_attr_t;
@@ -191,6 +192,8 @@ static raid_obj_id_t obj_locate_arraypart(raid_obj_tab_t *, uint32_t,
static raid_obj_id_t obj_locate_diskseg(raid_obj_tab_t *, uint32_t,
uint32_t, uint32_t);
static raid_obj_id_t obj_locate_task(raid_obj_tab_t *, uint32_t, uint32_t);
+static raid_obj_id_t obj_locate_prop(raid_obj_tab_t *, uint32_t, uint32_t,
+ uint32_t);
static raid_obj_id_t obj_get_controller(raid_obj_tab_t *, raid_obj_id_t);
static int obj_sys_compnum(raid_obj_tab_t *, raid_obj_id_t,
@@ -220,6 +223,7 @@ static int obj_hsp_get_attr(raid_obj_tab_t *, raid_obj_id_t);
static int obj_arraypart_get_attr(raid_obj_tab_t *, raid_obj_id_t);
static int obj_diskseg_get_attr(raid_obj_tab_t *, raid_obj_id_t);
static int obj_task_get_attr(raid_obj_tab_t *, raid_obj_id_t);
+static int obj_prop_get_attr(raid_obj_tab_t *, raid_obj_id_t);
static int obj_array_create(raid_obj_tab_t *, raid_obj_id_t, int,
raid_obj_id_t *, char **);
static int obj_array_delete(raid_obj_tab_t *, raid_obj_id_t, char **);
@@ -309,7 +313,9 @@ static raid_obj_op_t raid_obj_op_sys[OBJ_TYPE_ALL] = {
NULL, NULL}, /* array part object methods */
{NULL, NULL, obj_diskseg_get_attr, NULL, NULL, NULL, NULL, NULL, NULL},
{NULL, NULL, obj_task_get_attr, NULL, NULL, NULL, NULL,
- NULL, NULL} /* disk seg object methods */
+ NULL, NULL}, /* disk seg object methods */
+ {NULL, NULL, obj_prop_get_attr, NULL, NULL, NULL, NULL,
+ NULL, NULL} /* property object methods */
};
/*
@@ -750,6 +756,28 @@ raidcfg_get_attr(int handle, void *attr)
case OBJ_TYPE_TASK:
size = sizeof (task_attr_t);
break;
+ case OBJ_TYPE_PROP:
+ {
+ property_attr_t *src = data, *dst = attr;
+
+ dst->prop_id = src->prop_id;
+ dst->prop_type = src->prop_type;
+ if (dst->prop_size == 0) {
+ dst->prop_size = src->prop_size;
+ (void) mutex_unlock(&raidcfg_mp);
+ return (SUCCESS);
+ }
+
+ if (dst->prop_size < src->prop_size)
+ size = dst->prop_size;
+ else
+ size = src->prop_size;
+
+ (void) memcpy(dst->prop, src->prop, size);
+ (void) mutex_unlock(&raidcfg_mp);
+ return (SUCCESS);
+ }
+ break;
default:
(void) mutex_unlock(&raidcfg_mp);
return (ERR_DEVICE_TYPE);
@@ -1467,6 +1495,11 @@ raid_handle_to_obj(raid_obj_tab_t *raid_tab, raid_obj_handle_t handle)
obj_id = obj_locate_task(raid_tab,
handle_attr->controller_id, handle_attr->task_id);
break;
+ case OBJ_TYPE_PROP:
+ obj_id = obj_locate_prop(raid_tab,
+ handle_attr->controller_id, handle_attr->disk_id,
+ handle_attr->prop_id);
+ break;
default:
return (ERR_DEVICE_INVALID);
}
@@ -1493,6 +1526,7 @@ raid_obj_to_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
arraypart_attr_t *arraypart_attr;
diskseg_attr_t *diskseg_attr;
task_attr_t *task_attr;
+ property_attr_t *prop_attr;
if (obj_id == OBJ_SYSTEM)
return (OBJ_SYSTEM);
@@ -1586,6 +1620,18 @@ raid_obj_to_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
raid_handle_sys.handles[handle].controller_id =
controller_attr->controller_id;
break;
+ case OBJ_TYPE_PROP:
+ prop_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
+ raid_handle_sys.handles[handle].prop_id =
+ prop_attr->prop_id;
+ obj_id = raid_obj_get_container(raid_tab, obj_id);
+ disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
+ raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id;
+ obj_id = obj_get_controller(raid_tab, obj_id);
+ controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
+ raid_handle_sys.handles[handle].controller_id =
+ controller_attr->controller_id;
+ break;
default:
return (ERR_DEVICE_INVALID);
}
@@ -2129,7 +2175,34 @@ obj_locate_task(raid_obj_tab_t *raid_tab, uint32_t controller_id,
} while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE);
return (obj_id);
+}
+
+static raid_obj_id_t
+obj_locate_prop(raid_obj_tab_t *raid_tab, uint32_t controller_id,
+ uint32_t disk_id, uint32_t prop_id)
+{
+ raid_obj_id_t obj_id;
+ property_attr_t *prop_attr;
+
+ obj_id = obj_locate_disk(raid_tab, controller_id, disk_id);
+ if (obj_id < OBJ_NONE)
+ return (obj_id);
+
+ obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_PROP);
+ if (obj_id <= OBJ_NONE)
+ return (obj_id);
+
+ do {
+ (void) obj_get_attr(raid_tab, obj_id, (void **)(&prop_attr));
+ if (prop_attr->prop_id == prop_id)
+ break;
+ obj_id = obj_get_sibling(raid_tab, obj_id);
+ if (obj_id < OBJ_NONE)
+ return (obj_id);
+ } while (obj_id > OBJ_NONE);
+
+ return (obj_id);
}
static raid_obj_id_t
@@ -2697,6 +2770,10 @@ obj_array_set_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
*value != CACHE_RD_ON)
return (ERR_OP_ILLEGAL);
break;
+ case SET_ACTIVATION_PLY:
+ if (*value != ARRAY_ACT_ACTIVATE)
+ return (ERR_OP_ILLEGAL);
+ break;
default:
return (ERR_OP_ILLEGAL);
}
@@ -2741,7 +2818,8 @@ obj_disk_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
if (comp_type != OBJ_TYPE_DISK_SEG &&
comp_type != OBJ_TYPE_HSP &&
- comp_type != OBJ_TYPE_TASK)
+ comp_type != OBJ_TYPE_TASK &&
+ comp_type != OBJ_TYPE_PROP)
return (0);
ret = obj_get_attr(raid_tab, obj_id, (void **)(&attr));
if ((ret != SUCCESS) || (attr == NULL)) {
@@ -2787,7 +2865,8 @@ obj_disk_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
if (comp_type != OBJ_TYPE_DISK_SEG &&
comp_type != OBJ_TYPE_HSP &&
- comp_type != OBJ_TYPE_TASK)
+ comp_type != OBJ_TYPE_TASK &&
+ comp_type != OBJ_TYPE_PROP)
return (0);
if (comp_num <= 0 || comp_list == NULL)
@@ -2835,6 +2914,7 @@ obj_disk_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
diskseg_attr_t *diskseg_attr;
hsp_attr_t *hsp_attr;
task_attr_t *task_attr;
+ property_attr_t *prop_attr;
void *attr_buf;
attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i));
@@ -2856,6 +2936,10 @@ obj_disk_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
task_attr = attr_buf;
task_attr->task_id = *(ids + i);
break;
+ case OBJ_TYPE_PROP:
+ prop_attr = attr_buf;
+ prop_attr->prop_id = *(ids + i);
+ break;
default:
free(ids);
return (ERR_DEVICE_INVALID);
@@ -3078,6 +3162,74 @@ obj_task_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
}
static int
+obj_prop_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
+{
+ property_attr_t *attr, *attr_new;
+ disk_attr_t *disk_attr;
+ controller_attr_t *ctl_attrp;
+ raid_lib_t *raid_lib;
+ int ret = SUCCESS, fd;
+ raid_obj_id_t controller_obj_id, disk_obj_id;
+
+ if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_PROP)
+ return (ERR_DEVICE_TYPE);
+
+ if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
+ return (SUCCESS);
+
+ attr = raid_obj_get_data_ptr(raid_tab, obj_id);
+ if (attr == NULL)
+ return (ERR_DEVICE_INVALID);
+
+ disk_obj_id = raid_obj_get_container(raid_tab, obj_id);
+ if (disk_obj_id < OBJ_NONE)
+ return (ERR_DEVICE_INVALID);
+
+ disk_attr = raid_obj_get_data_ptr(raid_tab, disk_obj_id);
+ if (disk_attr == NULL)
+ return (ERR_DEVICE_INVALID);
+
+ controller_obj_id = obj_get_controller(raid_tab, obj_id);
+ if (controller_obj_id < OBJ_NONE)
+ return (ERR_DEVICE_INVALID);
+
+ ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
+ if (ctl_attrp == NULL) {
+ return (ERR_DEVICE_INVALID);
+ }
+
+ raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
+ fd = raid_obj_get_fd(raid_tab, controller_obj_id);
+ if ((raid_lib == NULL) || (fd == 0))
+ return (ERR_DRIVER_CLOSED);
+
+ /* Get the property size at first */
+ attr->prop_size = 0;
+ ret = raid_lib->get_attr(ctl_attrp->controller_id,
+ disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr);
+
+ if (ret < SUCCESS)
+ return (ret);
+
+ /* Allocate memory for property and fill the buffer */
+ attr_new = realloc(attr, sizeof (property_attr_t) + attr->prop_size);
+ if (attr_new == NULL)
+ return (ERR_NOMEM);
+
+ (void) raid_obj_set_data_ptr(raid_tab, obj_id, attr_new);
+
+ ret = raid_lib->get_attr(ctl_attrp->controller_id,
+ disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr_new);
+
+ if (ret < SUCCESS)
+ return (ret);
+
+ (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED);
+
+ return (ret);
+}
+
+static int
obj_array_create(raid_obj_tab_t *raid_tab, raid_obj_id_t array_obj_id,
int num_of_comp, raid_obj_id_t *disk_list, char **plugin_err_str)
{
@@ -3802,6 +3954,9 @@ raid_obj_attr_new(raid_obj_type_id_t obj_type)
case OBJ_TYPE_TASK:
obj_attr = calloc(1, sizeof (task_attr_t));
break;
+ case OBJ_TYPE_PROP:
+ obj_attr = calloc(1, sizeof (property_attr_t));
+ break;
default:
break;
}
diff --git a/usr/src/lib/libraidcfg/common/raidcfg.h b/usr/src/lib/libraidcfg/common/raidcfg.h
index 995397b015..8c4b8969e1 100644
--- a/usr/src/lib/libraidcfg/common/raidcfg.h
+++ b/usr/src/lib/libraidcfg/common/raidcfg.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,6 +74,7 @@ typedef struct {
typedef diskseg_attr_t raidcfg_diskseg_t;
typedef task_attr_t raidcfg_task_t;
+typedef property_attr_t raidcfg_prop_t;
/*
* raidcfg common library APIs
diff --git a/usr/src/lib/libraidcfg/common/raidcfg_spi.h b/usr/src/lib/libraidcfg/common/raidcfg_spi.h
index cd79a973a8..5c37f0a847 100644
--- a/usr/src/lib/libraidcfg/common/raidcfg_spi.h
+++ b/usr/src/lib/libraidcfg/common/raidcfg_spi.h
@@ -82,6 +82,11 @@ extern "C" {
#define CACHE_RD_ON 1
/*
+ * Array activation action
+ */
+#define ARRAY_ACT_ACTIVATE 0
+
+/*
* Array status
*/
#define ARRAY_STATE_OPTIMAL 0
@@ -90,6 +95,11 @@ extern "C" {
#define ARRAY_STATE_MISSING 3
/*
+ * Array activation state
+ */
+#define ARRAY_STATE_INACTIVATE 0x8000
+
+/*
* Disk state
*/
#define DISK_STATE_GOOD 0
@@ -128,6 +138,7 @@ extern "C" {
*/
#define SET_CACHE_WR_PLY 0
#define SET_CACHE_RD_PLY 1
+#define SET_ACTIVATION_PLY 2
/*
* Sub-commands for act method of object
@@ -206,6 +217,7 @@ typedef enum {
OBJ_TYPE_ARRAY_PART,
OBJ_TYPE_DISK_SEG,
OBJ_TYPE_TASK,
+ OBJ_TYPE_PROP,
OBJ_TYPE_ALL
} raid_obj_type_id_t;
@@ -232,6 +244,13 @@ typedef enum {
} raidtask_state_t;
/*
+ * Properties
+ */
+typedef enum {
+ PROP_GUID
+} property_type_t;
+
+/*
* Attributes of all RAID objects
*/
typedef union {
@@ -308,6 +327,13 @@ typedef struct {
} task_attr_t;
typedef struct {
+ uint32_t prop_id;
+ uint32_t prop_size;
+ property_type_t prop_type;
+ char prop[1];
+} property_attr_t;
+
+typedef struct {
uint32_t array_id;
uint32_t disk_id;
} hsp_relation_t;
diff --git a/usr/src/uts/common/sys/mpt/mpi_raid.h b/usr/src/uts/common/sys/mpt/mpi_raid.h
index d420952d7e..a4e8257566 100644
--- a/usr/src/uts/common/sys/mpt/mpi_raid.h
+++ b/usr/src/uts/common/sys/mpt/mpi_raid.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,6 +49,8 @@ typedef struct msg_raid_action {
#define MPI_RAID_ACTION_DELETE_PHYSDISK 0x0E
#define MPI_RAID_ACTION_FAIL_PHYSDISK 0x0F
#define MPI_RAID_ACTION_REPLACE_PHYSDISK 0x10
+#define MPI_RAID_ACTION_ACTIVATE_VOLUME 0x11
+#define MPI_RAID_ACTION_INACTIVATE_VOLUME 0x12
#define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC 0x00000001