c9e45581ad
This patch allows a failed path group initialisation command to be retried. It adds a generic MP_RETRY flag and a "pg_init_retries" feature to device-mapper multipath which limits the number of retries. 1. A hw handler sends a path initialization command to the storage and the command completes with an error code indicating the command should be retried. 2. The hardware handler calls dm_pg_init_complete() with MP_RETRY set in err_flags to ask the dm multipath core to retry. 3. If the retry limit has not been exceeded, pg_init() is retried. Otherwise fail_path() is called. If you are using the userspace multipath-tools or device-mapper-multipath package, you can set pg_init_retries in the 'device' section of your /etc/multipath.conf file. For example: features "2 pg_init_retries 7" The number of PG retries attempted is reported in the 'dmsetup status' output. Signed-off-by: Dave Wysochanski <dwysocha@redhat.com> Acked-by: Mike Christie <michaelc@cs.wisc.edu> Acked-by: Chandra Seetharaman <sekharan@us.ibm.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
64 lines
1.6 KiB
C
64 lines
1.6 KiB
C
/*
|
|
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
|
*
|
|
* This file is released under the GPL.
|
|
*
|
|
* Multipath hardware handler registration.
|
|
*/
|
|
|
|
#ifndef DM_HW_HANDLER_H
|
|
#define DM_HW_HANDLER_H
|
|
|
|
#include <linux/device-mapper.h>
|
|
|
|
#include "dm-mpath.h"
|
|
|
|
struct hw_handler_type;
|
|
struct hw_handler {
|
|
struct hw_handler_type *type;
|
|
struct mapped_device *md;
|
|
void *context;
|
|
};
|
|
|
|
/*
|
|
* Constructs a hardware handler object, takes custom arguments
|
|
*/
|
|
/* Information about a hardware handler type */
|
|
struct hw_handler_type {
|
|
char *name;
|
|
struct module *module;
|
|
|
|
int (*create) (struct hw_handler *handler, unsigned int argc,
|
|
char **argv);
|
|
void (*destroy) (struct hw_handler *hwh);
|
|
|
|
void (*pg_init) (struct hw_handler *hwh, unsigned bypassed,
|
|
struct dm_path *path);
|
|
unsigned (*error) (struct hw_handler *hwh, struct bio *bio);
|
|
int (*status) (struct hw_handler *hwh, status_type_t type,
|
|
char *result, unsigned int maxlen);
|
|
};
|
|
|
|
/* Register a hardware handler */
|
|
int dm_register_hw_handler(struct hw_handler_type *type);
|
|
|
|
/* Unregister a hardware handler */
|
|
int dm_unregister_hw_handler(struct hw_handler_type *type);
|
|
|
|
/* Returns a registered hardware handler type */
|
|
struct hw_handler_type *dm_get_hw_handler(const char *name);
|
|
|
|
/* Releases a hardware handler */
|
|
void dm_put_hw_handler(struct hw_handler_type *hwht);
|
|
|
|
/* Default err function */
|
|
unsigned dm_scsi_err_handler(struct hw_handler *hwh, struct bio *bio);
|
|
|
|
/* Error flags for err and dm_pg_init_complete */
|
|
#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
|