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 /* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
  40 
  41 #include <sys/errno.h>
  42 #include <syslog.h>
  43 #include <ctype.h>
  44 #include <stdlib.h>
  45 #include <time.h>
  46 #include <sys/types.h>
  47 #include <unistd.h>
  48 #include <libzfs.h>
  49 #include <pthread.h>
  50 #include "tlm.h"
  51 #include "tlm_proto.h"
  52 #include <ndmpd_prop.h>
  53 #include <sys/mtio.h>
  54 #include <sys/mnttab.h>
  55 #include <sys/mntent.h>
  56 #include <sys/statvfs.h>
  57 #include <sys/scsi/impl/uscsi.h>
  58 #include <sys/scsi/scsi.h>
  59 #include <sys/mtio.h>
  60 #include <thread.h>
  61 #include <synch.h>
  62 #include <sys/mutex.h>
  63 #include <sys/sysmacros.h>
  64 #include <sys/mkdev.h>
  65 
  66 /*
  67  * Tar archiving ops vector
  68  */
  69 tm_ops_t tm_tar_ops = {
  70         "tar",
  71         tar_putfile,
  72         tar_putdir,
  73         NULL,
  74         tar_getfile,
  75         tar_getdir,
  76         NULL
  77 };
  78 
  79 extern  libzfs_handle_t *zlibh;
  80 extern  mutex_t zlib_mtx;
  81 
  82 /*
  83  * get the next tape buffer from the drive's pool of buffers
  84  */
  85 /*ARGSUSED*/
  86 char *
  87 tlm_get_write_buffer(long want, long *actual_size,
  88     tlm_buffers_t *buffers, int zero)
  89 {
  90         int     buf = buffers->tbs_buffer_in;
  91         tlm_buffer_t *buffer = &buffers->tbs_buffer[buf];
  92         int     align_size = RECORDSIZE - 1;
  93         char    *rec;
  94 
  95         /*
  96          * make sure the allocation is in chunks of 512 bytes
  97          */
  98         want += align_size;
  99         want &= ~align_size;
 100 
 101         *actual_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
 102         if (*actual_size <= 0) {
 103                 /*
 104                  * no room, send this one
 105                  * and wait for a free one
 106                  */
 107                 if (!buffer->tb_full) {
 108                         /*
 109                          * we are now ready to send a full buffer
 110                          * instead of trying to get a new buffer
 111                          *
 112                          * do not send if we failed to get a buffer
 113                          * on the previous call
 114                          */
 115                         buffer->tb_full = TRUE;
 116 
 117                         /*
 118                          * tell the writer that a buffer is available
 119                          */
 120                         tlm_buffer_release_in_buf(buffers);
 121 
 122                         buffer = tlm_buffer_advance_in_idx(buffers);
 123                 }
 124 
 125                 buffer = tlm_buffer_in_buf(buffers, NULL);
 126 
 127                 if (buffer->tb_full) {
 128                         /*
 129                          * wait for the writer to free up a buffer
 130                          */
 131                         tlm_buffer_out_buf_timed_wait(buffers, 500);
 132                 }
 133 
 134                 buffer = tlm_buffer_in_buf(buffers, NULL);
 135                 if (buffer->tb_full) {
 136                         /*
 137                          * the next buffer is still full
 138                          * of data from previous activity
 139                          *
 140                          * nothing has changed.
 141                          */
 142                         return (0);
 143                 }
 144 
 145                 buffer->tb_buffer_spot = 0;
 146                 *actual_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
 147         }
 148 
 149         *actual_size = min(want, *actual_size);
 150         rec = &buffer->tb_buffer_data[buffer->tb_buffer_spot];
 151         buffer->tb_buffer_spot += *actual_size;
 152         buffers->tbs_offset += *actual_size;
 153         if (zero) {
 154                 (void) memset(rec, 0, *actual_size);
 155         }
 156         return (rec);
 157 }
 158 
 159 /*
 160  * get a read record from the tape buffer,
 161  * and read a tape block if necessary
 162  */
 163 /*ARGSUSED*/
 164 char *
 165 tlm_get_read_buffer(int want, int *error,
 166     tlm_buffers_t *buffers, int *actual_size)
 167 {
 168         tlm_buffer_t *buffer;
 169         int     align_size = RECORDSIZE - 1;
 170         int     buf;
 171         int     current_size;
 172         char    *rec;
 173 
 174         buf = buffers->tbs_buffer_out;
 175         buffer = &buffers->tbs_buffer[buf];
 176 
 177         /*
 178          * make sure the allocation is in chunks of 512 bytes
 179          */
 180         want += align_size;
 181         want &= ~align_size;
 182 
 183         current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
 184         if (buffer->tb_full && current_size <= 0) {
 185                 /*
 186                  * no more data, release this
 187                  * one and go get another
 188                  */
 189 
 190                 /*
 191                  * tell the reader that a buffer is available
 192                  */
 193                 buffer->tb_full = FALSE;
 194                 tlm_buffer_release_out_buf(buffers);
 195 
 196                 buffer = tlm_buffer_advance_out_idx(buffers);
 197                 current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
 198         }
 199 
 200         if (!buffer->tb_full) {
 201                 /*
 202                  * next buffer is not full yet.
 203                  * wait for the reader.
 204                  */
 205                 tlm_buffer_in_buf_timed_wait(buffers, 500);
 206 
 207                 buffer = tlm_buffer_out_buf(buffers, NULL);
 208                 if (!buffer->tb_full) {
 209                         /*
 210                          * we do not have anything from the tape yet
 211                          */
 212                         return (0);
 213                 }
 214 
 215                 current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
 216         }
 217 
 218         /* Make sure we got something */
 219         if (current_size <= 0)
 220                 return (NULL);
 221 
 222         current_size = min(want, current_size);
 223         rec = &buffer->tb_buffer_data[buffer->tb_buffer_spot];
 224         buffer->tb_buffer_spot += current_size;
 225         *actual_size = current_size;
 226 
 227         /*
 228          * the error flag is only sent back one time,
 229          * since the flag refers to a previous read
 230          * attempt, not the data in this buffer.
 231          */
 232         *error = buffer->tb_errno;
 233 
 234         return (rec);
 235 }
 236 
 237 
 238 /*
 239  * unread a previously read buffer back to the tape buffer
 240  */
 241 void
 242 tlm_unget_read_buffer(tlm_buffers_t *buffers, int size)
 243 {
 244         tlm_buffer_t *buffer;
 245         int     align_size = RECORDSIZE - 1;
 246         int     buf;
 247         int     current_size;
 248 
 249         buf = buffers->tbs_buffer_out;
 250         buffer = &buffers->tbs_buffer[buf];
 251 
 252         /*
 253          * make sure the allocation is in chunks of 512 bytes
 254          */
 255         size += align_size;
 256         size &= ~align_size;
 257 
 258         current_size = min(size, buffer->tb_buffer_spot);
 259         buffer->tb_buffer_spot -= current_size;
 260 }
 261 
 262 
 263 /*
 264  * unwrite a previously written buffer
 265  */
 266 void
 267 tlm_unget_write_buffer(tlm_buffers_t *buffers, int size)
 268 {
 269         tlm_buffer_t *buffer;
 270         int     align_size = RECORDSIZE - 1;
 271         int     buf;
 272         int     current_size;
 273 
 274         buf = buffers->tbs_buffer_in;
 275         buffer = &buffers->tbs_buffer[buf];
 276 
 277         /*
 278          * make sure the allocation is in chunks of 512 bytes
 279          */
 280         size += align_size;
 281         size &= ~align_size;
 282 
 283         current_size = min(size, buffer->tb_buffer_spot);
 284         buffer->tb_buffer_spot -= current_size;
 285 }
 286 
 287 
 288 /*
 289  * build a checksum for a TAR header record
 290  */
 291 void
 292 tlm_build_header_checksum(tlm_tar_hdr_t *r)
 293 {
 294         int     i;
 295         int     sum = 0;
 296         char *c = (char *)r;
 297 
 298         (void) memcpy(r->th_chksum, CHKBLANKS, strlen(CHKBLANKS));
 299         for (i = 0; i < RECORDSIZE; i++) {
 300                 sum += c[i] & 0xFF;
 301         }
 302         (void) snprintf(r->th_chksum, sizeof (r->th_chksum), "%6o", sum);
 303 }
 304 
 305 /*
 306  * verify the tar header checksum
 307  */
 308 int
 309 tlm_vfy_tar_checksum(tlm_tar_hdr_t *tar_hdr)
 310 {
 311         int     chksum = oct_atoi(tar_hdr->th_chksum);
 312         uchar_t *p = (uchar_t *)tar_hdr;
 313         int     sum = 0;        /* initial value of checksum */
 314         int     i;              /* loop counter */
 315 
 316         /*
 317          * compute the checksum
 318          */
 319         for (i = 0; i < RECORDSIZE; i++) {
 320                 sum += p[i] & 0xFF;
 321         }
 322 
 323         if (sum == 0) {
 324                 syslog(LOG_DEBUG,
 325                     "should be %d, is 0", chksum);
 326                 /* a zero record ==> end of tar file */
 327                 return (0);
 328         }
 329 
 330         /*
 331          * subtract out the label's checksum values
 332          * this lets us undo the old checksum "in-
 333          * place", no need to swap blanks in and out
 334          */
 335         for (i = 0; i < 8; i++) {
 336                 sum -= 0xFF & tar_hdr->th_chksum[i];
 337         }
 338 
 339         /*
 340          * replace the old checksum field with blanks
 341          */
 342         sum += ' ' * 8;
 343 
 344         if (sum != chksum) {
 345                 syslog(LOG_DEBUG,
 346                     "should be %d, is %d", chksum, sum);
 347         }
 348 
 349         return ((sum == chksum) ? 1 : -1);
 350 }
 351 
 352 /*
 353  * get internal scsi_sasd entry for this tape drive
 354  */
 355 int
 356 tlm_get_scsi_sasd_entry(int lib, int drv)
 357 {
 358         int entry;
 359         int i, n;
 360         scsi_link_t *sl;
 361         tlm_drive_t *dp;
 362 
 363         entry = -1;
 364         dp = tlm_drive(lib, drv);
 365         if (!dp) {
 366                 syslog(LOG_DEBUG, "NULL dp for (%d.%d)", lib, drv);
 367         } else if (!dp->td_slink) {
 368                 syslog(LOG_DEBUG, "NULL dp->td_slink for (%d.%d)", lib, drv);
 369         } else if (!dp->td_slink->sl_sa) {
 370                 syslog(LOG_DEBUG, "NULL dp->td_slink->sl_sa for (%d.%d)",
 371                     lib, drv);
 372         } else {
 373                 /* search through the SASD table */
 374                 n = sasd_dev_count();
 375                 for (i = 0; i < n; i++) {
 376                         sl = sasd_dev_slink(i);
 377                         if (!sl)
 378                                 continue;
 379 
 380                         if (dp->td_slink->sl_sa == sl->sl_sa &&
 381                             dp->td_scsi_id == sl->sl_sid &&
 382                             dp->td_lun == sl->sl_lun) {
 383                                 /* all 3 variables match */
 384                                 entry = i;
 385                                 break;
 386                         }
 387                 }
 388         }
 389 
 390         return (entry);
 391 }
 392 
 393 /*
 394  * get the OS device name for this tape
 395  */
 396 char *
 397 tlm_get_tape_name(int lib, int drv)
 398 {
 399         int entry;
 400 
 401         entry = tlm_get_scsi_sasd_entry(lib, drv);
 402         if (entry >= 0) {
 403                 sasd_drive_t *sd;
 404 
 405                 if ((sd = sasd_drive(entry)) != 0)
 406                         return (sd->sd_name);
 407         }
 408 
 409         return ("");
 410 }
 411 
 412 /*
 413  * create the IPC area between the reader and writer
 414  */
 415 tlm_cmd_t *
 416 tlm_create_reader_writer_ipc(boolean_t write, long data_transfer_size)
 417 {
 418         tlm_cmd_t *cmd;
 419 
 420         cmd = ndmp_malloc(sizeof (tlm_cmd_t));
 421         if (cmd == NULL)
 422                 return (NULL);
 423 
 424         cmd->tc_reader = TLM_BACKUP_RUN;
 425         cmd->tc_writer = TLM_BACKUP_RUN;
 426         cmd->tc_ref = 1;
 427 
 428         cmd->tc_buffers = tlm_allocate_buffers(write, data_transfer_size);
 429         if (cmd->tc_buffers == NULL) {
 430                 free(cmd);
 431                 return (NULL);
 432         }
 433 
 434         (void) mutex_init(&cmd->tc_mtx, 0, NULL);
 435         (void) cond_init(&cmd->tc_cv, 0, NULL);
 436 
 437         return (cmd);
 438 }
 439 
 440 /*
 441  * release(destroy) the IPC between the reader and writer
 442  */
 443 void
 444 tlm_release_reader_writer_ipc(tlm_cmd_t *cmd)
 445 {
 446         if (--cmd->tc_ref <= 0) {
 447                 (void) mutex_lock(&cmd->tc_mtx);
 448                 tlm_release_buffers(cmd->tc_buffers);
 449                 (void) cond_destroy(&cmd->tc_cv);
 450                 (void) mutex_unlock(&cmd->tc_mtx);
 451                 (void) mutex_destroy(&cmd->tc_mtx);
 452                 free(cmd);
 453         }
 454 }
 455 
 456 
 457 /*
 458  * NDMP support begins here.
 459  */
 460 
 461 /*
 462  * Initialize the file history callback functions
 463  */
 464 lbr_fhlog_call_backs_t *
 465 lbrlog_callbacks_init(void *cookie, path_hist_func_t log_pname_func,
 466     dir_hist_func_t log_dir_func, node_hist_func_t log_node_func)
 467 {
 468         lbr_fhlog_call_backs_t *p;
 469 
 470         p = ndmp_malloc(sizeof (lbr_fhlog_call_backs_t));
 471         if (p == NULL)
 472                 return (NULL);
 473 
 474         p->fh_cookie = cookie;
 475         p->fh_logpname = (func_t)log_pname_func;
 476         p->fh_log_dir = (func_t)log_dir_func;
 477         p->fh_log_node = (func_t)log_node_func;
 478         return (p);
 479 }
 480 
 481 /*
 482  * Cleanup the callbacks
 483  */
 484 void
 485 lbrlog_callbacks_done(lbr_fhlog_call_backs_t *p)
 486 {
 487         if (p != NULL)
 488                 (void) free((char *)p);
 489 }
 490 
 491 /*
 492  * Call back for file history directory info
 493  */
 494 int
 495 tlm_log_fhdir(tlm_job_stats_t *job_stats, char *dir, struct stat64 *stp,
 496     fs_fhandle_t *fhp)
 497 {
 498         int rv;
 499         lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
 500 
 501         rv = 0;
 502         if (job_stats == NULL) {
 503                 syslog(LOG_DEBUG, "log_fhdir: jstat is NULL");
 504         } else if (dir == NULL) {
 505                 syslog(LOG_DEBUG, "log_fhdir: dir is NULL");
 506         } else if (stp == NULL) {
 507                 syslog(LOG_DEBUG, "log_fhdir: stp is NULL");
 508         } else if ((cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks)
 509             == NULL) {
 510                 syslog(LOG_DEBUG, "log_fhdir: cbp is NULL");
 511         } else if (cbp->fh_log_dir == NULL) {
 512                 syslog(LOG_DEBUG, "log_fhdir: callback is NULL");
 513         } else
 514                 rv = (*cbp->fh_log_dir)(cbp, dir, stp, fhp);
 515 
 516         return (rv);
 517 }
 518 
 519 /*
 520  * Call back for file history node info
 521  */
 522 int
 523 tlm_log_fhnode(tlm_job_stats_t *job_stats, char *dir, char *file,
 524     struct stat64 *stp, u_longlong_t off)
 525 {
 526         int rv;
 527         lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
 528 
 529         rv = 0;
 530         if (job_stats == NULL) {
 531                 syslog(LOG_DEBUG, "log_fhnode: jstat is NULL");
 532         } else if (dir == NULL) {
 533                 syslog(LOG_DEBUG, "log_fhnode: dir is NULL");
 534         } else if (file == NULL) {
 535                 syslog(LOG_DEBUG, "log_fhnode: file is NULL");
 536         } else if (stp == NULL) {
 537                 syslog(LOG_DEBUG, "log_fhnode: stp is NULL");
 538         } else if ((cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks)
 539             == NULL) {
 540                 syslog(LOG_DEBUG, "log_fhnode: cbp is NULL");
 541         } else if (cbp->fh_log_node == NULL) {
 542                 syslog(LOG_DEBUG, "log_fhnode: callback is NULL");
 543         } else
 544                 rv = (*cbp->fh_log_node)(cbp, dir, file, stp, off);
 545 
 546         return (rv);
 547 }
 548 
 549 /*
 550  * Call back for file history path info
 551  */
 552 int
 553 tlm_log_fhpath_name(tlm_job_stats_t *job_stats, char *pathname,
 554     struct stat64 *stp, u_longlong_t off)
 555 {
 556         int rv;
 557         lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
 558 
 559         rv = 0;
 560         if (!job_stats) {
 561                 syslog(LOG_DEBUG, "log_fhpath_name: jstat is NULL");
 562         } else if (!pathname) {
 563                 syslog(LOG_DEBUG, "log_fhpath_name: pathname is NULL");
 564         } else if (!stp) {
 565                 syslog(LOG_DEBUG, "log_fhpath_name: stp is NULL");
 566         } else if ((cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks)
 567             == 0) {
 568                 syslog(LOG_DEBUG, "log_fhpath_name: cbp is NULL");
 569         } else if (!cbp->fh_logpname) {
 570                 syslog(LOG_DEBUG, "log_fhpath_name: callback is NULL");
 571         } else
 572                 rv = (*cbp->fh_logpname)(cbp, pathname, stp, off);
 573 
 574         return (rv);
 575 }
 576 
 577 
 578 /*
 579  * Log call back to report the entry recovery
 580  */
 581 int
 582 tlm_entry_restored(tlm_job_stats_t *job_stats, char *name, int pos)
 583 {
 584         lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
 585 
 586         if (job_stats == NULL) {
 587                 syslog(LOG_DEBUG, "entry_restored: jstat is NULL");
 588                 return (0);
 589         }
 590         cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks;
 591         if (cbp == NULL) {
 592                 syslog(LOG_DEBUG, "entry_restored is NULL");
 593                 return (0);
 594         }
 595         return (*cbp->fh_logpname)(cbp, name, 0, (longlong_t)pos);
 596 }
 597 /*
 598  * NDMP support ends here.
 599  */
 600 
 601 /*
 602  * Function: tlm_cat_path
 603  * Concatenates two path names
 604  * or directory name and file name
 605  * into a buffer passed by the caller. A slash
 606  * is inserted if required. Buffer is assumed
 607  * to hold PATH_MAX characters.
 608  *
 609  * Parameters:
 610  *      char *buf       - buffer to write new dir/name string
 611  *      char *dir       - directory name
 612  *      char *name      - file name
 613  *
 614  * Returns:
 615  *      TRUE            - No errors. buf contains the dir/name string
 616  *      FALSE           - Error. buf is not modified.
 617  */
 618 boolean_t
 619 tlm_cat_path(char *buf, char *dir, char *name)
 620 {
 621         char *fmt;
 622         int dirlen = strlen(dir);
 623         int filelen = strlen(name);
 624 
 625         if ((dirlen + filelen + 1) >= PATH_MAX) {
 626                 return (FALSE);
 627         }
 628 
 629         if (*dir == '\0' || *name == '\0' || dir[dirlen - 1] == '/' ||
 630             *name == '/') {
 631                 fmt = "%s%s";
 632         } else {
 633                 fmt = "%s/%s";
 634         }
 635 
 636         /* check for ".../" and "/...." */
 637         if ((dirlen > 0) && (dir[dirlen - 1] == '/') && (*name == '/'))
 638                 name += strspn(name, "/");
 639 
 640         /* LINTED variable format */
 641         (void) snprintf(buf, TLM_MAX_PATH_NAME, fmt, dir, name);
 642 
 643         return (TRUE);
 644 }
 645 
 646 /*
 647  * Get the checkpoint (snapshot) creation time.
 648  * This is necessary to check for checkpoints not being stale.
 649  */
 650 int
 651 tlm_get_chkpnt_time(char *path, time_t *tp)
 652 {
 653         zfs_handle_t *zhp;
 654 
 655         if (path == NULL || *path == '\0' || tp == NULL) {
 656                 syslog(LOG_ERR, "tlm_get_chkpnt_time: bad params");
 657                 return (-1);
 658         }
 659 
 660         (void) mutex_lock(&zlib_mtx);
 661         if ((zhp = zfs_open(zlibh, path, ZFS_TYPE_DATASET)) == NULL) {
 662                 syslog(LOG_DEBUG, "tlm_get_chkpnt_time: open %s failed",
 663                     path);
 664                 (void) mutex_unlock(&zlib_mtx);
 665                 return (-1);
 666         }
 667 
 668         *tp = zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
 669 
 670         zfs_close(zhp);
 671         (void) mutex_unlock(&zlib_mtx);
 672 
 673         return (0);
 674 }
 675 
 676 /*
 677  * Release an array of pointers and the pointers themselves.
 678  */
 679 void
 680 tlm_release_list(char **lpp)
 681 {
 682         char **save;
 683 
 684         if ((save = lpp) == 0)
 685                 return;
 686 
 687         while (*lpp)
 688                 free(*lpp++);
 689 
 690         free(save);
 691 }
 692 
 693 /*
 694  * Print the list of array of strings in the backup log
 695  */
 696 void
 697 tlm_log_list(char *title, char **lpp)
 698 {
 699         int i;
 700 
 701         if (!lpp)
 702                 return;
 703 
 704         syslog(LOG_DEBUG, "%s:", title);
 705 
 706         for (i = 0; *lpp; lpp++, i++)
 707                 syslog(LOG_DEBUG, "%d: [%s]", i, *lpp);
 708 }
 709 
 710 /*
 711  * Insert the backup snapshot name into the path.
 712  *
 713  * Input:
 714  *      name: Original path name.
 715  *
 716  * Output:
 717  *      name: Original name modified to include a snapshot.
 718  *
 719  * Returns:
 720  *      Original name modified to include a snapshot.
 721  */
 722 char *
 723 tlm_build_snapshot_name(char *name, char *sname, char *jname)
 724 {
 725         zfs_handle_t *zhp;
 726         char volname[ZFS_MAX_DATASET_NAME_LEN] = {'\0'};
 727         char mountpoint[PATH_MAX] = {'\0'};
 728         char zpoolname[ZFS_MAX_DATASET_NAME_LEN] = {'\0'};
 729         char *slash, *rest;
 730 
 731         if (get_zfsvolname(volname, ZFS_MAX_DATASET_NAME_LEN, name) == -1)
 732                 goto notzfs;
 733 
 734         (void) mutex_lock(&zlib_mtx);
 735         if ((zlibh == NULL) ||
 736             (zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == NULL) {
 737                 (void) mutex_unlock(&zlib_mtx);
 738                 goto notzfs;
 739         }
 740 
 741         if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint, PATH_MAX, NULL,
 742             NULL, 0, B_FALSE) != 0) {
 743                 zfs_close(zhp);
 744                 (void) mutex_unlock(&zlib_mtx);
 745                 goto notzfs;
 746         }
 747 
 748         zfs_close(zhp);
 749         (void) mutex_unlock(&zlib_mtx);
 750 
 751         (void) strlcpy(zpoolname, volname, ZFS_MAX_DATASET_NAME_LEN);
 752         slash = strchr(zpoolname, '/');
 753         if (slash != 0) {
 754                 *slash = '\0';
 755         }
 756 
 757         rest = name + strlen(mountpoint);
 758         (void) snprintf(sname,
 759             TLM_MAX_PATH_NAME, "/%s/%s%s", zpoolname, jname, rest);
 760 
 761         return (sname);
 762 
 763 notzfs:
 764         (void) strlcpy(sname, name, TLM_MAX_PATH_NAME);
 765         return (sname);
 766 }
 767 
 768 /*
 769  * Remove the checkpoint from a path name.
 770  *
 771  * Input:
 772  *      name: Full pathname with checkpoint embeded.
 773  *
 774  * Output:
 775  *      unchkp_name: real pathname with no checkpoint.
 776  *
 777  * Returns:
 778  *      Pointer to the un-checkpointed path.
 779  */
 780 char *
 781 tlm_remove_checkpoint(char *name, char *unchkp_name)
 782 {
 783         char *cp;
 784         int i;
 785         int plen;
 786 
 787         unchkp_name[0] = name[0];
 788         plen = strlen(TLM_SNAPSHOT_PREFIX);
 789         for (i = 1; i <= TLM_VOLNAME_MAX_LENGTH + 1; i++) {
 790                 switch (name[i]) {
 791                 case '.':
 792                         if (strncmp(&name[i], TLM_SNAPSHOT_PREFIX,
 793                             plen) == 0) {
 794                                 unchkp_name[i] = '\0';
 795                                 i += plen;
 796                                 if (name[i] == '\0') {
 797                                         /*
 798                                          * name == "/v1.chkpnt"
 799                                          */
 800                                         return (unchkp_name);
 801                                 }
 802                                 if ((cp = strchr(&name[++i], '/')) != NULL) {
 803                                         (void) strlcat(unchkp_name, cp,
 804                                             TLM_VOLNAME_MAX_LENGTH + 1);
 805                                 }
 806                                 return (unchkp_name);
 807                         } else {
 808                                 unchkp_name[i] = name[i];
 809                         }
 810                         break;
 811                 case '/':
 812                         return (name);
 813                 case 0:
 814                         return (name);
 815                 default:
 816                         unchkp_name[i] = name[i];
 817                         break;
 818                 }
 819         }
 820         return (name);
 821 }
 822 
 823 /*
 824  * see if we should exclude this file.
 825  */
 826 boolean_t
 827 tlm_is_excluded(char *dir, char *name, char **excl_files)
 828 {
 829         int     i;
 830         char    full_name[TLM_MAX_PATH_NAME];
 831 
 832         if (!dir || !name || !excl_files)
 833                 return (FALSE);
 834 
 835         if (!tlm_cat_path(full_name, dir, name)) {
 836                 syslog(LOG_DEBUG, "Path too long [%s][%s]",
 837                     dir, name);
 838                 return (FALSE);
 839         }
 840         for (i = 0; excl_files[i] != 0; i++) {
 841                 if (match(excl_files[i], full_name)) {
 842                         return (TRUE);
 843                 }
 844         }
 845         return (FALSE);
 846 }
 847 
 848 /*
 849  * Check if the path is too long
 850  */
 851 boolean_t
 852 tlm_is_too_long(int checkpointed, char *dir, char *nm)
 853 {
 854         int nlen, tot;
 855 
 856         tot = 0;
 857         if (dir)
 858                 tot += strlen(dir);
 859         if (checkpointed)
 860                 tot += strlen(TLM_SNAPSHOT_DIR) + 1;
 861         if (nm) {
 862                 if ((nlen = strlen(nm)) > 0)
 863                         tot += nlen + 1;
 864         }
 865         return ((tot >= PATH_MAX) ? TRUE : FALSE);
 866 }
 867 
 868 /*
 869  * Get the data offset of inside the buffer
 870  */
 871 longlong_t
 872 tlm_get_data_offset(tlm_cmd_t *lcmds)
 873 {
 874         if (!lcmds)
 875                 return (0LL);
 876 
 877         return (lcmds->tc_buffers->tbs_offset);
 878 }
 879 
 880 /*
 881  * Enable the barcode capability on the library
 882  */
 883 void
 884 tlm_enable_barcode(int l)
 885 {
 886         tlm_library_t *lp;
 887 
 888         if ((lp = tlm_library(l))) {
 889                 lp->tl_capability_barcodes = TRUE;
 890                 syslog(LOG_DEBUG,
 891                     "Barcode capability on library %d enabled.", l);
 892         }
 893 }
 894 
 895 /*
 896  * SASD SCSI support
 897  */
 898 static scsi_adapter_t my_sa;
 899 static int sasd_drive_count = 0;
 900 static scsi_sasd_drive_t *scsi_sasd_drives[128];
 901 
 902 /*
 903  * Count of SCSI devices
 904  */
 905 int
 906 sasd_dev_count(void)
 907 {
 908         return (sasd_drive_count);
 909 }
 910 
 911 /*
 912  * Return the SCSI device name
 913  */
 914 char *
 915 sasd_slink_name(scsi_link_t *slink)
 916 {
 917         int i;
 918 
 919         for (i = 0; i < sasd_drive_count; i++) {
 920                 if (&scsi_sasd_drives[i]->ss_slink == slink)
 921                         return (scsi_sasd_drives[i]->ss_sd.sd_name);
 922         }
 923         return (NULL);
 924 }
 925 
 926 /*
 927  * Return the SCSI drive structure
 928  */
 929 sasd_drive_t *
 930 sasd_slink_drive(scsi_link_t *slink)
 931 {
 932         int i;
 933 
 934         for (i = 0; i < sasd_drive_count; i++) {
 935                 if (&scsi_sasd_drives[i]->ss_slink == slink)
 936                         return (&scsi_sasd_drives[i]->ss_sd);
 937         }
 938         return (NULL);
 939 }
 940 
 941 /*
 942  * Return the SCSI link pointer for the given index
 943  */
 944 scsi_link_t *
 945 sasd_dev_slink(int entry)
 946 {
 947         scsi_link_t *rv;
 948 
 949         if (entry >= 0 && entry < sasd_drive_count)
 950                 rv = &scsi_sasd_drives[entry]->ss_slink;
 951         else
 952                 rv = NULL;
 953 
 954         return (rv);
 955 }
 956 
 957 /*
 958  * Return the SCSI drive for the given index
 959  */
 960 sasd_drive_t *
 961 sasd_drive(int entry)
 962 {
 963         sasd_drive_t *rv;
 964 
 965         if (entry >= 0 && entry < sasd_drive_count)
 966                 rv = &scsi_sasd_drives[entry]->ss_sd;
 967         else
 968                 rv = NULL;
 969 
 970         return (rv);
 971 }
 972 
 973 /*
 974  * Attach the SCSI device by updating the structures
 975  */
 976 void
 977 scsi_sasd_attach(scsi_adapter_t *sa, int sid, int lun, char *name,
 978     int type)
 979 {
 980         scsi_link_t *sl, *next;
 981         scsi_sasd_drive_t *ssd;
 982 
 983         ssd = ndmp_malloc(sizeof (scsi_sasd_drive_t));
 984         if (ssd == NULL)
 985                 return;
 986 
 987         scsi_sasd_drives[sasd_drive_count++] = ssd;
 988 
 989         switch (type) {
 990         case DTYPE_CHANGER:
 991                 (void) snprintf(ssd->ss_sd.sd_name,
 992                     sizeof (ssd->ss_sd.sd_name), "%s/%s", SCSI_CHANGER_DIR,
 993                     name);
 994                 break;
 995         case DTYPE_SEQUENTIAL:
 996                 (void) snprintf(ssd->ss_sd.sd_name,
 997                     sizeof (ssd->ss_sd.sd_name), "%s/%s", SCSI_TAPE_DIR, name);
 998                 break;
 999         }
1000 
1001         sl = &ssd->ss_slink;
1002         sl->sl_type = type;
1003         sl->sl_sa = sa;
1004         sl->sl_lun = lun;
1005         sl->sl_sid = sid;
1006         sl->sl_requested_max_active = 1;
1007 
1008         /* Insert slink */
1009         next = sa->sa_link_head.sl_next;
1010         sa->sa_link_head.sl_next = sl;
1011         sl->sl_next = next;
1012 }
1013 
1014 /*
1015  * Go through the attached devices and detect the tape
1016  * and robot by checking the /dev entries
1017  */
1018 int
1019 probe_scsi(void)
1020 {
1021         DIR *dirp;
1022         struct dirent *dp;
1023         scsi_adapter_t *sa = &my_sa;
1024         char *p;
1025         int lun = 0;
1026         int sid = 0;
1027         char *drive_type;
1028 
1029         /* Initialize the scsi adapter link */
1030         sa->sa_link_head.sl_next = &sa->sa_link_head;
1031 
1032         /* Scan for the changer */
1033         dirp = opendir(SCSI_CHANGER_DIR);
1034         if (dirp == NULL) {
1035                 syslog(LOG_DEBUG,
1036                     "Changer directory read error %s", SCSI_CHANGER_DIR);
1037         } else {
1038                 while ((dp = readdir(dirp)) != NULL) {
1039                         if ((strcmp(dp->d_name, ".") == 0) ||
1040                             (strcmp(dp->d_name, "..") == 0))
1041                                 continue;
1042 
1043                         if ((p = strchr(dp->d_name, 'd')) != NULL) {
1044                                 lun = atoi(++p);
1045                                 p = strchr(dp->d_name, 't');
1046                                 sid = atoi(++p);
1047                         }
1048                         else
1049                                 sid = atoi(dp->d_name);
1050 
1051                         scsi_sasd_attach(sa, 0, lun, dp->d_name,
1052                             DTYPE_CHANGER);
1053                 }
1054                 (void) closedir(dirp);
1055         }
1056 
1057         /* Scan for tape drives */
1058         dirp = opendir(SCSI_TAPE_DIR);
1059         if (dirp == NULL) {
1060                 syslog(LOG_DEBUG,
1061                     "Tape directory read error %s", SCSI_TAPE_DIR);
1062         } else {
1063                 drive_type = ndmpd_get_prop(NDMP_DRIVE_TYPE);
1064 
1065                 if ((strcasecmp(drive_type, "sysv") != 0) &&
1066                     (strcasecmp(drive_type, "bsd") != 0)) {
1067                         syslog(LOG_ERR, "Invalid ndmpd/drive-type value. "
1068                             "Valid values are 'sysv' and 'bsd'.");
1069                         return (-1);
1070                 }
1071 
1072                 while ((dp = readdir(dirp)) != NULL) {
1073                         if ((strcmp(dp->d_name, ".") == 0) ||
1074                             (strcmp(dp->d_name, "..") == 0))
1075                                 continue;
1076 
1077                         /* Skip special modes */
1078                         if (strpbrk(dp->d_name, "chlmu") != NULL)
1079                                 continue;
1080 
1081                         /* Pick the non-rewind device */
1082                         if (strchr(dp->d_name, 'n') == NULL)
1083                                 continue;
1084 
1085                         if (strcasecmp(drive_type, "sysv") == 0) {
1086                                 if (strchr(dp->d_name, 'b') != NULL)
1087                                         continue;
1088                         } else if (strcasecmp(drive_type, "bsd") == 0) {
1089                                 if (strchr(dp->d_name, 'b') == NULL)
1090                                         continue;
1091                         }
1092 
1093                         sid = atoi(dp->d_name);
1094 
1095                         /*
1096                          * SCSI ID should match with the ID of the device
1097                          * (will be checked by SCSI get elements page later)
1098                          */
1099                         scsi_sasd_attach(sa, sid, 0, dp->d_name,
1100                             DTYPE_SEQUENTIAL);
1101                 }
1102                 (void) closedir(dirp);
1103         }
1104 
1105         return (0);
1106 }
1107 
1108 /*
1109  * Get the SCSI device type (tape, robot)
1110  */
1111 /*ARGSUSED*/
1112 int
1113 scsi_get_devtype(char *adapter, int sid, int lun)
1114 {
1115         int rv;
1116         scsi_adapter_t *sa = &my_sa;
1117         scsi_link_t *sl, *sh;
1118 
1119         rv = -1;
1120         sh = &sa->sa_link_head;
1121         for (sl = sh->sl_next; sl != sh; sl = sl->sl_next)
1122                 if (sl->sl_sid == sid && sl->sl_lun == lun)
1123                         rv = sl->sl_type;
1124 
1125         return (rv);
1126 }
1127 
1128 
1129 /*
1130  * Check if the SCSI device exists
1131  */
1132 /*ARGSUSED*/
1133 int
1134 scsi_dev_exists(char *adapter, int sid, int lun)
1135 {
1136         scsi_adapter_t *sa = &my_sa;
1137         scsi_link_t *sl, *sh;
1138 
1139         sh = &sa->sa_link_head;
1140         for (sl = sh->sl_next; sl != sh; sl = sl->sl_next)
1141                 if (sl->sl_sid == sid && sl->sl_lun == lun)
1142                         return (1);
1143         return (0);
1144 }
1145 
1146 
1147 /*
1148  * Count of SCSI adapters
1149  */
1150 int
1151 scsi_get_adapter_count(void)
1152 {
1153         /* Currently support one adapter only */
1154         return (1);
1155 }
1156 
1157 /*
1158  * Return the SCSI adapter structure
1159  */
1160 /*ARGSUSED*/
1161 scsi_adapter_t *
1162 scsi_get_adapter(int adapter)
1163 {
1164         return (&my_sa);
1165 }
1166 
1167 /*
1168  * IOCTL wrapper with retries
1169  */
1170 int
1171 tlm_ioctl(int fd, int cmd, void *data)
1172 {
1173         int retries = 0;
1174 
1175         syslog(LOG_DEBUG, "tlm_ioctl fd %d cmd %d", fd, cmd);
1176         if (fd == 0 || data == NULL)
1177                 return (EINVAL);
1178 
1179         do {
1180                 if (ioctl(fd, cmd, data) == 0)
1181                         break;
1182 
1183                 if (errno != EIO && errno != 0) {
1184                         syslog(LOG_ERR,
1185                             "Failed to send command to device: %m.");
1186                         syslog(LOG_DEBUG, "IOCTL error %d", errno);
1187                         return (errno);
1188                 }
1189                 (void) sleep(1);
1190         } while (retries++ < MAXIORETRY);
1191 
1192         return (0);
1193 }
1194 
1195 /*
1196  * Checkpoint or snapshot calls
1197  */
1198 
1199 /*
1200  * Get the snapshot creation time
1201  */
1202 int
1203 chkpnt_creationtime_bypattern(char *volname, char *pattern, time_t *tp)
1204 {
1205         char chk_name[PATH_MAX];
1206         zfs_handle_t *zhp;
1207         char *p;
1208 
1209         if (!volname || !*volname)
1210                 return (-1);
1211 
1212         /* Should also return -1 if checkpoint not enabled */
1213 
1214         /* Remove the leading slash */
1215         p = volname;
1216         while (*p == '/')
1217                 p++;
1218 
1219         (void) strlcpy(chk_name, p, PATH_MAX);
1220         (void) strlcat(chk_name, "@", PATH_MAX);
1221         (void) strlcat(chk_name, pattern, PATH_MAX);
1222 
1223         (void) mutex_lock(&zlib_mtx);
1224         if ((zhp = zfs_open(zlibh, chk_name, ZFS_TYPE_DATASET)) == NULL) {
1225                 syslog(LOG_DEBUG, "chkpnt_creationtime: open %s failed",
1226                     chk_name);
1227                 (void) mutex_unlock(&zlib_mtx);
1228                 return (-1);
1229         }
1230 
1231         *tp = zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
1232         zfs_close(zhp);
1233         (void) mutex_unlock(&zlib_mtx);
1234 
1235         return (0);
1236 }
1237 
1238 
1239 /*
1240  * Get the ZFS volume name out of the given path
1241  */
1242 int
1243 get_zfsvolname(char *volname, int len, char *path)
1244 {
1245         struct stat64 stbuf;
1246         struct extmnttab ent;
1247         FILE *mntfp;
1248         int rv = 0;
1249 
1250         *volname = '\0';
1251         if (stat64(path, &stbuf) != 0) {
1252                 syslog(LOG_DEBUG, "stat64 failed open %s - %s",
1253                     volname, path);
1254                 return (-1);
1255         }
1256 
1257         if ((mntfp = fopen(MNTTAB, "r")) == NULL) {
1258                 syslog(LOG_DEBUG, "failed open mnttab");
1259                 return (-1);
1260         }
1261         while ((rv = getextmntent(mntfp, &ent, 0)) == 0) {
1262                 if (makedevice(ent.mnt_major, ent.mnt_minor) ==
1263                     stbuf.st_dev)
1264                         break;
1265         }
1266 
1267         if (rv == 0 &&
1268             strcmp(ent.mnt_fstype, MNTTYPE_ZFS) == 0) {
1269                 (void) strlcpy(volname, ent.mnt_special, len);
1270         } else {
1271                 rv = -1;
1272         }
1273         (void) fclose(mntfp);
1274         return (rv);
1275 }
1276 
1277 
1278 /*
1279  * Check if the volume type is snapshot volume
1280  */
1281 boolean_t
1282 fs_is_chkpntvol(char *path)
1283 {
1284         zfs_handle_t *zhp;
1285         char vol[ZFS_MAX_DATASET_NAME_LEN];
1286 
1287         if (!path || !*path)
1288                 return (FALSE);
1289 
1290         if (get_zfsvolname(vol, sizeof (vol), path) == -1)
1291                 return (FALSE);
1292 
1293         (void) mutex_lock(&zlib_mtx);
1294         if ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) == NULL) {
1295                 (void) mutex_unlock(&zlib_mtx);
1296                 return (FALSE);
1297         }
1298 
1299         if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) {
1300                 zfs_close(zhp);
1301                 (void) mutex_unlock(&zlib_mtx);
1302                 return (FALSE);
1303         }
1304         zfs_close(zhp);
1305         (void) mutex_unlock(&zlib_mtx);
1306 
1307         return (TRUE);
1308 }
1309 
1310 /*
1311  * Check if the volume is capable of checkpoints
1312  */
1313 boolean_t
1314 fs_is_chkpnt_enabled(char *path)
1315 {
1316         zfs_handle_t *zhp;
1317         char vol[ZFS_MAX_DATASET_NAME_LEN];
1318 
1319         if (!path || !*path)
1320                 return (FALSE);
1321 
1322         (void) mutex_lock(&zlib_mtx);
1323         if (get_zfsvolname(vol, sizeof (vol), path) == -1) {
1324                 (void) mutex_unlock(&zlib_mtx);
1325                 return (FALSE);
1326         }
1327 
1328         if ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) == NULL) {
1329                 (void) mutex_unlock(&zlib_mtx);
1330                 return (FALSE);
1331         }
1332         zfs_close(zhp);
1333         (void) mutex_unlock(&zlib_mtx);
1334 
1335         return (TRUE);
1336 }
1337 
1338 /*
1339  * Check if the volume is read-only
1340  */
1341 boolean_t
1342 fs_is_rdonly(char *path)
1343 {
1344         return (fs_is_chkpntvol(path));
1345 }
1346 
1347 /*
1348  * Min/max functions
1349  */
1350 unsigned
1351 min(unsigned a, unsigned b)
1352 {
1353         return (a < b ? a : b);
1354 }
1355 
1356 unsigned
1357 max(unsigned a, unsigned b)
1358 {
1359         return (a > b ? a : b);
1360 }
1361 
1362 longlong_t
1363 llmin(longlong_t a, longlong_t b)
1364 {
1365         return (a < b ? a : b);
1366 }