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