ctl_ha.h revision 274785
1229997Sken/*- 2229997Sken * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3229997Sken * Copyright (c) 2011 Spectra Logic Corporation 4229997Sken * All rights reserved. 5229997Sken * 6229997Sken * Redistribution and use in source and binary forms, with or without 7229997Sken * modification, are permitted provided that the following conditions 8229997Sken * are met: 9229997Sken * 1. Redistributions of source code must retain the above copyright 10229997Sken * notice, this list of conditions, and the following disclaimer, 11229997Sken * without modification. 12229997Sken * 2. Redistributions in binary form must reproduce at minimum a disclaimer 13229997Sken * substantially similar to the "NO WARRANTY" disclaimer below 14229997Sken * ("Disclaimer") and any redistribution must be conditioned upon 15229997Sken * including a substantially similar Disclaimer requirement for further 16229997Sken * binary redistribution. 17229997Sken * 18229997Sken * NO WARRANTY 19229997Sken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20229997Sken * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21229997Sken * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 22229997Sken * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23229997Sken * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24229997Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25229997Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26229997Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27229997Sken * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 28229997Sken * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29229997Sken * POSSIBILITY OF SUCH DAMAGES. 30229997Sken * 31229997Sken * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_ha.h#1 $ 32229997Sken * $FreeBSD: head/sys/cam/ctl/ctl_ha.h 274785 2014-11-21 06:27:37Z mav $ 33229997Sken */ 34229997Sken 35229997Sken#ifndef _CTL_HA_H_ 36229997Sken#define _CTL_HA_H_ 37229997Sken 38229997Sken/* 39229997Sken * CTL High Availability Modes: 40229997Sken * 41274785Smav * CTL_HA_MODE_ACT_STBY: One side is in Active state and processing commands, 42274785Smav * the other side is in Standby state, returning errors. 43229997Sken * CTL_HA_MODE_SER_ONLY: Commands are serialized to the other side. Write 44229997Sken * mirroring and read re-direction are assumed to 45229997Sken * happen in the back end. 46229997Sken * CTL_HA_MODE_XFER: Commands are serialized and data is transferred 47229997Sken * for write mirroring and read re-direction. 48229997Sken */ 49229997Sken 50229997Skentypedef enum { 51274785Smav CTL_HA_MODE_ACT_STBY, 52229997Sken CTL_HA_MODE_SER_ONLY, 53229997Sken CTL_HA_MODE_XFER 54229997Sken} ctl_ha_mode; 55229997Sken 56229997Sken 57229997Sken/* 58229997Sken * This is a stubbed out High Availability interface. It assumes two nodes 59229997Sken * staying in sync. 60229997Sken * 61229997Sken * The reason this interface is here, and stubbed out, is that CTL was 62229997Sken * originally written with support for Copan's (now SGI) high availability 63229997Sken * framework. That framework was not released by SGI, and would not have 64229997Sken * been generally applicable to FreeBSD anyway. 65229997Sken * 66229997Sken * The idea here is to show the kind of API that would need to be in place 67229997Sken * in a HA framework to work with CTL's HA hooks. This API is very close 68229997Sken * to the Copan/SGI API, so that the code using it could stay in place 69229997Sken * as-is. 70229997Sken * 71229997Sken * So, in summary, this is a shell without real substance, and much more 72229997Sken * work would be needed to actually make HA work. The implementation 73229997Sken * inside CTL will also need to change to fit the eventual implementation. 74229997Sken * The additional pieces we would need are: 75229997Sken * 76229997Sken * - HA "Supervisor" framework that can startup the components of the 77229997Sken * system, and initiate failover (i.e. active/active to single mode) 78229997Sken * and failback (single to active/active mode) state transitions. 79229997Sken * This framework would be able to recognize when an event happens 80229997Sken * that requires it to initiate state transitions in the components it 81229997Sken * manages. 82229997Sken * 83229997Sken * - HA communication framework. This framework should have the following 84229997Sken * features: 85229997Sken * - Separate channels for separate system components. The CTL 86229997Sken * instance on one node should communicate with the CTL instance 87229997Sken * on another node. 88229997Sken * - Short message passing. These messages would be fixed length, so 89229997Sken * they could be preallocated and easily passed between the nodes. 90229997Sken * i.e. conceptually like an ethernet packet. 91229997Sken * - DMA/large buffer capability. This would require some negotiation 92229997Sken * with the other node to define the destination. It could 93229997Sken * allow for "push" (i.e. initiated by the requesting node) DMA or 94229997Sken * "pull" (i.e. initiated by the target controller) DMA or both. 95229997Sken * - Communication channel status change notification. 96229997Sken * - HA capability in other portions of the storage stack. Having two CTL 97229997Sken * instances communicate is just one part of an overall HA solution. 98229997Sken * State needs to be synchronized at multiple levels of the system in 99229997Sken * order for failover to actually work. For instance, if CTL is using a 100229997Sken * file on a ZFS filesystem as its backing store, the ZFS array state 101229997Sken * should be synchronized with the other node, so that the other node 102229997Sken * can immediately take over if the node that is primary for a particular 103229997Sken * array fails. 104229997Sken */ 105229997Sken 106229997Sken/* 107229997Sken * Communication channel IDs for various system components. This is to 108229997Sken * make sure one CTL instance talks with another, one ZFS instance talks 109229997Sken * with another, etc. 110229997Sken */ 111229997Skentypedef enum { 112229997Sken CTL_HA_CHAN_NONE, 113229997Sken CTL_HA_CHAN_CTL, 114229997Sken CTL_HA_CHAN_ZFS, 115229997Sken CTL_HA_CHAN_MAX 116229997Sken} ctl_ha_channel; 117229997Sken 118229997Sken/* 119229997Sken * HA communication event notification. These are events generated by the 120229997Sken * HA communication subsystem. 121229997Sken * 122229997Sken * CTL_HA_EVT_MSG_RECV: Message received by the other node. 123229997Sken * CTL_HA_EVT_MSG_SENT: Message sent to the other node. 124229997Sken * CTL_HA_EVT_DISCONNECT: Communication channel disconnected. 125229997Sken * CTL_HA_EVT_DMA_SENT: DMA successfully sent to other node (push). 126229997Sken * CTL_HA_EVT_DMA_RECEIVED: DMA successfully received by other node (pull). 127229997Sken */ 128229997Skentypedef enum { 129229997Sken CTL_HA_EVT_NONE, 130229997Sken CTL_HA_EVT_MSG_RECV, 131229997Sken CTL_HA_EVT_MSG_SENT, 132229997Sken CTL_HA_EVT_DISCONNECT, 133229997Sken CTL_HA_EVT_DMA_SENT, 134229997Sken CTL_HA_EVT_DMA_RECEIVED, 135229997Sken CTL_HA_EVT_MAX 136229997Sken} ctl_ha_event; 137229997Sken 138229997Skentypedef enum { 139229997Sken CTL_HA_STATUS_WAIT, 140229997Sken CTL_HA_STATUS_SUCCESS, 141229997Sken CTL_HA_STATUS_ERROR, 142229997Sken CTL_HA_STATUS_INVALID, 143229997Sken CTL_HA_STATUS_DISCONNECT, 144229997Sken CTL_HA_STATUS_BUSY, 145229997Sken CTL_HA_STATUS_MAX 146229997Sken} ctl_ha_status; 147229997Sken 148229997Skentypedef enum { 149229997Sken CTL_HA_DATA_CTL, 150229997Sken CTL_HA_DATA_ZFS, 151229997Sken CTL_HA_DATA_MAX 152229997Sken} ctl_ha_dtid; 153229997Sken 154229997Skentypedef enum { 155229997Sken CTL_HA_DT_CMD_READ, 156229997Sken CTL_HA_DT_CMD_WRITE, 157229997Sken} ctl_ha_dt_cmd; 158229997Sken 159229997Skenstruct ctl_ha_dt_req; 160229997Sken 161229997Skentypedef void (*ctl_ha_dt_cb)(struct ctl_ha_dt_req *); 162229997Sken 163229997Skenstruct ctl_ha_dt_req { 164229997Sken ctl_ha_dt_cmd command; 165229997Sken void *context; 166229997Sken ctl_ha_dt_cb callback; 167229997Sken ctl_ha_dtid id; 168229997Sken int ret; 169229997Sken uint32_t size; 170229997Sken uint8_t *local; 171229997Sken uint8_t *remote; 172229997Sken}; 173229997Sken 174229997Skentypedef void (*ctl_evt_handler)(ctl_ha_channel channel, ctl_ha_event event, 175229997Sken int param); 176229997Skenvoid ctl_ha_register_evthandler(ctl_ha_channel channel, 177229997Sken ctl_evt_handler handler); 178229997Sken 179229997Skenstatic inline ctl_ha_status 180229997Skenctl_ha_msg_create(ctl_ha_channel channel, ctl_evt_handler handler) 181229997Sken{ 182229997Sken return (CTL_HA_STATUS_SUCCESS); 183229997Sken} 184229997Sken 185229997Sken/* 186229997Sken * Receive a message of the specified size. 187229997Sken */ 188229997Skenstatic inline ctl_ha_status 189229997Skenctl_ha_msg_recv(ctl_ha_channel channel, void *buffer, unsigned int size, 190229997Sken int wait) 191229997Sken{ 192229997Sken return (CTL_HA_STATUS_SUCCESS); 193229997Sken} 194229997Sken 195229997Sken/* 196229997Sken * Send a message of the specified size. 197229997Sken */ 198229997Skenstatic inline ctl_ha_status 199229997Skenctl_ha_msg_send(ctl_ha_channel channel, void *buffer, unsigned int size, 200229997Sken int wait) 201229997Sken{ 202229997Sken return (CTL_HA_STATUS_SUCCESS); 203229997Sken} 204229997Sken 205229997Sken/* 206229997Sken * Allocate a data transfer request structure. 207229997Sken */ 208229997Skenstatic inline struct ctl_ha_dt_req * 209229997Skenctl_dt_req_alloc(void) 210229997Sken{ 211229997Sken return (NULL); 212229997Sken} 213229997Sken 214229997Sken/* 215229997Sken * Free a data transfer request structure. 216229997Sken */ 217229997Skenstatic inline void 218229997Skenctl_dt_req_free(struct ctl_ha_dt_req *req) 219229997Sken{ 220229997Sken return; 221229997Sken} 222229997Sken 223229997Sken/* 224229997Sken * Issue a DMA request for a single buffer. 225229997Sken */ 226229997Skenstatic inline ctl_ha_status 227229997Skenctl_dt_single(struct ctl_ha_dt_req *req) 228229997Sken{ 229229997Sken return (CTL_HA_STATUS_WAIT); 230229997Sken} 231229997Sken 232229997Sken/* 233229997Sken * SINGLE: One node 234229997Sken * HA: Two nodes (Active/Active implied) 235229997Sken * SLAVE/MASTER: The component can set these flags to indicate which side 236229997Sken * is in control. It has no effect on the HA framework. 237229997Sken */ 238229997Skentypedef enum { 239229997Sken CTL_HA_STATE_UNKNOWN = 0x00, 240229997Sken CTL_HA_STATE_SINGLE = 0x01, 241229997Sken CTL_HA_STATE_HA = 0x02, 242229997Sken CTL_HA_STATE_MASK = 0x0F, 243229997Sken CTL_HA_STATE_SLAVE = 0x10, 244229997Sken CTL_HA_STATE_MASTER = 0x20 245229997Sken} ctl_ha_state; 246229997Sken 247229997Skentypedef enum { 248229997Sken CTL_HA_COMP_STATUS_OK, 249229997Sken CTL_HA_COMP_STATUS_FAILED, 250229997Sken CTL_HA_COMP_STATUS_ERROR 251229997Sken} ctl_ha_comp_status; 252229997Sken 253229997Skenstruct ctl_ha_component; 254229997Sken 255229997Skentypedef ctl_ha_comp_status (*ctl_hacmp_init_t)(struct ctl_ha_component *); 256229997Skentypedef ctl_ha_comp_status (*ctl_hacmp_start_t)(struct ctl_ha_component *, 257229997Sken ctl_ha_state); 258229997Sken 259229997Skenstruct ctl_ha_component { 260229997Sken char *name; 261229997Sken ctl_ha_state state; 262229997Sken ctl_ha_comp_status status; 263229997Sken ctl_hacmp_init_t init; 264229997Sken ctl_hacmp_start_t start; 265229997Sken ctl_hacmp_init_t quiesce; 266229997Sken}; 267229997Sken 268229997Sken#define CTL_HA_STATE_IS_SINGLE(state) ((state & CTL_HA_STATE_MASK) == \ 269229997Sken CTL_HA_STATE_SINGLE) 270229997Sken#define CTL_HA_STATE_IS_HA(state) ((state & CTL_HA_STATE_MASK) == \ 271229997Sken CTL_HA_STATE_HA) 272229997Sken 273229997Sken#endif /* _CTL_HA_H_ */ 274