xref: /illumos-gate/usr/src/cmd/ndmpd/include/tlm.h (revision 86ecf0b4)
1 /*
2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * BSD 3 Clause License
8  *
9  * Copyright (c) 2007, The Storage Networking Industry Association.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 	- Redistributions of source code must retain the above copyright
15  *	  notice, this list of conditions and the following disclaimer.
16  *
17  * 	- Redistributions in binary form must reproduce the above copyright
18  *	  notice, this list of conditions and the following disclaimer in
19  *	  the documentation and/or other materials provided with the
20  *	  distribution.
21  *
22  *	- Neither the name of The Storage Networking Industry Association (SNIA)
23  *	  nor the names of its contributors may be used to endorse or promote
24  *	  products derived from this software without specific prior written
25  *	  permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 #ifndef	_TLM_H_
40 #define	_TLM_H_
41 
42 #include <sys/types.h>
43 #include <synch.h>
44 #include <limits.h>
45 #include <cstack.h>
46 #include <sys/acl.h>
47 #include <stdio.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 #include <strings.h>
51 #include <sys/stat.h>
52 #include <time.h>
53 #include <sys/queue.h>
54 
55 #define	IS_SET(f, m)	(((f) & (m)) != 0)
56 
57 #define	TLM_MAX_BACKUP_JOB_NAME	32	/* max size of a job's name */
58 #define	TLM_TAPE_BUFFERS	10	/* number of rotating tape buffers */
59 #define	TLM_LINE_SIZE		128	/* size of text messages */
60 
61 
62 #define	TLM_BACKUP_RUN		0x00000001
63 #define	TLM_RESTORE_RUN		0x00000002
64 #define	TLM_STOP		0x00000009	/* graceful stop */
65 #define	TLM_ABORT		0x99999999	/* abandon the run */
66 
67 #define	TLM_EXTRA_SPACE		64
68 #define	TLM_MAX_PATH_NAME	(PATH_MAX + TLM_EXTRA_SPACE)
69 
70 #define	ENTRYTYPELEN	14
71 #define	PERMS		4
72 #define	ID_STR_MAX	20
73 #define	APPENDED_ID_MAX	(ID_STR_MAX + 1)
74 #define	ACL_ENTRY_SIZE	(ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX)
75 #define	TLM_MAX_ACL_TXT	MAX_ACL_ENTRIES * ACL_ENTRY_SIZE
76 
77 
78 /* operation flags */
79 #define	TLM_OP_CHOOSE_ARCHIVE	0x00000001	/* look for archive bit */
80 
81 /*
82  * Synchronization flags used when launching the TLM threads.
83  */
84 #define	TLM_TAPE_READER		0x00000001
85 #define	TLM_TAPE_WRITER		0x00000002
86 #define	TLM_SOCK_READER		0x00000004
87 #define	TLM_SOCK_WRITER		0x00000008
88 #define	TLM_BUF_READER		0x00000010
89 #define	TLM_BUF_WRITER		0x00000020
90 #define	TLM_TAR_READER		0x00000040
91 #define	TLM_TAR_WRITER		0x00000080
92 
93 #define	SCSI_SERIAL_PAGE	0x80
94 #define	SCSI_DEVICE_IDENT_PAGE	0x83
95 #define	SCMD_READ_ELEMENT_STATUS	0xB8
96 
97 typedef	int (*func_t)();
98 
99 typedef struct scsi_serial {
100 	int sr_flags;
101 	char sr_num[16];
102 } scsi_serial_t;
103 
104 typedef struct fs_fhandle {
105 	int fh_fid;
106 	char *fh_fpath;
107 } fs_fhandle_t;
108 
109 typedef struct scsi_link {
110 	struct scsi_link 	*sl_next;
111 	struct scsi_link 	*sl_prev;
112 	struct scsi_adapter 	*sl_sa;
113 	unsigned int		sl_sid;
114 	unsigned int		sl_lun;
115 	unsigned int		sl_requested_max_active;
116 	unsigned int		sl_granted_max_active;
117 	unsigned int		sl_n_active;
118 	unsigned int		sl_type; /* SCSI device type */
119 } scsi_link_t;
120 
121 typedef struct scsi_adapter {
122 	struct scsi_adapter	*sa_next;
123 	char			sa_name[16];
124 	struct scsi_link	sa_link_head;
125 } scsi_adapter_t;
126 
127 typedef struct sasd_drive {
128 	char		sd_name[256];
129 	char		sd_vendor[8 + 1];
130 	char		sd_id[16 + 1];
131 	char		sd_rev[4 + 1];
132 	char		sd_serial[16 + 1];
133 	char		sd_wwn[32 + 1];
134 } sasd_drive_t;
135 
136 typedef struct scsi_sasd_drive {
137 	sasd_drive_t	ss_sd;
138 	scsi_link_t	ss_slink;
139 } scsi_sasd_drive_t;
140 
141 
142 #define	DEFAULT_SLINK_MAX_XFER	(64*1024)
143 
144 typedef struct	tlm_info {
145 	int			ti_init_done;	/* initialization done ? */
146 	int			ti_library_count; /* number of libraries */
147 	struct tlm_library	*ti_library;	/* first in chain */
148 	struct tlm_chain_link	*ti_job_stats;  /* chain of job statistics */
149 } tlm_info_t;
150 
151 typedef struct	tlm_chain_link {
152 	struct tlm_chain_link	*tc_next;	/* next blob of statistics */
153 	struct tlm_chain_link	*tc_prev;	/* previous blob in the chain */
154 	int	tc_ref_count;			/* number of routines */
155 	void	*tc_data;			/* the data blob */
156 } tlm_chain_link_t;
157 
158 typedef struct	tlm_robot {
159 	struct tlm_robot	*tr_next;
160 	struct tlm_library	*tr_library;
161 	int	tr_number;
162 } tlm_robot_t;
163 
164 typedef struct	tlm_drive {
165 	struct tlm_drive	*td_next;
166 	struct tlm_library	*td_library;
167 	char	td_job_name[TLM_MAX_BACKUP_JOB_NAME];
168 	int	td_number;		/* number of this tape drive */
169 	int	td_element;		/* the library's number for the drive */
170 	struct	scsi_link *td_slink;	/* because the drive may be connected */
171 					/* to a different SCSI card than the */
172 					/* library */
173 	short	td_scsi_id;
174 	short	td_lun;
175 	short	td_volume_number;	/* for current job */
176 					/*  an index into the tape set */
177 	int	td_fd;			/* I/O file descriptor */
178 	int	td_errno;		/* system error number */
179 	long	td_exists	: 1;
180 
181 } tlm_drive_t;
182 
183 typedef struct	tlm_slot {
184 	struct tlm_slot		*ts_next;
185 	struct tlm_library	*ts_library;
186 	int	ts_number;		/* number of this slot */
187 	int	ts_element;
188 	short	ts_use_count;		/* number of times used since loaded */
189 	long	ts_status_full		: 1;
190 } tlm_slot_t;
191 
192 typedef struct	tlm_library {
193 	struct tlm_library	*tl_next;
194 	int	tl_number;		/* number of this tape library */
195 	long	tl_capability_robot	: 1,
196 		tl_capability_door	: 1,
197 		tl_capability_lock	: 1,
198 		tl_capability_slots	: 1,
199 		tl_capability_export	: 1,
200 		tl_capability_drives	: 1,
201 		tl_capability_barcodes	: 1,
202 		tl_ghost_drives		: 1;
203 		/*
204 		 * "ghost_drives" is used to make sure that
205 		 * all drives claimed by the library really
206 		 * exist ... libraries have been known to lie.
207 		 */
208 	struct	scsi_link *tl_slink;
209 
210 	int		tl_robot_count;
211 	tlm_robot_t	*tl_robot;
212 	int		tl_drive_count;
213 	tlm_drive_t	*tl_drive;
214 	int		tl_slot_count;
215 	tlm_slot_t	*tl_slot;
216 } tlm_library_t;
217 
218 typedef struct {
219 	unsigned char d_name[8];
220 } device_info_t;
221 
222 typedef struct {
223 	unsigned char p_number[4];
224 } port_info_t;
225 
226 typedef struct {
227 #ifdef _BIG_ENDIAN
228 	uint8_t	di_peripheral_qual	: 3,
229 		di_peripheral_dev_type	: 5;
230 	uint8_t	di_page_code;
231 	uint16_t	di_page_length;
232 #else
233 	uint8_t	di_peripheral_dev_type	: 5,
234 		di_peripheral_qual	: 3;
235 	uint8_t	di_page_code;
236 	uint16_t	di_page_length;
237 #endif
238 } device_ident_header_t;
239 
240 typedef struct {
241 #ifdef _BIG_ENDIAN
242 	uint8_t	ni_proto_ident	: 4,
243 		ni_code_set	: 4;
244 
245 	uint8_t	ni_PIV		: 1,
246 				: 1,
247 		ni_asso		: 2,
248 		ni_ident_type	: 4;
249 
250 	uint8_t	ni_reserved;
251 	uint8_t	ni_ident_length;
252 #else
253 	uint8_t	ni_code_set	: 4,
254 		ni_proto_ident	: 4;
255 
256 	uint8_t	ni_ident_type	: 4,
257 		ni_asso		: 2,
258 				: 1,
259 		ni_PIV		: 1;
260 	uint8_t	ni_reserved;
261 	uint8_t	ni_ident_length;
262 #endif
263 } name_ident_t;
264 
265 typedef struct {
266 	device_ident_header_t	np_header;
267 	name_ident_t		np_node;
268 	device_info_t		np_node_info;
269 	name_ident_t		np_port;
270 	device_info_t		np_port_info;
271 	name_ident_t		np_portno;
272 	port_info_t		np_portid;
273 } device_name_page_t;
274 
275 #define	TLM_NO_ERRORS			0x00000000
276 #define	TLM_ERROR_BUSY			0x00000001
277 #define	TLM_ERROR_INTERNAL		0x00000002
278 #define	TLM_ERROR_NO_ROBOTS		0x00000003
279 #define	TLM_TIMEOUT			0x00000004
280 #define	TLM_ERROR_RANGE			0x00000005
281 #define	TLM_EMPTY			0x00000006
282 #define	TLM_DRIVE_NOT_ASSIGNED		0x00000007
283 #define	TLM_NO_TAPE_NAME		0x00000008
284 #define	TLM_NO_BACKUP_DIR		0x00000009
285 #define	TLM_NO_BACKUP_HARDWARE		0x0000000a
286 #define	TLM_NO_SOURCE_FILE		0x0000000b
287 #define	TLM_NO_FREE_TAPES		0x0000000c
288 #define	TLM_EOT				0x0000000d
289 #define	TLM_SERIAL_NOT_FOUND		0x0000000e
290 #define	TLM_SMALL_READ			0x0000000f
291 #define	TLM_NO_RESTORE_FILE		0x00000010
292 #define	TLM_EOF				0x00000011
293 #define	TLM_NO_DIRECTORY		0x00000012
294 #define	TLM_NO_MEMORY			0x00000013
295 #define	TLM_WRITE_ERROR			0x00000014
296 #define	TLM_NO_SCRATCH_SPACE		0x00000015
297 #define	TLM_INVALID			0x00000016
298 #define	TLM_MOVE			0x00000017
299 #define	TLM_SKIP			0x00000018
300 #define	TLM_OPEN_ERR			0x00000019
301 
302 
303 #define	TLM_MAX_TAPE_DRIVES	16
304 #define	TLM_NAME_SIZE		100
305 #define	TLM_MAX_TAR_IMAGE	017777777770
306 
307 #define	TLM_VOLNAME_MAX_LENGTH	255
308 #define	NAME_MAX		255
309 
310 #define	TLM_MAGIC		"ustar  "
311 #define	TLM_SNAPSHOT_PREFIX	".zfs"
312 #define	TLM_SNAPSHOT_DIR	".zfs/snapshot"
313 
314 #define	RECORDSIZE	512
315 #define	NAMSIZ	100
316 #define	TUNMLEN	32
317 #define	TGNMLEN	32
318 
319 typedef struct	tlm_tar_hdr {
320 	char	th_name[TLM_NAME_SIZE];
321 	char	th_mode[8];
322 	char	th_uid[8];
323 	char	th_gid[8];
324 	char	th_size[12];
325 	char	th_mtime[12];
326 	char	th_chksum[8];
327 	char	th_linkflag;
328 	char	th_linkname[TLM_NAME_SIZE];
329 	char	th_magic[8];
330 	char	th_uname[TUNMLEN];
331 	char	th_gname[TGNMLEN];
332 	union {
333 		struct {
334 			char	th_devmajor[8];
335 			char	th_devminor[8];
336 		} th_dev;
337 		char	th_hlink_ino[12];
338 	} th_shared;
339 } tlm_tar_hdr_t;
340 
341 
342 
343 /*
344  * The linkflag defines the type of file
345  */
346 #define	LF_OLDNORMAL	'\0'		/* Normal disk file, Unix compat */
347 #define	LF_NORMAL	'0'		/* Normal disk file */
348 #define	LF_LINK		'1'		/* Link to previously dumped file */
349 #define	LF_SYMLINK	'2'		/* Symbolic link */
350 #define	LF_CHR		'3'		/* Character special file */
351 #define	LF_BLK		'4'		/* Block special file */
352 #define	LF_DIR		'5'		/* Directory */
353 #define	LF_FIFO		'6'		/* FIFO special file */
354 #define	LF_CONTIG	'7'		/* Contiguous file */
355 /* Further link types may be defined later. */
356 
357 #define	LF_DUMPDIR	'D'
358 					/*
359 					 * This is a dir entry that contains
360 					 * the names of files that were in
361 					 * the dir at the time the dump
362 					 * was made
363 					 */
364 #define	LF_HUMONGUS	'H'
365 					/*
366 					 * Identifies the NEXT file on the tape
367 					 * as a HUGE file
368 					 */
369 #define	LF_LONGLINK	'K'
370 					/*
371 					 * Identifies the NEXT file on the tape
372 					 * as having a long linkname
373 					 */
374 #define	LF_LONGNAME	'L'
375 					/*
376 					 * Identifies the NEXT file on the tape
377 					 * as having a long name.
378 					 */
379 #define	LF_MULTIVOL	'M'
380 					/*
381 					 * This is the continuation
382 					 * of a file that began on another
383 					 * volume
384 					 */
385 
386 #define	LF_VOLHDR	'V'		/* This file is a tape/volume header */
387 					/* Ignore it on extraction */
388 
389 #define	LF_ACL		'A'		/* Access Control List */
390 
391 #define	LF_XATTR	'E'		/* Extended attribute */
392 
393 #define	KILOBYTE	1024
394 
395 
396 /*
397  * ACL support structure
398  */
399 typedef struct sec_attr {
400 	char attr_type;
401 	char attr_len[7];
402 	char attr_info[TLM_MAX_ACL_TXT];
403 } sec_attr_t;
404 
405 typedef struct	tlm_acls {
406 	int	acl_checkpointed	: 1,	/* are checkpoints active ? */
407 		acl_clear_archive	: 1,	/* clear archive bit ? */
408 		acl_overwrite		: 1,	/* always overwrite ? */
409 		acl_update		: 1,	/* only update ? */
410 		acl_non_trivial		: 1;	/* real ACLs? */
411 		/*
412 		 * The following fields are here to allow
413 		 * the backup reader to open a file one time
414 		 * and keep the information for ACL, ATTRs,
415 		 * and reading the file.
416 		 */
417 	sec_attr_t acl_info;
418 
419 	char acl_root_dir[TLM_VOLNAME_MAX_LENGTH]; /* name of root filesystem */
420 	fs_fhandle_t acl_dir_fh;		/* parent dir's info */
421 	fs_fhandle_t acl_fil_fh;		/* file's info */
422 	struct stat64 acl_attr;			/* file system attributes */
423 } tlm_acls_t;
424 
425 
426 /*
427  * Tape manager's data archiving ops vector
428  *
429  * This vector represents the granular operations for
430  * performing backup/restore. Each backend should provide
431  * such a vector interface in order to be invoked by NDMP
432  * server.
433  * The reserved callbacks are kept for different backup
434  * types which are volume-based rather than file-based
435  * e.g. zfs send.
436  */
437 typedef struct tm_ops {
438 	char *tm_name;
439 	int (*tm_putfile)();
440 	int (*tm_putdir)();
441 	int (*tm_putvol)();	/* Reserved */
442 	int (*tm_getfile)();
443 	int (*tm_getdir)();
444 	int (*tm_getvol)();	/* Reserved */
445 } tm_ops_t;
446 
447 /* The checksum field is filled with this while the checksum is computed. */
448 #define	CHKBLANKS	"        "	/* 8 blanks, no null */
449 
450 #define	LONGNAME_PREFIX	"././_LoNg_NaMe_"
451 extern void ndmp_log(ulong_t, char *, char *, ...);
452 char ndmp_log_info[256];
453 #define	NDMP_LOG(p, ...) { \
454 				(void) snprintf(ndmp_log_info, \
455 				    sizeof (ndmp_log_info), \
456 				    "[%d][%s:%d]", \
457 				    (int)pthread_self(), __func__, __LINE__); \
458 				ndmp_log(p, ndmp_log_info, __VA_ARGS__); \
459 			}
460 extern void *ndmp_malloc(size_t size);
461 
462 /*
463  * ZFS metadata plug-in module structures
464  */
465 #define	ZFS_MAX_PROPS		100
466 #define	ZFS_META_MAGIC		"ZFSMETA"
467 
468 typedef struct ndmp_metadata_property {
469 	char mp_name[NAME_MAX];
470 	char mp_value[NAME_MAX];
471 	char mp_source[NAME_MAX];
472 } ndmp_metadata_property_t;
473 
474 typedef struct ndmp_metadata_header {
475 	char nh_plname[100];
476 	uint_t nh_plversion;
477 	char nh_magic[10];
478 	void *nh_handle;
479 	int nh_count;
480 	char nh_dataset[NAME_MAX];
481 	ndmp_metadata_property_t nh_property[1];
482 } ndmp_metadata_header_t;
483 
484 /*
485  * Node in struct hardlink_q
486  *
487  * inode: the inode of the hardlink
488  * path: the name of the hardlink, used during restore
489  * offset: tape offset of the data records for the hardlink, used during backup
490  * is_tmp: indicate whether the file was created temporarily for restoring
491  * other links during a non-DAR partial restore
492  */
493 struct hardlink_node {
494 	unsigned long inode;
495 	char *path;
496 	unsigned long long offset;
497 	int is_tmp;
498 	SLIST_ENTRY(hardlink_node) next_hardlink;
499 };
500 
501 /*
502  * Hardlinks that have been backed up or restored.
503  *
504  * During backup, each node represents a file whose
505  *   (1) inode has multiple links
506  *   (2) data has been backed up
507  *
508  * When we run into a file with multiple links during backup,
509  * we first check the list to see whether a file with the same inode
510  * has been backed up.  If yes, we backup an empty record, while
511  * making the file history of this file contain the data offset
512  * of the offset of the file that has been backed up.  If no,
513  * we backup this file, and add an entry to the list.
514  *
515  * During restore, each node represents an LF_LINK type record whose
516  * data has been restored (v.s. a hard link has been created).
517  *
518  * During restore, when we run into a record of LF_LINK type, we
519  * first check the queue to see whether a file with the same inode
520  * has been restored.  If yes, we create a hardlink to it.
521  * If no, we restore the data, and add an entry to the list.
522  */
523 struct hardlink_q {
524 	struct hardlink_node *slh_first;
525 };
526 
527 /* Utility functions from handling hardlink */
528 extern struct hardlink_q *hardlink_q_init();
529 extern void hardlink_q_cleanup(struct hardlink_q *qhead);
530 extern int hardlink_q_get(struct hardlink_q *qhead, unsigned long inode,
531     unsigned long long *offset, char **path);
532 extern int hardlink_q_add(struct hardlink_q *qhead, unsigned long inode,
533     unsigned long long offset, char *path, int is_tmp);
534 
535 #endif	/* !_TLM_H_ */
536