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