Print this page
    
NEX-9532 NDMP: readdir errors when file/directory has special characters
Reviewed by: Peer Dampmann <peer.dampmann@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@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>
NEX-2990 ndmpd dumping core when used with ndmpcopy
NEX-2911 NDMP logging should use syslog and is too chatty
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
          +++ new/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
   1    1  /*
   2    2   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
   3      - * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
   4    3   */
   5    4  
   6    5  /*
   7    6   * BSD 3 Clause License
   8    7   *
   9    8   * Copyright (c) 2007, The Storage Networking Industry Association.
  10    9   *
  11   10   * Redistribution and use in source and binary forms, with or without
  12   11   * modification, are permitted provided that the following conditions
  13   12   * are met:
  14   13   *      - Redistributions of source code must retain the above copyright
  15   14   *        notice, this list of conditions and the following disclaimer.
  16   15   *
  17   16   *      - Redistributions in binary form must reproduce the above copyright
  18   17   *        notice, this list of conditions and the following disclaimer in
  19   18   *        the documentation and/or other materials provided with the
  20   19   *        distribution.
  21   20   *
  22   21   *      - Neither the name of The Storage Networking Industry Association (SNIA)
  23   22   *        nor the names of its contributors may be used to endorse or promote
  24   23   *        products derived from this software without specific prior written
  25   24   *        permission.
  26   25   *
  27   26   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28   27   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
  29   28   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30   29   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  31   30   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  32   31   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33   32   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34   33   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35   34   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36   35   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37   36   * POSSIBILITY OF SUCH DAMAGE.
  38   37   */
       38 +/* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
       39 +
       40 +#include <syslog.h>
  39   41  #include <stdlib.h>
  40   42  #include <ctype.h>
  41   43  #include <stdio.h>
  42   44  #include <limits.h>
  43   45  #include <string.h>
  44   46  #include <time.h>
  45   47  #include <sys/types.h>
  46   48  #include <sys/acl.h>
  47   49  #include <sys/mkdev.h>
  48   50  #include <utime.h>
  49   51  #include <unistd.h>
  50   52  #include <pthread.h>
  51   53  #include <archives.h>
  52   54  #include <priv.h>
  53   55  #include <tlm.h>
  54   56  #include <libzfs.h>
  55   57  #include <pwd.h>
  56   58  #include <grp.h>
  57   59  #include <ndmpd_prop.h>
  58   60  #include "tlm_proto.h"
  59   61  
  60   62  
  61   63  #define PM_EXACT_OR_CHILD(m)    ((m) == PM_EXACT || (m) == PM_CHILD)
  62   64  #define ERROR_IS_FATAL(err)     ((err) == ENOSPC || (err) == EDQUOT)
  63   65  
  64   66  typedef boolean_t name_match_fp_t(char *s, char *t);
  65   67  
  66   68  static int set_acl(char *name, tlm_acls_t *acls);
  67   69  static int restore_file(int *fp,
  68   70      char *real_name,
  69   71      long size,
  70   72      longlong_t huge_size,
  71   73      tlm_acls_t *,
  72   74      boolean_t want_this_file,
  73   75      tlm_cmd_t *,
  74   76      tlm_job_stats_t *,
  75   77      long *);
  76   78  static long restore_xattr_hdr(int *fp,
  77   79      char *name,
  78   80      char *fname,
  79   81      long size,
  80   82      tlm_acls_t *acls,
  81   83      tlm_cmd_t *local_commands,
  82   84      tlm_job_stats_t *job_stats);
  83   85  static int get_long_name(int lib,
  84   86      int drv,
  85   87      long recsize,
  86   88      char *name,
  87   89      long *buf_spot,
  88   90      tlm_cmd_t *local_commands);
  89   91  static int get_humongus_file_header(int lib,
  90   92      int drv,
  91   93      long recsize,
  92   94      longlong_t *size,
  93   95      char *name,
  94   96      tlm_cmd_t *);
  95   97  static int create_directory(char *dir,
  96   98      tlm_job_stats_t *);
  97   99  static int create_hard_link(char *name,
  98  100      char *link,
  99  101      tlm_acls_t *,
 100  102      tlm_job_stats_t *);
 101  103  static int create_sym_link(char *dst,
 102  104      char *target,
 103  105      tlm_acls_t *,
 104  106      tlm_job_stats_t *);
 105  107  static int create_special(char,
 106  108      char *name,
 107  109      tlm_acls_t *,
 108  110      int,
 109  111      int,
 110  112      tlm_job_stats_t *);
 111  113  static long load_acl_info(int lib,
 112  114      int drv,
 113  115      long size,
 114  116      tlm_acls_t *,
 115  117      long *acl_spot,
 116  118      tlm_cmd_t *);
 117  119  static char *get_read_buffer(int want,
 118  120      int *error,
 119  121      int *actual_size,
 120  122      tlm_cmd_t *);
 121  123  static boolean_t wildcard_enabled(void);
 122  124  static boolean_t is_file_wanted(char *name,
 123  125      char **sels,
 124  126      char **exls,
 125  127      int flags,
 126  128      int *mchtype,
 127  129      int *pos);
 128  130  static char *catnames(struct rs_name_maker *rnp,
 129  131      char *buf,
 130  132      int pos,
 131  133      char *path);
 132  134  
 133  135  static char *rs_new_name(struct rs_name_maker *rnp,
 134  136      char *real_name,
 135  137      int pos,
 136  138      char *path);
 137  139  
 138  140  static void rs_create_new_bkpath(char *bk_path,
 139  141      char *path,
 140  142      char *pbuf);
 141  143  
 142  144  typedef struct stack_ent {
 143  145          char *se_name;
 144  146          tlm_acls_t se_acls;
 145  147  } stack_ent_t;
 146  148  
 147  149  
 148  150  /*
 149  151   * dtree_push
 150  152   */
 151  153  int
 152  154  dtree_push(cstack_t *stp, char *nmp, tlm_acls_t *acls)
 153  155  {
 154  156          int len;
 155  157          stack_ent_t *sp;
 156  158  
 157  159          sp = ndmp_malloc(sizeof (stack_ent_t));
 158  160          if (!sp || !nmp || !acls) {
 159  161                  free(sp);
 160  162                  return (-1);
 161  163          }
 162  164  
 163  165          len = strlen(nmp) + 1;
 164  166          sp->se_name = ndmp_malloc(len);
 165  167          if (!sp->se_name) {
 166  168                  free(sp);
 167  169                  return (-1);
 168  170          }
 169  171  
 170  172          (void) strlcpy(sp->se_name, nmp, len);
 171  173          (void) memcpy(&sp->se_acls, acls, sizeof (*acls));
 172  174          (void) memset(acls, 0, sizeof (tlm_acls_t));
 173  175  
 174  176          return (cstack_push(stp, (void *)sp, sizeof (*sp)));
 175  177  }
 176  178  
 177  179  /*
 178  180   * dtree_pop
 179  181   */
 180  182  int
 181  183  dtree_pop(cstack_t *stp)
 182  184  {
 183  185          int err;
 184  186          stack_ent_t *sp;
 185  187  
 186  188          err = cstack_pop(stp, (void **)&sp, (void *)NULL);
 187  189          if (err)
 188  190                  return (-1);
 189  191  
 190  192          err = set_acl(sp->se_name, &sp->se_acls);
 191  193  
 192  194          free(sp->se_name);
 193  195          free(sp);
 194  196          return (err);
 195  197  }
 196  198  
 197  199  
 198  200  /*
 199  201   * dtree_peek
 200  202   */
 201  203  char *
 202  204  dtree_peek(cstack_t *stp)
 203  205  {
 204  206          int err;
 205  207          stack_ent_t *sp;
 206  208  
 207  209          err = cstack_top(stp, (void **)&sp, (void *)NULL);
 208  210          if (err)
 209  211                  return (NULL);
 210  212  
 211  213          return (sp->se_name);
 212  214  }
 213  215  
 214  216  /*
 215  217   * NBU and EBS may not send us the correct file list containing hardlinks
 216  218   * during a DAR restore, e.g. they appear always send the first name
 217  219   * associated with an inode, even if other link names were
 218  220   * selected for the restore.  As a workaround, we use the file name entry
 219  221   * in sels[] (ignore the name in the tar header) as restore target.
 220  222   */
  
    | 
      ↓ open down ↓ | 
    172 lines elided | 
    
      ↑ open up ↑ | 
  
 221  223  static char *
 222  224  rs_darhl_new_name(struct rs_name_maker *rnp, char *name, char **sels, int *pos,
 223  225      char *longname)
 224  226  {
 225  227          int x;
 226  228  
 227  229          for (x = 0; sels[x] != NULL; x++) {
 228  230                  if (strcmp(sels[x], " ")) {
 229  231                          *pos = x;
 230  232                          (void) strlcpy(longname, sels[x], TLM_MAX_PATH_NAME);
 231      -                        NDMP_LOG(LOG_DEBUG,
      233 +                        syslog(LOG_DEBUG,
 232  234                              "to replace hardlink name [%s], pos [%d]",
 233  235                              longname, *pos);
 234  236  
 235  237                          return (rs_new_name(rnp, name, *pos, longname));
 236  238                  }
 237  239          }
 238  240  
 239  241          return (NULL);
 240  242  }
 241  243  
 242  244  
 243  245  /*
 244  246   * Main dir restore function for tar
 245  247   *
 246  248   * If this function returns non-zero return value it means that fatal error
 247  249   * was encountered.
 248  250   */
 249  251  int
 250  252  tar_getdir(tlm_commands_t *commands,
 251  253      tlm_cmd_t *local_commands,
 252  254      tlm_job_stats_t *job_stats,
 253  255      struct rs_name_maker *rnp,
 254  256      int lib,
 255  257      int drv,
 256  258      char **sels, /* what to get off the tape */
 257  259      char **exls, /* what to leave behind */
 258  260      int flags,
 259  261      int DAR,
 260  262      char *bk_path,
 261  263      struct hardlink_q *hardlink_q)
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
 262  264  {
 263  265          int     fp = 0;         /* file being restored ... */
 264  266                                  /*  ...need to preserve across volume changes */
 265  267          tlm_acls_t *acls;       /* file access info */
 266  268          char    *longname;
 267  269          boolean_t is_long_name = FALSE;
 268  270          char    *longlink;
 269  271          char    *hugename;
 270  272          longlong_t huge_size = 0;       /* size of a HUGE file */
 271  273          long    acl_spot;               /* any ACL info on the next volume */
 272      -        long    file_size;              /* size of file to restore */
      274 +        long    file_size = 0;          /* size of file to restore */
 273  275          long    size_left = 0;          /* need this after volume change */
 274  276          int     last_action = 0;        /* what we are doing at EOT */
 275  277          boolean_t multi_volume = FALSE; /* is this a multi-volume switch ? */
 276  278          int     chk_rv;                 /* scratch area */
 277  279  
 278  280          int     mchtype, pos;
 279  281                                          /*
 280  282                                           * if an exact match is found for
 281  283                                           * restore and its position in the
 282  284                                           * selections list
 283  285                                           */
 284  286          int     nzerohdr;               /* the number of empty tar headers */
 285  287          int     rv;
 286  288          long nm_end, lnk_end;
 287  289          char    *name, *nmp;
 288  290          cstack_t *stp;
 289  291          char    *bkpath;
 290  292          char    *parentlnk;
 291  293          int dir_dar = 0;
 292  294  
 293  295          /*
 294  296           * The directory where temporary files may be created during a partial
 295  297           * non-DAR restore of hardlinks.  It is intended to be initialized by
 296  298           * an environment variable that can be set by user.
 297  299           *
 298  300           * It is not initialized for now.   We keep it here for future use.
 299  301           */
 300  302          char *tmplink_dir = NULL;
 301  303          int dar_recovered = 0;
 302  304          char *thname_buf;
 303  305  
 304  306          /*
 305  307           * startup
 306  308           */
 307  309  
 308  310          longname = ndmp_malloc(TLM_MAX_PATH_NAME);
 309  311          longlink = ndmp_malloc(TLM_MAX_PATH_NAME);
 310  312          hugename = ndmp_malloc(TLM_MAX_PATH_NAME);
 311  313          parentlnk = ndmp_malloc(TLM_MAX_PATH_NAME);
 312  314          thname_buf = ndmp_malloc(TLM_MAX_PATH_NAME);
 313  315          name = ndmp_malloc(TLM_MAX_PATH_NAME);
 314  316          acls = ndmp_malloc(sizeof (tlm_acls_t));
 315  317          stp = cstack_new();
 316  318          if (longname == NULL || longlink == NULL || hugename == NULL ||
 317  319              name == NULL || acls == NULL || stp == NULL || parentlnk == NULL ||
 318  320              thname_buf == NULL) {
 319  321                  cstack_delete(stp);
 320  322                  free(longname);
 321  323                  free(longlink);
 322  324                  free(hugename);
 323  325                  free(parentlnk);
 324  326                  free(name);
 325  327                  free(acls);
 326  328                  free(thname_buf);
 327  329                  return (-TLM_NO_SCRATCH_SPACE);
 328  330          }
 329  331  
  
    | 
      ↓ open down ↓ | 
    47 lines elided | 
    
      ↑ open up ↑ | 
  
 330  332          acl_spot = 0;
 331  333          *hugename = '\0';
 332  334          *parentlnk = '\0';
 333  335          nm_end = 0;
 334  336          *longname = '\0';
 335  337          lnk_end = 0;
 336  338          *longlink = '\0';
 337  339          (void) memset(acls, 0, sizeof (tlm_acls_t));
 338  340          if (IS_SET(flags, RSFLG_OVR_ALWAYS)) {
 339  341                  acls->acl_overwrite = TRUE;
 340      -                NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_ALWAYS");
      342 +                syslog(LOG_DEBUG, "RSFLG_OVR_ALWAYS");
 341  343          } else if (IS_SET(flags, RSFLG_OVR_UPDATE)) {
 342  344                  acls->acl_update = TRUE;
 343      -                NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_UPDATE");
      345 +                syslog(LOG_DEBUG, "RSFLG_OVR_UPDATE");
 344  346          }
 345  347  
 346  348          /*
 347  349           * work
 348  350           */
 349  351          rv = 0;
 350  352          nzerohdr = 0;
 351  353          while (commands->tcs_writer != TLM_ABORT &&
 352  354              local_commands->tc_writer != TLM_STOP && rv == 0) {
 353  355                  tlm_tar_hdr_t fake_tar_hdr;
 354  356                  char    *file_name;
 355  357                  char    *link_name;
 356  358                  int     erc;
 357  359                  int     actual_size;
 358  360                  boolean_t want_this_file;
 359  361                  int     want = sizeof (tlm_tar_hdr_t);
 360  362                  tlm_tar_hdr_t *tar_hdr;
 361  363  
 362  364                  /* The inode of an LF_LINK type. */
 363  365                  unsigned long hardlink_inode = 0;
 364  366  
 365  367                  /*
 366  368                   * Indicate whether a file with the same inode has been
 367  369                   * restored.
 368  370                   */
 369  371                  int hardlink_done = 0;
 370  372  
 371  373                  /* The path of the restored hardlink file */
 372  374                  char *hardlink_target = NULL;
 373  375                  int is_hardlink = 0;
 374  376  
 375  377                  /*
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
 376  378                   * Whether a temporary file should be created for restoring
 377  379                   * hardlink.
 378  380                   */
 379  381                  int hardlink_tmp_file = 0;
 380  382                  char *hardlink_tmp_name = ".tmphlrsnondar";
 381  383  
 382  384                  /* used to make up hardlink_tmp_name */
 383  385                  static int hardlink_tmp_idx = 0;
 384  386  
 385  387                  if (multi_volume) {
 386      -                        NDMP_LOG(LOG_DEBUG, "multi_volume %c %d",
      388 +                        syslog(LOG_DEBUG, "multi_volume %c %d",
 387  389                              last_action, size_left);
 388  390  
 389  391                          /*
 390  392                           * the previous volume is out of data
 391  393                           * and is back in the rack, a new tape
 392  394                           * is loaded and ready to read.
 393  395                           *
 394  396                           * We need to pick up where we left off.
 395  397                           */
 396  398                          (void) memset(&fake_tar_hdr, 0, sizeof (fake_tar_hdr));
 397  399                          file_size = size_left;
 398  400                          tar_hdr = &fake_tar_hdr;
 399  401                          tar_hdr->th_linkflag = last_action;
 400  402  
 401  403                          multi_volume = FALSE;
 402  404                          last_action = 0;
 403  405                  } else {
 404  406                          tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(want,
 405  407                              &erc, &actual_size, local_commands);
 406  408  
 407  409                          if (tar_hdr == NULL) {
 408  410                                  rv = -1;
 409  411                                  continue;
 410  412                          }
 411  413  
 412  414                          /*
 413  415                           * we can ignore read errors here because
 414  416                           *   1) they are logged by Restore Reader
 415  417                           *   2) we are not doing anything important here
 416  418                           *      just looking for the next work record.
 417  419                           */
 418  420                          if (actual_size < want) {
 419  421                                  /*
 420  422                                   * EOF hits here
 421  423                                   *
 422  424                                   * wait for another buffer to come along
 423  425                                   * or until the Reader thread tells us
 424  426                                   * that no more tapes will be loaded ...
 425  427                                   * time to stop.
 426  428                                   */
  
    | 
      ↓ open down ↓ | 
    30 lines elided | 
    
      ↑ open up ↑ | 
  
 427  429                                  continue;
 428  430                          }
 429  431  
 430  432                          /*
 431  433                           * check for "we are lost"
 432  434                           */
 433  435                          chk_rv = tlm_vfy_tar_checksum(tar_hdr);
 434  436                          if (chk_rv == 0) {
 435  437                                  /* one of the end of tar file marks */
 436  438                                  if (++nzerohdr >= 2) {
 437      -                                        NDMP_LOG(LOG_DEBUG,
      439 +                                        syslog(LOG_DEBUG,
 438  440                                              "nzerohdr %d, breaking",
 439  441                                              nzerohdr);
 440  442                                          /* end of tar file */
 441  443                                          break;
 442  444                                  }
 443      -                                NDMP_LOG(LOG_DEBUG, "nzerohdr %d, continuing",
      445 +                                syslog(LOG_DEBUG, "nzerohdr %d, continuing",
 444  446                                      nzerohdr);
 445  447                                  continue;
 446  448                          } else if (chk_rv < 0) {
 447  449                                  nzerohdr = 0;
 448  450                                  /* skip this record */
 449  451                                  continue;
 450  452                          }
 451  453                          nzerohdr = 0;
 452  454  
 453  455                          /*
 454  456                           * When files are spanned to the next tape, the
 455  457                           * information of the acls must not be over-written
 456  458                           * by the information of the LF_MULTIVOL and LF_VOLHDR
 457  459                           * header, whose information is irrelevant to the file.
 458  460                           * The information of the original header must be
 459  461                           * kept in the 'acl'.
 460  462                           */
 461  463                          if (tar_hdr->th_linkflag != LF_MULTIVOL &&
 462  464                              tar_hdr->th_linkflag != LF_VOLHDR) {
 463  465                                  if (tar_hdr->th_linkflag != LF_HUMONGUS) {
 464  466                                          acls->acl_attr.st_mode =
 465  467                                              oct_atoi(tar_hdr->th_mode);
 466  468                                          acls->acl_attr.st_size =
 467  469                                              oct_atoi(tar_hdr->th_size);
 468  470                                          acls->acl_attr.st_uid =
 469  471                                              oct_atoi(tar_hdr->th_uid);
 470  472                                          acls->acl_attr.st_gid =
 471  473                                              oct_atoi(tar_hdr->th_gid);
 472  474                                          acls->acl_attr.st_mtime =
 473  475                                              oct_atoi(tar_hdr->th_mtime);
 474  476                                          (void) strlcpy(acls->uname,
 475  477                                              tar_hdr->th_uname,
 476  478                                              sizeof (acls->uname));
  
    | 
      ↓ open down ↓ | 
    23 lines elided | 
    
      ↑ open up ↑ | 
  
 477  479                                          (void) strlcpy(acls->gname,
 478  480                                              tar_hdr->th_gname,
 479  481                                              sizeof (acls->gname));
 480  482                                  }
 481  483                                  file_size = oct_atoi(tar_hdr->th_size);
 482  484                                  acl_spot = 0;
 483  485                                  last_action = tar_hdr->th_linkflag;
 484  486                          }
 485  487                  }
 486  488  
 487      -                NDMP_LOG(LOG_DEBUG, "n [%s] f [%c] s %lld m %o u %d g %d t %d",
 488      -                    tar_hdr->th_name, tar_hdr->th_linkflag,
 489      -                    acls->acl_attr.st_size, acls->acl_attr.st_mode,
 490      -                    acls->acl_attr.st_uid, acls->acl_attr.st_gid,
 491      -                    acls->acl_attr.st_mtime);
 492      -
 493  489                  /*
 494  490                   * If the restore is running using DAR we should check for
 495  491                   * extended attribute entries
 496  492                   */
 497  493                  if (dar_recovered &&
 498  494                      tar_hdr->th_linkflag != LF_XATTR)
 499  495                          break;
 500  496  
 501  497                  rs_create_new_bkpath(bk_path, tar_hdr->th_name, thname_buf);
 502  498  
 503  499                  switch (tar_hdr->th_linkflag) {
 504  500                  case LF_MULTIVOL:
 505  501                          multi_volume = TRUE;
 506  502                          break;
 507  503                  case LF_LINK:
 508  504                          is_hardlink = 1;
 509  505                          hardlink_inode =
 510  506                              oct_atoi(tar_hdr->th_shared.th_hlink_ino);
 511  507  
 512  508                          /*
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
 513  509                           * Check if we have restored a link with the same inode
 514  510                           * If the inode is 0, we have to restore it as a
 515  511                           * regular file.
 516  512                           */
 517  513                          if (hardlink_inode) {
 518  514                                  hardlink_done = !hardlink_q_get(hardlink_q,
 519  515                                      hardlink_inode, 0, &hardlink_target);
 520  516                          }
 521  517  
 522  518                          if (hardlink_done) {
 523      -                                NDMP_LOG(LOG_DEBUG,
      519 +                                syslog(LOG_DEBUG,
 524  520                                      "found hardlink, inode = %u, target = [%s]",
 525  521                                      hardlink_inode,
 526  522                                      hardlink_target? hardlink_target : "--");
 527  523  
 528  524                                  /* create a hardlink to hardlink_target */
 529  525                                  file_name = (*longname == 0) ?
 530  526                                      thname_buf : longname;
 531  527  
 532  528                                  if (!is_file_wanted(file_name, sels, exls,
 533  529                                      flags, &mchtype, &pos)) {
 534  530                                          nmp = NULL;
 535  531                                          /*
 536  532                                           * This means that DMA did not send us
 537  533                                           * the correct fh_info for the file
 538  534                                           * in restore list.  We use the file
 539  535                                           * name entry in sels[] (ignore the
 540  536                                           * name in the tar header) as restore
 541  537                                           * target.
  
    | 
      ↓ open down ↓ | 
    8 lines elided | 
    
      ↑ open up ↑ | 
  
 542  538                                           */
 543  539                                          if (DAR) {
 544  540                                                  nmp = rs_darhl_new_name(rnp,
 545  541                                                      name, sels, &pos,
 546  542                                                      file_name);
 547  543                                          }
 548  544                                  } else {
 549  545                                          nmp = rs_new_name(rnp, name, pos,
 550  546                                              file_name);
 551  547                                          if (!nmp) {
 552      -                                                NDMP_LOG(LOG_DEBUG,
      548 +                                                syslog(LOG_ERR,
 553  549                                                      "can't make name for %s",
 554  550                                                      longname);
 555  551                                          }
 556  552                                  }
 557  553  
 558  554                                  if (nmp) {
 559  555                                          if (hardlink_target) {
 560  556                                                  erc = create_hard_link(
 561  557                                                      hardlink_target, nmp,
 562  558                                                      acls, job_stats);
 563  559                                                  if (ERROR_IS_FATAL(erc)) {
 564  560                                                          rv = erc;
 565  561                                                          continue;
 566  562                                                  }
 567  563                                                  if (erc == 0) {
 568  564                                                          (void)
 569  565                                                              tlm_entry_restored(
 570  566                                                              job_stats,
 571  567                                                              file_name, pos);
 572      -                                                        NDMP_LOG(LOG_DEBUG,
      568 +                                                        syslog(LOG_DEBUG,
 573  569                                                              "restored %s -> %s",
 574  570                                                              nmp,
 575  571                                                              hardlink_target);
 576  572                                                  }
 577  573                                          } else {
 578      -                                                NDMP_LOG(LOG_DEBUG,
      574 +                                                syslog(LOG_DEBUG,
 579  575                                                      "no target for hardlink %s",
 580  576                                                      nmp);
 581  577                                          }
 582  578  
 583  579                                          name[0] = 0;
 584  580                                          is_long_name = FALSE;
 585  581                                  }
 586  582  
 587  583                                  nm_end = 0;
 588  584                                  longname[0] = 0;
 589  585                                  lnk_end = 0;
 590  586                                  longlink[0] = 0;
 591  587  
 592  588                                  break;
 593  589                          }
 594  590                          /* otherwise fall through, restore like a normal file */
 595  591                          /*FALLTHROUGH*/
 596  592                  case LF_OLDNORMAL:
 597  593                          /*
 598  594                           * check for TAR's end-of-tape method
 599  595                           * of zero filled records.
 600  596                           */
 601  597                          if (tar_hdr->th_name[0] == 0) {
 602  598                                  break;
 603  599                          }
 604  600                          /*
 605  601                           * otherwise fall through,
 606  602                           * this is an old style normal file header
 607  603                           */
 608  604                          /*FALLTHROUGH*/
 609  605                  case LF_NORMAL:
 610  606                  case LF_CONTIG:
 611  607                          job_stats->js_files_so_far++;
 612  608                          if (*hugename != 0) {
 613  609                                  (void) strlcpy(longname, hugename,
 614  610                                      TLM_MAX_PATH_NAME);
 615  611                          } else if (*longname == 0) {
 616  612                                  if (tar_hdr->th_name[0] != '/') {
 617  613                                          /*
 618  614                                           * check for old tar format, it
 619  615                                           * does not have a leading "/"
 620  616                                           */
 621  617                                          longname[0] = '/';
 622  618                                          longname[1] = 0;
 623  619                                          (void) strlcat(longname,
 624  620                                              tar_hdr->th_name,
 625  621                                              TLM_MAX_PATH_NAME);
 626  622                                  } else {
 627  623                                          (void) strlcpy(longname,
 628  624                                              thname_buf,
 629  625                                              TLM_MAX_PATH_NAME);
 630  626                                  }
 631  627                          }
 632  628  
 633  629                          want_this_file = is_file_wanted(longname, sels, exls,
 634  630                              flags, &mchtype, &pos);
 635  631                          if (!want_this_file) {
 636  632                                  nmp = NULL;
 637  633                                  /*
 638  634                                   * This means that DMA did not send us valid
 639  635                                   * fh_info for the file in restore list.  We
 640  636                                   * use the file name entry in sels[] (ignore
 641  637                                   * the name in the tar header) as restore
 642  638                                   * target.
 643  639                                   */
 644  640                                  if (DAR && (tar_hdr->th_linkflag == LF_LINK)) {
 645  641                                          nmp = rs_darhl_new_name(rnp, name,
 646  642                                              sels, &pos, longname);
 647  643                                          if (nmp == NULL) {
 648  644                                                  rv = ENOMEM;
 649  645                                                  continue;
 650  646                                          }
 651  647  
 652  648                                          want_this_file = TRUE;
 653  649                                          mchtype = PM_EXACT;
 654  650                                  }
 655  651                          } else {
 656  652                                  nmp = rs_new_name(rnp, name, pos, longname);
 657  653                                  if (!nmp)
 658  654                                          want_this_file = FALSE;
 659  655                          }
 660  656  
 661  657                          if (nmp)
 662  658                                  (void) strlcpy(parentlnk, nmp, strlen(nmp) + 1);
 663  659  
 664  660                          /*
 665  661                           * For a hardlink, even if it's not asked to be
 666  662                           * restored, we restore it to a temporary location,
 667  663                           * in case other links to the same file need to be
 668  664                           * restored later.
 669  665                           *
 670  666                           * The temp files are created in tmplink_dir, with
 671  667                           * names like ".tmphlrsnondar*".  They are cleaned up
 672  668                           * at the completion of a restore.  However, if a
 673  669                           * restore were interrupted, e.g. by a system reboot,
 674  670                           * they would have to be cleaned up manually in order
 675  671                           * for the disk space to be freed.
 676  672                           *
 677  673                           * If tmplink_dir is NULL, no temperorary files are
 678  674                           * created during a restore.  This may result in some
 679  675                           * hardlinks not being restored during a partial
 680  676                           * restore.
 681  677                           */
 682  678                          if (is_hardlink && !DAR && !want_this_file && !nmp) {
  
    | 
      ↓ open down ↓ | 
    94 lines elided | 
    
      ↑ open up ↑ | 
  
 683  679                                  if (tmplink_dir) {
 684  680                                          (void) snprintf(name, TLM_MAX_PATH_NAME,
 685  681                                              "%s/%s_%d", tmplink_dir,
 686  682                                              hardlink_tmp_name,
 687  683                                              hardlink_tmp_idx);
 688  684                                          nmp = name;
 689  685  
 690  686                                          hardlink_tmp_idx++;
 691  687                                          hardlink_tmp_file = 1;
 692  688                                          want_this_file = TRUE;
 693      -                                        NDMP_LOG(LOG_DEBUG,
      689 +                                        syslog(LOG_DEBUG,
 694  690                                              "To restore temp hardlink file %s.",
 695  691                                              nmp);
 696  692                                  } else {
 697      -                                        NDMP_LOG(LOG_DEBUG,
      693 +                                        syslog(LOG_DEBUG,
 698  694                                              "No tmplink_dir specified.");
 699  695                                  }
 700  696                          }
 701  697  
 702  698                          rv = restore_file(&fp, nmp, file_size,
 703  699                              huge_size, acls, want_this_file, local_commands,
 704  700                              job_stats, &size_left);
 705  701                          if (rv != 0)
 706  702                                  continue;
 707  703  
 708  704                          /*
 709  705                           * In the case of non-DAR, we have to record the first
 710  706                           * link for an inode that has multiple links. That's
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
 711  707                           * the only link with data records actually backed up.
 712  708                           * In this way, when we run into the other links, they
 713  709                           * will be treated as links, and we won't go to look
 714  710                           * for the data records to restore.  This is not a
 715  711                           * problem for DAR, where DMA tells the tape where
 716  712                           * to locate the data records.
 717  713                           */
 718  714                          if (is_hardlink && !DAR) {
 719  715                                  if (hardlink_q_add(hardlink_q, hardlink_inode,
 720  716                                      0, nmp, hardlink_tmp_file))
 721      -                                        NDMP_LOG(LOG_DEBUG,
      717 +                                        syslog(LOG_ERR,
 722  718                                              "failed to add (%u, %s) to HL q",
 723  719                                              hardlink_inode, nmp);
 724  720                          }
 725  721  
 726  722                          /* remove / reverse the temporary stuff */
 727  723                          if (hardlink_tmp_file) {
 728  724                                  nmp = NULL;
 729  725                                  want_this_file = FALSE;
 730  726                                  hardlink_tmp_file = 0;
 731  727                          }
 732  728  
 733  729                          /*
 734  730                           * Check if it is time to set the attribute
 735  731                           * of the restored directory
 736  732                           */
 737  733                          while (nmp && ((bkpath = dtree_peek(stp)) != NULL)) {
 738  734                                  int erc;
 739  735  
 740  736                                  if (strstr(nmp, bkpath))
 741  737                                          break;
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
 742  738  
 743  739                                  erc = dtree_pop(stp);
 744  740                                  if (ERROR_IS_FATAL(erc)) {
 745  741                                          rv = erc;
 746  742                                          break;
 747  743                                  }
 748  744                          }
 749  745                          if (rv != 0)
 750  746                                  continue;
 751  747  
 752      -                        NDMP_LOG(LOG_DEBUG, "sizeleft %s %d, %lld", longname,
 753      -                            size_left, huge_size);
 754      -
 755  748                          if (want_this_file) {
 756  749                                  job_stats->js_bytes_total += file_size;
 757  750                                  job_stats->js_files_total++;
 758  751                          }
 759  752  
 760  753                          huge_size -= file_size;
 761  754                          if (huge_size < 0) {
 762  755                                  huge_size = 0;
 763  756                          }
 764  757                          if (size_left == 0 && huge_size == 0) {
 765  758                                  if (PM_EXACT_OR_CHILD(mchtype)) {
 766  759                                          (void) tlm_entry_restored(job_stats,
 767  760                                              longname, pos);
 768  761  
 769  762                                          /*
 770  763                                           * Add an entry to hardlink_q to record
 771  764                                           * this hardlink.
 772  765                                           */
 773  766                                          if (is_hardlink) {
 774      -                                                NDMP_LOG(LOG_DEBUG,
      767 +                                                syslog(LOG_DEBUG,
 775  768                                                      "Restored hardlink file %s",
 776  769                                                      nmp);
 777  770  
 778  771                                                  if (DAR) {
 779  772                                                          (void) hardlink_q_add(
 780  773                                                              hardlink_q,
 781  774                                                              hardlink_inode, 0,
 782  775                                                              nmp, 0);
 783  776                                                  }
 784  777                                          }
 785  778                                  }
 786  779  
 787  780                                  nm_end = 0;
 788  781                                  longname[0] = 0;
 789  782                                  lnk_end = 0;
 790  783                                  longlink[0] = 0;
 791  784                                  hugename[0] = 0;
 792  785                                  name[0] = 0;
 793  786                                  is_long_name = FALSE;
 794  787                          }
 795  788                          break;
 796  789                  case LF_XATTR:
 797  790                          file_name = (*longname == 0) ? thname_buf :
 798  791                              longname;
 799  792  
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
 800  793                          size_left = restore_xattr_hdr(&fp, parentlnk,
 801  794                              file_name, file_size, acls, local_commands,
 802  795                              job_stats);
 803  796  
 804  797                          break;
 805  798                  case LF_SYMLINK:
 806  799                          file_name = (*longname == 0) ? thname_buf :
 807  800                              longname;
 808  801                          link_name = (*longlink == 0) ?
 809  802                              tar_hdr->th_linkname : longlink;
 810      -                        NDMP_LOG(LOG_DEBUG, "file_name[%s]", file_name);
 811      -                        NDMP_LOG(LOG_DEBUG, "link_name[%s]", link_name);
      803 +                        syslog(LOG_DEBUG, "file_name[%s]", file_name);
      804 +                        syslog(LOG_DEBUG, "link_name[%s]", link_name);
 812  805                          if (is_file_wanted(file_name, sels, exls, flags,
 813  806                              &mchtype, &pos)) {
 814  807                                  nmp = rs_new_name(rnp, name, pos, file_name);
 815  808                                  if (nmp) {
 816  809                                          erc = create_sym_link(nmp, link_name,
 817  810                                              acls, job_stats);
 818  811                                          if (ERROR_IS_FATAL(erc)) {
 819  812                                                  rv = erc;
 820  813                                                  continue;
 821  814                                          }
 822  815                                          if (erc == 0 &&
 823  816                                              PM_EXACT_OR_CHILD(mchtype))
 824  817                                                  (void) tlm_entry_restored(
 825  818                                                      job_stats, file_name, pos);
 826  819                                          name[0] = 0;
 827  820                                  }
 828  821                          }
 829  822                          nm_end = 0;
 830  823                          longname[0] = 0;
 831  824                          lnk_end = 0;
 832  825                          longlink[0] = 0;
 833  826                          break;
 834  827                  case LF_DIR:
 835  828                          file_name = *longname == 0 ? thname_buf :
 836  829                              longname;
 837  830                          if (is_file_wanted(file_name, sels, exls, flags,
 838  831                              &mchtype, &pos)) {
 839  832                                  dir_dar = DAR;
 840  833                                  nmp = rs_new_name(rnp, name, pos, file_name);
 841  834                                  if (nmp && mchtype != PM_PARENT) {
 842  835                                          (void) strlcpy(parentlnk, nmp,
 843  836                                              strlen(nmp));
 844  837                                          erc = create_directory(nmp, job_stats);
 845  838                                          if (ERROR_IS_FATAL(erc)) {
 846  839                                                  rv = erc;
 847  840                                                  continue;
 848  841                                          }
 849  842                                          if (erc == 0 &&
 850  843                                              PM_EXACT_OR_CHILD(mchtype))
 851  844                                                  (void) tlm_entry_restored(
 852  845                                                      job_stats, file_name, pos);
 853  846                                          /*
 854  847                                           * Check if it is time to set
 855  848                                           * the attribute of the restored
 856  849                                           * directory
 857  850                                           */
 858  851                                          while ((bkpath = dtree_peek(stp))
 859  852                                              != NULL) {
 860  853                                                  int rc;
 861  854  
 862  855                                                  if (strstr(nmp, bkpath))
 863  856                                                          break;
 864  857                                                  rc = dtree_pop(stp);
 865  858                                                  if (ERROR_IS_FATAL(rc)) {
 866  859                                                          rv = rc;
 867  860                                                          break;
 868  861                                                  }
 869  862                                          }
 870  863                                          if (rv != 0)
 871  864                                                  continue;
 872  865  
 873  866                                          (void) dtree_push(stp, nmp, acls);
 874  867                                          name[0] = 0;
 875  868                                  }
 876  869                          } else {
 877  870                                  dir_dar = 0;
 878  871                          }
 879  872                          nm_end = 0;
 880  873                          longname[0] = 0;
 881  874                          lnk_end = 0;
 882  875                          longlink[0] = 0;
 883  876                          break;
 884  877                  case LF_FIFO:
 885  878                  case LF_BLK:
 886  879                  case LF_CHR:
 887  880                          file_name = *longname == 0 ? thname_buf :
 888  881                              longname;
 889  882                          if (is_file_wanted(file_name, sels, exls, flags,
 890  883                              &mchtype, &pos)) {
 891  884                                  nmp = rs_new_name(rnp, name, pos, file_name);
 892  885                                  if (nmp) {
 893  886                                          erc = create_special(
 894  887                                              tar_hdr->th_linkflag, nmp, acls,
 895  888                                              oct_atoi(tar_hdr->th_shared.
 896  889                                              th_dev.th_devmajor),
 897  890                                              oct_atoi(tar_hdr->th_shared.
 898  891                                              th_dev.th_devminor), job_stats);
 899  892                                          if (ERROR_IS_FATAL(erc)) {
 900  893                                                  rv = erc;
 901  894                                                  continue;
 902  895                                          }
 903  896                                          if (erc == 0 &&
 904  897                                              PM_EXACT_OR_CHILD(mchtype))
 905  898                                                  (void) tlm_entry_restored(
 906  899                                                      job_stats, file_name, pos);
 907  900                                          name[0] = 0;
 908  901                                  }
 909  902                          }
 910  903                          nm_end = 0;
 911  904                          longname[0] = 0;
 912  905                          lnk_end = 0;
  
    | 
      ↓ open down ↓ | 
    91 lines elided | 
    
      ↑ open up ↑ | 
  
 913  906                          longlink[0] = 0;
 914  907                          break;
 915  908                  case LF_LONGLINK:
 916  909                          file_size = min(file_size,
 917  910                              TLM_MAX_PATH_NAME - lnk_end - 1);
 918  911                          file_size = max(0, file_size);
 919  912                          size_left = get_long_name(lib, drv, file_size, longlink,
 920  913                              &lnk_end, local_commands);
 921  914  
 922  915                          if (size_left != 0)
 923      -                                NDMP_LOG(LOG_DEBUG,
      916 +                                syslog(LOG_DEBUG,
 924  917                                      "fsize %d sleft %d lnkend %d",
 925  918                                      file_size, size_left, lnk_end);
 926  919                          break;
 927  920                  case LF_LONGNAME:
 928  921                          file_size = min(file_size,
 929  922                              TLM_MAX_PATH_NAME - nm_end - 1);
 930  923                          file_size = max(0, file_size);
 931  924                          size_left = get_long_name(lib, drv, file_size, longname,
 932  925                              &nm_end, local_commands);
 933  926  
 934  927                          if (size_left != 0)
 935      -                                NDMP_LOG(LOG_DEBUG,
      928 +                                syslog(LOG_DEBUG,
 936  929                                      "fsize %d sleft %d nmend %d",
 937  930                                      file_size, size_left, nm_end);
 938  931                          is_long_name = TRUE;
 939  932                          break;
 940  933                  case LF_ACL:
 941  934                          size_left = load_acl_info(lib, drv, file_size, acls,
 942  935                              &acl_spot, local_commands);
 943  936                          break;
 944  937                  case LF_VOLHDR:
 945  938                          break;
 946  939                  case LF_HUMONGUS:
 947  940                          (void) memset(hugename, 0, TLM_MAX_PATH_NAME);
 948  941                          (void) get_humongus_file_header(lib, drv, file_size,
 949  942                              &huge_size, hugename, local_commands);
 950  943                          break;
 951  944                  default:
 952  945                          break;
 953  946  
 954  947                  }
 955  948  
 956  949                  /*
 957  950                   * If the restore is running using DAR we should check for
 958  951                   * long file names and HUGE file sizes.
 959  952                   */
 960  953                  if (DAR && tar_hdr->th_linkflag != LF_ACL &&
 961  954                      tar_hdr->th_linkflag != LF_XATTR &&
 962  955                      !huge_size && !is_long_name && !dir_dar)
 963  956                          dar_recovered = 1;
 964  957          }
 965  958  
 966  959          /*
 967  960           * tear down
 968  961           */
 969  962          if (rv != 0)
 970  963                  commands->tcs_reader = TLM_ABORT;
 971  964          if (fp != 0) {
 972  965                  (void) close(fp);
 973  966          }
 974  967          while (dtree_pop(stp) != -1)
 975  968                  ;
 976  969          cstack_delete(stp);
 977  970          free(acls);
 978  971          free(longname);
 979  972          free(parentlnk);
 980  973          free(longlink);
 981  974          free(hugename);
 982  975          free(name);
 983  976          free(thname_buf);
 984  977          return (rv);
 985  978  }
 986  979  
 987  980  /*
 988  981   * Main file restore function for tar (should run as a thread)
 989  982   */
 990  983  int
  
    | 
      ↓ open down ↓ | 
    45 lines elided | 
    
      ↑ open up ↑ | 
  
 991  984  tar_getfile(tlm_backup_restore_arg_t *argp)
 992  985  {
 993  986          tlm_job_stats_t *job_stats;
 994  987          char    **sels;         /* list of files desired */
 995  988          char    **exls;         /* list of files not wanted */
 996  989          char    *dir;           /* where to restore the files */
 997  990          char    job[TLM_MAX_BACKUP_JOB_NAME+1];
 998  991                                  /* the restore job name */
 999  992          int     erc;            /* error return codes */
1000  993          int     flags;
      994 +        int     i;
1001  995          struct  rs_name_maker rn;
1002  996          tlm_commands_t *commands;
1003  997          tlm_cmd_t *local_commands;
1004  998          char *list = NULL;
1005  999  
1006 1000          commands = argp->ba_commands;
1007 1001          local_commands = argp->ba_cmd;
1008 1002  
1009 1003          flags = 0;
1010 1004  
1011 1005          dir = ndmp_malloc(TLM_MAX_PATH_NAME);
1012 1006          if (dir == NULL) {
1013 1007                  local_commands->tc_reader = TLM_STOP;
1014 1008                  (void) pthread_barrier_wait(&argp->ba_barrier);
1015 1009                  return (-1);
1016 1010          }
1017 1011  
1018 1012          (void) strlcpy(job, argp->ba_job, TLM_MAX_BACKUP_JOB_NAME+1);
1019 1013          (void) strlcpy(dir, argp->ba_dir, TLM_MAX_PATH_NAME);
  
    | 
      ↓ open down ↓ | 
    9 lines elided | 
    
      ↑ open up ↑ | 
  
1020 1014  
1021 1015          flags |= RSFLG_OVR_ALWAYS;
1022 1016          flags |= RSFLG_IGNORE_CASE;
1023 1017  
1024 1018          /*
1025 1019           * do not test for "dir" having no string, since that
1026 1020           * is a legal condition.  Restore to origional location
1027 1021           * will not have a restore directory.
1028 1022           */
1029 1023          if (*job == '\0') {
1030      -                NDMP_LOG(LOG_DEBUG, "No job defined");
     1024 +                syslog(LOG_DEBUG, "No job defined");
1031 1025                  local_commands->tc_reader = TLM_STOP;
1032 1026                  free(dir);
1033 1027                  (void) pthread_barrier_wait(&argp->ba_barrier);
1034 1028                  return (-1);
1035 1029          }
1036 1030  
1037      -        sels = argp->ba_sels;
     1031 +        sels = ndmp_malloc(sizeof (char *) * (argp->ba_count + 1));
     1032 +            /* One extra for NULL terminate */
1038 1033          if (sels == NULL) {
1039 1034                  local_commands->tc_reader = TLM_STOP;
1040 1035                  free(dir);
1041 1036                  (void) pthread_barrier_wait(&argp->ba_barrier);
1042 1037                  return (-1);
1043 1038          }
     1039 +
     1040 +        (void) memset(sels, 0, (argp->ba_count + 1) * sizeof (char *));
     1041 +        for (i = 0; i < argp->ba_count; i++) {
     1042 +                sels[i] = argp->ba_sels[i];
     1043 +        }
     1044 +
1044 1045          exls = &list;
1045 1046  
1046 1047          tlm_log_list("selections", sels);
1047      -        tlm_log_list("exclusions", exls);
1048 1048  
1049 1049          if (wildcard_enabled())
1050 1050                  flags |= RSFLG_MATCH_WCARD;
1051 1051  
1052 1052          local_commands->tc_ref++;
1053 1053          commands->tcs_writer_count++;
1054 1054  
1055 1055          /*
1056 1056           * let the launcher continue
1057 1057           */
1058 1058          (void) pthread_barrier_wait(&argp->ba_barrier);
1059 1059  
1060 1060          job_stats = tlm_ref_job_stats(job);
1061 1061  
1062 1062          rn.rn_fp = catnames;
1063 1063          rn.rn_nlp = dir;
1064 1064  
1065 1065          /*
1066 1066           * work
1067 1067           */
1068      -        NDMP_LOG(LOG_DEBUG, "start restore job %s", job);
1069 1068          erc = tar_getdir(commands, local_commands, job_stats, &rn, 1, 1,
1070 1069              sels, exls, flags, 0, NULL, NULL);
1071 1070  
1072 1071          /*
1073 1072           * teardown
1074 1073           */
1075      -        NDMP_LOG(LOG_DEBUG, "end restore job %s", job);
1076 1074          tlm_un_ref_job_stats(job);
1077 1075          tlm_release_list(sels);
1078      -        tlm_release_list(exls);
1079 1076  
1080 1077          commands->tcs_writer_count--;
1081 1078          local_commands->tc_reader = TLM_STOP;
1082 1079          tlm_release_reader_writer_ipc(local_commands);
1083 1080          free(dir);
1084 1081          return (erc);
1085 1082  }
1086 1083  
1087 1084  /*
1088 1085   * Creates the directories all the way down to the
1089 1086   * end if they dont exist
1090 1087   */
1091 1088  int
1092 1089  make_dirs(char *dir)
1093 1090  {
1094 1091          char c;
1095 1092          char *cp, *end;
1096 1093          struct stat64 st;
  
    | 
      ↓ open down ↓ | 
    8 lines elided | 
    
      ↑ open up ↑ | 
  
1097 1094  
1098 1095          cp = dir;
1099 1096          cp += strspn(cp, "/");
1100 1097          end = dir + strlen(dir);
1101 1098          do {
1102 1099                  if (*cp == '\0' || *cp == '/') {
1103 1100                          c = *cp;
1104 1101                          *cp = '\0';
1105 1102                          if (lstat64(dir, &st) < 0)
1106 1103                                  if (mkdir(dir, 0777) < 0) {
1107      -                                        NDMP_LOG(LOG_DEBUG, "Error %d"
     1104 +                                        syslog(LOG_ERR, "Error %d"
1108 1105                                              " creating directory %s",
1109 1106                                              errno, dir);
1110 1107                                          *cp = c;
1111 1108                                          return (errno);
1112 1109                                  }
1113 1110  
1114 1111                          *cp = c;
1115 1112                  }
1116 1113          } while (++cp <= end);
1117 1114  
1118 1115          return (0);
1119 1116  }
1120 1117  
1121 1118  /*
  
    | 
      ↓ open down ↓ | 
    4 lines elided | 
    
      ↑ open up ↑ | 
  
1122 1119   * Creates the directories leading to the given path
1123 1120   */
1124 1121  int
1125 1122  mkbasedir(char *path)
1126 1123  {
1127 1124          int rv;
1128 1125          char *cp;
1129 1126          struct stat64 st;
1130 1127  
1131 1128          if (!path || !*path) {
1132      -                NDMP_LOG(LOG_DEBUG, "Invalid argument");
     1129 +                syslog(LOG_ERR, "Invalid argument");
1133 1130                  return (-1);
1134 1131          }
1135 1132  
1136 1133          cp = strrchr(path, '/');
1137 1134          if (cp)
1138 1135                  *cp = '\0';
1139 1136          rv = lstat64(path, &st);
1140 1137          if (rv < 0)     /* need new directories */
1141 1138                  rv = make_dirs(path);
1142 1139          if (cp)
1143 1140                  *cp = '/';
1144 1141  
1145 1142          return (rv);
1146 1143  }
1147 1144  
1148 1145  
1149 1146  /*
1150 1147   * read the file off the tape back onto disk
1151 1148   *
1152 1149   * If the function returns a non-zero return code, it means that fatal error
1153 1150   * was encountered and restore should terminate immediately.
1154 1151   */
1155 1152  static int
1156 1153  restore_file(int *fp,
1157 1154      char *real_name,
1158 1155      long size,
1159 1156      longlong_t huge_size,
1160 1157      tlm_acls_t *acls,
1161 1158      boolean_t want_this_file,
  
    | 
      ↓ open down ↓ | 
    19 lines elided | 
    
      ↑ open up ↑ | 
  
1162 1159      tlm_cmd_t *local_commands,
1163 1160      tlm_job_stats_t *job_stats,
1164 1161      long *size_left)
1165 1162  {
1166 1163          struct stat64   attr;
1167 1164          int     ret, rv;
1168 1165  
1169 1166          *size_left = 0;
1170 1167          if (!real_name) {
1171 1168                  if (want_this_file) {
1172      -                        NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
     1169 +                        syslog(LOG_DEBUG, "No file name but wanted!");
1173 1170                          want_this_file = FALSE;
1174 1171                  }
1175      -        } else
1176      -                NDMP_LOG(LOG_DEBUG, "new file[%s]", real_name);
     1172 +        }
1177 1173  
1178 1174          /*
1179 1175           * OK, some FM is creeping in here ...
1180 1176           * int *fp is used to keep the
1181 1177           * backup file channel open through
1182 1178           * the interruption of EOT and
1183 1179           * processing the headers of the
1184 1180           * next tape.  So, if *fp is zero
1185 1181           * then no file is open yet and all
1186 1182           * is normal.  If *fp has a number
1187 1183           * then we are returning after an
1188 1184           * EOT break.
1189 1185           *
1190 1186           * *fp is now also open for HUGE files
1191 1187           * that are put back in sections.
1192 1188           */
1193 1189  
1194 1190          if (*fp == 0 && want_this_file) {
1195 1191  
1196 1192                  ret = mkbasedir(real_name);
1197 1193                  if (ret != 0) {
1198 1194                          job_stats->js_errors++;
1199 1195                          if (ERROR_IS_FATAL(ret))
1200 1196                                  return (ret);
1201 1197                  }
1202 1198  
1203 1199                  ret = stat64(real_name, (struct stat64 *)&attr);
1204 1200                  if (ret < 0) {
1205 1201                          /*EMPTY*/
1206 1202                          /* new file */
1207 1203                  } else if (acls->acl_overwrite) {
1208 1204                          /*EMPTY*/
1209 1205                          /* take this file no matter what */
1210 1206                  } else if (acls->acl_update) {
1211 1207                          if (attr.st_mtime < acls->acl_attr.st_mtime) {
1212 1208                                  /*EMPTY*/
1213 1209                                  /* tape is newer */
1214 1210                          } else {
1215 1211                                  /* disk file is newer */
1216 1212                                  want_this_file = FALSE;
1217 1213                          }
1218 1214                  } else {
1219 1215                          /*
  
    | 
      ↓ open down ↓ | 
    33 lines elided | 
    
      ↑ open up ↑ | 
  
1220 1216                           * no overwrite, no update,
1221 1217                           * do not ever replace old files.
1222 1218                           */
1223 1219                          want_this_file = TRUE;
1224 1220                  }
1225 1221                  if (want_this_file) {
1226 1222  
1227 1223                          *fp = open(real_name, O_CREAT | O_TRUNC | O_WRONLY,
1228 1224                              S_IRUSR | S_IWUSR);
1229 1225                          if (*fp == -1) {
1230      -                                NDMP_LOG(LOG_ERR,
     1226 +                                syslog(LOG_ERR,
1231 1227                                      "Could not open %s for restore: %d",
1232 1228                                      real_name, errno);
1233 1229                                  job_stats->js_errors++;
1234 1230                                  want_this_file = FALSE;
1235 1231                                  /*
1236 1232                                   * In case of non-fatal error we cannot return
1237 1233                                   * here, because the file is still on the tape
1238 1234                                   * and must be skipped over.
1239 1235                                   */
1240 1236                                  if (ERROR_IS_FATAL(errno))
1241 1237                                          return (errno);
1242 1238                          }
1243 1239                  }
1244 1240                  (void) strlcpy(local_commands->tc_file_name, real_name,
1245 1241                      TLM_MAX_PATH_NAME);
1246 1242          }
1247 1243  
1248 1244          /*
1249 1245           * this is the size left in the next segment
1250 1246           */
1251 1247          huge_size -= size;
1252 1248  
1253 1249          /*
1254 1250           * work
1255 1251           */
1256 1252          rv = 0;
1257 1253          while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
1258 1254                  int     actual_size;
1259 1255                  int     error;
1260 1256                  char    *rec;
1261 1257                  int     write_size;
1262 1258  
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
1263 1259                  /*
1264 1260                   * Use bytes_in_file field to tell reader the amount
1265 1261                   * of data still need to be read for this file.
1266 1262                   */
1267 1263                  job_stats->js_bytes_in_file = size;
1268 1264  
1269 1265                  error = 0;
1270 1266                  rec = get_read_buffer(size, &error, &actual_size,
1271 1267                      local_commands);
1272 1268                  if (actual_size <= 0) {
1273      -                        NDMP_LOG(LOG_DEBUG,
     1269 +                        syslog(LOG_ERR,
1274 1270                              "RESTORE WRITER> error %d, actual_size %d",
1275 1271                              error, actual_size);
1276 1272  
1277 1273                          /* no more data for this file for now */
1278 1274                          job_stats->js_bytes_in_file = 0;
1279 1275                          *size_left = size;
1280 1276                          return (0);
1281 1277                  } else if (error) {
1282      -                        NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
     1278 +                        syslog(LOG_ERR, "Error %d in file [%s]",
1283 1279                              error, local_commands->tc_file_name);
1284 1280                          break;
1285 1281                  }
1286 1282  
1287 1283                  write_size = min(size, actual_size);
1288 1284                  if (want_this_file) {
1289 1285                          ret = write(*fp, rec, write_size);
1290 1286                          if (ret < 0) {
1291      -                                NDMP_LOG(LOG_ERR,
     1287 +                                syslog(LOG_ERR,
1292 1288                                      "Write error %d for file [%s]", errno,
1293 1289                                      local_commands->tc_file_name);
1294 1290                                  job_stats->js_errors++;
1295 1291                                  if (ERROR_IS_FATAL(errno)) {
1296 1292                                          rv = errno;
1297 1293                                          break;
1298 1294                                  }
1299 1295                          } else {
1300 1296                                  NS_ADD(wdisk, ret);
1301 1297                                  NS_INC(wfile);
1302 1298                                  if (ret < write_size) {
1303      -                                        NDMP_LOG(LOG_ERR,
     1299 +                                        syslog(LOG_ERR,
1304 1300                                              "Partial write for file [%s]",
1305 1301                                              local_commands->tc_file_name);
1306 1302                                  }
1307 1303                          }
1308 1304                  }
1309 1305                  size -= write_size;
1310 1306          }
1311 1307  
1312 1308          /* no more data for this file for now */
1313 1309          job_stats->js_bytes_in_file = 0;
1314 1310  
1315 1311          /*
1316 1312           * teardown
1317 1313           */
1318 1314          if (*fp != 0 && huge_size <= 0) {
1319 1315                  (void) close(*fp);
1320 1316                  *fp = 0;
1321 1317                  if (rv == 0) {
1322 1318                          ret = set_acl(real_name, acls);
1323 1319                          if (ERROR_IS_FATAL(ret))
1324 1320                                  return (ret);
1325 1321                  }
1326 1322          }
1327 1323          return (rv);
1328 1324  }
1329 1325  
1330 1326  /*
1331 1327   * Set the extended attributes file attribute
1332 1328   */
1333 1329  static void
1334 1330  set_xattr(int fd, struct stat64 st)
1335 1331  {
1336 1332          struct timeval times[2];
1337 1333  
1338 1334          times[0].tv_sec = st.st_atime;
1339 1335          times[1].tv_sec = st.st_mtime;
1340 1336  
1341 1337          (void) fchmod(fd, st.st_mode);
1342 1338          (void) fchown(fd, st.st_uid, st.st_gid);
1343 1339          (void) futimesat(fd, ".", times);
1344 1340  }
1345 1341  
1346 1342  /*
1347 1343   * Read the system attribute file in a single buffer to write
1348 1344   * it as a single write. A partial write to system attribute would
1349 1345   * cause an EINVAL on write.
1350 1346   */
1351 1347  static char *
1352 1348  get_read_one_buf(char *rec, int actual_size, int size, int *error,
1353 1349      tlm_cmd_t *lc)
1354 1350  {
1355 1351          char *buf, *p;
1356 1352          int read_size;
1357 1353          int len;
1358 1354  
1359 1355          if (actual_size > size)
1360 1356                  return (rec);
1361 1357  
1362 1358          buf = ndmp_malloc(size);
1363 1359          if (buf == NULL) {
1364 1360                  *error = ENOMEM;
1365 1361                  return (NULL);
1366 1362          }
1367 1363          (void) memcpy(buf, rec, actual_size);
1368 1364          rec = buf;
1369 1365          buf += actual_size;
1370 1366          while (actual_size < size) {
1371 1367                  p = get_read_buffer(size - actual_size, error, &read_size, lc);
1372 1368                  len = min(size - actual_size, read_size);
1373 1369                  (void) memcpy(buf, p, len);
1374 1370                  actual_size += len;
1375 1371                  buf += len;
1376 1372          }
1377 1373          return (rec);
1378 1374  }
1379 1375  
1380 1376  
1381 1377  /*
1382 1378   * read the extended attribute header and write
1383 1379   * it to the file
1384 1380   */
1385 1381  static long
1386 1382  restore_xattr_hdr(int *fp,
1387 1383      char *name,
1388 1384      char *fname,
1389 1385      long size,
1390 1386      tlm_acls_t *acls,
1391 1387      tlm_cmd_t *local_commands,
1392 1388      tlm_job_stats_t *job_stats)
  
    | 
      ↓ open down ↓ | 
    79 lines elided | 
    
      ↑ open up ↑ | 
  
1393 1389  {
1394 1390          tlm_tar_hdr_t *tar_hdr;
1395 1391          struct xattr_hdr *xhdr;
1396 1392          struct xattr_buf *xbuf;
1397 1393          int namelen;
1398 1394          char *xattrname;
1399 1395          int actual_size;
1400 1396          int error;
1401 1397  
1402 1398          if (!fname) {
1403      -                NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
1404      -        } else {
1405      -                NDMP_LOG(LOG_DEBUG, "new xattr[%s]", fname);
     1399 +                syslog(LOG_DEBUG, "No file name but wanted!");
1406 1400          }
1407 1401  
1408 1402          error = 0;
1409 1403          xhdr = (struct xattr_hdr *)get_read_buffer(size, &error,
1410 1404              &actual_size, local_commands);
1411 1405          if (xhdr == NULL || error != 0) {
1412      -                NDMP_LOG(LOG_DEBUG,
     1406 +                syslog(LOG_ERR,
1413 1407                      "Could not read xattr [%s:%s] for restore. ",
1414 1408                      name, fname);
1415 1409                  job_stats->js_errors++;
1416 1410                  return (0);
1417 1411          }
1418 1412  
1419 1413          /* Check extended attribute header */
1420 1414          if (strcmp(xhdr->h_version, XATTR_ARCH_VERS) != 0) {
1421      -                NDMP_LOG(LOG_DEBUG,
     1415 +                syslog(LOG_ERR,
1422 1416                      "Unrecognized header format [%s]", xhdr->h_version);
1423 1417                  return (0);
1424 1418          }
1425 1419          xbuf = (struct xattr_buf *)(((char *)xhdr) + sizeof (struct xattr_hdr));
1426 1420  
1427 1421          (void) sscanf(xbuf->h_namesz, "%7d", &namelen);
1428 1422          xattrname = xbuf->h_names + strlen(xbuf->h_names) + 1;
1429 1423  
1430 1424          if (*fp == 0) {
1431 1425                  int fd;
1432 1426  
1433 1427                  fd = attropen(name, xattrname, O_CREAT | O_RDWR, 0755);
1434 1428                  if (fd == -1) {
1435      -                        NDMP_LOG(LOG_DEBUG,
     1429 +                        syslog(LOG_ERR,
1436 1430                              "Could not open xattr [%s:%s] for restore err=%d.",
1437 1431                              name, xattrname, errno);
1438 1432                          job_stats->js_errors++;
1439 1433                          return (0);
1440 1434                  }
1441 1435                  (void) strlcpy(local_commands->tc_file_name, xattrname,
1442 1436                      TLM_MAX_PATH_NAME);
1443 1437                  *fp = fd;
1444 1438          }
1445 1439  
1446 1440          /* Get the actual extended attribute file */
1447 1441          tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(sizeof (*tar_hdr),
1448 1442              &error, &actual_size, local_commands);
1449 1443          if (tar_hdr == NULL || error != 0) {
1450      -                NDMP_LOG(LOG_DEBUG,
     1444 +                syslog(LOG_ERR,
1451 1445                      "Could not read xattr data [%s:%s] for restore. ",
1452 1446                      fname, xattrname);
1453 1447                  job_stats->js_errors++;
1454 1448                  return (0);
1455 1449          }
1456 1450          acls->acl_attr.st_mode = oct_atoi(tar_hdr->th_mode);
1457 1451          acls->acl_attr.st_size = oct_atoi(tar_hdr->th_size);
1458 1452          acls->acl_attr.st_uid = oct_atoi(tar_hdr->th_uid);
1459 1453          acls->acl_attr.st_gid = oct_atoi(tar_hdr->th_gid);
1460 1454          acls->acl_attr.st_mtime = oct_atoi(tar_hdr->th_mtime);
1461 1455  
1462      -        NDMP_LOG(LOG_DEBUG, "xattr_hdr: %s size %d mode %06o uid %d gid %d",
1463      -            xattrname, acls->acl_attr.st_size, acls->acl_attr.st_mode,
1464      -            acls->acl_attr.st_uid, acls->acl_attr.st_gid);
1465      -
1466 1456          size = acls->acl_attr.st_size;
1467 1457          while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
1468 1458                  char    *rec;
1469 1459                  int     write_size;
1470 1460                  int     sysattr_write = 0;
1471 1461  
1472 1462                  error = 0;
1473 1463                  rec = get_read_buffer(size, &error, &actual_size,
1474 1464                      local_commands);
1475 1465  
1476 1466                  if ((actual_size < size) && sysattr_rw(xattrname)) {
1477 1467                          rec = get_read_one_buf(rec, actual_size, size, &error,
1478 1468                              local_commands);
1479 1469                          if (rec == NULL) {
1480      -                                NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
     1470 +                                syslog(LOG_ERR, "Error %d in file [%s]",
1481 1471                                      error, xattrname);
1482 1472                                  return (size);
1483 1473                          }
1484 1474                          actual_size = size;
1485 1475                          sysattr_write = 1;
1486 1476                  }
1487 1477                  if (actual_size <= 0) {
1488      -                        NDMP_LOG(LOG_DEBUG,
     1478 +                        syslog(LOG_ERR,
1489 1479                              "RESTORE WRITER> error %d, actual_size %d",
1490 1480                              error, actual_size);
1491 1481  
1492 1482                          return (size);
1493 1483                  } else if (error) {
1494      -                        NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
     1484 +                        syslog(LOG_ERR, "Error %d in file [%s]",
1495 1485                              error, local_commands->tc_file_name);
1496 1486                          break;
1497 1487                  } else {
1498 1488                          write_size = min(size, actual_size);
1499 1489                          if ((write_size = write(*fp, rec, write_size)) < 0) {
1500 1490                                  if (sysattr_write)
1501 1491                                          free(rec);
1502 1492  
1503 1493                                  break;
1504 1494                          }
1505 1495  
1506 1496                          NS_ADD(wdisk, write_size);
1507 1497                          NS_INC(wfile);
1508 1498                          size -= write_size;
1509 1499                  }
1510 1500                  if (sysattr_write)
1511 1501                          free(rec);
1512 1502          }
1513 1503  
1514 1504          if (*fp != 0) {
1515 1505                  set_xattr(*fp, acls->acl_attr);
1516 1506                  (void) close(*fp);
1517 1507                  *fp = 0;
1518 1508          }
1519 1509          return (0);
1520 1510  }
1521 1511  
1522 1512  /*
1523 1513   * Match the name with the list
1524 1514   */
1525 1515  static int
1526 1516  exact_find(char *name, char **list)
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
1527 1517  {
1528 1518          boolean_t found;
1529 1519          int i;
1530 1520          char *cp;
1531 1521  
1532 1522          found = FALSE;
1533 1523          for (i = 0; *list != NULL; list++, i++) {
1534 1524                  cp = *list + strspn(*list, "/");
1535 1525                  if (match(cp, name)) {
1536 1526                          found = TRUE;
1537      -                        NDMP_LOG(LOG_DEBUG, "exact_find> found[%s]", cp);
     1527 +                        syslog(LOG_DEBUG, "exact_find> found[%s]", cp);
1538 1528                          break;
1539 1529                  }
1540 1530          }
1541 1531  
1542 1532          return (found);
1543 1533  }
1544 1534  
1545 1535  /*
1546 1536   * On error, return FALSE and prevent restoring(probably) unwanted data.
1547 1537   */
1548 1538  static int
1549 1539  is_parent(char *parent, char *child, int flags)
1550 1540  {
1551 1541          char tmp[TLM_MAX_PATH_NAME];
1552 1542          boolean_t rv;
1553 1543  
1554 1544          if (IS_SET(flags, RSFLG_MATCH_WCARD)) {
1555 1545                  if (!tlm_cat_path(tmp, parent, "*")) {
1556      -                        NDMP_LOG(LOG_DEBUG,
     1546 +                        syslog(LOG_ERR,
1557 1547                              "is_parent> path too long [%s]", parent);
1558 1548                          rv = FALSE;
1559 1549                  } else
1560 1550                          rv = (match(tmp, child) != 0) ? TRUE : FALSE;
1561 1551          } else {
1562 1552                  if (!tlm_cat_path(tmp, parent, "/")) {
1563      -                        NDMP_LOG(LOG_DEBUG,
     1553 +                        syslog(LOG_ERR,
1564 1554                              "is_parent> path too long [%s]", parent);
1565 1555                          rv = FALSE;
1566 1556                  } else
1567 1557                          rv = (strncmp(tmp, child, strlen(tmp)) == 0) ?
1568 1558                              TRUE : FALSE;
1569 1559          }
1570 1560  
1571 1561          return (rv);
1572 1562  }
1573 1563  
1574 1564  /*
1575 1565   * Used to match the filename inside the list
1576 1566   */
1577 1567  static boolean_t
1578 1568  strexactcmp(char *s, char *t)
1579 1569  {
1580 1570          return ((strcmp(s, t) == 0) ? TRUE : FALSE);
1581 1571  }
1582 1572  
1583 1573  /*
1584 1574   * Check if the file is needed to be restored
  
    | 
      ↓ open down ↓ | 
    11 lines elided | 
    
      ↑ open up ↑ | 
  
1585 1575   */
1586 1576  static boolean_t
1587 1577  is_file_wanted(char *name,
1588 1578      char **sels,
1589 1579      char **exls,
1590 1580      int flags,
1591 1581      int *mchtype,
1592 1582      int *pos)
1593 1583  {
1594 1584          char *p_sel;
1595      -        char *uc_name, *retry, *namep;
     1585 +        char *uc_name = NULL, *retry, *namep;
1596 1586          boolean_t found;
1597 1587          int i;
1598 1588          name_match_fp_t *cmp_fp;
1599 1589  
1600 1590          if (name == NULL || sels == NULL || exls == NULL)
1601 1591                  return (FALSE);
1602 1592  
1603 1593          found = FALSE;
1604 1594          if (mchtype != NULL)
1605 1595                  *mchtype = PM_NONE;
1606 1596          if (pos != NULL)
1607 1597                  *pos = 0;
1608 1598  
1609 1599          /*
1610 1600           * For empty selection, restore everything
1611 1601           */
1612 1602          if (*sels == NULL || **sels == '\0') {
1613      -                NDMP_LOG(LOG_DEBUG, "is_file_wanted: Restore all");
     1603 +                syslog(LOG_DEBUG, "is_file_wanted: Restore all");
1614 1604                  return (TRUE);
1615 1605          }
1616 1606  
1617 1607          retry = ndmp_malloc(TLM_MAX_PATH_NAME);
1618 1608          if (retry == NULL)
1619 1609                  return (FALSE);
1620 1610  
1621 1611          if (IS_SET(flags, RSFLG_MATCH_WCARD))
1622 1612                  cmp_fp = match;
1623 1613          else
1624 1614                  cmp_fp = strexactcmp;
1625 1615  
1626 1616          namep = name + strspn(name, "/");
1627 1617  
  
    | 
      ↓ open down ↓ | 
    4 lines elided | 
    
      ↑ open up ↑ | 
  
1628 1618          if (IS_SET(flags, RSFLG_IGNORE_CASE)) {
1629 1619                  uc_name = ndmp_malloc(TLM_MAX_PATH_NAME);
1630 1620                  if (uc_name == NULL) {
1631 1621                          free(retry);
1632 1622                          return (FALSE);
1633 1623                  }
1634 1624                  (void) strlcpy(uc_name, namep, TLM_MAX_PATH_NAME);
1635 1625                  (void) strupr(uc_name);
1636 1626                  namep = uc_name;
1637 1627          }
1638      -        NDMP_LOG(LOG_DEBUG, "is_file_wanted> flg: 0x%x name: [%s]",
1639      -            flags, name);
1640 1628  
1641 1629          for (i = 0; *sels != NULL; sels++, i++) {
1642 1630                  p_sel = *sels + strspn(*sels, "/");
1643 1631  
1644 1632                  /*
1645 1633                   * Try exact match.
1646 1634                   */
1647 1635                  if ((*cmp_fp)(p_sel, namep)) {
1648      -                        NDMP_LOG(LOG_DEBUG, "match1> pos: %d [%s][%s]",
1649      -                            i, p_sel, name);
1650 1636                          found = TRUE;
1651 1637                          if (mchtype != NULL)
1652 1638                                  *mchtype = PM_EXACT;
1653 1639                          break;
1654 1640                  }
1655 1641                  /*
1656 1642                   * Try "entry/" and the current selection.  The
1657 1643                   * current selection may be something like "<something>/".
1658 1644                   */
1659 1645                  (void) tlm_cat_path(retry, namep, "/");
1660 1646                  if ((*cmp_fp)(p_sel, retry)) {
1661      -                        NDMP_LOG(LOG_DEBUG, "match2> pos %d [%s][%s]",
     1647 +                        syslog(LOG_DEBUG, "match2> pos %d [%s][%s]",
1662 1648                              i, p_sel, name);
1663 1649                          found = TRUE;
1664 1650                          if (mchtype != NULL)
1665 1651                                  *mchtype = PM_EXACT;
1666 1652                          break;
1667 1653                  }
1668 1654                  /*
1669 1655                   * If the following check returns true it means that the
1670 1656                   * 'name' is an entry below the 'p_sel' hierarchy.
1671 1657                   */
1672 1658                  if (is_parent(p_sel, namep, flags)) {
1673      -                        NDMP_LOG(LOG_DEBUG, "parent1> pos %d [%s][%s]",
1674      -                            i, p_sel, name);
1675 1659                          found = TRUE;
1676 1660                          if (mchtype != NULL)
1677 1661                                  *mchtype = PM_CHILD;
1678 1662                          break;
1679 1663                  }
1680 1664                  /*
1681 1665                   * There is a special case for parent directories of a
1682 1666                   * selection.  If 'p_sel' is something like "*d1", the
1683 1667                   * middle directories of the final entry can't be determined
1684 1668                   * until the final entry matches with 'p_sel'.  At that
1685 1669                   * time the middle directories of the entry have been passed
1686 1670                   * and they can't be restored.
1687 1671                   */
1688 1672                  if (is_parent(namep, p_sel, flags)) {
1689      -                        NDMP_LOG(LOG_DEBUG, "parent2> pos %d [%s][%s]",
     1673 +                        syslog(LOG_DEBUG, "parent2> pos %d [%s][%s]",
1690 1674                              i, p_sel, name);
1691 1675                          found = TRUE;
1692 1676                          if (mchtype != NULL)
1693 1677                                  *mchtype = PM_PARENT;
1694 1678                          break;
1695 1679                  }
1696 1680          }
1697 1681  
1698 1682          /* Check for exclusions.  */
1699 1683          if (found && exact_find(namep, exls)) {
1700 1684                  if (mchtype != NULL)
1701 1685                          *mchtype = PM_NONE;
1702 1686                  found = FALSE;
1703 1687          }
1704 1688          if (found && pos != NULL)
1705 1689                  *pos = i;
1706 1690  
1707 1691          if (IS_SET(flags, RSFLG_IGNORE_CASE))
1708 1692                  free(uc_name);
1709 1693          free(retry);
1710 1694          return (found);
1711 1695  }
1712 1696  
1713 1697  /*
1714 1698   * Read the specified amount data into the buffer.  Detects EOT or EOF
1715 1699   * during read.
1716 1700   *
1717 1701   * Returns the number of bytes actually read.  On error returns -1.
1718 1702   */
1719 1703  static int
1720 1704  input_mem(int l,
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
1721 1705      int d,
1722 1706      tlm_cmd_t *lcmds,
1723 1707      char *mem,
1724 1708      int len)
1725 1709  {
1726 1710          int err;
1727 1711          int toread, actual_size, rec_size;
1728 1712          char *rec;
1729 1713  
1730 1714          if (l <= 0 || d <= 0 || !lcmds || !mem) {
1731      -                NDMP_LOG(LOG_DEBUG, "Invalid argument");
     1715 +                syslog(LOG_ERR, "Invalid argument");
1732 1716                  return (-1);
1733 1717          }
1734 1718  
1735 1719          toread = len;
1736 1720          while (toread > 0) {
1737 1721                  rec = get_read_buffer(toread, &err, &actual_size, lcmds);
1738 1722                  if (actual_size <= 0) {
1739      -                        NDMP_LOG(LOG_DEBUG, "err %d act_size %d detected",
     1723 +                        syslog(LOG_ERR, "err %d act_size %d detected",
1740 1724                              err, actual_size);
1741 1725                          break;
1742 1726                  } else if (err) {
1743      -                        NDMP_LOG(LOG_DEBUG, "error %d reading data", err);
     1727 +                        syslog(LOG_ERR, "error %d reading data", err);
1744 1728                          return (-1);
1745 1729                  }
1746 1730                  rec_size = min(actual_size, toread);
1747 1731                  (void) memcpy(mem, rec, rec_size);
1748 1732                  mem += rec_size;
1749 1733                  toread -= rec_size;
1750 1734          }
1751 1735  
1752 1736          return (len - toread);
1753 1737  }
1754 1738  
1755 1739  /*
1756 1740   * pick up the name and size of a HUGE file
1757 1741   */
1758 1742  static  int
  
    | 
      ↓ open down ↓ | 
    5 lines elided | 
    
      ↑ open up ↑ | 
  
1759 1743  get_humongus_file_header(int lib,
1760 1744      int drv,
1761 1745      long recsize,
1762 1746      longlong_t *size,
1763 1747      char *name,
1764 1748      tlm_cmd_t *local_commands)
1765 1749  {
1766 1750          char *p_record, *value;
1767 1751          int rv;
1768 1752  
1769      -        NDMP_LOG(LOG_DEBUG, "HUGE Record found: %d", recsize);
     1753 +        syslog(LOG_WARNING, "HUGE Record found: %d", recsize);
1770 1754  
1771 1755          rv = 0;
1772 1756          if (recsize == 0) {
1773 1757                  /*
1774 1758                   * The humongus_file_header was written in a
1775 1759                   * RECORDSIZE block and the header.size field of this
1776 1760                   * record was 0 before this fix.  For backward compatiblity
1777 1761                   * read only one RECORDSIZE-size block if the header.size
1778 1762                   * field is 0.  Otherwise the header.size field should show
1779 1763                   * the length of the data of this header.
1780 1764                   */
1781      -                NDMP_LOG(LOG_DEBUG, "Old HUGE record found");
     1765 +                syslog(LOG_WARNING, "Old HUGE record found");
1782 1766                  recsize = RECORDSIZE;
1783 1767          }
1784 1768  
1785 1769          if (input_mem(lib, drv, local_commands, name, recsize) != recsize) {
1786 1770                  rv = -1;
1787 1771                  *size = 0;
1788 1772                  *name = '\0';
1789      -                NDMP_LOG(LOG_DEBUG, "Error reading a HUGE file name");
     1773 +                syslog(LOG_ERR, "Error reading a HUGE file name");
1790 1774          } else {
1791      -                NDMP_LOG(LOG_DEBUG, "HUGE [%s]", name);
     1775 +                syslog(LOG_DEBUG, "HUGE [%s]", name);
1792 1776  
1793 1777                  p_record = name;
1794 1778                  value = parse(&p_record, " ");
1795 1779                  *size = atoll(value);
1796 1780                  /*
1797 1781                   * Note: Since the backed up names are not longer than
1798 1782                   * NAME_MAX and the buffer passed to us is
1799 1783                   * TLM_MAX_PATH_NAME, it should be safe to use strlcpy
1800 1784                   * without check on the buffer size.
1801 1785                   */
1802 1786                  (void) strlcpy(name, p_record, TLM_MAX_PATH_NAME);
1803 1787          }
1804 1788  
1805      -        NDMP_LOG(LOG_DEBUG, "HUGE Record %lld [%s]", *size, name);
     1789 +        syslog(LOG_DEBUG, "HUGE Record %lld [%s]", *size, name);
1806 1790  
1807 1791          return (rv);
1808 1792  }
1809 1793  
1810 1794  /*
1811 1795   * pick up the long name from the special tape file
1812 1796   */
1813 1797  static int
1814 1798  get_long_name(int lib,
1815 1799      int drv,
1816 1800      long recsize,
1817 1801      char *name,
1818 1802      long *buf_spot,
1819 1803      tlm_cmd_t *local_commands)
1820 1804  {
1821 1805          int nread;
1822 1806  
1823      -        NDMP_LOG(LOG_DEBUG, "LONGNAME Record found rs %d bs %d", recsize,
     1807 +        syslog(LOG_DEBUG, "LONGNAME Record found rs %d bs %d", recsize,
1824 1808              *buf_spot);
1825 1809  
1826 1810          if (*buf_spot < 0)
1827 1811                  *buf_spot = 0;
1828 1812  
1829 1813          nread = input_mem(lib, drv, local_commands, name + *buf_spot,
1830 1814              recsize);
1831 1815          if (nread < 0) {
1832 1816                  nread = recsize; /* return 0 as size left */
1833 1817                  name[*buf_spot] = '\0';
1834      -                NDMP_LOG(LOG_ERR, "Error %d reading a long file name %s.",
     1818 +                syslog(LOG_ERR, "Error %d reading a long file name %s.",
1835 1819                      nread, name);
1836 1820          } else {
1837 1821                  *buf_spot += nread;
1838 1822                  name[*buf_spot] = '\0';
1839      -                NDMP_LOG(LOG_DEBUG, "LONGNAME [%s]", name);
     1823 +                syslog(LOG_DEBUG, "LONGNAME [%s]", name);
1840 1824          }
1841 1825  
1842 1826          return (recsize - nread);
1843 1827  }
1844 1828  
1845 1829  /*
1846 1830   * create a new directory
1847 1831   */
1848 1832  static int
1849 1833  create_directory(char *dir, tlm_job_stats_t *job_stats)
1850 1834  {
1851 1835          struct stat64 attr;
1852 1836          char    *p;
1853 1837          char    temp;
1854 1838          int     erc;
1855 1839  
1856 1840          /*
1857 1841           * Make sure all directories in this path exist, create them if
1858 1842           * needed.
1859 1843           */
1860      -        NDMP_LOG(LOG_DEBUG, "new dir[%s]", dir);
1861 1844  
1862 1845          erc = 0;
1863 1846          p = &dir[1];
1864 1847          do {
1865 1848                  temp = *p;
1866 1849                  if (temp == '/' || temp == 0) {
1867 1850                          *p = 0;
1868 1851                          if (stat64(dir, &attr) < 0) {
1869 1852                                  if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
1870 1853                                          erc = errno;
1871 1854                                          job_stats->js_errors++;
1872      -                                        NDMP_LOG(LOG_DEBUG,
     1855 +                                        syslog(LOG_ERR,
1873 1856                                              "Could not create directory %s: %d",
1874 1857                                              dir, errno);
1875 1858                                          break;
1876 1859                                  }
1877 1860                          }
1878 1861                          *p = temp;
1879 1862                  }
1880 1863                  p++;
1881 1864          } while (temp != 0);
1882 1865  
1883 1866          return (erc);
1884 1867  }
1885 1868  
1886 1869  /*
1887 1870   * create a new hardlink
1888 1871   */
1889 1872  static int
1890 1873  create_hard_link(char *name_old, char *name_new,
1891 1874      tlm_acls_t *acls, tlm_job_stats_t *job_stats)
1892 1875  {
1893 1876          int erc;
1894 1877  
1895 1878          erc = mkbasedir(name_new);
1896 1879          if (erc != 0)
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
1897 1880                  return (erc);
1898 1881  
1899 1882          if (link(name_old, name_new) != 0)
1900 1883                  erc = errno;
1901 1884  
1902 1885          if (erc) {
1903 1886                  /* Nothing to do if the destination already exists */
1904 1887                  if (erc == EEXIST)
1905 1888                          return (0);
1906 1889                  job_stats->js_errors++;
1907      -                NDMP_LOG(LOG_DEBUG, "error %d (errno %d) hardlink [%s] to [%s]",
     1890 +                syslog(LOG_ERR, "error %d (errno %d) hardlink [%s] to [%s]",
1908 1891                      erc, errno, name_new, name_old);
1909 1892                  return (erc);
1910 1893          }
1911 1894          return (set_acl(name_new, acls));
1912 1895  }
1913 1896  
1914 1897  /*
1915 1898   * create a new symlink
1916 1899   */
1917 1900  /*ARGSUSED*/
1918 1901  static int
1919 1902  create_sym_link(char *dst, char *target, tlm_acls_t *acls,
1920 1903      tlm_job_stats_t *job_stats)
1921 1904  {
  
    | 
      ↓ open down ↓ | 
    4 lines elided | 
    
      ↑ open up ↑ | 
  
1922 1905          int erc;
1923 1906          struct stat64 *st;
1924 1907  
1925 1908          erc = mkbasedir(dst);
1926 1909          if (erc != 0)
1927 1910                  return (erc);
1928 1911  
1929 1912          st = &acls->acl_attr;
1930 1913          if (symlink(target, dst) != 0) {
1931 1914                  erc = errno;
1932      -                job_stats->js_errors++;
1933      -                NDMP_LOG(LOG_DEBUG, "error %d softlink [%s] to [%s]",
1934      -                    errno, dst, target);
     1915 +                if (errno == EEXIST) {
     1916 +                        erc = 0;
     1917 +                        syslog(LOG_DEBUG,
     1918 +                            "softlink [%s] to [%s] already existed",
     1919 +                            dst, target);
     1920 +                } else {
     1921 +                        job_stats->js_errors++;
     1922 +                        syslog(LOG_ERR, "error %d softlink [%s] to [%s]",
     1923 +                            errno, dst, target);
     1924 +                }
1935 1925          } else {
1936 1926                  st->st_mode |= S_IFLNK;
1937 1927                  erc = set_acl(dst, acls);
1938 1928          }
1939 1929  
1940 1930          return (erc);
1941 1931  }
1942 1932  
1943 1933  /*
1944 1934   * create a new FIFO, char/block device special files
1945 1935   */
1946 1936  static int
1947 1937  create_special(char flag, char *name, tlm_acls_t *acls, int major, int minor,
1948 1938      tlm_job_stats_t *job_stats)
1949 1939  {
1950 1940          dev_t dev;
1951 1941          mode_t mode;
1952 1942  
1953 1943          switch (flag) {
1954 1944          case LF_CHR:
1955 1945                  mode = S_IFCHR;
1956 1946                  dev = makedev(major, minor);
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
1957 1947                  break;
1958 1948          case LF_BLK:
1959 1949                  mode = S_IFBLK;
1960 1950                  dev = makedev(major, minor);
1961 1951                  break;
1962 1952          case LF_FIFO:
1963 1953                  mode = S_IFIFO;
1964 1954                  dev = 0;
1965 1955                  break;
1966 1956          default:
1967      -                NDMP_LOG(LOG_ERR, "unsupported flag %d", flag);
     1957 +                syslog(LOG_ERR, "unsupported flag %d", flag);
1968 1958                  return (-1);
1969 1959          }
1970 1960  
1971 1961          /* Remove the old entry first */
1972 1962          if (rmdir(name) < 0) {
1973 1963                  if (errno == ENOTDIR)
1974 1964                          (void) unlink(name);
1975 1965          }
1976 1966          if (mknod(name, 0777 | mode, dev) != 0) {
1977 1967                  job_stats->js_errors++;
1978      -                NDMP_LOG(LOG_DEBUG, "error %d mknod [%s] major"
     1968 +                syslog(LOG_ERR, "error %d mknod [%s] major"
1979 1969                      " %d minor %d", errno, name, major, minor);
1980 1970                  return (errno);
1981 1971          }
1982 1972          return (set_acl(name, acls));
1983 1973  }
1984 1974  
1985 1975  /*
1986 1976   * read in the ACLs for the next file
1987 1977   */
1988 1978  static long
1989 1979  load_acl_info(int lib,
1990 1980      int drv,
1991 1981      long file_size,
1992 1982      tlm_acls_t *acls,
1993 1983      long *acl_spot,
1994 1984      tlm_cmd_t *local_commands)
1995 1985  {
1996 1986          char *bp;
1997 1987          int nread;
1998 1988  
1999 1989          /*
2000 1990           * If the ACL is spanned on tapes, then the acl_spot should NOT be
2001 1991           * 0 on next calls to this function to read the rest of the ACL
2002 1992           * on next tapes.
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
2003 1993           */
2004 1994          if (*acl_spot == 0) {
2005 1995                  (void) memset(acls, 0, sizeof (tlm_acls_t));
2006 1996          }
2007 1997  
2008 1998          bp = ((char *)&acls->acl_info) + *acl_spot;
2009 1999          nread = input_mem(lib, drv, local_commands, (void *)bp, file_size);
2010 2000          if (nread < 0) {
2011 2001                  *acl_spot = 0;
2012 2002                  (void) memset(acls, 0, sizeof (tlm_acls_t));
2013      -                NDMP_LOG(LOG_DEBUG, "Error reading ACL data");
     2003 +                syslog(LOG_ERR, "Error reading ACL data");
2014 2004                  return (0);
2015 2005          }
2016 2006          *acl_spot += nread;
2017 2007          acls->acl_non_trivial = TRUE;
2018 2008  
2019 2009          return (file_size - nread);
2020 2010  }
2021 2011  
2022 2012  static int
2023 2013  ndmp_set_eprivs_least(void)
2024 2014  {
2025 2015          priv_set_t *priv_set;
2026 2016  
2027 2017          if ((priv_set = priv_allocset()) == NULL) {
2028      -                NDMP_LOG(LOG_ERR, "Out of memory.");
     2018 +                syslog(LOG_ERR, "Out of memory.");
2029 2019                  return (-1);
2030 2020          }
2031 2021  
2032 2022          priv_basicset(priv_set);
2033 2023  
2034 2024          (void) priv_addset(priv_set, PRIV_PROC_AUDIT);
2035 2025          (void) priv_addset(priv_set, PRIV_PROC_SETID);
2036 2026          (void) priv_addset(priv_set, PRIV_PROC_OWNER);
2037 2027          (void) priv_addset(priv_set, PRIV_FILE_CHOWN);
2038 2028          (void) priv_addset(priv_set, PRIV_FILE_CHOWN_SELF);
2039 2029          (void) priv_addset(priv_set, PRIV_FILE_DAC_READ);
  
    | 
      ↓ open down ↓ | 
    1 lines elided | 
    
      ↑ open up ↑ | 
  
2040 2030          (void) priv_addset(priv_set, PRIV_FILE_DAC_SEARCH);
2041 2031          (void) priv_addset(priv_set, PRIV_FILE_DAC_WRITE);
2042 2032          (void) priv_addset(priv_set, PRIV_FILE_OWNER);
2043 2033          (void) priv_addset(priv_set, PRIV_FILE_SETID);
2044 2034          (void) priv_addset(priv_set, PRIV_SYS_LINKDIR);
2045 2035          (void) priv_addset(priv_set, PRIV_SYS_DEVICES);
2046 2036          (void) priv_addset(priv_set, PRIV_SYS_MOUNT);
2047 2037          (void) priv_addset(priv_set, PRIV_SYS_CONFIG);
2048 2038  
2049 2039          if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) == -1) {
2050      -                NDMP_LOG(LOG_ERR, "Additional privileges required.");
     2040 +                syslog(LOG_ERR, "Additional privileges required.");
2051 2041                  priv_freeset(priv_set);
2052 2042                  return (-1);
2053 2043          }
2054 2044          priv_freeset(priv_set);
2055 2045          return (0);
2056 2046  }
2057 2047  
2058 2048  static int
2059 2049  ndmp_set_eprivs_all(void)
2060 2050  {
2061 2051          priv_set_t *priv_set;
2062 2052  
2063 2053          if ((priv_set = priv_allocset()) == NULL) {
2064      -                NDMP_LOG(LOG_ERR, "Out of memory.");
     2054 +                syslog(LOG_ERR, "Out of memory.");
2065 2055                  return (-1);
2066 2056          }
2067 2057  
2068 2058          priv_fillset(priv_set);
2069 2059  
2070 2060          if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) != 0) {
2071      -                NDMP_LOG(LOG_ERR, "Additional privileges required.");
     2061 +                syslog(LOG_ERR, "Additional privileges required.");
2072 2062                  return (-1);
2073 2063          }
2074 2064          priv_freeset(priv_set);
2075 2065          return (0);
2076 2066  }
2077 2067  
2078 2068  /*
2079 2069   * Set the standard attributes of the file
2080 2070   */
2081 2071  static int
2082 2072  set_attr(char *name, tlm_acls_t *acls)
2083 2073  {
2084 2074          struct utimbuf tbuf;
2085 2075          boolean_t priv_all = FALSE;
2086 2076          struct stat64 *st;
2087 2077          uid_t uid;
  
    | 
      ↓ open down ↓ | 
    6 lines elided | 
    
      ↑ open up ↑ | 
  
2088 2078          gid_t gid;
2089 2079          struct passwd *pwd;
2090 2080          struct group *grp;
2091 2081          int erc = 0;
2092 2082  
2093 2083  
2094 2084          if (!name || !acls)
2095 2085                  return (0);
2096 2086  
2097 2087          st = &acls->acl_attr;
2098      -        NDMP_LOG(LOG_DEBUG, "set_attr: %s uid %d gid %d uname %s gname %s "
2099      -            "mode %o", name, st->st_uid, st->st_gid, acls->uname, acls->gname,
2100      -            st->st_mode);
2101 2088  
2102 2089          uid = st->st_uid;
2103 2090          if ((pwd = getpwnam(acls->uname)) != NULL) {
2104      -                NDMP_LOG(LOG_DEBUG, "set_attr: new uid %d old %d",
2105      -                    pwd->pw_uid, uid);
2106 2091                  uid = pwd->pw_uid;
2107 2092          }
2108 2093  
2109 2094          gid = st->st_gid;
2110 2095          if ((grp = getgrnam(acls->gname)) != NULL) {
2111      -                NDMP_LOG(LOG_DEBUG, "set_attr: new gid %d old %d",
2112      -                    grp->gr_gid, gid);
2113 2096                  gid = grp->gr_gid;
2114 2097          }
2115 2098  
2116 2099          erc = lchown(name, uid, gid);
2117 2100          if (erc != 0) {
2118 2101                  erc = errno;
2119      -                NDMP_LOG(LOG_ERR,
     2102 +                syslog(LOG_ERR,
2120 2103                      "Could not set uid or/and gid for file %s.", name);
2121 2104          }
2122 2105  
2123 2106          if ((st->st_mode & (S_ISUID | S_ISGID)) != 0) {
2124 2107                  /*
2125 2108                   * Change effective privileges to 'all' which is required to
2126 2109                   * change setuid bit for 'root' owned files. If fails, just
2127 2110                   * send error to log file and proceed.
2128 2111                   */
2129 2112                  if (ndmp_set_eprivs_all()) {
2130      -                        NDMP_LOG(LOG_ERR,
     2113 +                        syslog(LOG_ERR,
2131 2114                              "Could not set effective privileges to 'all'.");
2132 2115                  } else {
2133 2116                          priv_all = TRUE;
2134 2117                  }
2135 2118          }
2136 2119  
2137 2120          if (!S_ISLNK(st->st_mode)) {
2138 2121                  erc = chmod(name, st->st_mode);
2139 2122                  if (erc != 0) {
2140 2123                          erc = errno;
2141      -                        NDMP_LOG(LOG_ERR, "Could not set correct file"
     2124 +                        syslog(LOG_ERR, "Could not set correct file"
2142 2125                              " permission for file %s: %d", name, errno);
2143 2126                  }
2144 2127  
2145 2128                  tbuf.modtime = st->st_mtime;
2146 2129                  tbuf.actime = st->st_atime;
2147 2130                  (void) utime(name, &tbuf);
2148 2131          }
2149 2132  
2150 2133          if (priv_all == TRUE) {
2151 2134                  /*
2152 2135                   * Give up the 'all' privileges for effective sets and go back
2153 2136                   * to least required privileges. If fails, just send error to
2154 2137                   * log file and proceed.
2155 2138                   */
2156 2139                  if (ndmp_set_eprivs_least())
2157      -                        NDMP_LOG(LOG_ERR,
     2140 +                        syslog(LOG_ERR,
2158 2141                              "Could not set least required privileges.");
2159 2142          }
2160 2143  
2161 2144          return (erc);
2162 2145  }
2163 2146  
2164 2147  /*
2165 2148   * Set the ACL info for the file
2166 2149   */
2167 2150  static int
2168 2151  set_acl(char *name, tlm_acls_t *acls)
2169 2152  {
2170 2153          int erc;
2171 2154          acl_t *aclp = NULL;
2172 2155  
2173      -        if (name)
2174      -                NDMP_LOG(LOG_DEBUG, "set_acl: %s", name);
2175 2156          if (acls == NULL)
2176 2157                  return (0);
2177 2158  
2178 2159          /* Need a place to save real modification time */
2179 2160  
2180 2161          erc = set_attr(name, acls);
2181 2162          if (ERROR_IS_FATAL(erc))
2182 2163                  return (erc);
2183 2164  
2184 2165          if (!acls->acl_non_trivial) {
2185 2166                  (void) memset(acls, 0, sizeof (tlm_acls_t));
2186      -                NDMP_LOG(LOG_DEBUG, "set_acl: skipping trivial");
2187 2167                  return (erc);
2188 2168          }
2189 2169  
2190 2170          erc = acl_fromtext(acls->acl_info.attr_info, &aclp);
2191 2171          if (erc != 0) {
2192      -                NDMP_LOG(LOG_DEBUG,
     2172 +                syslog(LOG_ERR,
2193 2173                      "TAPE RESTORE> acl_fromtext errno %d", erc);
2194 2174          }
2195 2175          if (aclp) {
2196 2176                  erc = acl_set(name, aclp);
2197 2177                  if (erc < 0) {
2198 2178                          erc = errno;
2199      -                        NDMP_LOG(LOG_DEBUG,
     2179 +                        syslog(LOG_ERR,
2200 2180                              "TAPE RESTORE> acl_set errno %d", errno);
2201 2181                  }
2202 2182                  acl_free(aclp);
2203 2183          }
2204 2184          (void) memset(acls, 0, sizeof (tlm_acls_t));
2205 2185          return (erc);
2206 2186  }
2207 2187  
2208 2188  /*
2209 2189   * a wrapper to tlm_get_read_buffer so that
2210 2190   * we can cleanly detect ABORT commands
2211 2191   * without involving the TLM library with
2212 2192   * our problems.
2213 2193   */
2214 2194  static char *
2215 2195  get_read_buffer(int want,
2216 2196      int *error,
2217 2197      int *actual_size,
2218 2198      tlm_cmd_t *local_commands)
2219 2199  {
2220 2200          while (local_commands->tc_writer == TLM_RESTORE_RUN) {
2221 2201                  char    *rec;
2222 2202                  rec = tlm_get_read_buffer(want, error,
2223 2203                      local_commands->tc_buffers, actual_size);
2224 2204                  if (rec != 0) {
2225 2205                          return (rec);
2226 2206                  }
2227 2207          }
2228 2208  
2229 2209          /*
2230 2210           * the job is ending, give Writer a buffer that will never be read ...
2231 2211           * it does not matter anyhow, we are aborting.
2232 2212           */
2233 2213          *actual_size = RECORDSIZE;
2234 2214          return (NULL);
2235 2215  }
2236 2216  
2237 2217  /*
2238 2218   * Enable wildcard for restore options
2239 2219   */
2240 2220  static boolean_t
2241 2221  wildcard_enabled(void)
2242 2222  {
2243 2223          char *cp;
2244 2224  
2245 2225          cp = ndmpd_get_prop_default(NDMP_RESTORE_WILDCARD_ENABLE, "n");
2246 2226          return ((toupper(*cp) == 'Y') ? TRUE : FALSE);
2247 2227  }
2248 2228  
2249 2229  
2250 2230  /*
  
    | 
      ↓ open down ↓ | 
    41 lines elided | 
    
      ↑ open up ↑ | 
  
2251 2231   * Concatenate two names
2252 2232   */
2253 2233  /*ARGSUSED*/
2254 2234  static char *
2255 2235  catnames(struct rs_name_maker *rnp, char *buf, int pos, char *path)
2256 2236  {
2257 2237          char *rv;
2258 2238  
2259 2239          rv = NULL;
2260 2240          if (!buf) {
2261      -                NDMP_LOG(LOG_DEBUG, "buf is NULL");
     2241 +                syslog(LOG_DEBUG, "buf is NULL");
2262 2242          } else if (!path) {
2263      -                NDMP_LOG(LOG_DEBUG, "path is NULL");
     2243 +                syslog(LOG_DEBUG, "path is NULL");
2264 2244          } else if (!rnp->rn_nlp) {
2265      -                NDMP_LOG(LOG_DEBUG, "rn_nlp is NULL [%s]", path);
     2245 +                syslog(LOG_DEBUG, "rn_nlp is NULL [%s]", path);
2266 2246          } else if (!tlm_cat_path(buf, rnp->rn_nlp, path)) {
2267      -                NDMP_LOG(LOG_DEBUG, "Path too long [%s][%s]",
     2247 +                syslog(LOG_DEBUG, "Path too long [%s][%s]",
2268 2248                      rnp->rn_nlp, path);
2269 2249          } else
2270 2250                  rv = buf;
2271 2251  
2272 2252          return (rv);
2273 2253  }
2274 2254  
2275 2255  
2276 2256  /*
2277 2257   * Create a new name path for restore
2278 2258   */
2279 2259  static char *
2280 2260  rs_new_name(struct rs_name_maker *rnp, char *buf, int pos, char *path)
2281 2261  {
2282 2262          if (!rnp || !rnp->rn_fp)
2283 2263                  return (NULL);
2284 2264  
2285 2265          return (*rnp->rn_fp)(rnp, buf, pos, path);
2286 2266  }
2287 2267  
2288 2268  /*
2289 2269   * Clear the extra "/" in the tar header if exists
2290 2270   */
2291 2271  static void
2292 2272  rs_create_new_bkpath(char *bk_path, char *path, char *pbuf)
2293 2273  {
2294 2274          char *p, *slashp;
2295 2275  
2296 2276          if ((p = strstr(path, bk_path)) == NULL) {
2297 2277                  (void) strlcpy(pbuf, path, TLM_MAX_PATH_NAME);
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
2298 2278                  return;
2299 2279          }
2300 2280          if (*(p += strlen(bk_path)) == '/')
2301 2281                  p++;
2302 2282  
2303 2283          slashp = bk_path + strlen(bk_path) - 1;
2304 2284          if (*slashp == '/')
2305 2285                  (void) snprintf(pbuf, TLM_MAX_PATH_NAME, "%s%s", bk_path, p);
2306 2286          else
2307 2287                  (void) snprintf(pbuf, TLM_MAX_PATH_NAME, "%s/%s", bk_path, p);
2308      -
2309      -        NDMP_LOG(LOG_DEBUG, "old path [%s] new path [%s]", path, pbuf);
2310 2288  }
2311 2289  
2312 2290  
2313 2291  /*
2314 2292   * Iterate over ZFS metadata stored in the backup stream and use the callback
2315 2293   * to restore it.
2316 2294   */
2317 2295  int
2318 2296  ndmp_iter_zfs(ndmp_context_t *nctx, int (*np_restore_property)(nvlist_t *,
2319 2297      void *), void *ptr)
2320 2298  {
2321 2299          tlm_commands_t *cmds;
2322 2300          ndmp_metadata_header_t *mhp;
2323 2301          ndmp_metadata_header_ext_t *mhpx;
2324 2302          ndmp_metadata_property_t *mpp;
2325 2303          ndmp_metadata_property_ext_t *mppx;
2326 2304          tlm_cmd_t *lcmd;
2327 2305          int actual_size;
2328 2306          nvlist_t *nvl;
2329 2307          nvlist_t *valp;
2330 2308          nvpair_t *nvp = NULL;
2331 2309          char plname[100];
2332 2310          char *mhbuf, *pp, *tp;
2333 2311          int rv, i;
2334 2312          int size, lsize, sz;
2335 2313          int align = RECORDSIZE - 1;
2336 2314  
2337 2315          if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2338 2316                  return (-1);
2339 2317  
2340 2318          nctx->nc_plname = plname;
2341 2319          if ((lcmd = cmds->tcs_command) == NULL ||
2342 2320              lcmd->tc_buffers == NULL)
2343 2321                  return (-1);
2344 2322  
2345 2323          /* Default minimum bytes needed */
2346 2324          size = sizeof (ndmp_metadata_header_t) +
2347 2325              ZFS_MAX_PROPS * sizeof (ndmp_metadata_property_t);
2348 2326          size += align;
2349 2327          size &= ~align;
2350 2328  
2351 2329          if ((mhbuf = malloc(size)) == NULL)
2352 2330                  return (-1);
2353 2331  
2354 2332          /* LINTED improper alignment */
2355 2333          while ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2356 2334              &actual_size, lcmd)) != NULL) {
2357 2335                  pp = mhbuf;
2358 2336  
2359 2337                  if (strncmp(mhp->nh_magic, ZFS_META_MAGIC,
2360 2338                      sizeof (mhp->nh_magic)) != 0 &&
2361 2339                      strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT,
2362 2340                      sizeof (mhp->nh_magic)) != 0) {
2363 2341                          /* No more metadata */
2364 2342                          tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2365 2343                          free(mhbuf);
2366 2344                          return (0);
2367 2345                  }
2368 2346  
2369 2347                  if (strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT,
2370 2348                      sizeof (mhp->nh_magic)) == 0) {
2371 2349                          mhpx = (ndmp_metadata_header_ext_t *)mhp;
2372 2350                          if (mhpx->nh_total_bytes > size) {
2373 2351                                  if ((pp = realloc(mhbuf, mhpx->nh_total_bytes))
2374 2352                                      == NULL) {
2375 2353                                          free(mhbuf);
2376 2354                                          return (-1);
2377 2355                                  }
2378 2356                                  mhbuf = pp;
2379 2357                          }
2380 2358                          size = mhpx->nh_total_bytes;
2381 2359                  }
2382 2360  
2383 2361                  (void) memcpy(pp, (char *)mhp, (actual_size < size) ?
2384 2362                      actual_size : size);
2385 2363                  pp += (actual_size < size) ? actual_size : size;
2386 2364  
2387 2365                  sz = actual_size;
2388 2366                  while (sz < size &&
2389 2367                      ((tp = get_read_buffer(size - sz, &rv, &lsize,
2390 2368                      lcmd))) != NULL) {
2391 2369                          (void) memcpy(pp, tp, lsize);
2392 2370                          sz += lsize;
2393 2371                          pp += lsize;
2394 2372                  }
2395 2373                  if (sz > size) {
2396 2374                          tlm_unget_read_buffer(lcmd->tc_buffers, sz - size);
2397 2375                  }
2398 2376  
2399 2377                  /* LINTED improper alignment */
2400 2378                  mhp = (ndmp_metadata_header_t *)mhbuf;
  
    | 
      ↓ open down ↓ | 
    81 lines elided | 
    
      ↑ open up ↑ | 
  
2401 2379  
2402 2380                  nvl = NULL;
2403 2381                  if (strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT,
2404 2382                      sizeof (mhp->nh_magic)) == 0) {
2405 2383                          /* New metadata format */
2406 2384                          /* LINTED improper alignment */
2407 2385                          mhpx = (ndmp_metadata_header_ext_t *)mhbuf;
2408 2386  
2409 2387                          if (mhpx->nh_major > META_HDR_MAJOR_VERSION) {
2410 2388                                  /* Major header mismatch */
2411      -                                NDMP_LOG(LOG_ERR, "metadata header mismatch",
     2389 +                                syslog(LOG_ERR, "metadata header mismatch",
2412 2390                                      "M%d != M%d", mhpx->nh_major,
2413 2391                                      META_HDR_MAJOR_VERSION);
2414 2392                                  free(mhbuf);
2415 2393                                  return (-1);
2416 2394                          }
2417 2395                          if (mhpx->nh_major == META_HDR_MAJOR_VERSION &&
2418 2396                              mhpx->nh_minor > META_HDR_MINOR_VERSION) {
2419 2397                                  /* Minor header mismatch */
2420      -                                NDMP_LOG(LOG_ERR, "Warning:"
     2398 +                                syslog(LOG_ERR, "Warning:"
2421 2399                                      "metadata header mismatch m%d != m%d",
2422 2400                                      mhpx->nh_minor,
2423 2401                                      META_HDR_MINOR_VERSION);
2424 2402                                  continue;
2425 2403                          }
2426 2404  
2427 2405                          nctx->nc_plversion = mhpx->nh_plversion;
2428 2406                          (void) strlcpy(plname, mhpx->nh_plname,
2429 2407                              sizeof (plname));
2430 2408  
2431 2409                          if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
2432 2410                                  goto nvlist_err;
2433 2411  
2434 2412                          mppx = &mhpx->nh_property[0];
2435 2413                          for (i = 0; i < mhpx->nh_count && mppx; i++, mppx++) {
2436 2414                                  if (!*mppx->mp_name)
2437 2415                                          continue;
2438 2416                                  valp = NULL;
2439 2417                                  if (nvlist_alloc(&valp,
2440 2418                                      NV_UNIQUE_NAME, 0) != 0 ||
2441 2419                                      nvlist_add_string(valp, "value",
2442 2420                                      mppx->mp_value) != 0 ||
2443 2421                                      nvlist_add_string(valp, "source",
2444 2422                                      mppx->mp_source) != 0 ||
2445 2423                                      nvlist_add_nvlist(nvl, mppx->mp_name,
2446 2424                                      valp) != 0) {
2447 2425                                          nvlist_free(valp);
2448 2426                                          goto nvlist_err;
2449 2427                                  }
2450 2428                                  nvlist_free(valp);
2451 2429                          }
2452 2430                  } else {
2453 2431                          nctx->nc_plversion = mhp->nh_plversion;
2454 2432                          (void) strlcpy(plname, mhp->nh_plname,
2455 2433                              sizeof (plname));
2456 2434  
2457 2435                          if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
2458 2436                                  goto nvlist_err;
2459 2437  
2460 2438                          mpp = &mhp->nh_property[0];
2461 2439                          for (i = 0; i < mhp->nh_count && mpp; i++, mpp++) {
2462 2440                                  if (!*mpp->mp_name)
2463 2441                                          continue;
2464 2442                                  valp = NULL;
2465 2443                                  if (nvlist_alloc(&valp,
2466 2444                                      NV_UNIQUE_NAME, 0) != 0 ||
2467 2445                                      nvlist_add_string(valp, "value",
2468 2446                                      mpp->mp_value) != 0 ||
2469 2447                                      nvlist_add_string(valp, "source",
2470 2448                                      mpp->mp_source) != 0 ||
2471 2449                                      nvlist_add_nvlist(nvl, mpp->mp_name,
2472 2450                                      valp) != 0) {
2473 2451                                          nvlist_free(valp);
2474 2452                                          goto nvlist_err;
2475 2453                                  }
2476 2454                                  nvlist_free(valp);
2477 2455                          }
2478 2456                  }
2479 2457  
2480 2458                  if (np_restore_property(nvl, ptr) != 0)
2481 2459                          goto nvlist_err;
2482 2460  
2483 2461                  while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL &&
2484 2462                      nvpair_value_nvlist(nvp, &valp) == 0) {
2485 2463                          nvlist_free(valp);
2486 2464                  }
2487 2465                  nvlist_free(nvl);
2488 2466          }
2489 2467  
2490 2468          free(mhbuf);
2491 2469          return (0);
2492 2470  
2493 2471  nvlist_err:
2494 2472          free(mhbuf);
2495 2473  
2496 2474          while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL &&
2497 2475              nvpair_value_nvlist(nvp, &valp) == 0) {
2498 2476                  nvlist_free(valp);
2499 2477          }
2500 2478          nvlist_free(nvl);
2501 2479          return (-1);
2502 2480  }
2503 2481  
2504 2482  /*
2505 2483   * Returns the version number of the plugin which created the metadata
2506 2484   */
2507 2485  uint_t
2508 2486  ndmp_context_get_version(ndmp_context_t *nctx)
2509 2487  {
2510 2488          tlm_commands_t *cmds;
2511 2489          ndmp_metadata_header_t *mhp;
2512 2490          tlm_cmd_t *lcmd;
2513 2491          int actual_size;
2514 2492          int rv;
2515 2493          int size;
2516 2494          int align = RECORDSIZE - 1;
2517 2495  
2518 2496          if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2519 2497                  return (0);
2520 2498  
2521 2499          if ((lcmd = cmds->tcs_command) == NULL ||
2522 2500              lcmd->tc_buffers == NULL)
2523 2501                  return (0);
2524 2502  
2525 2503          size = sizeof (ndmp_metadata_header_t);
2526 2504          size += align;
2527 2505          size &= ~align;
2528 2506  
2529 2507          /* LINTED improper alignment */
2530 2508          if ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2531 2509              &actual_size, lcmd)) != NULL) {
2532 2510                  if (strncmp(mhp->nh_magic, ZFS_META_MAGIC,
2533 2511                      sizeof (mhp->nh_magic)) != 0) {
2534 2512                          /* No more metadata */
2535 2513                          tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2536 2514                          return (0);
2537 2515                  }
2538 2516  
2539 2517                  nctx->nc_plversion = mhp->nh_plversion;
2540 2518                  tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2541 2519          }
2542 2520  
2543 2521          return (nctx->nc_plversion);
2544 2522  }
  
    | 
      ↓ open down ↓ | 
    114 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX