tlm.h revision 7917:5c4442486198
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	SCMD_READ_ELEMENT_STATUS		0xB8
94
95typedef	int (*func_t)();
96
97typedef struct fs_fhandle {
98	int fh_fid;
99	char *fh_fpath;
100} fs_fhandle_t;
101
102typedef struct scsi_link {
103	struct scsi_link 	*sl_next;
104	struct scsi_link 	*sl_prev;
105	struct scsi_adapter 	*sl_sa;
106	unsigned int		sl_sid;
107	unsigned int		sl_lun;
108	unsigned int		sl_requested_max_active;
109	unsigned int		sl_granted_max_active;
110	unsigned int		sl_n_active;
111	unsigned int		sl_type; /* SCSI device type */
112} scsi_link_t;
113
114typedef struct scsi_adapter {
115	struct scsi_adapter	*sa_next;
116	char			sa_name[16];
117	struct scsi_link	sa_link_head;
118} scsi_adapter_t;
119
120typedef struct sasd_drive {
121	char		sd_name[256];
122	char		sd_vendor[8 + 1];
123	char		sd_id[16 + 1];
124	char		sd_rev[4 + 1];
125} sasd_drive_t;
126
127typedef struct scsi_sasd_drive {
128	sasd_drive_t	ss_sd;
129	scsi_link_t	ss_slink;
130} scsi_sasd_drive_t;
131
132
133#define	DEFAULT_SLINK_MAX_XFER	(64*1024)
134
135typedef struct	tlm_info {
136	int			ti_init_done;	/* initialization done ? */
137	int			ti_library_count; /* number of libraries */
138	struct tlm_library	*ti_library;	/* first in chain */
139	struct tlm_chain_link	*ti_job_stats;  /* chain of job statistics */
140} tlm_info_t;
141
142typedef struct	tlm_chain_link {
143	struct tlm_chain_link	*tc_next;	/* next blob of statistics */
144	struct tlm_chain_link	*tc_prev;	/* previous blob in the chain */
145	int	tc_ref_count;			/* number of routines */
146	void	*tc_data;			/* the data blob */
147} tlm_chain_link_t;
148
149typedef struct	tlm_robot {
150	struct tlm_robot	*tr_next;
151	struct tlm_library	*tr_library;
152	int	tr_number;
153} tlm_robot_t;
154
155typedef struct	tlm_drive {
156	struct tlm_drive	*td_next;
157	struct tlm_library	*td_library;
158	char	td_job_name[TLM_MAX_BACKUP_JOB_NAME];
159	int	td_number;		/* number of this tape drive */
160	int	td_element;		/* the library's number for the drive */
161	struct	scsi_link *td_slink;	/* because the drive may be connected */
162					/* to a different SCSI card than the */
163					/* library */
164	short	td_scsi_id;
165	short	td_lun;
166	short	td_volume_number;	/* for current job */
167					/*  an index into the tape set */
168	int	td_fd;			/* I/O file descriptor */
169	int	td_errno;		/* system error number */
170	long	td_exists	: 1;
171
172} tlm_drive_t;
173
174typedef struct	tlm_slot {
175	struct tlm_slot		*ts_next;
176	struct tlm_library	*ts_library;
177	int	ts_number;		/* number of this slot */
178	int	ts_element;
179	short	ts_use_count;		/* number of times used since loaded */
180	long	ts_status_full		: 1;
181} tlm_slot_t;
182
183typedef struct	tlm_library {
184	struct tlm_library	*tl_next;
185	int	tl_number;		/* number of this tape library */
186	long	tl_capability_robot	: 1,
187		tl_capability_door	: 1,
188		tl_capability_lock	: 1,
189		tl_capability_slots	: 1,
190		tl_capability_export	: 1,
191		tl_capability_drives	: 1,
192		tl_capability_barcodes	: 1,
193		tl_ghost_drives		: 1;
194		/*
195		 * "ghost_drives" is used to make sure that
196		 * all drives claimed by the library really
197		 * exist ... libraries have been known to lie.
198		 */
199	struct	scsi_link *tl_slink;
200
201	int		tl_robot_count;
202	tlm_robot_t	*tl_robot;
203	int		tl_drive_count;
204	tlm_drive_t	*tl_drive;
205	int		tl_slot_count;
206	tlm_slot_t	*tl_slot;
207} tlm_library_t;
208
209#define	TLM_NO_ERRORS			0x00000000
210#define	TLM_ERROR_BUSY			0x00000001
211#define	TLM_ERROR_INTERNAL		0x00000002
212#define	TLM_ERROR_NO_ROBOTS		0x00000003
213#define	TLM_TIMEOUT			0x00000004
214#define	TLM_ERROR_RANGE			0x00000005
215#define	TLM_EMPTY			0x00000006
216#define	TLM_DRIVE_NOT_ASSIGNED		0x00000007
217#define	TLM_NO_TAPE_NAME		0x00000008
218#define	TLM_NO_BACKUP_DIR		0x00000009
219#define	TLM_NO_BACKUP_HARDWARE		0x0000000a
220#define	TLM_NO_SOURCE_FILE		0x0000000b
221#define	TLM_NO_FREE_TAPES		0x0000000c
222#define	TLM_EOT				0x0000000d
223#define	TLM_SERIAL_NOT_FOUND		0x0000000e
224#define	TLM_SMALL_READ			0x0000000f
225#define	TLM_NO_RESTORE_FILE		0x00000010
226#define	TLM_EOF				0x00000011
227#define	TLM_NO_DIRECTORY		0x00000012
228#define	TLM_NO_MEMORY			0x00000013
229#define	TLM_WRITE_ERROR			0x00000014
230#define	TLM_NO_SCRATCH_SPACE		0x00000015
231#define	TLM_INVALID			0x00000016
232#define	TLM_MOVE			0x00000017
233#define	TLM_SKIP			0x00000018
234#define	TLM_OPEN_ERR			0x00000019
235
236
237#define	TLM_MAX_TAPE_DRIVES	16
238#define	TLM_NAME_SIZE		100
239#define	TLM_MAX_TAR_IMAGE	017777777770
240
241#define	TLM_VOLNAME_MAX_LENGTH	255
242#define	NAME_MAX		255
243
244#define	TLM_MAGIC		"ustar  "
245#define	TLM_SNAPSHOT_PREFIX	".zfs"
246#define	TLM_SNAPSHOT_DIR	".zfs/snapshot"
247
248#define	RECORDSIZE	512
249#define	NAMSIZ	100
250#define	TUNMLEN	32
251#define	TGNMLEN	32
252
253typedef struct	tlm_tar_hdr {
254	char	th_name[TLM_NAME_SIZE];
255	char	th_mode[8];
256	char	th_uid[8];
257	char	th_gid[8];
258	char	th_size[12];
259	char	th_mtime[12];
260	char	th_chksum[8];
261	char	th_linkflag;
262	char	th_linkname[TLM_NAME_SIZE];
263	char	th_magic[8];
264	char	th_uname[TUNMLEN];
265	char	th_gname[TGNMLEN];
266	union {
267		struct {
268			char	th_devmajor[8];
269			char	th_devminor[8];
270		} th_dev;
271		char	th_hlink_ino[12];
272	} th_shared;
273} tlm_tar_hdr_t;
274
275
276
277/*
278 * The linkflag defines the type of file
279 */
280#define	LF_OLDNORMAL	'\0'		/* Normal disk file, Unix compat */
281#define	LF_NORMAL	'0'		/* Normal disk file */
282#define	LF_LINK		'1'		/* Link to previously dumped file */
283#define	LF_SYMLINK	'2'		/* Symbolic link */
284#define	LF_CHR		'3'		/* Character special file */
285#define	LF_BLK		'4'		/* Block special file */
286#define	LF_DIR		'5'		/* Directory */
287#define	LF_FIFO		'6'		/* FIFO special file */
288#define	LF_CONTIG	'7'		/* Contiguous file */
289/* Further link types may be defined later. */
290
291#define	LF_DUMPDIR	'D'
292					/*
293					 * This is a dir entry that contains
294					 * the names of files that were in
295					 * the dir at the time the dump
296					 * was made
297					 */
298#define	LF_HUMONGUS	'H'
299					/*
300					 * Identifies the NEXT file on the tape
301					 * as a HUGE file
302					 */
303#define	LF_LONGLINK	'K'
304					/*
305					 * Identifies the NEXT file on the tape
306					 * as having a long linkname
307					 */
308#define	LF_LONGNAME	'L'
309					/*
310					 * Identifies the NEXT file on the tape
311					 * as having a long name.
312					 */
313#define	LF_MULTIVOL	'M'
314					/*
315					 * This is the continuation
316					 * of a file that began on another
317					 * volume
318					 */
319
320#define	LF_VOLHDR	'V'		/* This file is a tape/volume header */
321					/* Ignore it on extraction */
322
323#define	LF_ACL		'A'		/* Access Control List */
324
325#define	LF_XATTR	'E'		/* Extended attribute */
326
327#define	KILOBYTE	1024
328
329
330/*
331 * ACL support structure
332 */
333typedef struct sec_attr {
334	char attr_type;
335	char attr_len[7];
336	char attr_info[TLM_MAX_ACL_TXT];
337} sec_attr_t;
338
339typedef struct	tlm_acls {
340	int	acl_checkpointed	: 1,	/* are checkpoints active ? */
341		acl_clear_archive	: 1,	/* clear archive bit ? */
342		acl_overwrite		: 1,	/* always overwrite ? */
343		acl_update		: 1,	/* only update ? */
344		acl_non_trivial		: 1;	/* real ACLs? */
345		/*
346		 * The following fields are here to allow
347		 * the backup reader to open a file one time
348		 * and keep the information for ACL, ATTRs,
349		 * and reading the file.
350		 */
351	sec_attr_t acl_info;
352
353	char acl_root_dir[TLM_VOLNAME_MAX_LENGTH]; /* name of root filesystem */
354	fs_fhandle_t acl_dir_fh;		/* parent dir's info */
355	fs_fhandle_t acl_fil_fh;		/* file's info */
356	struct stat64 acl_attr;			/* file system attributes */
357} tlm_acls_t;
358
359
360/*
361 * Tape manager's data archiving ops vector
362 *
363 * This vector represents the granular operations for
364 * performing backup/restore. Each backend should provide
365 * such a vector interface in order to be invoked by NDMP
366 * server.
367 * The reserved callbacks are kept for different backup
368 * types which are volume-based rather than file-based
369 * e.g. zfs send.
370 */
371typedef struct tm_ops {
372	char *tm_name;
373	int (*tm_putfile)();
374	int (*tm_putdir)();
375	int (*tm_putvol)();	/* Reserved */
376	int (*tm_getfile)();
377	int (*tm_getdir)();
378	int (*tm_getvol)();	/* Reserved */
379} tm_ops_t;
380
381/* The checksum field is filled with this while the checksum is computed. */
382#define	CHKBLANKS	"        "	/* 8 blanks, no null */
383
384#define	LONGNAME_PREFIX	"././_LoNg_NaMe_"
385extern void ndmp_log(ulong_t, char *, char *, ...);
386char ndmp_log_info[256];
387#define	NDMP_LOG(p, ...) { \
388				(void) snprintf(ndmp_log_info, \
389				    sizeof (ndmp_log_info), \
390				    "[%d][%s:%d]", \
391				    (int)pthread_self(), __func__, __LINE__); \
392				ndmp_log(p, ndmp_log_info, __VA_ARGS__); \
393			}
394extern void *ndmp_malloc(size_t size);
395
396/*
397 * ZFS metadata plug-in module structures
398 */
399#define	ZFS_MAX_PROPS		100
400#define	ZFS_META_MAGIC		"ZFSMETA"
401
402typedef struct ndmp_metadata_property {
403	char mp_name[NAME_MAX];
404	char mp_value[NAME_MAX];
405	char mp_source[NAME_MAX];
406} ndmp_metadata_property_t;
407
408typedef struct ndmp_metadata_header {
409	char nh_plname[100];
410	uint_t nh_plversion;
411	char nh_magic[10];
412	void *nh_handle;
413	int nh_count;
414	char nh_dataset[NAME_MAX];
415	ndmp_metadata_property_t nh_property[1];
416} ndmp_metadata_header_t;
417
418/*
419 * Node in struct hardlink_q
420 *
421 * inode: the inode of the hardlink
422 * path: the name of the hardlink, used during restore
423 * offset: tape offset of the data records for the hardlink, used during backup
424 * is_tmp: indicate whether the file was created temporarily for restoring
425 * other links during a non-DAR partial restore
426 */
427struct hardlink_node {
428	unsigned long inode;
429	char *path;
430	unsigned long long offset;
431	int is_tmp;
432	SLIST_ENTRY(hardlink_node) next_hardlink;
433};
434
435/*
436 * Hardlinks that have been backed up or restored.
437 *
438 * During backup, each node represents a file whose
439 *   (1) inode has multiple links
440 *   (2) data has been backed up
441 *
442 * When we run into a file with multiple links during backup,
443 * we first check the list to see whether a file with the same inode
444 * has been backed up.  If yes, we backup an empty record, while
445 * making the file history of this file contain the data offset
446 * of the offset of the file that has been backed up.  If no,
447 * we backup this file, and add an entry to the list.
448 *
449 * During restore, each node represents an LF_LINK type record whose
450 * data has been restored (v.s. a hard link has been created).
451 *
452 * During restore, when we run into a record of LF_LINK type, we
453 * first check the queue to see whether a file with the same inode
454 * has been restored.  If yes, we create a hardlink to it.
455 * If no, we restore the data, and add an entry to the list.
456 */
457struct hardlink_q {
458	struct hardlink_node *slh_first;
459};
460
461/* Utility functions from handling hardlink */
462extern struct hardlink_q *hardlink_q_init();
463extern void hardlink_q_cleanup(struct hardlink_q *qhead);
464extern int hardlink_q_get(struct hardlink_q *qhead, unsigned long inode,
465    unsigned long long *offset, char **path);
466extern int hardlink_q_add(struct hardlink_q *qhead, unsigned long inode,
467    unsigned long long offset, char *path, int is_tmp);
468
469#endif	/* !_TLM_H_ */
470