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