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