1 /*
   2  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2015 by Delphix. All rights reserved.
   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 #include <sys/fs/zfs.h>
  55 #include <libzfs.h>
  56 
  57 #define IS_SET(f, m)    (((f) & (m)) != 0)
  58 
  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 */
  62 
  63 
  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 */
  68 
  69 #define TLM_EXTRA_SPACE         64
  70 #define TLM_MAX_PATH_NAME       (PATH_MAX + TLM_EXTRA_SPACE)
  71 
  72 #define ENTRYTYPELEN    14
  73 #define PERMS           4
  74 #define ID_STR_MAX      20
  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
  78 
  79 
  80 /* operation flags */
  81 #define TLM_OP_CHOOSE_ARCHIVE   0x00000001      /* look for archive bit */
  82 
  83 /*
  84  * Synchronization flags used when launching the TLM threads.
  85  */
  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
  94 
  95 #define SCSI_SERIAL_PAGE        0x80
  96 #define SCSI_DEVICE_IDENT_PAGE  0x83
  97 #define SCMD_READ_ELEMENT_STATUS        0xB8
  98 
  99 #define OCTAL7CHAR      07777777
 100 #define SYSATTR_RDONLY  "SUNWattr_ro"
 101 #define SYSATTR_RW      "SUNWattr_rw"
 102 
 103 typedef int (*func_t)();
 104 
 105 typedef struct scsi_serial {
 106         int sr_flags;
 107         char sr_num[16];
 108 } scsi_serial_t;
 109 
 110 typedef struct fs_fhandle {
 111         int fh_fid;
 112         char *fh_fpath;
 113 } fs_fhandle_t;
 114 
 115 typedef struct scsi_link {
 116         struct scsi_link        *sl_next;
 117         struct scsi_link        *sl_prev;
 118         struct scsi_adapter     *sl_sa;
 119         unsigned int            sl_sid;
 120         unsigned int            sl_lun;
 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 */
 125 } scsi_link_t;
 126 
 127 typedef struct scsi_adapter {
 128         struct scsi_adapter     *sa_next;
 129         char                    sa_name[16];
 130         struct scsi_link        sa_link_head;
 131 } scsi_adapter_t;
 132 
 133 typedef struct sasd_drive {
 134         char            sd_name[256];
 135         char            sd_vendor[8 + 1];
 136         char            sd_id[16 + 1];
 137         char            sd_rev[4 + 1];
 138         char            sd_serial[16 + 1];
 139         char            sd_wwn[32 + 1];
 140 } sasd_drive_t;
 141 
 142 typedef struct scsi_sasd_drive {
 143         sasd_drive_t    ss_sd;
 144         scsi_link_t     ss_slink;
 145 } scsi_sasd_drive_t;
 146 
 147 
 148 #define DEFAULT_SLINK_MAX_XFER  (64*1024)
 149 
 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 */
 155 } tlm_info_t;
 156 
 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 */
 162 } tlm_chain_link_t;
 163 
 164 typedef struct  tlm_robot {
 165         struct tlm_robot        *tr_next;
 166         struct tlm_library      *tr_library;
 167         int     tr_number;
 168 } tlm_robot_t;
 169 
 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 */
 178                                         /* library */
 179         short   td_scsi_id;
 180         short   td_lun;
 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 */
 185         long    td_exists       : 1;
 186 
 187 } tlm_drive_t;
 188 
 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 */
 193         int     ts_element;
 194         short   ts_use_count;           /* number of times used since loaded */
 195         long    ts_status_full          : 1;
 196 } tlm_slot_t;
 197 
 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,
 208                 tl_ghost_drives         : 1;
 209                 /*
 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.
 213                  */
 214         struct  scsi_link *tl_slink;
 215 
 216         int             tl_robot_count;
 217         tlm_robot_t     *tl_robot;
 218         int             tl_drive_count;
 219         tlm_drive_t     *tl_drive;
 220         int             tl_slot_count;
 221         tlm_slot_t      *tl_slot;
 222 } tlm_library_t;
 223 
 224 typedef struct {
 225 #ifdef _BIG_ENDIAN
 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;
 230 #else
 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;
 235 #endif
 236 } device_ident_header_t;
 237 
 238 typedef struct {
 239 #ifdef _BIG_ENDIAN
 240         uint8_t ni_proto_ident  : 4,
 241                 ni_code_set     : 4;
 242 
 243         uint8_t ni_PIV          : 1,
 244                                 : 1,
 245                 ni_asso         : 2,
 246                 ni_ident_type   : 4;
 247 
 248         uint8_t ni_reserved;
 249         uint8_t ni_ident_length;
 250 #else
 251         uint8_t ni_code_set     : 4,
 252                 ni_proto_ident  : 4;
 253 
 254         uint8_t ni_ident_type   : 4,
 255                 ni_asso         : 2,
 256                                 : 1,
 257                 ni_PIV          : 1;
 258         uint8_t ni_reserved;
 259         uint8_t ni_ident_length;
 260 #endif
 261 } name_ident_t;
 262 
 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
 289 
 290 
 291 #define TLM_MAX_TAPE_DRIVES     16
 292 #define TLM_NAME_SIZE           100
 293 #define TLM_MAX_TAR_IMAGE       017777777770
 294 
 295 #define TLM_VOLNAME_MAX_LENGTH  255
 296 #define NAME_MAX                255
 297 
 298 #define TLM_MAGIC               "ustar  "
 299 #define TLM_SNAPSHOT_PREFIX     ".zfs"
 300 #define TLM_SNAPSHOT_DIR        ".zfs/snapshot"
 301 
 302 #define RECORDSIZE      512
 303 #define NAMSIZ  100
 304 
 305 typedef struct  tlm_tar_hdr {
 306         char    th_name[TLM_NAME_SIZE];
 307         char    th_mode[8];
 308         char    th_uid[8];
 309         char    th_gid[8];
 310         char    th_size[12];
 311         char    th_mtime[12];
 312         char    th_chksum[8];
 313         char    th_linkflag;
 314         char    th_linkname[TLM_NAME_SIZE];
 315         char    th_magic[8];
 316         char    th_uname[32];
 317         char    th_gname[32];
 318         union {
 319                 struct {
 320                         char    th_devmajor[8];
 321                         char    th_devminor[8];
 322                 } th_dev;
 323                 char    th_hlink_ino[12];
 324         } th_shared;
 325 } tlm_tar_hdr_t;
 326 
 327 
 328 
 329 /*
 330  * The linkflag defines the type of file
 331  */
 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. */
 342 
 343 #define LF_DUMPDIR      'D'
 344                                         /*
 345                                          * This is a dir entry that contains
 346                                          * the names of files that were in
 347                                          * the dir at the time the dump
 348                                          * was made
 349                                          */
 350 #define LF_HUMONGUS     'H'
 351                                         /*
 352                                          * Identifies the NEXT file on the tape
 353                                          * as a HUGE file
 354                                          */
 355 #define LF_LONGLINK     'K'
 356                                         /*
 357                                          * Identifies the NEXT file on the tape
 358                                          * as having a long linkname
 359                                          */
 360 #define LF_LONGNAME     'L'
 361                                         /*
 362                                          * Identifies the NEXT file on the tape
 363                                          * as having a long name.
 364                                          */
 365 #define LF_MULTIVOL     'M'
 366                                         /*
 367                                          * This is the continuation
 368                                          * of a file that began on another
 369                                          * volume
 370                                          */
 371 
 372 #define LF_VOLHDR       'V'             /* This file is a tape/volume header */
 373                                         /* Ignore it on extraction */
 374 
 375 #define LF_ACL          'A'             /* Access Control List */
 376 
 377 #define LF_XATTR        'E'             /* Extended attribute */
 378 
 379 #define KILOBYTE        1024
 380 
 381 
 382 /*
 383  * ACL support structure
 384  */
 385 typedef struct sec_attr {
 386         char attr_type;
 387         char attr_len[7];
 388         char attr_info[TLM_MAX_ACL_TXT];
 389 } sec_attr_t;
 390 
 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? */
 397                 /*
 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.
 402                  */
 403         sec_attr_t acl_info;
 404 
 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 */
 409         char uname[32];
 410         char gname[32];
 411 } tlm_acls_t;
 412 
 413 
 414 /*
 415  * Tape manager's data archiving ops vector
 416  *
 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
 420  * server.
 421  * The reserved callbacks are kept for different backup
 422  * types which are volume-based rather than file-based
 423  * e.g. zfs send.
 424  */
 425 typedef struct tm_ops {
 426         char *tm_name;
 427         int (*tm_putfile)();
 428         int (*tm_putdir)();
 429         int (*tm_putvol)();     /* Reserved */
 430         int (*tm_getfile)();
 431         int (*tm_getdir)();
 432         int (*tm_getvol)();     /* Reserved */
 433 } tm_ops_t;
 434 
 435 /* The checksum field is filled with this while the checksum is computed. */
 436 #define CHKBLANKS       "        "      /* 8 blanks, no null */
 437 
 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), \
 444                                     "[%d][%s:%d]", \
 445                                     (int)pthread_self(), __func__, __LINE__); \
 446                                 ndmp_log(p, ndmp_log_info, __VA_ARGS__); \
 447                         }
 448 extern void *ndmp_malloc(size_t size);
 449 
 450 /*
 451  * ZFS metadata plug-in module structures
 452  */
 453 #define ZFS_MAX_PROPS           100
 454 #define ZFS_META_MAGIC          "ZFSMETA"
 455 #define ZFS_META_MAGIC_EXT      "ZFSMETA2"
 456 
 457 /* Add new major/minor for header changes */
 458 typedef enum {
 459         META_HDR_MAJOR_0,       /* Original format */
 460         META_HDR_MAJOR_1,       /* Extended format */
 461 } ndmp_metadata_header_major_t;
 462 
 463 #define META_HDR_MAJOR_VERSION  META_HDR_MAJOR_1
 464 
 465 typedef enum {
 466         META_HDR_MINOR_0,
 467 } ndmp_metadata_header_minor_t;
 468 
 469 #define META_HDR_MINOR_VERSION  META_HDR_MINOR_0
 470 
 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;
 477 
 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;
 483 
 484 typedef struct ndmp_metadata_top_header {
 485         char th_plname[100];
 486         uint_t th_plversion;
 487         char th_magic[10];
 488         void *th_reserved_1;
 489         int th_count;
 490 } ndmp_metadata_top_header_t;
 491 
 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;
 498 
 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;
 504         int32_t nh_major;
 505         int32_t nh_minor;
 506         ndmp_metadata_property_ext_t nh_property[1];
 507 } ndmp_metadata_header_ext_t;
 508 
 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
 513 
 514 typedef struct ndmp_metadata_handle {
 515         void *ml_handle;
 516         int32_t ml_quota_prop;
 517         union {
 518                 ndmp_metadata_header_t *u_hdr;
 519                 ndmp_metadata_header_ext_t *u_xhdr;
 520         } ml_hdr_u;
 521 } ndmp_metadata_handle_t;
 522 
 523 #define ml_hdr  ml_hdr_u.u_hdr
 524 #define ml_xhdr ml_hdr_u.u_xhdr
 525 
 526 /*
 527  * Node in struct hardlink_q
 528  *
 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
 534  */
 535 struct hardlink_node {
 536         unsigned long inode;
 537         char *path;
 538         unsigned long long offset;
 539         int is_tmp;
 540         SLIST_ENTRY(hardlink_node) next_hardlink;
 541 };
 542 
 543 /*
 544  * Hardlinks that have been backed up or restored.
 545  *
 546  * During backup, each node represents a file whose
 547  *   (1) inode has multiple links
 548  *   (2) data has been backed up
 549  *
 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.
 556  *
 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).
 559  *
 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.
 564  */
 565 struct hardlink_q {
 566         struct hardlink_node *slh_first;
 567 };
 568 
 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);
 576 
 577 #endif  /* !_TLM_H_ */