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_ */