Print this page
    
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/ndmp/ndmpd_dtime.c
          +++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_dtime.c
   1    1  /*
   2    2   * Copyright (c) 2008, 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
  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
  
    | 
      ↓ open down ↓ | 
    31 lines elided | 
    
      ↑ open up ↑ | 
  
  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   39  
  40   40  #include <sys/param.h>
  41   41  #include <sys/types.h>
       42 +#include <syslog.h>
  42   43  #include <ctype.h>
  43   44  #include <errno.h>
  44   45  #include <fcntl.h>
  45   46  #include <limits.h>
  46   47  #include <stdarg.h>
  47   48  #include <stdio.h>
  48   49  #include <stdlib.h>
  49   50  #include <string.h>
  50   51  #include <time.h>
  51   52  #include <unistd.h>
  52   53  #include <libnvpair.h>
  53      -#include "ndmpd_log.h"
  54   54  #include "ndmpd.h"
  55   55  
  56   56  /*
  57   57   * The dumpdates file on file system.
  58   58   */
  59   59  #define NDMP_DUMPDATES  "dumpdates"
  60   60  
  61   61  
  62   62  /*
  63   63   * Offsets into the ctime string to various parts.
  64   64   */
  65   65  #define E_MONTH         4
  66   66  #define E_DAY           8
  67   67  #define E_HOUR          11
  68   68  #define E_MINUTE        14
  69   69  #define E_SECOND        17
  70   70  #define E_YEAR          20
  71   71  
  72   72  
  73   73  /*
  74   74   * The contents of the file dumpdates is maintained on a linked list.
  75   75   */
  76   76  typedef struct dumpdates {
  77   77          char dd_name[TLM_MAX_PATH_NAME];
  78   78          char dd_level;
  79   79          time_t dd_ddate;
  80   80          struct dumpdates *dd_next;
  81   81  } dumpdates_t;
  82   82  
  83   83  
  84   84  /*
  85   85   * Month names used in ctime string.
  86   86   */
  87   87  static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
  88   88  
  89   89  
  90   90  /*
  91   91   * Binary lock for accessing the dumpdates file.
  92   92   */
  93   93  mutex_t ndmp_dd_lock = DEFAULTMUTEX;
  94   94  
  95   95  int ndmp_isdst = -1;
  96   96  
  97   97  char *zfs_dumpdate_props[] = {
  98   98          "dumpdates:level0",
  99   99          "dumpdates:level1",
 100  100          "dumpdates:level2",
 101  101          "dumpdates:level3",
 102  102          "dumpdates:level4",
 103  103          "dumpdates:level5",
 104  104          "dumpdates:level6",
 105  105          "dumpdates:level7",
 106  106          "dumpdates:level8",
 107  107          "dumpdates:level9",
 108  108  };
 109  109  
 110  110  
 111  111  /*
 112  112   * lookup
 113  113   *
 114  114   * Look up the month (3-character) name and return its number.
 115  115   *
 116  116   * Returns -1 if the months name is not valid.
 117  117   */
 118  118  static int
 119  119  lookup(char *str)
 120  120  {
 121  121          register char *cp, *cp2;
 122  122  
 123  123          if (!str)
 124  124                  return (-1);
 125  125  
 126  126          for (cp = months, cp2 = str; *cp != '\0'; cp += 3)
 127  127                  if (strncmp(cp, cp2, 3) == 0)
 128  128                          return ((cp-months) / 3);
 129  129          return (-1);
 130  130  }
 131  131  
 132  132  
 133  133  /*
 134  134   * unctime
 135  135   *
 136  136   * Convert a ctime(3) format string into a system format date.
 137  137   * Return the date thus calculated.
 138  138   *
 139  139   * Return -1 if the string is not in ctime format.
 140  140   */
 141  141  static int
 142  142  unctime(char *str, time_t *t)
 143  143  {
 144  144          struct tm then;
 145  145          char dbuf[26];
 146  146  
 147  147          if (!str || !t)
 148  148                  return (-1);
 149  149  
 150  150          (void) memset(&then, 0, sizeof (then));
 151  151          (void) strlcpy(dbuf, str, sizeof (dbuf) - 1);
 152  152          dbuf[sizeof (dbuf) - 1] = '\0';
 153  153          dbuf[E_MONTH+3] = '\0';
  
    | 
      ↓ open down ↓ | 
    90 lines elided | 
    
      ↑ open up ↑ | 
  
 154  154          if ((then.tm_mon = lookup(&dbuf[E_MONTH])) < 0)
 155  155                  return (-1);
 156  156  
 157  157          then.tm_mday = atoi(&dbuf[E_DAY]);
 158  158          then.tm_hour = atoi(&dbuf[E_HOUR]);
 159  159          then.tm_min = atoi(&dbuf[E_MINUTE]);
 160  160          then.tm_sec = atoi(&dbuf[E_SECOND]);
 161  161          then.tm_year = atoi(&dbuf[E_YEAR]) - 1900;
 162  162          then.tm_isdst = ndmp_isdst;
 163  163  
 164      -        NDMP_LOG(LOG_DEBUG,
      164 +        syslog(LOG_DEBUG,
 165  165              "yday %d wday %d %d/%d/%d %02d:%02d:%02d",
 166  166              then.tm_yday, then.tm_wday, then.tm_year, then.tm_mon,
 167  167              then.tm_mday, then.tm_hour, then.tm_min, then.tm_sec);
 168  168  
 169  169          *t = mktime(&then);
 170  170  
 171  171          return (0);
 172  172  }
 173  173  
 174  174  
 175  175  /*
 176  176   * ddates_pathname
 177  177   *
 178  178   * Create the dumpdates file full path name.
 179  179   */
 180  180  static char *
 181  181  ddates_pathname(char *buf)
 182  182  {
 183  183          return (ndmpd_make_bk_dir_path(buf, NDMP_DUMPDATES));
 184  184  }
 185  185  
 186  186  
 187  187  /*
 188  188   * getaline
 189  189   *
 190  190   * Get a line from the file and handle the continued lines.
 191  191   */
 192  192  static char *
 193  193  getaline(FILE *fp, char *line, int llen)
 194  194  {
 195  195          char *save;
 196  196          int len;
 197  197  
 198  198          if (!fp || !line)
 199  199                  return (NULL);
 200  200  
 201  201          *(save = line) = '\0';
 202  202          do {
 203  203                  if (fgets(line, llen, fp) != line)
 204  204                          return (NULL);
 205  205  
 206  206                  /* comment line? */
 207  207                  if (*line == '#')
 208  208                          continue;
 209  209  
 210  210                  len = strlen(line);
 211  211                  /* short line */
 212  212                  if (len <= 0)
 213  213                          continue;
 214  214  
 215  215                  line += len-1;
 216  216                  if (*line != '\n')
 217  217                          return (NULL);
 218  218  
 219  219                  /* trim the trailing new line */
 220  220                  *line = '\0';
 221  221                  if (--len <= 0)
 222  222                          break;
 223  223  
 224  224                  if (*(line-1) != '\\')
 225  225                          break;
 226  226  
 227  227                  *(line-1) = '\n';
 228  228                  llen -= len;
 229  229          } while (llen > 0);
 230  230  
 231  231          return (save);
 232  232  }
 233  233  
 234  234  
 235  235  /*
 236  236   * get_ddname
 237  237   *
 238  238   * Get the path name from the buffer passed.
 239  239   *
 240  240   * Returns the beginning of the path name.  The buffer pointer is moved
 241  241   * forward to point to where the next field (the dump level) begins.
 242  242   */
 243  243  static char *
 244  244  get_ddname(char **bpp)
 245  245  {
 246  246          char *h, *t, *save;
 247  247  
 248  248          if (!bpp || !*bpp)
 249  249                  return (NULL);
 250  250  
 251  251          *bpp += strspn(*bpp, "\t ");
 252  252          save = h = t = *bpp;
 253  253          while (*t) {
 254  254                  if (*t == '\t' || *t == ' ') {
 255  255                          /* consume the '\t' or space character */
 256  256                          t++;
 257  257                          break;
 258  258                  }
 259  259  
 260  260                  if (*t == '\\')
 261  261                          switch (*(t+1)) {
 262  262                          case '\t':
 263  263                          case ' ':
 264  264                                  t++; /* skip the '\\' */
 265  265                          default:
 266  266                                  break;  /* nothing */
 267  267                          }
 268  268  
 269  269                  *h++ = *t++;
 270  270          }
 271  271  
 272  272          *bpp = t;
 273  273          *h++ = '\0';
 274  274          return (save);
 275  275  }
 276  276  
 277  277  
 278  278  /*
 279  279   * get_ddlevel
 280  280   *
 281  281   * Get the dump level from the buffer passed.
 282  282   *
 283  283   * Returns the dump level found.  The buffer pointer is moved
 284  284   * forward to point to where the next field (the dump date) begins.
 285  285   */
 286  286  static int
 287  287  get_ddlevel(char **bpp)
 288  288  {
 289  289          char *t, *save;
 290  290  
  
    | 
      ↓ open down ↓ | 
    116 lines elided | 
    
      ↑ open up ↑ | 
  
 291  291          if (!bpp || !*bpp)
 292  292                  return (-1);
 293  293  
 294  294          *bpp += strspn(*bpp, "\t ");
 295  295          save = t = *bpp;
 296  296  
 297  297          /*
 298  298           * For 'F', 'A', 'I', and 'D' return the character itself.
 299  299           */
 300  300          if (IS_LBR_BKTYPE(*t)) {
 301      -                NDMP_LOG(LOG_DEBUG, "Lbr bk type %c", *t);
      301 +                syslog(LOG_DEBUG, "Lbr bk type %c", *t);
 302  302                  /*
 303  303                   * Skip the backup type character and null terminate the
 304  304                   * string.
 305  305                   */
 306  306                  *++t = '\0';
 307  307                  *bpp = ++t;
 308  308                  return (toupper(*save));
 309  309          }
 310  310  
 311  311          while (isdigit(*t))
 312  312                  t++;
 313  313  
 314  314          *t++ = '\0';
 315  315          *bpp = t;
 316  316          return (atoi(save));
 317  317  }
 318  318  
 319  319  
 320  320  /*
 321  321   * get_ddate
 322  322   *
 323  323   * Get the dump date from the buffer passed.
 324  324   *
 325  325   * Returns the dump date string. The buffer pointer is moved
 326  326   * forward.  It points to the end of the buffer now.
 327  327   */
 328  328  static char *
 329  329  get_ddate(char **bpp)
 330  330  {
 331  331          char *save;
 332  332  
 333  333          if (!bpp || !*bpp)
 334  334                  return (NULL);
 335  335  
 336  336          *bpp += strspn(*bpp, "\t ");
 337  337          save = *bpp;
 338  338          *bpp += strlen(*bpp);
 339  339          return (save);
 340  340  }
 341  341  
 342  342  
 343  343  /*
 344  344   * put_ddname
 345  345   *
 346  346   * Print the dump path name to the dumpdates file.  It escapes the space,
 347  347   * '\t' and new line characters in the path name.  The same characters are
 348  348   * considered in the get_ddname().
 349  349   */
 350  350  static void
 351  351  put_ddname(FILE *fp, char *nm)
 352  352  {
 353  353          if (!nm)
 354  354                  return;
 355  355  
 356  356          while (*nm)
 357  357                  switch (*nm) {
 358  358                  case ' ':
 359  359                  case '\n':
 360  360                  case '\t':
 361  361                          (void) fputc('\\', fp);
 362  362                          /* FALLTHROUGH */
 363  363                  default:
 364  364                          (void) fputc(*nm++, fp);
 365  365                  }
 366  366  }
 367  367  
 368  368  
 369  369  /*
 370  370   * put_ddlevel
 371  371   *
 372  372   * Print the dump level into the dumpdates file.
 373  373   */
 374  374  static void
 375  375  put_ddlevel(FILE *fp, int level)
 376  376  {
 377  377          if (!fp)
 378  378                  return;
 379  379  
 380  380          (void) fprintf(fp, IS_LBR_BKTYPE(level) ? "%c" : "%d", level);
 381  381  }
 382  382  
 383  383  
 384  384  /*
 385  385   * put_ddate
 386  386   *
  
    | 
      ↓ open down ↓ | 
    75 lines elided | 
    
      ↑ open up ↑ | 
  
 387  387   * Print the dump date into the dumpdates file.
 388  388   */
 389  389  static void put_ddate(FILE *fp,
 390  390          time_t t)
 391  391  {
 392  392          char tbuf[64];
 393  393  
 394  394          if (!fp)
 395  395                  return;
 396  396  
 397      -        NDMP_LOG(LOG_DEBUG, "[%u]", t);
 398      -
 399  397          (void) ctime_r(&t, tbuf, sizeof (tbuf));
 400  398          /* LINTED variable format specifier */
 401  399          (void) fprintf(fp, tbuf);
 402  400  }
 403  401  
 404  402  
 405  403  /*
 406  404   * dd_free
 407  405   *
 408  406   * Free the linked list of dumpdates entries.
 409  407   */
 410  408  static void
 411  409  dd_free(dumpdates_t *ddheadp)
 412  410  {
 413  411          dumpdates_t *save;
 414  412  
 415  413          if (!ddheadp)
 416  414                  return;
 417  415  
 418  416          ddheadp = ddheadp->dd_next;
 419  417          while (ddheadp) {
 420  418                  save = ddheadp->dd_next;
 421  419                  free(ddheadp);
 422  420                  ddheadp = save;
 423  421          }
 424  422  }
 425  423  
 426  424  
 427  425  /*
 428  426   * makedumpdate
 429  427   *
 430  428   * Make the dumpdate node based on the string buffer passed to it.
 431  429   */
 432  430  static int
 433  431  makedumpdate(dumpdates_t *ddp, char *tbuf)
 434  432  {
 435  433          char *nmp, *un_buf;
 436  434          int rv;
 437  435  
 438  436          /*
  
    | 
      ↓ open down ↓ | 
    30 lines elided | 
    
      ↑ open up ↑ | 
  
 439  437           * While parsing each line, if a line contains one of the
 440  438           * LBR-type levels, then checking the return value of
 441  439           * get_ddlevel() against negative values, it OK.  Because
 442  440           * neither of the 'F', 'A', 'I' nor 'D' have negative
 443  441           * ASCII value.
 444  442           */
 445  443          if (!ddp || !tbuf)
 446  444                  rv = -1;
 447  445          else if (!(nmp = get_ddname(&tbuf))) {
 448  446                  rv = -1;
 449      -                NDMP_LOG(LOG_DEBUG, "get_ddname failed 0x%p", nmp);
      447 +                syslog(LOG_ERR, "get_ddname failed 0x%p", nmp);
 450  448          } else if ((ddp->dd_level = get_ddlevel(&tbuf)) < 0) {
 451  449                  rv = -1;
 452      -                NDMP_LOG(LOG_DEBUG, "dd_level < 0 %d", ddp->dd_level);
      450 +                syslog(LOG_ERR, "dd_level < 0 %d", ddp->dd_level);
 453  451          } else if (!(un_buf = get_ddate(&tbuf))) {
 454  452                  rv = -1;
 455      -                NDMP_LOG(LOG_DEBUG, "get_ddate failed 0x%p", un_buf);
      453 +                syslog(LOG_ERR, "get_ddate failed 0x%p", un_buf);
 456  454          } else if (unctime(un_buf, &ddp->dd_ddate) < 0) {
 457  455                  rv = -1;
 458      -                NDMP_LOG(LOG_DEBUG, "unctime failed \"%s\"", un_buf);
      456 +                syslog(LOG_ERR, "unctime failed \"%s\"", un_buf);
 459  457          } else {
 460  458                  (void) strlcpy(ddp->dd_name, nmp, TLM_MAX_PATH_NAME);
 461  459                  rv = 0;
 462  460          }
 463  461  
 464  462          return (rv);
 465  463  }
 466  464  
 467  465  
 468  466  /*
 469  467   * getrecord
 470  468   *
 471  469   * Read a record of dumpdates file and parse it.
 472  470   * The records that span multiple lines are covered.
 473  471   *
 474  472   * Returns:
 475  473   *   0 on success
 476  474   *   < 0 on error
 477  475   */
 478  476  static int
 479  477  getrecord(FILE *fp, dumpdates_t *ddatep, int *recno)
 480  478  {
 481  479          char tbuf[BUFSIZ];
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
 482  480  
 483  481          if (!fp || !ddatep || !recno)
 484  482                  return (-1);
 485  483  
 486  484          do {
 487  485                  if (getaline(fp, tbuf, sizeof (tbuf)) != tbuf)
 488  486                          return (-1);
 489  487          } while (!*tbuf);
 490  488  
 491  489          if (makedumpdate(ddatep, tbuf) < 0)
 492      -                NDMP_LOG(LOG_DEBUG,
      490 +                syslog(LOG_ERR,
 493  491                      "Unknown intermediate format in %s, line %d", tbuf, *recno);
 494  492  
 495  493          (*recno)++;
 496  494  
 497      -        if (IS_LBR_BKTYPE(ddatep->dd_level & 0xff)) {
 498      -                NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]",
 499      -                    ddatep->dd_name, ddatep->dd_level, ddatep->dd_ddate);
 500      -        } else
 501      -                NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]",
 502      -                    ddatep->dd_name, ddatep->dd_level, ddatep->dd_ddate);
 503      -
 504  495          return (0);
 505  496  }
 506  497  
 507  498  
 508  499  /*
 509  500   * readdumptimes
 510  501   *
 511  502   * Read the dumpdates file and make a linked list of its entries.
 512  503   *
 513  504   * Returns:
 514  505   *   0 on success
 515  506   *   < 0 on error
 516  507   */
 517  508  static int
 518  509  readdumptimes(FILE *fp, dumpdates_t *ddheadp)
 519  510  {
 520  511          int recno;
 521  512          register struct dumpdates *ddwalk;
 522  513  
 523  514          if (!fp || !ddheadp)
 524  515                  return (-1);
 525  516  
 526  517          recno = 1;
 527  518          (void) memset((void *)ddheadp, 0, sizeof (*ddheadp));
 528  519          for (; ; ) {
 529  520                  ddwalk = ndmp_malloc(sizeof (*ddwalk));
 530  521                  if (!ddwalk)
 531  522                          return (-1);
 532  523  
 533  524                  if (getrecord(fp, ddwalk, &recno) < 0) {
 534  525                          free(ddwalk);
 535  526                          break;
 536  527                  }
 537  528  
 538  529                  ddwalk->dd_next = ddheadp->dd_next;
 539  530                  ddheadp->dd_next = ddwalk;
 540  531                  ddheadp = ddwalk;
 541  532          }
 542  533  
 543  534          return (0);
 544  535  }
 545  536  
 546  537  
 547  538  /*
  
    | 
      ↓ open down ↓ | 
    34 lines elided | 
    
      ↑ open up ↑ | 
  
 548  539   * dumprecout
 549  540   *
 550  541   * Print a record into the dumpdates file.
 551  542   */
 552  543  static void
 553  544  dumprecout(FILE *fp, dumpdates_t *ddp)
 554  545  {
 555  546          if (!ddp)
 556  547                  return;
 557  548  
 558      -        if (IS_LBR_BKTYPE(ddp->dd_level)) {
 559      -                NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]",
 560      -                    ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
 561      -        } else
 562      -                NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]",
 563      -                    ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
 564      -
 565  549          put_ddname(fp, ddp->dd_name);
 566  550          (void) fputc('\t', fp);
 567  551          put_ddlevel(fp, ddp->dd_level);
 568  552          (void) fputc('\t', fp);
 569  553          put_ddate(fp, ddp->dd_ddate);
 570  554  }
 571  555  
 572  556  
 573  557  /*
 574  558   * initdumptimes
 575  559   *
 576  560   * Open the dumpdates file and read it into memory.
 577  561   *
 578  562   * Returns:
 579  563   *   0 on success
 580  564   *   < 0 on error
 581  565   *
 582  566   */
 583  567  static int
 584  568  initdumptimes(dumpdates_t *ddheadp)
 585  569  {
 586  570          char fname[PATH_MAX];
 587  571          int rv;
 588  572          FILE *fp;
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
 589  573  
 590  574          if (!ddheadp)
 591  575                  return (-1);
 592  576  
 593  577          if (!ddates_pathname(fname))
 594  578                  return (-1);
 595  579  
 596  580          fp = fopen(fname, "r");
 597  581          if (!fp) {
 598  582                  if (errno != ENOENT) {
 599      -                        NDMP_LOG(LOG_ERR, "Cannot read %s: %m.", fname);
      583 +                        syslog(LOG_ERR, "Cannot read %s: %m.", fname);
 600  584                          return (-1);
 601  585                  }
 602  586                  /*
 603  587                   * Dumpdates does not exist, make an empty one.
 604  588                   */
 605      -                NDMP_LOG(LOG_DEBUG,
      589 +                syslog(LOG_DEBUG,
 606  590                      "No file `%s', making an empty one", fname);
 607  591  
 608  592                  fp = fopen(fname, "w");
 609  593                  if (!fp) {
 610      -                        NDMP_LOG(LOG_ERR, "Cannot create %s: %m.", fname);
      594 +                        syslog(LOG_ERR, "Cannot create %s: %m.", fname);
 611  595                          return (-1);
 612  596                  }
 613  597                  (void) fclose(fp);
 614  598  
 615  599                  fp = fopen(fname, "r");
 616  600                  if (!fp) {
 617      -                        NDMP_LOG(LOG_ERR,
      601 +                        syslog(LOG_ERR,
 618  602                              "Cannot read %s after creating it. %m.", fname);
 619  603                          return (-1);
 620  604                  }
 621  605          }
 622  606  
 623  607          rv = readdumptimes(fp, ddheadp);
 624  608          (void) fclose(fp);
 625  609  
 626  610          return (rv);
 627  611  }
 628  612  
 629  613  
 630  614  /*
 631  615   * putdumptime
 632  616   *
 633  617   * Put the record specified by path, level and backup date to the file.
 634  618   * Update the record if such entry already exists; append if not.
 635  619   *
 636  620   * Returns:
 637  621   *   0 on success
 638  622   *   < 0 on error
 639  623   */
 640  624  static int
 641  625  putdumptime(char *path, int level, time_t ddate)
 642  626  {
 643  627          int found;
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
 644  628          char fname[PATH_MAX], bakfname[PATH_MAX];
 645  629          FILE *rfp, *wfp;
 646  630          dumpdates_t ddhead, tmpdd;
 647  631          register dumpdates_t *ddp;
 648  632          int rv;
 649  633  
 650  634          if (!path)
 651  635                  return (-1);
 652  636  
 653  637          if (IS_LBR_BKTYPE(level)) {
 654      -                NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]", path, level, ddate);
      638 +                syslog(LOG_DEBUG, "Lbr: [%s][%c][%u]", path, level, ddate);
 655  639          } else {
 656      -                NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]", path, level, ddate);
      640 +                syslog(LOG_DEBUG, "[%s][%d][%u]", path, level, ddate);
 657  641          }
 658  642  
 659  643          if (!ddates_pathname(fname)) {
 660      -                NDMP_LOG(LOG_ERR, "Cannot get dumpdate file path name.");
      644 +                syslog(LOG_ERR, "Cannot get dumpdate file path name.");
 661  645                  return (-1);
 662  646          }
 663  647  
 664  648          rfp = fopen(fname, "r");
 665  649          if (!rfp) {
 666      -                NDMP_LOG(LOG_DEBUG, "Creating %s.", fname);
      650 +                syslog(LOG_DEBUG, "Creating %s.", fname);
 667  651                  (void) memset((void *)&ddhead, 0, sizeof (ddhead));
 668  652                  if (initdumptimes(&ddhead) < 0) {
 669      -                        NDMP_LOG(LOG_ERR, "Could not initialize %s.",
      653 +                        syslog(LOG_ERR, "Could not initialize %s.",
 670  654                              NDMP_DUMPDATES);
 671  655                          dd_free(&ddhead);
 672  656                          return (-1);
 673  657                  }
 674  658          } else {
 675  659                  rv = readdumptimes(rfp, &ddhead);
 676  660  
 677  661                  if (rv < 0) {
 678      -                        NDMP_LOG(LOG_ERR, "Error reading dumpdates file.");
      662 +                        syslog(LOG_ERR, "Error reading dumpdates file.");
 679  663                          (void) fclose(rfp);
 680  664                          dd_free(&ddhead);
 681  665                          return (-1);
 682  666                  }
 683  667                  (void) fclose(rfp);
 684  668          }
 685  669  
 686  670          (void) snprintf(bakfname, PATH_MAX, "%s.bak", fname);
 687  671          wfp = fopen(bakfname, "w");
 688  672          if (!wfp) {
 689      -                NDMP_LOG(LOG_ERR, "Cannot open %s: %m.", bakfname);
      673 +                syslog(LOG_ERR, "Cannot open %s: %m.", bakfname);
 690  674                  dd_free(&ddhead);
 691  675                  return (-1);
 692  676          }
 693  677  
 694      -        NDMP_LOG(LOG_DEBUG, "[%s][%s]", fname, bakfname);
      678 +        syslog(LOG_DEBUG, "[%s][%s]", fname, bakfname);
 695  679  
 696  680          /* try to locate the entry in the file */
 697  681          found = 0;
 698  682          for (ddp = ddhead.dd_next; ddp; ddp = ddp->dd_next) {
 699  683                  if (ddp->dd_level != level)
 700  684                          continue;
 701  685                  if (strcmp(path, ddp->dd_name))
 702  686                          continue;
 703  687  
 704      -                NDMP_LOG(LOG_DEBUG, "Found: [%s][%d][%u]",
      688 +                syslog(LOG_DEBUG, "Found: [%s][%d][%u]",
 705  689                      ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
 706  690  
 707  691                  /* update the record for the entry */
 708  692                  found = 1;
 709  693                  ddp->dd_ddate = ddate;
 710  694  
 711      -                NDMP_LOG(LOG_DEBUG,
      695 +                syslog(LOG_DEBUG,
 712  696                      "Updated to: [%s][%d][%u]",
 713  697                      ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
 714  698          }
 715  699  
 716  700          /* dump all the read records */
 717  701          for (ddp = ddhead.dd_next; ddp; ddp = ddp->dd_next)
 718  702                  dumprecout(wfp, ddp);
 719  703  
 720  704          dd_free(&ddhead);
 721  705  
 722  706          /* append a new record */
 723  707          if (!found) {
 724  708                  (void) strlcpy(tmpdd.dd_name, path, TLM_MAX_PATH_NAME);
 725  709                  tmpdd.dd_level = level;
 726  710                  tmpdd.dd_ddate = ddate;
 727  711                  dumprecout(wfp, &tmpdd);
 728  712          }
 729  713  
 730  714          (void) fclose(wfp);
 731  715          (void) rename(bakfname, fname);
 732  716  
 733  717          return (0);
 734  718  }
 735  719  
 736  720  
 737  721  /*
 738  722   * append_dumptime
 739  723   *
 740  724   * Append the record specified by path, level and backup date to the file.
 741  725   */
 742  726  static int
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
 743  727  append_dumptime(char *fname, char *path, int level, time_t ddate)
 744  728  {
 745  729          char fpath[PATH_MAX], bakfpath[PATH_MAX];
 746  730          FILE *fp;
 747  731          dumpdates_t tmpdd;
 748  732  
 749  733          if (!fname || !*fname || !path || !*path)
 750  734                  return (-1);
 751  735  
 752  736          if (IS_LBR_BKTYPE(level & 0xff)) {
 753      -                NDMP_LOG(LOG_DEBUG,
      737 +                syslog(LOG_DEBUG,
 754  738                      "Lbr: [%s][%s][%c][%u]",
 755  739                      fname, path, level, ddate);
 756  740          } else
 757      -                NDMP_LOG(LOG_DEBUG, "[%s][%s][%d][%u]",
      741 +                syslog(LOG_DEBUG, "[%s][%s][%d][%u]",
 758  742                      fname, path, level, ddate);
 759  743  
 760  744          if (!ndmpd_make_bk_dir_path(fpath, fname)) {
 761      -                NDMP_LOG(LOG_ERR, "Cannot get dumpdate file path name %s.",
      745 +                syslog(LOG_ERR, "Cannot get dumpdate file path name %s.",
 762  746                      fname);
 763  747                  return (-1);
 764  748          }
 765  749  
 766  750          (void) snprintf(bakfpath, PATH_MAX, "%s.bak", fpath);
 767  751  
 768  752          /*
 769  753           * If the file is there and can be opened then make a
 770  754           * backup copy it.
 771  755           */
 772  756          fp = fopen(fpath, "r");
 773  757          if (fp) {
 774  758                  (void) fclose(fp);
 775  759                  if (filecopy(bakfpath, fpath) != 0) {
 776      -                        NDMP_LOG(LOG_ERR, "Cannot copy %s to %s: %m.",
      760 +                        syslog(LOG_ERR, "Cannot copy %s to %s: %m.",
 777  761                              fpath, bakfpath);
 778  762                          return (-1);
 779  763                  }
 780  764          }
 781  765  
 782  766          /* open the new copy to append the record to it */
 783  767          fp = fopen(bakfpath, "a");
 784  768          if (!fp) {
 785      -                NDMP_LOG(LOG_ERR, "Cannot open %s: %m.", bakfpath);
      769 +                syslog(LOG_ERR, "Cannot open %s: %m.", bakfpath);
 786  770                  return (-1);
 787  771          }
 788  772  
 789      -        NDMP_LOG(LOG_DEBUG, "[%s][%s]", fpath, bakfpath);
      773 +        syslog(LOG_DEBUG, "[%s][%s]", fpath, bakfpath);
 790  774  
 791  775          /* append a new record */
 792  776          (void) strlcpy(tmpdd.dd_name, path, TLM_MAX_PATH_NAME);
 793  777          tmpdd.dd_level = level;
 794  778          tmpdd.dd_ddate = ddate;
 795  779          dumprecout(fp, &tmpdd);
 796  780  
 797  781          (void) fclose(fp);
 798  782          (void) rename(bakfpath, fpath);
 799  783  
 800  784          return (0);
 801  785  }
 802  786  
 803  787  
 804  788  /*
 805  789   * find_date
 806  790   *
 807  791   * Find the specified date
 808  792   */
 809  793  static dumpdates_t *
 810  794  find_date(dumpdates_t *ddp, char *path, int level, time_t t)
 811  795  {
 812  796          for (; ddp; ddp = ddp->dd_next)
 813  797                  if (ddp->dd_level == level && ddp->dd_ddate > t &&
 814  798                      strcmp(path, ddp->dd_name) == 0)
 815  799                          break;
 816  800  
 817  801          return (ddp);
 818  802  }
 819  803  
 820  804  
 821  805  /*
 822  806   * Get the dumpdate of the last level backup done on the path.
 823  807   * The last level normally is (level - 1) in case of NetBackup
 824  808   * but some DMAs allow that previous level could be anything
 825  809   * between 0 and the current level.
 826  810   *
 827  811   * Returns:
 828  812   *   0 on success
 829  813   *   < 0 on error
 830  814   */
 831  815  int
 832  816  ndmpd_get_dumptime(char *path, int *level, time_t *ddate)
 833  817  {
 834  818          int i;
  
    | 
      ↓ open down ↓ | 
    35 lines elided | 
    
      ↑ open up ↑ | 
  
 835  819          dumpdates_t ddhead, *ddp, *save;
 836  820          char vol[ZFS_MAX_DATASET_NAME_LEN];
 837  821          nvlist_t *userprops;
 838  822          zfs_handle_t *zhp;
 839  823          nvlist_t *propval = NULL;
 840  824          char *strval = NULL;
 841  825  
 842  826          if (!path || !level || !ddate)
 843  827                  return (-1);
 844  828  
 845      -        NDMP_LOG(LOG_DEBUG, "[%s] level %d",
      829 +        syslog(LOG_DEBUG, "[%s] level %d",
 846  830              path, *level);
 847  831  
 848  832          if (*level == 0) {
 849  833                  *ddate = (time_t)0;
 850  834                  return (0);
 851  835          }
 852  836  
 853  837          (void) mutex_lock(&zlib_mtx);
 854  838          /* Check if this is a ZFS dataset */
 855  839          if ((zlibh != NULL) &&
 856  840              (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
 857  841              ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
 858  842                  if ((userprops = zfs_get_user_props(zhp)) == NULL) {
 859  843                          *level = 0;
 860  844                          *ddate = (time_t)0;
 861  845                          zfs_close(zhp);
 862  846                          (void) mutex_unlock(&zlib_mtx);
 863  847                          return (0);
 864  848                  }
 865  849                  for (i = *level - 1; i >= 0; i--) {
 866  850                          if (nvlist_lookup_nvlist(userprops,
 867  851                              zfs_dumpdate_props[i], &propval) == 0) {
 868  852                                  *level = i;
 869  853                                  break;
 870  854                          }
 871  855                  }
 872  856                  if (propval == NULL ||
 873  857                      nvlist_lookup_string(propval, ZPROP_VALUE,
 874  858                      &strval) != 0) {
 875  859                          *level = 0;
 876  860                          *ddate = (time_t)0;
 877  861                          zfs_close(zhp);
 878  862                          (void) mutex_unlock(&zlib_mtx);
 879  863                          return (0);
 880  864                  }
 881  865                  if (unctime(strval, ddate) < 0) {
 882  866                          zfs_close(zhp);
 883  867                          (void) mutex_unlock(&zlib_mtx);
 884  868                          return (-1);
 885  869                  }
 886  870  
 887  871                  zfs_close(zhp);
 888  872                  (void) mutex_unlock(&zlib_mtx);
 889  873                  return (0);
 890  874          }
 891  875          (void) mutex_unlock(&zlib_mtx);
 892  876  
 893  877          (void) memset((void *)&ddhead, 0, sizeof (ddhead));
 894  878          if (initdumptimes(&ddhead) < 0) {
 895  879                  dd_free(&ddhead);
 896  880                  return (-1);
 897  881          }
 898  882  
 899  883          /*
 900  884           * Empty dumpdates file means level 0 for all paths.
 901  885           */
 902  886          if ((ddp = ddhead.dd_next) == 0) {
 903  887                  if (!IS_LBR_BKTYPE(*level & 0xff))
 904  888                          *level = 0;
 905  889                  *ddate = 0;
  
    | 
      ↓ open down ↓ | 
    50 lines elided | 
    
      ↑ open up ↑ | 
  
 906  890                  return (0);
 907  891          }
 908  892  
 909  893          /*
 910  894           * If it's not level backup, then find the exact record
 911  895           * type.
 912  896           */
 913  897          if (IS_LBR_BKTYPE(*level & 0xff)) {
 914  898                  save = find_date(ddp, path, *level, *ddate);
 915  899  
 916      -                NDMP_LOG(LOG_DEBUG,
      900 +                syslog(LOG_DEBUG,
 917  901                      "LBR_BKTYPE save 0x%p", save);
 918  902  
 919  903                  *ddate = save ? save->dd_ddate : (time_t)0;
 920  904          } else {
 921  905                  /*
 922  906                   * Go find the entry with the same name for a maximum of a
 923  907                   * lower increment and older date.
 924  908                   */
 925  909                  save = NULL;
 926  910                  for (i = *level - 1; i >= 0; i--) {
 927  911                          save = find_date(ddp, path, i, *ddate);
 928  912                          if (save) {
 929  913                                  *level = save->dd_level;
 930  914                                  *ddate = save->dd_ddate;
 931  915                                  break;
 932  916                          }
 933  917                  }
 934  918  
 935  919                  if (!save) {
 936  920                          *level = 0;
 937  921                          *ddate = (time_t)0;
 938  922                  }
 939  923          }
 940  924  
 941  925          dd_free(&ddhead);
 942  926  
 943  927          return (0);
 944  928  }
 945  929  
 946  930  
 947  931  /*
 948  932   * Put the date and the level of the back up for the
 949  933   * specified path in the dumpdates file.  If there is a line
 950  934   * for the same path and the same level, the date is updated.
 951  935   * Otherwise, a line is appended to the file.
 952  936   *
 953  937   * Returns:
 954  938   *   0 on success
  
    | 
      ↓ open down ↓ | 
    28 lines elided | 
    
      ↑ open up ↑ | 
  
 955  939   *   < 0 on error
 956  940   */
 957  941  int
 958  942  ndmpd_put_dumptime(char *path, int level, time_t ddate)
 959  943  {
 960  944          char vol[ZFS_MAX_DATASET_NAME_LEN];
 961  945          zfs_handle_t *zhp;
 962  946          char tbuf[64];
 963  947          int rv;
 964  948  
 965      -        NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]", path, level,
      949 +        syslog(LOG_DEBUG, "[%s][%d][%u]", path, level,
 966  950              ddate);
 967  951  
 968  952          /* Check if this is a ZFS dataset */
 969  953          (void) mutex_lock(&zlib_mtx);
 970  954          if ((zlibh != NULL) &&
 971  955              (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
 972  956              ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
 973  957  
 974  958                  (void) ctime_r(&ddate, tbuf, sizeof (tbuf));
 975  959                  rv = zfs_prop_set(zhp, zfs_dumpdate_props[level], tbuf);
 976  960                  zfs_close(zhp);
 977  961  
 978  962                  (void) mutex_unlock(&zlib_mtx);
 979  963                  return (rv);
 980  964          }
 981  965          (void) mutex_unlock(&zlib_mtx);
 982  966  
 983  967          (void) mutex_lock(&ndmp_dd_lock);
 984  968          rv = putdumptime(path, level, ddate);
 985  969          (void) mutex_unlock(&ndmp_dd_lock);
 986  970  
 987  971          return (rv);
 988  972  }
 989  973  
 990  974  
 991  975  /*
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
 992  976   * Append a backup date record to the specified file.
 993  977   */
 994  978  int
 995  979  ndmpd_append_dumptime(char *fname, char *path, int level, time_t ddate)
 996  980  {
 997  981          char vol[ZFS_MAX_DATASET_NAME_LEN];
 998  982          zfs_handle_t *zhp;
 999  983          char tbuf[64];
1000  984          int rv;
1001  985  
1002      -        NDMP_LOG(LOG_DEBUG, "[%s][%s][%d][%u]", fname,
      986 +        syslog(LOG_DEBUG, "[%s][%s][%d][%u]", fname,
1003  987              path, level, ddate);
1004  988  
1005  989          /* Check if this is a ZFS dataset */
1006  990          (void) mutex_lock(&zlib_mtx);
1007  991          if ((zlibh != NULL) &&
1008  992              (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
1009  993              ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
1010  994  
1011  995                  (void) ctime_r(&ddate, tbuf, sizeof (tbuf));
1012  996                  rv = zfs_prop_set(zhp, zfs_dumpdate_props[level], tbuf);
1013  997                  zfs_close(zhp);
1014  998  
1015  999                  (void) mutex_unlock(&zlib_mtx);
1016 1000                  return (rv);
1017 1001          }
1018 1002          (void) mutex_unlock(&zlib_mtx);
1019 1003  
1020 1004          (void) mutex_lock(&ndmp_dd_lock);
1021 1005          rv = append_dumptime(fname, path, level, ddate);
1022 1006          (void) mutex_unlock(&ndmp_dd_lock);
1023 1007  
1024 1008          return (rv);
1025 1009  }
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX