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