2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015 by Delphix. All rights reserved.
9 * Copyright (c) 2007, The Storage Networking Industry Association.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
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
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
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.
42 #include <sys/types.h>
53 #include <sys/queue.h>
54 #include <sys/fs/zfs.h>
57 #define IS_SET(f, m) (((f) & (m)) != 0)
59 #define TLM_MAX_BACKUP_JOB_NAME 32 /* max size of a job's name */
60 #define TLM_TAPE_BUFFERS 10 /* number of rotating tape buffers */
61 #define TLM_LINE_SIZE 128 /* size of text messages */
64 #define TLM_BACKUP_RUN 0x00000001
65 #define TLM_RESTORE_RUN 0x00000002
66 #define TLM_STOP 0x00000009 /* graceful stop */
67 #define TLM_ABORT 0x99999999 /* abandon the run */
69 #define TLM_EXTRA_SPACE 64
70 #define TLM_MAX_PATH_NAME (PATH_MAX + TLM_EXTRA_SPACE)
72 #define ENTRYTYPELEN 14
75 #define APPENDED_ID_MAX (ID_STR_MAX + 1)
76 #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX)
77 #define TLM_MAX_ACL_TXT MAX_ACL_ENTRIES * ACL_ENTRY_SIZE
81 #define TLM_OP_CHOOSE_ARCHIVE 0x00000001 /* look for archive bit */
84 * Synchronization flags used when launching the TLM threads.
86 #define TLM_TAPE_READER 0x00000001
87 #define TLM_TAPE_WRITER 0x00000002
88 #define TLM_SOCK_READER 0x00000004
89 #define TLM_SOCK_WRITER 0x00000008
90 #define TLM_BUF_READER 0x00000010
91 #define TLM_BUF_WRITER 0x00000020
92 #define TLM_TAR_READER 0x00000040
93 #define TLM_TAR_WRITER 0x00000080
95 #define SCSI_SERIAL_PAGE 0x80
96 #define SCSI_DEVICE_IDENT_PAGE 0x83
97 #define SCMD_READ_ELEMENT_STATUS 0xB8
99 #define OCTAL7CHAR 07777777
100 #define SYSATTR_RDONLY "SUNWattr_ro"
101 #define SYSATTR_RW "SUNWattr_rw"
103 typedef int (*func_t
)();
105 typedef struct scsi_serial
{
110 typedef struct fs_fhandle
{
115 typedef struct scsi_link
{
116 struct scsi_link
*sl_next
;
117 struct scsi_link
*sl_prev
;
118 struct scsi_adapter
*sl_sa
;
121 unsigned int sl_requested_max_active
;
122 unsigned int sl_granted_max_active
;
123 unsigned int sl_n_active
;
124 unsigned int sl_type
; /* SCSI device type */
127 typedef struct scsi_adapter
{
128 struct scsi_adapter
*sa_next
;
130 struct scsi_link sa_link_head
;
133 typedef struct sasd_drive
{
135 char sd_vendor
[8 + 1];
138 char sd_serial
[16 + 1];
142 typedef struct scsi_sasd_drive
{
144 scsi_link_t ss_slink
;
148 #define DEFAULT_SLINK_MAX_XFER (64*1024)
150 typedef struct tlm_info
{
151 int ti_init_done
; /* initialization done ? */
152 int ti_library_count
; /* number of libraries */
153 struct tlm_library
*ti_library
; /* first in chain */
154 struct tlm_chain_link
*ti_job_stats
; /* chain of job statistics */
157 typedef struct tlm_chain_link
{
158 struct tlm_chain_link
*tc_next
; /* next blob of statistics */
159 struct tlm_chain_link
*tc_prev
; /* previous blob in the chain */
160 int tc_ref_count
; /* number of routines */
161 void *tc_data
; /* the data blob */
164 typedef struct tlm_robot
{
165 struct tlm_robot
*tr_next
;
166 struct tlm_library
*tr_library
;
170 typedef struct tlm_drive
{
171 struct tlm_drive
*td_next
;
172 struct tlm_library
*td_library
;
173 char td_job_name
[TLM_MAX_BACKUP_JOB_NAME
];
174 int td_number
; /* number of this tape drive */
175 int td_element
; /* the library's number for the drive */
176 struct scsi_link
*td_slink
; /* because the drive may be connected */
177 /* to a different SCSI card than the */
181 short td_volume_number
; /* for current job */
182 /* an index into the tape set */
183 int td_fd
; /* I/O file descriptor */
184 int td_errno
; /* system error number */
189 typedef struct tlm_slot
{
190 struct tlm_slot
*ts_next
;
191 struct tlm_library
*ts_library
;
192 int ts_number
; /* number of this slot */
194 short ts_use_count
; /* number of times used since loaded */
195 long ts_status_full
: 1;
198 typedef struct tlm_library
{
199 struct tlm_library
*tl_next
;
200 int tl_number
; /* number of this tape library */
201 long tl_capability_robot
: 1,
202 tl_capability_door
: 1,
203 tl_capability_lock
: 1,
204 tl_capability_slots
: 1,
205 tl_capability_export
: 1,
206 tl_capability_drives
: 1,
207 tl_capability_barcodes
: 1,
210 * "ghost_drives" is used to make sure that
211 * all drives claimed by the library really
212 * exist ... libraries have been known to lie.
214 struct scsi_link
*tl_slink
;
217 tlm_robot_t
*tl_robot
;
219 tlm_drive_t
*tl_drive
;
226 uint8_t di_peripheral_qual
: 3,
227 di_peripheral_dev_type
: 5;
228 uint8_t di_page_code
;
229 uint16_t di_page_length
;
231 uint8_t di_peripheral_dev_type
: 5,
232 di_peripheral_qual
: 3;
233 uint8_t di_page_code
;
234 uint16_t di_page_length
;
236 } device_ident_header_t
;
240 uint8_t ni_proto_ident
: 4,
249 uint8_t ni_ident_length
;
251 uint8_t ni_code_set
: 4,
254 uint8_t ni_ident_type
: 4,
259 uint8_t ni_ident_length
;
263 #define TLM_NO_ERRORS 0x00000000
264 #define TLM_ERROR_BUSY 0x00000001
265 #define TLM_ERROR_INTERNAL 0x00000002
266 #define TLM_ERROR_NO_ROBOTS 0x00000003
267 #define TLM_TIMEOUT 0x00000004
268 #define TLM_ERROR_RANGE 0x00000005
269 #define TLM_EMPTY 0x00000006
270 #define TLM_DRIVE_NOT_ASSIGNED 0x00000007
271 #define TLM_NO_TAPE_NAME 0x00000008
272 #define TLM_NO_BACKUP_DIR 0x00000009
273 #define TLM_NO_BACKUP_HARDWARE 0x0000000a
274 #define TLM_NO_SOURCE_FILE 0x0000000b
275 #define TLM_NO_FREE_TAPES 0x0000000c
276 #define TLM_EOT 0x0000000d
277 #define TLM_SERIAL_NOT_FOUND 0x0000000e
278 #define TLM_SMALL_READ 0x0000000f
279 #define TLM_NO_RESTORE_FILE 0x00000010
280 #define TLM_EOF 0x00000011
281 #define TLM_NO_DIRECTORY 0x00000012
282 #define TLM_NO_MEMORY 0x00000013
283 #define TLM_WRITE_ERROR 0x00000014
284 #define TLM_NO_SCRATCH_SPACE 0x00000015
285 #define TLM_INVALID 0x00000016
286 #define TLM_MOVE 0x00000017
287 #define TLM_SKIP 0x00000018
288 #define TLM_OPEN_ERR 0x00000019
291 #define TLM_MAX_TAPE_DRIVES 16
292 #define TLM_NAME_SIZE 100
293 #define TLM_MAX_TAR_IMAGE 017777777770
295 #define TLM_VOLNAME_MAX_LENGTH 255
298 #define TLM_MAGIC "ustar "
299 #define TLM_SNAPSHOT_PREFIX ".zfs"
300 #define TLM_SNAPSHOT_DIR ".zfs/snapshot"
302 #define RECORDSIZE 512
305 typedef struct tlm_tar_hdr
{
306 char th_name
[TLM_NAME_SIZE
];
314 char th_linkname
[TLM_NAME_SIZE
];
323 char th_hlink_ino
[12];
330 * The linkflag defines the type of file
332 #define LF_OLDNORMAL '\0' /* Normal disk file, Unix compat */
333 #define LF_NORMAL '0' /* Normal disk file */
334 #define LF_LINK '1' /* Link to previously dumped file */
335 #define LF_SYMLINK '2' /* Symbolic link */
336 #define LF_CHR '3' /* Character special file */
337 #define LF_BLK '4' /* Block special file */
338 #define LF_DIR '5' /* Directory */
339 #define LF_FIFO '6' /* FIFO special file */
340 #define LF_CONTIG '7' /* Contiguous file */
341 /* Further link types may be defined later. */
343 #define LF_DUMPDIR 'D'
345 * This is a dir entry that contains
346 * the names of files that were in
347 * the dir at the time the dump
350 #define LF_HUMONGUS 'H'
352 * Identifies the NEXT file on the tape
355 #define LF_LONGLINK 'K'
357 * Identifies the NEXT file on the tape
358 * as having a long linkname
360 #define LF_LONGNAME 'L'
362 * Identifies the NEXT file on the tape
363 * as having a long name.
365 #define LF_MULTIVOL 'M'
367 * This is the continuation
368 * of a file that began on another
372 #define LF_VOLHDR 'V' /* This file is a tape/volume header */
373 /* Ignore it on extraction */
375 #define LF_ACL 'A' /* Access Control List */
377 #define LF_XATTR 'E' /* Extended attribute */
379 #define KILOBYTE 1024
383 * ACL support structure
385 typedef struct sec_attr
{
388 char attr_info
[TLM_MAX_ACL_TXT
];
391 typedef struct tlm_acls
{
392 int acl_checkpointed
: 1, /* are checkpoints active ? */
393 acl_clear_archive
: 1, /* clear archive bit ? */
394 acl_overwrite
: 1, /* always overwrite ? */
395 acl_update
: 1, /* only update ? */
396 acl_non_trivial
: 1; /* real ACLs? */
398 * The following fields are here to allow
399 * the backup reader to open a file one time
400 * and keep the information for ACL, ATTRs,
401 * and reading the file.
405 char acl_root_dir
[TLM_VOLNAME_MAX_LENGTH
]; /* name of root filesystem */
406 fs_fhandle_t acl_dir_fh
; /* parent dir's info */
407 fs_fhandle_t acl_fil_fh
; /* file's info */
408 struct stat64 acl_attr
; /* file system attributes */
415 * Tape manager's data archiving ops vector
417 * This vector represents the granular operations for
418 * performing backup/restore. Each backend should provide
419 * such a vector interface in order to be invoked by NDMP
421 * The reserved callbacks are kept for different backup
422 * types which are volume-based rather than file-based
425 typedef struct tm_ops
{
429 int (*tm_putvol
)(); /* Reserved */
432 int (*tm_getvol
)(); /* Reserved */
435 /* The checksum field is filled with this while the checksum is computed. */
436 #define CHKBLANKS " " /* 8 blanks, no null */
438 #define LONGNAME_PREFIX "././_LoNg_NaMe_"
439 extern void ndmp_log(ulong_t
, char *, char *, ...);
440 char ndmp_log_info
[256];
441 #define NDMP_LOG(p, ...) { \
442 (void) snprintf(ndmp_log_info, \
443 sizeof (ndmp_log_info), \
445 (int)pthread_self(), __func__, __LINE__); \
446 ndmp_log(p, ndmp_log_info, __VA_ARGS__); \
448 extern void *ndmp_malloc(size_t size
);
451 * ZFS metadata plug-in module structures
453 #define ZFS_MAX_PROPS 100
454 #define ZFS_META_MAGIC "ZFSMETA"
455 #define ZFS_META_MAGIC_EXT "ZFSMETA2"
457 /* Add new major/minor for header changes */
459 META_HDR_MAJOR_0
, /* Original format */
460 META_HDR_MAJOR_1
, /* Extended format */
461 } ndmp_metadata_header_major_t
;
463 #define META_HDR_MAJOR_VERSION META_HDR_MAJOR_1
467 } ndmp_metadata_header_minor_t
;
469 #define META_HDR_MINOR_VERSION META_HDR_MINOR_0
471 /* To support older backups */
472 typedef struct ndmp_metadata_property
{
473 char mp_name
[NAME_MAX
];
474 char mp_value
[NAME_MAX
];
475 char mp_source
[NAME_MAX
];
476 } ndmp_metadata_property_t
;
478 typedef struct ndmp_metadata_property_ext
{
479 char mp_name
[ZFS_MAX_DATASET_NAME_LEN
];
480 char mp_value
[ZFS_MAXPROPLEN
];
481 char mp_source
[ZFS_MAXPROPLEN
];
482 } ndmp_metadata_property_ext_t
;
484 typedef struct ndmp_metadata_top_header
{
490 } ndmp_metadata_top_header_t
;
492 /* Original metadata format */
493 typedef struct ndmp_metadata_header
{
494 ndmp_metadata_top_header_t nh_hdr
;
495 char nh_dataset
[NAME_MAX
];
496 ndmp_metadata_property_t nh_property
[1];
497 } ndmp_metadata_header_t
;
499 /* Extended metadata format */
500 typedef struct ndmp_metadata_header_ext
{
501 ndmp_metadata_top_header_t nh_hdr
;
502 char nh_dataset
[ZFS_MAX_DATASET_NAME_LEN
];
503 int32_t nh_total_bytes
;
506 ndmp_metadata_property_ext_t nh_property
[1];
507 } ndmp_metadata_header_ext_t
;
509 #define nh_plname nh_hdr.th_plname
510 #define nh_plversion nh_hdr.th_plversion
511 #define nh_magic nh_hdr.th_magic
512 #define nh_count nh_hdr.th_count
514 typedef struct ndmp_metadata_handle
{
516 int32_t ml_quota_prop
;
518 ndmp_metadata_header_t
*u_hdr
;
519 ndmp_metadata_header_ext_t
*u_xhdr
;
521 } ndmp_metadata_handle_t
;
523 #define ml_hdr ml_hdr_u.u_hdr
524 #define ml_xhdr ml_hdr_u.u_xhdr
527 * Node in struct hardlink_q
529 * inode: the inode of the hardlink
530 * path: the name of the hardlink, used during restore
531 * offset: tape offset of the data records for the hardlink, used during backup
532 * is_tmp: indicate whether the file was created temporarily for restoring
533 * other links during a non-DAR partial restore
535 struct hardlink_node
{
538 unsigned long long offset
;
540 SLIST_ENTRY(hardlink_node
) next_hardlink
;
544 * Hardlinks that have been backed up or restored.
546 * During backup, each node represents a file whose
547 * (1) inode has multiple links
548 * (2) data has been backed up
550 * When we run into a file with multiple links during backup,
551 * we first check the list to see whether a file with the same inode
552 * has been backed up. If yes, we backup an empty record, while
553 * making the file history of this file contain the data offset
554 * of the offset of the file that has been backed up. If no,
555 * we backup this file, and add an entry to the list.
557 * During restore, each node represents an LF_LINK type record whose
558 * data has been restored (v.s. a hard link has been created).
560 * During restore, when we run into a record of LF_LINK type, we
561 * first check the queue to see whether a file with the same inode
562 * has been restored. If yes, we create a hardlink to it.
563 * If no, we restore the data, and add an entry to the list.
566 struct hardlink_node
*slh_first
;
569 /* Utility functions from handling hardlink */
570 extern struct hardlink_q
*hardlink_q_init();
571 extern void hardlink_q_cleanup(struct hardlink_q
*qhead
);
572 extern int hardlink_q_get(struct hardlink_q
*qhead
, unsigned long inode
,
573 unsigned long long *offset
, char **path
);
574 extern int hardlink_q_add(struct hardlink_q
*qhead
, unsigned long inode
,
575 unsigned long long offset
, char *path
, int is_tmp
);
577 #endif /* !_TLM_H_ */