Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 292553 Details for
Bug 195685
RFE: Add dm-hp-sw to kernel to allow use of active/passive sans with dm multipathing
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
Updated rhel4.7 patch - currently under test and looking promising
rhel4u7-second.patch (text/x-patch), 12.43 KB, created by
Dave Wysochanski
on 2008-01-22 19:46:29 UTC
(
hide
)
Description:
Updated rhel4.7 patch - currently under test and looking promising
Filename:
MIME Type:
Creator:
Dave Wysochanski
Created:
2008-01-22 19:46:29 UTC
Size:
12.43 KB
patch
obsolete
>Index: linux-2.6.9/drivers/md/Kconfig >=================================================================== >--- linux-2.6.9.orig/drivers/md/Kconfig >+++ linux-2.6.9/drivers/md/Kconfig >@@ -230,5 +230,11 @@ config DM_MULTIPATH_EMC > ---help--- > Multipath support for EMC CX/AX series hardware. > >+config DM_MULTIPATH_HP >+ tristate "HP MSA multipath support (EXPERIMENTAL)" >+ depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL >+ ---help--- >+ Multipath support for HP MSA (Active/Passive) series hardware. >+ > endmenu > >Index: linux-2.6.9/drivers/md/Makefile >=================================================================== >--- linux-2.6.9.orig/drivers/md/Makefile >+++ linux-2.6.9/drivers/md/Makefile >@@ -7,6 +7,7 @@ dm-mod-objs := dm.o dm-table.o dm-target > dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o > dm-snapshot-objs := dm-snap.o dm-exception-store.o > dm-mirror-objs := dm-log.o dm-raid1.o >+dm-hp-sw-objs := dm-mpath-hp-sw.o > raid6-objs := raid6main.o raid6algos.o raid6recov.o raid6tables.o \ > raid6int1.o raid6int2.o raid6int4.o \ > raid6int8.o raid6int16.o raid6int32.o \ >@@ -32,6 +33,7 @@ obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o > obj-$(CONFIG_DM_CRYPT) += dm-crypt.o > obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o > obj-$(CONFIG_DM_MULTIPATH_EMC) += dm-emc.o >+obj-$(CONFIG_DM_MULTIPATH_HP) += dm-hp-sw.o > obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o > obj-$(CONFIG_DM_MIRROR) += dm-mirror.o > obj-$(CONFIG_DM_ZERO) += dm-zero.o >Index: linux-2.6.9/drivers/md/dm-mpath-hp-sw.c >=================================================================== >--- /dev/null >+++ linux-2.6.9/drivers/md/dm-mpath-hp-sw.c >@@ -0,0 +1,227 @@ >+/* >+ * Copyright (C) 2005 Mike Christie, All rights reserved. >+ * Copyright (C) 2007 Red Hat, Inc. All rights reserved. >+ * Authors: Mike Christie >+ * Dave Wysochanski >+ * >+ * This file is released under the GPL. >+ * >+ * This module implements the specific path activation code for >+ * HP StorageWorks and FSC FibreCat Asymmetric (Active/Passive) >+ * storage arrays. >+ * These storage arrays have controller-based failover, not >+ * LUN-based failover. However, LUN-based failover is the design >+ * of dm-multipath. Thus, this module is written for LUN-based failover. >+ */ >+#include <linux/blkdev.h> >+#include <linux/list.h> >+#include <linux/types.h> >+#include <scsi/scsi.h> >+#include <scsi/scsi_cmnd.h> >+#include <scsi/scsi_request.h> >+#include <scsi/scsi_device.h> >+#include <scsi/scsi_dbg.h> >+ >+#include "dm.h" >+#include "dm-hw-handler.h" >+ >+#define DM_MSG_PREFIX "multipath hp-sw: " >+#define DM_HP_HWH_NAME "hp-sw" >+#define DM_HP_HWH_VER "1.0.0" >+ >+/* >+ * hp_sw_error_is_retryable - Is an HP-specific check condition retryable? >+ * @sc: scsi_cmnd completing with error status >+ * >+ * Examine error codes of request and determine whether the error is retryable. >+ * Some error codes are already retried by scsi-ml (see >+ * scsi_decide_disposition), but some HP specific codes are not. >+ * The intent of this routine is to supply the logic for the HP specific >+ * check conditions. >+ * >+ * Returns: >+ * 1 - command completed with retryable error >+ * 0 - command completed with non-retryable error >+ * >+ * Possible optimizations >+ * 1. More hardware-specific error codes >+ */ >+static int hp_sw_error_is_retryable(struct scsi_cmnd *sc) >+{ >+ struct scsi_request *srq = sc->sc_request; >+ >+ /* >+ * NOT_READY is known to be retryable >+ * For now we just dump out the sense data and call it retryable >+ */ >+ if ((status_byte(sc->result) == CHECK_CONDITION) && >+ (driver_byte(srq->sr_result) & DRIVER_SENSE)) >+ scsi_print_sense("", sc); >+ >+ /* >+ * At this point we don't have complete information about all the error >+ * codes from this hardware, so we are just conservative and retry >+ * when in doubt. >+ */ >+ return 1; >+} >+ >+/* >+ * hp_sw_cmd_done - Completion handler for HP path activation. >+ * @sc: scsi_cmnd that is completed >+ * >+ * Check sense data, free scsi_request structure, and notify dm that >+ * pg initialization has completed. >+ * >+ * Context: scsi-ml softirq >+ * >+ */ >+static void hp_sw_cmd_done(struct scsi_cmnd * sc) >+{ >+ struct scsi_request *srq; >+ struct path *path; >+ unsigned err_flags = 0; >+ >+ srq = sc->sc_request; >+ path = srq->upper_private_data; >+ if (!sc->result) >+ goto out; >+ >+ if (hp_sw_error_is_retryable(sc)) { >+ err_flags = MP_RETRY; >+ goto out; >+ } >+ >+ DMWARN(DM_MSG_PREFIX "%s path activation fail - error=0x%x", >+ path->dev->name, srq->sr_result); >+ err_flags = MP_FAIL_PATH; >+ >+out: >+ scsi_release_request(srq); >+ dm_pg_init_complete(path, err_flags); >+} >+ >+/* >+ * hp_sw_get_request - Allocate an HP specific path activation request >+ * @path: path on which request will be sent (needed for request queue) >+ * @cmd: scsi START_STOP cdb >+ * @cmd_size: size of 'cmd' >+ * >+ * The START command is used for path activation request. >+ * These arrays are controller-based failover, not LUN based. >+ * One START command issued to a single path will fail over all >+ * LUNs for the same controller. >+ * >+ * Possible optimizations >+ * 1. Make timeout configurable >+ * 2. Preallocate request >+ */ >+static struct scsi_request *hp_sw_get_request(struct path *path, >+ unsigned char *cdb, >+ unsigned cdb_size) >+{ >+ struct scsi_device *sdp; >+ struct scsi_request *srq; >+ >+ /* >+ * Get scsi_device from sysfs struct device, then allocate the >+ * request and fill in the cdb. >+ */ >+ sdp = to_scsi_device(path->dev->bdev->bd_disk->driverfs_dev); >+ >+ srq = scsi_allocate_request(sdp, GFP_ATOMIC); >+ if (!srq) { >+ DMERR(DM_MSG_PREFIX "scsi_allocate_request() failed."); >+ return NULL; >+ } >+ srq->upper_private_data = path; >+ >+ memset(cdb, 0, cdb_size); >+ cdb[0] = START_STOP; >+ cdb[4] = 1; >+ >+ return srq; >+} >+ >+/* >+ * hp_sw_pg_init - HP path activation implementation. >+ * @hwh: hardware handler specific data >+ * @bypassed: unused; is the path group bypassed? (see dm-mpath.c) >+ * @path: path to send initialization command >+ * >+ * Send an HP-specific path activation command on 'path'. >+ * Do not try to optimize in any way, just send the activation command. >+ * More than one path activation command may be sent to the same controller. >+ * This seems to work fine for basic failover support. >+ * >+ * Possible optimizations >+ * 1. Detect an in-progress activation request and avoid submitting another one >+ * 2. Model the controller and only send a single activation request at a time >+ * 3. Determine the state of a path before sending an activation request >+ * >+ * Context: kmpathd (see process_queued_ios() in dm-mpath.c) >+ */ >+static void hp_sw_pg_init(struct hw_handler *hwh, unsigned bypassed, >+ struct path *path) >+{ >+ struct scsi_request *srq; >+ unsigned char cdb[MAX_COMMAND_SIZE]; >+ >+ srq = hp_sw_get_request(path, cdb, sizeof(cdb)); >+ if (!srq) >+ goto retry; >+ >+ scsi_do_req(srq, (void *) cdb, (void *) NULL, 0, >+ hp_sw_cmd_done, 60*HZ, 0); >+ return; >+ >+retry: >+ dm_pg_init_complete(path, MP_RETRY); >+} >+ >+static int hp_sw_create(struct hw_handler *hwh, unsigned argc, char **argv) >+{ >+ return 0; >+} >+ >+static void hp_sw_destroy(struct hw_handler *hwh) >+{ >+} >+ >+static struct hw_handler_type hp_sw_hwh = { >+ .name = DM_HP_HWH_NAME, >+ .module = THIS_MODULE, >+ .create = hp_sw_create, >+ .destroy = hp_sw_destroy, >+ .pg_init = hp_sw_pg_init, >+}; >+ >+static int __init hp_sw_init(void) >+{ >+ int r; >+ >+ r = dm_register_hw_handler(&hp_sw_hwh); >+ if (r < 0) >+ DMERR(DM_MSG_PREFIX "register failed %d", r); >+ else >+ DMINFO(DM_MSG_PREFIX "version " DM_HP_HWH_VER " loaded"); >+ >+ return r; >+} >+ >+static void __exit hp_sw_exit(void) >+{ >+ int r; >+ >+ r = dm_unregister_hw_handler(&hp_sw_hwh); >+ if (r < 0) >+ DMERR(DM_MSG_PREFIX "unregister failed %d", r); >+} >+ >+module_init(hp_sw_init); >+module_exit(hp_sw_exit); >+ >+MODULE_DESCRIPTION("DM Multipath HP StorageWorks / FSC FibreCat (A/P) support"); >+MODULE_AUTHOR("Mike Christie, Dave Wysochanski <dm-devel@redhat.com>"); >+MODULE_LICENSE("GPL"); >+MODULE_VERSION(DM_HP_HWH_VER); >Index: linux-2.6.9/drivers/md/dm-hw-handler.h >=================================================================== >--- linux-2.6.9.orig/drivers/md/dm-hw-handler.h >+++ linux-2.6.9/drivers/md/dm-hw-handler.h >@@ -57,5 +57,6 @@ unsigned dm_scsi_err_handler(struct hw_h > #define MP_FAIL_PATH 1 > #define MP_BYPASS_PG 2 > #define MP_ERROR_IO 4 /* Don't retry this I/O */ >+#define MP_RETRY 8 > > #endif >Index: linux-2.6.9/drivers/md/dm-mpath.c >=================================================================== >--- linux-2.6.9.orig/drivers/md/dm-mpath.c >+++ linux-2.6.9/drivers/md/dm-mpath.c >@@ -74,6 +74,8 @@ struct multipath { > unsigned queue_io; /* Must we queue all I/O? */ > unsigned queue_if_no_path; /* Queue I/O if last path fails? */ > unsigned saved_queue_if_no_path;/* Saved state during suspension */ >+ unsigned pg_init_retries; /* Number of times to retry pg_init */ >+ unsigned pg_init_count; /* Number of times pg_init called */ > > struct work_struct process_queued_ios; > struct bio_list queued_ios; >@@ -228,6 +230,8 @@ static void __switch_pg(struct multipath > m->pg_init_required = 0; > m->queue_io = 0; > } >+ >+ m->pg_init_count = 0; > } > > static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg) >@@ -432,6 +436,7 @@ static void process_queued_ios(void *dat > must_queue = 0; > > if (m->pg_init_required && !m->pg_init_in_progress) { >+ m->pg_init_count++; > m->pg_init_required = 0; > m->pg_init_in_progress = 1; > init_required = 1; >@@ -695,9 +700,11 @@ static int parse_features(struct arg_set > { > int r; > unsigned argc; >+ const char *param_name; > > static struct param _params[] = { >- {0, 1, ESTR("invalid number of feature args")}, >+ {0, 3, "invalid number of feature args"}, >+ {1, 50, "pg_init_retries must be between 1 and 50"}, > }; > > r = read_param(_params, shift(as), &argc, &ti->error); >@@ -707,12 +714,28 @@ static int parse_features(struct arg_set > if (!argc) > return 0; > >- if (!strnicmp(shift(as), MESG_STR("queue_if_no_path"))) >- return queue_if_no_path(m, 1, 0); >- else { >+ do { >+ param_name = shift(as); >+ argc--; >+ >+ if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) { >+ r = queue_if_no_path(m, 1, 0); >+ continue; >+ } >+ >+ if (!strnicmp(param_name, MESG_STR("pg_init_retries")) && >+ (argc >= 1)) { >+ r = read_param(_params + 1, shift(as), >+ &m->pg_init_retries, &ti->error); >+ argc--; >+ continue; >+ } >+ > ti->error = "Unrecognised multipath feature request"; >- return -EINVAL; >- } >+ r = -EINVAL; >+ } while (argc && !r); >+ >+ return r; > } > > static int multipath_ctr(struct dm_target *ti, unsigned int argc, >@@ -989,6 +1012,26 @@ static int bypass_pg_num(struct multipat > } > > /* >+ * Should we retry pg_init immediately? >+ */ >+static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath) >+{ >+ unsigned long flags; >+ int limit_reached = 0; >+ >+ spin_lock_irqsave(&m->lock, flags); >+ >+ if (m->pg_init_count <= m->pg_init_retries) >+ m->pg_init_required = 1; >+ else >+ limit_reached = 1; >+ >+ spin_unlock_irqrestore(&m->lock, flags); >+ >+ return limit_reached; >+} >+ >+/* > * pg_init must call this when it has completed its initialisation > */ > void dm_pg_init_complete(struct path *path, unsigned err_flags) >@@ -998,8 +1041,14 @@ void dm_pg_init_complete(struct path *pa > struct multipath *m = pg->m; > unsigned long flags; > >- /* We insist on failing the path if the PG is already bypassed. */ >- if (err_flags && pg->bypassed) >+ /* >+ * If requested, retry pg_init until maximum number of retries exceeded. >+ * If retry not requested and PG already bypassed, always fail the path. >+ */ >+ if (err_flags & MP_RETRY) { >+ if (pg_init_limit_reached(m, pgpath)) >+ err_flags |= MP_FAIL_PATH; >+ } else if (err_flags && pg->bypassed) > err_flags |= MP_FAIL_PATH; > > if (err_flags & MP_FAIL_PATH) >@@ -1009,7 +1058,7 @@ void dm_pg_init_complete(struct path *pa > bypass_pg(m, pg, 1); > > spin_lock_irqsave(&m->lock, flags); >- if (err_flags) { >+ if (err_flags & ~MP_RETRY) { > m->current_pgpath = NULL; > m->current_pg = NULL; > } else if (!m->pg_init_required) >@@ -1163,11 +1212,15 @@ static int multipath_status(struct dm_ta > > /* Features */ > if (type == STATUSTYPE_INFO) >- DMEMIT("1 %u ", m->queue_size); >- else if (m->queue_if_no_path) >- DMEMIT("1 queue_if_no_path "); >- else >- DMEMIT("0 "); >+ DMEMIT("2 %u %u ", m->queue_size, m->pg_init_count); >+ else { >+ DMEMIT("%u ", m->queue_if_no_path + >+ (m->pg_init_retries > 0) * 2); >+ if (m->queue_if_no_path) >+ DMEMIT("queue_if_no_path "); >+ if (m->pg_init_retries) >+ DMEMIT("pg_init_retries %u ", m->pg_init_retries); >+ } > > if (hwh->type && hwh->type->status) > sz += hwh->type->status(hwh, type, result + sz, maxlen - sz);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 195685
:
131053
|
131073
|
131074
|
132388
|
140056
|
140721
|
140741
|
142204
|
142207
|
148162
|
148204
|
155210
|
292333
| 292553