summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2017-03-26 14:12:11 +0200
committerMichael Brown2017-03-26 15:06:02 +0200
commitbb5a54b79a414082d0b39d478a8b3332c56d68e5 (patch)
treec022d5b8ed56be56414eb007273aeacd57c44d37 /src/include
parent[block] Add dummy SAN device (diff)
downloadipxe-bb5a54b79a414082d0b39d478a8b3332c56d68e5.tar.gz
ipxe-bb5a54b79a414082d0b39d478a8b3332c56d68e5.tar.xz
ipxe-bb5a54b79a414082d0b39d478a8b3332c56d68e5.zip
[block] Add basic multipath support
Add basic support for multipath block devices. The "sanboot" and "sanhook" commands now accept a list of SAN URIs. We open all URIs concurrently. The first connection to become available for issuing block device commands is marked as the active path and used for all subsequent commands; all other connections are then closed. Whenever the active path fails, we reopen all URIs and repeat the process. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ipxe/sanboot.h46
-rw-r--r--src/include/usr/autoboot.h3
2 files changed, 37 insertions, 12 deletions
diff --git a/src/include/ipxe/sanboot.h b/src/include/ipxe/sanboot.h
index c2e57f71..a8b0291d 100644
--- a/src/include/ipxe/sanboot.h
+++ b/src/include/ipxe/sanboot.h
@@ -16,9 +16,29 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
#include <ipxe/uri.h>
#include <ipxe/retry.h>
+#include <ipxe/process.h>
#include <ipxe/blockdev.h>
#include <config/sanboot.h>
+/** A SAN path */
+struct san_path {
+ /** Containing SAN device */
+ struct san_device *sandev;
+ /** Path index */
+ unsigned int index;
+ /** SAN device URI */
+ struct uri *uri;
+ /** List of open/closed paths */
+ struct list_head list;
+
+ /** Underlying block device interface */
+ struct interface block;
+ /** Process */
+ struct process process;
+ /** Path status */
+ int path_rc;
+};
+
/** A SAN device */
struct san_device {
/** Reference count */
@@ -26,16 +46,9 @@ struct san_device {
/** List of SAN devices */
struct list_head list;
- /** SAN device URI */
- struct uri *uri;
/** Drive number */
unsigned int drive;
- /** Underlying block device interface */
- struct interface block;
- /** Current device status */
- int block_rc;
-
/** Command interface */
struct interface command;
/** Command timeout timer */
@@ -57,6 +70,15 @@ struct san_device {
/** Driver private data */
void *priv;
+
+ /** Current active path */
+ struct san_path *active;
+ /** List of opened SAN paths */
+ struct list_head opened;
+ /** List of closed SAN paths */
+ struct list_head closed;
+ /** SAN paths */
+ struct san_path path[0];
};
/**
@@ -99,11 +121,12 @@ struct san_device {
/**
* Hook SAN device
*
- * @v uri URI
* @v drive Drive number
+ * @v uris List of URIs
+ * @v count Number of URIs
* @ret drive Drive number, or negative error
*/
-int san_hook ( struct uri *uri, unsigned int drive );
+int san_hook ( unsigned int drive, struct uri **uris, unsigned int count );
/**
* Unhook SAN device
@@ -191,7 +214,7 @@ static inline uint64_t sandev_capacity ( struct san_device *sandev ) {
* @ret needs_reopen SAN device needs to be reopened
*/
static inline int sandev_needs_reopen ( struct san_device *sandev ) {
- return ( sandev->block_rc != 0 );
+ return ( sandev->active == NULL );
}
extern struct san_device * sandev_find ( unsigned int drive );
@@ -203,7 +226,8 @@ extern int sandev_rw ( struct san_device *sandev, uint64_t lba,
struct interface *data,
uint64_t lba, unsigned int count,
userptr_t buffer, size_t len ) );
-extern struct san_device * alloc_sandev ( struct uri *uri, size_t priv_size );
+extern struct san_device * alloc_sandev ( struct uri **uris, unsigned int count,
+ size_t priv_size );
extern int register_sandev ( struct san_device *sandev );
extern void unregister_sandev ( struct san_device *sandev );
extern unsigned int san_default_drive ( void );
diff --git a/src/include/usr/autoboot.h b/src/include/usr/autoboot.h
index 4db226b9..c62d06c6 100644
--- a/src/include/usr/autoboot.h
+++ b/src/include/usr/autoboot.h
@@ -30,7 +30,8 @@ extern void set_autoboot_busloc ( unsigned int bus_type,
unsigned int location );
extern void set_autoboot_ll_addr ( const void *ll_addr, size_t len );
-extern int uriboot ( struct uri *filename, struct uri *root_path, int drive,
+extern int uriboot ( struct uri *filename, struct uri **root_paths,
+ unsigned int root_path_count, int drive,
unsigned int flags );
extern struct uri *
fetch_next_server_and_filename ( struct settings *settings );