1 /*
2  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 /*
6  * BSD 3 Clause License
7  *
8  * Copyright (c) 2007, The Storage Networking Industry Association.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 	- Redistributions of source code must retain the above copyright
14  *	  notice, this list of conditions and the following disclaimer.
15  *
16  * 	- Redistributions in binary form must reproduce the above copyright
17  *	  notice, this list of conditions and the following disclaimer in
18  *	  the documentation and/or other materials provided with the
19  *	  distribution.
20  *
21  *	- Neither the name of The Storage Networking Industry Association (SNIA)
22  *	  nor the names of its contributors may be used to endorse or promote
23  *	  products derived from this software without specific prior written
24  *	  permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 /* Copyright (c) 2007, The Storage Networking Industry Association. */
39 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
40 /* Copyright 2014 Nexenta Systems, Inc.  All rights reserved. */
41 #ifndef	_LIBNDMP_H
42 #define	_LIBNDMP_H
43 
44 #include <rpc/types.h>
45 #include <libscf.h>
46 #include <libnvpair.h>
47 
48 #ifdef	__cplusplus
49 extern "C" {
50 #endif
51 
52 /* NDMP supported versions */
53 #define	NDMP_V2		2
54 #define	NDMP_V3		3
55 #define	NDMP_V4		4
56 
57 /* Device type */
58 #define	NDMP_SINQ_SEQ_ACCESS_DEVICE	0x01
59 #define	NDMP_SINQ_TAPE_ROBOT		0x08
60 
61 extern int ndmp_errno;
62 
63 /* NDMP plugin module API */
64 #define	NDMP_PLUGIN_VERSION	1
65 
66 typedef struct ndmp_context {
67 	char *nc_plname;
68 	uint_t nc_plversion;
69 	void *nc_pldata;	/* data private to the plugin */
70 	void *nc_cmds;
71 	void *nc_params;
72 	void *nc_ddata;		/* data private to the daemon */
73 } ndmp_context_t;
74 
75 typedef struct ndmp_plugin {
76 	const char *np_plid;	/* plugin identifier */
77 	uint_t np_plversion;	/* plugin version */
78 	void *np_pldata;	/* for private use by the plugin */
79 
80 	/* Plugin entry points */
81 	int (*np_pre_backup)(struct ndmp_plugin *, ndmp_context_t *,
82 		const char *);
83 	int (*np_post_backup)(struct ndmp_plugin *, ndmp_context_t *,
84 		int);
85 	int (*np_pre_restore)(struct ndmp_plugin *, ndmp_context_t *,
86 		const char *, const char *);
87 	int (*np_post_restore)(struct ndmp_plugin *, ndmp_context_t *,
88 		int);
89 } ndmp_plugin_t;
90 
91 typedef enum ndmp_log_dma_type {
92 	NDMP_LOGD_NORMAL = 0,
93 	NDMP_LOGD_DEBUG = 1,
94 	NDMP_LOGD_ERROR = 2,
95 	NDMP_LOGD_WARNING = 3
96 } ndmp_log_dma_type_t;
97 
98 typedef enum {
99 	NDMP_BUTYPE_TAR = 0,
100 	NDMP_BUTYPE_DUMP,
101 	NDMP_BUTYPE_ZFS
102 } ndmpd_backup_type_t;
103 
104 extern ndmpd_backup_type_t ndmp_get_backup_type(ndmp_context_t *);
105 
106 /* libndmp error codes */
107 #define	ENDMP_BASE	2000
108 enum {
109 	ENDMP_DOOR_SRV_TIMEOUT = ENDMP_BASE,
110 	ENDMP_INVALID_ARG,
111 	ENDMP_DOOR_SRV_OPERATION,
112 	ENDMP_DOOR_OPEN,
113 	ENDMP_MEM_ALLOC,
114 	ENDMP_DOOR_ENCODE_START,
115 	ENDMP_DOOR_ENCODE_FINISH,
116 	ENDMP_DOOR_DECODE_FINISH,
117 	ENDMP_SMF_PERM,
118 	ENDMP_SMF_INTERNAL,
119 	ENDMP_SMF_PROP,
120 	ENDMP_SMF_PROP_GRP
121 };
122 
123 /* Tape device open mode */
124 typedef enum ndmp_tp_open_mode {
125 	NDMP_TP_READ_MODE,
126 	NDMP_TP_WRITE_MODE,
127 	NDMP_TP_RAW_MODE,
128 	NDMP_TP_RAW1_MODE = 0x7fffffff,
129 	NDMP_TP_RAW2_MODE = NDMP_TP_RAW_MODE
130 } ndmp_tp_open_mode_t;
131 
132 /* Mover state */
133 typedef enum ndmp_mv_state {
134 	NDMP_MV_STATE_IDLE,
135 	NDMP_MV_STATE_LISTEN,
136 	NDMP_MV_STATE_ACTIVE,
137 	NDMP_MV_STATE_PAUSED,
138 	NDMP_MV_STATE_HALTED
139 } ndmp_mv_state_t;
140 
141 /* Mover mode */
142 typedef enum ndmp_mv_mode {
143 	NDMP_MV_MODE_READ,
144 	NDMP_MV_MODE_WRITE,
145 	NDMP_MV_MODE_NOACTION
146 } ndmp_mv_mode_t;
147 
148 /* Mover pause reson */
149 typedef enum ndmp_mv_pause_reason {
150 	NDMP_MV_PAUSE_NA,
151 	NDMP_MV_PAUSE_EOM,
152 	NDMP_MV_PAUSE_EOF,
153 	NDMP_MV_PAUSE_SEEK,
154 	NDMP_MV_PAUSE_MEDIA_ERROR,
155 	NDMP_MV_PAUSE_EOW
156 } ndmp_mv_pause_reason_t;
157 
158 /* Mover halt reason */
159 typedef enum ndmp_mv_halt_reason {
160 	NDMP_MV_HALT_NA,
161 	NDMP_MV_HALT_CONNECT_CLOSED,
162 	NDMP_MV_HALT_ABORTED,
163 	NDMP_MV_HALT_INTERNAL_ERROR,
164 	NDMP_MV_HALT_CONNECT_ERROR,
165 	NDMP_MV_HALT_MEDIA_ERROR
166 } ndmp_mv_halt_reason_t;
167 
168 /* Address type */
169 typedef enum ndmp_ad_type {
170 	NDMP_AD_LOCAL,
171 	NDMP_AD_TCP,
172 	NDMP_AD_FC,
173 	NDMP_AD_IPC
174 } ndmp_ad_type_t;
175 
176 /* NDMP data operation */
177 typedef enum ndmp_dt_operation {
178 	NDMP_DT_OP_NOACTION,
179 	NDMP_DT_OP_BACKUP,
180 	NDMP_DT_OP_RECOVER,
181 	NDMP_DT_OP_RECOVER_FILEHIST
182 } ndmp_dt_operation_t;
183 
184 /* NDMP data state */
185 typedef enum ndmp_dt_state {
186 	NDMP_DT_STATE_IDLE,
187 	NDMP_DT_STATE_ACTIVE,
188 	NDMP_DT_STATE_HALTED,
189 	NDMP_DT_STATE_LISTEN,
190 	NDMP_DT_STATE_CONNECTED
191 } ndmp_dt_state_t;
192 
193 /* NDMP data halt reason */
194 typedef enum ndmp_dt_halt_reason {
195 	NDMP_DT_HALT_NA,
196 	NDMP_DT_HALT_SUCCESSFUL,
197 	NDMP_DT_HALT_ABORTED,
198 	NDMP_DT_HALT_INTERNAL_ERROR,
199 	NDMP_DT_HALT_CONNECT_ERROR
200 } ndmp_dt_halt_reason_t;
201 
202 /* Device information structure */
203 typedef struct ndmp_devinfo {
204 	uint_t nd_dev_type;	/* SCSI device type */
205 	char *nd_name;		/* Device name */
206 	uint_t nd_lun;		/* Lun number */
207 	uint_t nd_sid;		/* Scsi id */
208 	char *nd_vendor;	/* Vendor name */
209 	char *nd_product;	/* Product name */
210 	char *nd_revision;	/* Revision */
211 	char *nd_serial;	/* Serial */
212 	char *nd_wwn;		/* World wide name */
213 } ndmp_devinfo_t;
214 
215 /* Scsi device info sturcture */
216 typedef struct ndmp_scsi {
217 	int ns_scsi_open;		/* Scsi device open */
218 					/* -1 if not open */
219 	char *ns_adapter_name;		/* Scsi adapter name */
220 	int ns_valid_target_set;	/* Scsi valid target */
221 	/* scsi_id and lun are set only if valid_target_set is set */
222 	int ns_scsi_id;			/* Scsi id */
223 	int ns_lun;			/* Scsi lun */
224 } ndmp_scsi_t;
225 
226 typedef struct ndmp_tape {
227 	int nt_fd;			/* Tape device file descriptor */
228 	/* The data below is set only if "fd" is not -1 */
229 	ulong_t nt_rec_count;		/* Number of records written */
230 	ndmp_tp_open_mode_t nt_mode;	/* Tape device open mode */
231 	char *nt_dev_name;		/* Device name */
232 	char *nt_adapter_name;		/* Adapter name */
233 	int nt_sid;			/* Scsi id	*/
234 	int nt_lun;			/* Lun number	*/
235 } ndmp_tape_t;
236 
237 /* NDMP mover info structure */
238 typedef struct ndmp_mover {
239 	ndmp_mv_state_t nm_state;		/* Current state */
240 	ndmp_mv_mode_t nm_mode;			/* Current mode */
241 	ndmp_mv_pause_reason_t nm_pause_reason;	/* Current reason */
242 	ndmp_mv_halt_reason_t nm_halt_reason;	/* Current reason */
243 	ulong_t	nm_rec_size;			/* Tape I/O record size */
244 	ulong_t	nm_rec_num;			/* Current record num */
245 	u_longlong_t nm_mov_pos;		/* Current data stream pos */
246 	u_longlong_t nm_window_offset;		/* Valid data window begin */
247 	u_longlong_t nm_window_length;		/* Valid data window length */
248 	int nm_sock;				/* Data conn socket */
249 
250 	/* Filled in V3 and V4 only */
251 	int nm_listen_sock;			/* Data conn listen socket */
252 	ndmp_ad_type_t nm_addr_type;		/* Current address type */
253 	char *nm_tcp_addr;			/* Only if addr_type is tcp */
254 } ndmp_mover_t;
255 
256 typedef struct ndmp_dt_name {
257 	char *nn_name;
258 	char *nn_dest;
259 } ndmp_dt_name_t;
260 
261 /* NDMP name/value pair structure */
262 typedef struct ndmp_dt_pval {
263 	char *np_name;
264 	char *np_value;
265 } ndmp_dt_pval_t;
266 
267 typedef struct ndmp_dt_name_v3 {
268 	char *nn3_opath;
269 	char *nn3_dpath;
270 	u_longlong_t nn3_node;
271 	u_longlong_t nn3_fh_info;
272 } ndmp_dt_name_v3_t;
273 
274 typedef struct ndmp_dt_v3 {
275 	int dv3_listen_sock;
276 	u_longlong_t dv3_bytes_processed;
277 	ndmp_dt_name_v3_t *dv3_nlist;		/* V3 recover file list */
278 } ndmp_dt_v3_t;
279 
280 /* NDMP data structure */
281 typedef struct ndmp_data {
282 	ndmp_dt_operation_t nd_oper;		/* Current operation */
283 	ndmp_dt_state_t nd_state;		/* Current state */
284 	ndmp_dt_halt_reason_t nd_halt_reason;	/* Current reason */
285 	int nd_sock;				/* Listen and data socket */
286 	ndmp_ad_type_t nd_addr_type;		/* Current address type */
287 	char *nd_tcp_addr;			/* Only if addr_type is tcp */
288 	int nd_abort;				/* Abort operation flag */
289 						/* 0 = No, otherwise Yes */
290 	u_longlong_t nd_read_offset;		/* Data read seek offset */
291 	u_longlong_t nd_read_length;		/* Data read length */
292 	u_longlong_t nd_total_size;		/* Backup data size */
293 	ulong_t nd_env_len;			/* Environment length */
294 	ndmp_dt_pval_t *nd_env;			/* Environment from backup */
295 						/* or recover request */
296 	ulong_t nld_nlist_len;			/* Recover file list length */
297 	union {
298 		/* Filled in V2 */
299 		ndmp_dt_name_t *nld_nlist;	/* Recover file list */
300 		/* Filled in V3 */
301 		ndmp_dt_v3_t nld_dt_v3;		/* V3 data */
302 	} nd_nlist;
303 } ndmp_data_t;
304 
305 /* NDMP session information  */
306 typedef struct ndmp_session_info {
307 	int nsi_sid;		/* Session id   */
308 	int nsi_pver;		/* NDMP protocol version */
309 	int nsi_auth;		/* Authorized ? 0="no", else "yes" */
310 	int nsi_eof;		/* Connection EOF flag */
311 				/* 0="no", else "yes" */
312 	char *nsi_cl_addr;	/* Client address */
313 	ndmp_scsi_t nsi_scsi;	/* Scsi device information */
314 	ndmp_tape_t nsi_tape;	/* Tape device information */
315 	ndmp_mover_t nsi_mover;	/* Mover information */
316 	ndmp_data_t nsi_data;	/* Data information */
317 } ndmp_session_info_t;
318 
319 /* Stats data */
320 typedef struct ndmp_stat {
321 	int ns_trun;		/* Number of worker threads running */
322 	int ns_twait;		/* Number of blocked worker threads */
323 	int ns_nbk;		/* Number of backups operations running */
324 	int ns_nrs;		/* Number of restores operations running */
325 	int ns_rfile;		/* Number of files being read */
326 	int ns_wfile;		/* Number of files being written */
327 	uint64_t ns_rdisk;	/* Number of disk blocks being read */
328 	uint64_t ns_wdisk;	/* Number of disk blocks being written */
329 	uint64_t ns_rtape;	/* Number of tape blocks being read */
330 	uint64_t ns_wtape;	/* Number of tape blocks being written */
331 } ndmp_stat_t;
332 
333 /* Common encode/decode functions used by door clients/servers.  */
334 typedef struct ndmp_door_ctx {
335 	char *ptr;
336 	char *start_ptr;
337 	char *end_ptr;
338 	int status;
339 } ndmp_door_ctx_t;
340 
341 extern int ndmp_get_devinfo(ndmp_devinfo_t **, size_t *);
342 extern void ndmp_get_devinfo_free(ndmp_devinfo_t *, size_t);
343 extern int ndmp_get_dbglevel(void);
344 extern int ndmp_get_session_info(ndmp_session_info_t **, size_t *);
345 extern void ndmp_get_session_info_free(ndmp_session_info_t *, size_t);
346 extern int ndmp_get_stats(ndmp_stat_t *);
347 extern int ndmp_terminate_session(int);
348 extern int ndmp_set_dbglevel(int);
349 extern const char *ndmp_strerror(int);
350 extern int ndmp_door_status(void);
351 extern int ndmp_get_prop(const char *, char **);
352 extern int ndmp_set_prop(const char *, const char *);
353 extern int ndmp_service_refresh(void);
354 extern char *ndmp_base64_encode(const char *);
355 extern char *ndmp_base64_decode(const char *);
356 extern ndmp_door_ctx_t *ndmp_door_decode_start(char *, int);
357 extern int ndmp_door_decode_finish(ndmp_door_ctx_t *);
358 extern ndmp_door_ctx_t *ndmp_door_encode_start(char *, int);
359 extern int ndmp_door_encode_finish(ndmp_door_ctx_t *, unsigned int *);
360 extern int32_t ndmp_door_get_int32(ndmp_door_ctx_t *);
361 extern uint32_t ndmp_door_get_uint32(ndmp_door_ctx_t *);
362 extern char *ndmp_door_get_string(ndmp_door_ctx_t *);
363 extern void ndmp_door_put_int32(ndmp_door_ctx_t *, int32_t);
364 extern void ndmp_door_put_uint32(ndmp_door_ctx_t *, uint32_t);
365 extern void ndmp_door_put_string(ndmp_door_ctx_t *, char *);
366 extern void ndmp_door_free_string(char *);
367 extern int64_t ndmp_door_get_int64(ndmp_door_ctx_t *);
368 extern uint64_t ndmp_door_get_uint64(ndmp_door_ctx_t *);
369 extern void ndmp_door_put_uint64(ndmp_door_ctx_t *, uint64_t);
370 extern void ndmp_door_put_short(ndmp_door_ctx_t *, short);
371 extern short ndmp_door_get_short(ndmp_door_ctx_t *);
372 extern void ndmp_door_put_ushort(ndmp_door_ctx_t *, unsigned short);
373 extern unsigned short ndmp_door_get_ushort(ndmp_door_ctx_t *);
374 extern void ndmp_door_put_buf(ndmp_door_ctx_t *, unsigned char *, int);
375 extern int ndmp_door_get_buf(ndmp_door_ctx_t *, unsigned char *, int);
376 
377 extern int ndmp_include_zfs(ndmp_context_t *, const char *);
378 extern int ndmp_iter_zfs(ndmp_context_t *, int (*)(nvlist_t *, void *), void *);
379 extern uint_t ndmp_context_get_version(ndmp_context_t *);
380 extern void ndmp_context_set_specific(ndmp_context_t *, void *);
381 extern void *ndmp_context_get_specific(ndmp_context_t *);
382 void ndmp_log_dma(ndmp_context_t *, ndmp_log_dma_type_t, const char *, ...);
383 
384 #ifdef	__cplusplus
385 }
386 #endif
387 
388 #endif /* _LIBNDMP_H */
389