forked from open-iscsi/tcmu-runner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tcmu-runner.h
205 lines (174 loc) · 6.01 KB
/
tcmu-runner.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
* Copyright (c) 2014 Red Hat, Inc.
*
* This file is licensed to you under your choice of the GNU Lesser
* General Public License, version 2.1 or any later version (LGPLv2.1 or
* later), or the Apache License 2.0.
*/
/*
* This header defines the interface between tcmu-runner and its loadable
* subtype handlers.
*/
#ifndef __TCMU_RUNNER_H
#define __TCMU_RUNNER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include <sys/uio.h>
#include "ccan/list/list.h"
#include "scsi_defs.h"
#include "libtcmu_log.h"
#include "libtcmu_common.h"
#include "alua.h"
#include "scsi.h"
struct tcmur_cmd;
struct tcmur_cmd {
/* Pointer to tcmulib_get_next_command's cmd. */
struct tcmulib_cmd *lib_cmd;
/* Used by compound commands like CAW, format unit, etc. */
struct iovec *iovec;
size_t iov_cnt;
/*
* Some handlers will manipulcate the iov_base pointer while copying
* to/from it. This is a pointer to the original pointer.
*/
void *iov_base_copy;
void *cmd_state;
/* Bytes to read/write from iovec */
size_t requested;
struct list_node cmds_list_entry;
struct timespec start_time;
bool timed_out;
/* callback to finish/continue command processing */
void (*done)(struct tcmu_device *dev, struct tcmur_cmd *cmd, int ret);
};
struct tcmulib_cfg_info;
struct tcmur_handler {
const char *name; /* Human-friendly name */
const char *subtype; /* Name for cfgstring matching */
const char *cfg_desc; /* Description of this backstore's config string */
void *opaque; /* Handler private data. */
/*
* As much as possible, check that the cfgstring will result
* in a working device when given to us as dev->cfgstring in
* the ->open() call.
*
* This function is optional but gives configuration tools a
* chance to warn users in advance if the device they're
* trying to create is invalid.
*
* Returns true if string is valid. Only if false, set *reason
* to a string that says why. The string will be free()ed.
* Suggest using asprintf().
*/
bool (*check_config)(const char *cfgstring, char **reason);
int (*reconfig)(struct tcmu_device *dev, struct tcmulib_cfg_info *cfg);
/* Per-device added/removed callbacks */
int (*open)(struct tcmu_device *dev, bool reopen);
void (*close)(struct tcmu_device *dev);
/*
* If > 0, runner will execute up to nr_threads IO callouts from
* threads.
* if 0, runner will call IO callouts from the cmd proc thread or
* completion context for compound commands.
*/
int nr_threads;
/*
* handle_cmd only handlers return:
*
* - TCMU_STS_OK if the command has been executed successfully
* - TCMU_STS_NOT_HANDLED if opcode is not handled
* - TCMU_STS_ASYNC_HANDLED if opcode is handled asynchronously
* - Non TCMU_STS_OK code indicating failure
* - TCMU_STS_PASSTHROUGH_ERR For handlers that require low level
* SCSI processing and want to setup their own sense buffers.
*
* Handlers that completely execute cmds from the handle_cmd's calling
* context must return a TCMU_STS code from handle_cmd.
*
* Async handlers that queue a command from handle_cmd and complete
* from their own async context return:
*
* - TCMU_STS_OK if the handler has queued the command.
* - TCMU_STS_NOT_HANDLED if the command is not supported.
* - TCMU_STS_NO_RESOURCE if the handler was not able to allocate
* resources to queue the command.
*
* If TCMU_STS_OK is returned from the callout the handler must call
* tcmur_cmd_complete with TCMU_STS return code to complete the command.
*/
int (*handle_cmd)(struct tcmu_device *dev, struct tcmur_cmd *cmd);
/*
* Below callouts are only executed by generic_handle_cmd.
*
* Handlers that completely execute cmds from the callout's calling
* context must return a TCMU_STS code from the callout.
*
* Async handlers that queue a command from the callout and complete
* it from their own async context return:
* - TCMU_STS_OK if the handler has queued the command.
* - TCMU_STS_NO_RESOURCE if the handler was not able to allocate
* resources to queue the command.
*
* If TCMU_STS_OK is returned from the callout the handler must call
* tcmur_cmd_complete with a TCMU_STS return code to complete the
* command.
*/
int (*read)(struct tcmu_device *dev, struct tcmur_cmd *cmd,
struct iovec *iovec, size_t iov_cnt, size_t len, off_t off);
int (*write)(struct tcmu_device *dev, struct tcmur_cmd *cmd,
struct iovec *iovec, size_t iov_cnt, size_t len, off_t off);
int (*flush)(struct tcmu_device *dev, struct tcmur_cmd *cmd);
int (*unmap)(struct tcmu_device *dev, struct tcmur_cmd *cmd,
uint64_t off, uint64_t len);
/*
* If the lock is acquired and the tag is not TCMU_INVALID_LOCK_TAG,
* it must be associated with the lock and returned by get_lock_tag on
* local and remote nodes. When unlock is successful, the tag
* associated with the lock must be deleted.
*
* Returns a TCMU_STS indicating success/failure.
*/
int (*lock)(struct tcmu_device *dev, uint16_t tag);
int (*unlock)(struct tcmu_device *dev);
/*
* Return tag set in lock call in tag buffer and a TCMU_STS
* indicating success/failure.
*/
int (*get_lock_tag)(struct tcmu_device *dev, uint16_t *tag);
/*
* Must return TCMUR_DEV_LOCK state value.
*/
int (*get_lock_state)(struct tcmu_device *dev);
/*
* internal field, don't touch this
*
* indicates to tcmu-runner whether this is an internal handler loaded
* via dlopen or an external handler registered via dbus. In the
* latter case opaque will point to a struct dbus_info.
*/
bool _is_dbus_handler;
/*
* Update the logdir called by dynamic config thread.
*/
bool (*update_logdir)(void);
};
void tcmur_cmd_complete(struct tcmu_device *dev, void *data, int rc);
/*
* Each tcmu-runner (tcmur) handler plugin must export the
* following. It usually just calls tcmur_register_handler.
*
* int handler_init(void);
*/
/*
* APIs for tcmur only
*/
int tcmur_register_handler(struct tcmur_handler *handler);
bool tcmur_unregister_handler(struct tcmur_handler *handler);
#ifdef __cplusplus
}
#endif
#endif