Print this page
NEX-13374 NDMP should be able to backup unmounted ZFS filesystems
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Revert "NEX-5801 Snapshots left over after failed backups"
This reverts commit f182fb95f09036db71fbfc6f0a6b90469b761f21.
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-2990 ndmpd dumping core when used with ndmpcopy
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-1512 NDMP fails in Restore files with Symantec Netbackup
NEX-1263 socket buffer sizes in NDMP are set to very low value
Reviewed by: sarah.jelinek@nexenta.com
Reviewed by: marcel.telka@nexenta.com
Reviewed by: albert.lee@nexenta.com
Reviewed by: hans.rosenfeld@nexenta.com
NEX-727 Netbackup Catalog verification hangs waiting for NDMP server
NEX-559 NDMP cannot backup/restore a file which spans multiple tapes

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c
          +++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c
↓ open down ↓ 29 lines elided ↑ open up ↑
  30   30   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31   31   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32   32   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33   33   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34   34   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35   35   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36   36   * POSSIBILITY OF SUCH DAMAGE.
  37   37   */
  38   38  /* Copyright (c) 2007, The Storage Networking Industry Association. */
  39   39  /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
  40      -/* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
       40 +/* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
  41   41  
  42   42  #include <sys/types.h>
       43 +#include <syslog.h>
  43   44  #include <assert.h>
  44   45  #include <ctype.h>
  45   46  #include <errno.h>
  46   47  #include <stdio.h>
  47   48  #include <stdlib.h>
  48   49  #include <unistd.h>
  49   50  #include <strings.h>
  50   51  #include <time.h>
  51   52  #include "ndmpd.h"
  52   53  #include <bitmap.h>
↓ open down ↓ 93 lines elided ↑ open up ↑
 146  147  /*
 147  148   * List of things to be exluded from backup.
 148  149   */
 149  150  static char *exls[] = {
 150  151          EXCL_PROC,
 151  152          EXCL_TMP,
 152  153          NULL, /* reserved for a copy of the "backup.directory" */
 153  154          NULL
 154  155  };
 155  156  
 156      -
 157  157  /*
 158      - * The counter for creating unique names with "ndmp.%d" format.
      158 + * The counter for creating unique names with "NDMP_RCF_BASENAME.%d" format.
 159  159   */
 160      -#define NDMP_RCF_BASENAME       "ndmp."
 161  160  static int ndmp_job_cnt = 0;
 162  161  
 163  162  static int scsi_test_unit_ready(int dev_id);
      163 +static int ndmpd_mkdir(const char *);
 164  164  
 165  165  /*
 166  166   * ndmpd_add_file_handler
 167  167   *
 168  168   * Adds a file handler to the file handler list.
 169  169   * The file handler list is used by ndmpd_api_dispatch.
 170  170   *
 171  171   * Parameters:
 172  172   *   session (input) - session pointer.
 173  173   *   cookie  (input) - opaque data to be passed to file hander when called.
↓ open down ↓ 127 lines elided ↑ open up ↑
 301  301          moverfd = session->ns_mover.md_sock;
 302  302          /* If connection is closed by the peer */
 303  303          if (moverfd >= 0 &&
 304  304              session->ns_mover.md_mode == NDMP_MOVER_MODE_WRITE) {
 305  305                  int closed, reason;
 306  306  
 307  307                  closed = ndmp_connection_closed(moverfd);
 308  308                  if (closed) {
 309  309                          /* Connection closed or internal error */
 310  310                          if (closed > 0) {
 311      -                                NDMP_LOG(LOG_DEBUG,
      311 +                                syslog(LOG_DEBUG,
 312  312                                      "ndmp mover: connection closed by peer");
 313  313                                  reason = NDMP_MOVER_HALT_CONNECT_CLOSED;
 314  314                          } else {
 315      -                                NDMP_LOG(LOG_DEBUG,
      315 +                                syslog(LOG_DEBUG,
 316  316                                      "ndmp mover: Internal error");
 317  317                                  reason = NDMP_MOVER_HALT_INTERNAL_ERROR;
 318  318                          }
 319  319                          ndmpd_mover_error(session, reason);
 320  320  
 321  321                  }
 322  322          }
 323  323  }
 324  324  
 325  325  
↓ open down ↓ 70 lines elided ↑ open up ↑
 396  396                  ndmp_check_mover_state(session);
 397  397                  n = select(FD_SETSIZE, &rfds, &wfds, &efds, &timeout);
 398  398          } while (n == 0 && block == TRUE);
 399  399  
 400  400          if (n < 0) {
 401  401                  int connection_fd = ndmp_get_fd(session->ns_connection);
 402  402  
 403  403                  if (errno == EINTR)
 404  404                          return (0);
 405  405  
 406      -                NDMP_LOG(LOG_DEBUG, "Select error: %m");
 407      -
 408  406                  nlp = ndmp_get_nlp(session);
 409  407                  (void) mutex_lock(&nlp->nlp_mtx);
 410  408                  for (handler = session->ns_file_handler_list; handler != 0;
 411  409                      handler = handler->fh_next) {
 412  410                          if ((handler->fh_class & class_mask) == 0)
 413  411                                  continue;
 414  412  
 415  413                          if (handler->fh_mode & NDMPD_SELECT_MODE_READ) {
 416  414                                  if (FD_ISSET(handler->fh_fd, &rfds) &&
 417  415                                      connection_fd == handler->fh_fd)
↓ open down ↓ 97 lines elided ↑ open up ↑
 515  513                  namebuf = strdup(env[i].name);
 516  514                  if (namebuf == 0)
 517  515                          return (NDMP_NO_MEM_ERR);
 518  516  
 519  517                  valbuf = strdup(env[i].value);
 520  518                  if (valbuf == 0) {
 521  519                          free(namebuf);
 522  520                          return (NDMP_NO_MEM_ERR);
 523  521                  }
 524  522  
 525      -                NDMP_LOG(LOG_DEBUG, "env(%s): \"%s\"",
      523 +                syslog(LOG_DEBUG, "env(%s): \"%s\"",
 526  524                      namebuf, valbuf);
 527  525  
 528  526                  (void) mutex_lock(&session->ns_lock);
 529  527                  session->ns_data.dd_env[i].name = namebuf;
 530  528                  session->ns_data.dd_env[i].value = valbuf;
 531  529                  session->ns_data.dd_env_len++;
 532  530                  (void) mutex_unlock(&session->ns_lock);
 533  531          }
 534  532  
 535  533          return (NDMP_NO_ERR);
↓ open down ↓ 51 lines elided ↑ open up ↑
 587  585      ulong_t nlistlen)
 588  586  {
 589  587          ulong_t i;
 590  588          char *namebuf;
 591  589          char *destbuf;
 592  590  
 593  591          if (nlistlen == 0)
 594  592                  return (NDMP_NO_ERR);
 595  593  
 596  594          session->ns_data.dd_nlist_len = 0;
 597      -        session->ns_data.dd_nlist = ndmp_malloc(sizeof (ndmp_name)*nlistlen);
      595 +        session->ns_data.dd_nlist =
      596 +            ndmp_malloc(sizeof (ndmp_name)*(nlistlen + 1));
 598  597          if (session->ns_data.dd_nlist == 0)
 599  598                  return (NDMP_NO_MEM_ERR);
 600  599  
 601  600          for (i = 0; i < nlistlen; i++) {
 602  601                  namebuf = ndmp_malloc(strlen(nlist[i].name) + 1);
 603  602                  if (namebuf == 0)
 604  603                          return (NDMP_NO_MEM_ERR);
 605  604  
 606  605                  destbuf = ndmp_malloc(strlen(nlist[i].dest) + 1);
 607  606                  if (destbuf == 0) {
↓ open down ↓ 131 lines elided ↑ open up ↑
 739  738                  else if (!(tp->nm3_newnm = strdup(sp->new_name))) {
 740  739                          rv = NDMP_NO_MEM_ERR;
 741  740                          break;
 742  741                  }
 743  742  
 744  743                  tp->nm3_node = quad_to_long_long(sp->node);
 745  744                  tp->nm3_fh_info = quad_to_long_long(sp->fh_info);
 746  745                  tp->nm3_err = NDMP_NO_ERR;
 747  746                  session->ns_data.dd_nlist_len++;
 748  747  
 749      -                NDMP_LOG(LOG_DEBUG, "orig \"%s\"", tp->nm3_opath);
 750      -                NDMP_LOG(LOG_DEBUG, "dest \"%s\"", NDMP_SVAL(tp->nm3_dpath));
 751      -                NDMP_LOG(LOG_DEBUG, "name \"%s\"", NDMP_SVAL(tp->nm3_newnm));
 752      -                NDMP_LOG(LOG_DEBUG, "node %lld", tp->nm3_node);
 753      -                NDMP_LOG(LOG_DEBUG, "fh_info %lld", tp->nm3_fh_info);
 754  748          }
 755  749  
 756  750          if (rv != NDMP_NO_ERR)
 757  751                  ndmpd_free_nlist_v3(session);
 758  752  
 759  753          return (rv);
 760  754  }
 761  755  
 762  756  
 763  757  /*
↓ open down ↓ 14 lines elided ↑ open up ↑
 778  772          case 1:
 779  773          case 2:
 780  774                  ndmpd_free_nlist_v2(session);
 781  775                  break;
 782  776          case 3:
 783  777          case 4:
 784  778                  ndmpd_free_nlist_v3(session);
 785  779                  break;
 786  780  
 787  781          default:
 788      -                NDMP_LOG(LOG_DEBUG, "Unknown version %d",
      782 +                syslog(LOG_DEBUG, "Unknown version %d",
 789  783                      session->ns_protocol_version);
 790  784          }
 791  785  }
 792  786  
 793  787  
 794  788  /*
 795  789   * fh_cmpv3
 796  790   *
 797  791   * Comparison function used in sorting the Nlist based on their
 798  792   * file history info (offset of the entry on the tape)
↓ open down ↓ 57 lines elided ↑ open up ↑
 856  850   *   Parameters:
 857  851   *     connection (input) - connection pointer.
 858  852   *
 859  853   *   Return:
 860  854   *     void
 861  855   */
 862  856  void
 863  857  ndmp_send_reply(ndmp_connection_t *connection, void *reply, char *msg)
 864  858  {
 865  859          if (ndmp_send_response(connection, NDMP_NO_ERR, reply) < 0)
 866      -                NDMP_LOG(LOG_DEBUG, "%s", msg);
      860 +                syslog(LOG_DEBUG, "%s", msg);
 867  861  }
 868  862  
 869  863  
 870  864  /*
 871  865   * ndmp_mtioctl
 872  866   *
 873  867   * Performs numerous filemark operations.
 874  868   *
 875  869   * Parameters:
 876  870   *      fd - file descriptor of the device
↓ open down ↓ 1 lines elided ↑ open up ↑
 878  872   *      count - the number of operations to be performed
 879  873   */
 880  874  int
 881  875  ndmp_mtioctl(int fd, int cmd, int count)
 882  876  {
 883  877          struct mtop mp;
 884  878  
 885  879          mp.mt_op = cmd;
 886  880          mp.mt_count = count;
 887  881          if (ioctl(fd, MTIOCTOP, &mp) < 0) {
 888      -                NDMP_LOG(LOG_ERR, "Failed to send command to tape: %m.");
      882 +                syslog(LOG_ERR, "Failed to send command to tape: %m.");
 889  883                  return (-1);
 890  884          }
 891  885  
 892  886          return (0);
 893  887  }
 894  888  
 895  889  
 896  890  /*
 897  891   * quad_to_long_long
 898  892   *
↓ open down ↓ 28 lines elided ↑ open up ↑
 927  921  set_socket_options(int sock)
 928  922  {
 929  923          int val;
 930  924  
 931  925          /* set send buffer size */
 932  926          val = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CSS, "60"));
 933  927          if (val <= 0)
 934  928                  val = 60;
 935  929          val <<= 10; /* convert the value from kilobytes to bytes */
 936  930          if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, sizeof (val)) < 0)
 937      -                NDMP_LOG(LOG_ERR, "SO_SNDBUF failed: %m");
      931 +                syslog(LOG_ERR, "SO_SNDBUF failed: %m");
 938  932  
 939  933          /* set receive buffer size */
 940  934          val = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CRS, "60"));
 941  935          if (val <= 0)
 942  936                  val = 60;
 943  937          val <<= 10; /* convert the value from kilobytes to bytes */
 944  938          if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, sizeof (val)) < 0)
 945      -                NDMP_LOG(LOG_ERR, "SO_RCVBUF failed: %m");
      939 +                syslog(LOG_ERR, "SO_RCVBUF failed: %m");
 946  940  
 947  941          /* don't wait to group tcp data */
 948  942          val = 1;
 949  943          if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)) != 0)
 950      -                NDMP_LOG(LOG_ERR, "TCP_NODELAY failed: %m");
      944 +                syslog(LOG_ERR, "TCP_NODELAY failed: %m");
 951  945  
 952  946          /* tcp keep-alive */
 953  947          val = 1;
 954  948          if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof (val)) != 0)
 955      -                NDMP_LOG(LOG_ERR, "SO_KEEPALIVE failed: %m");
      949 +                syslog(LOG_ERR, "SO_KEEPALIVE failed: %m");
 956  950  }
 957  951  
 958  952  /*
 959  953   * ndmp_get_max_tok_seq
 960  954   *
 961  955   * Get the maximum permitted token sequence for token-based
 962  956   * backups.
 963  957   *
 964  958   * Parameters:
 965  959   *   void
↓ open down ↓ 26 lines elided ↑ open up ↑
 992  986          if (session == NULL)
 993  987                  return (0);
 994  988  
 995  989          if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
 996  990                  xfer_size = atoi(ndmpd_get_prop_default(NDMP_MOVER_RECSIZE,
 997  991                      "60"));
 998  992                  if (xfer_size > 0)
 999  993                          xfer_size *= KILOBYTE;
1000  994                  else
1001  995                          xfer_size = REMOTE_RECORD_SIZE;
1002      -                NDMP_LOG(LOG_DEBUG, "Remote operation: %d", xfer_size);
      996 +                syslog(LOG_DEBUG, "Remote operation: %d", xfer_size);
1003  997          } else {
1004      -                NDMP_LOG(LOG_DEBUG,
      998 +                syslog(LOG_DEBUG,
1005  999                      "Local operation: %lu", session->ns_mover.md_record_size);
1006 1000                  if ((xfer_size = session->ns_mover.md_record_size) == 0)
1007 1001                          xfer_size = MAX_RECORD_SIZE;
1008 1002          }
1009 1003  
1010      -        NDMP_LOG(LOG_DEBUG, "xfer_size: %d", xfer_size);
     1004 +        syslog(LOG_DEBUG, "xfer_size: %d", xfer_size);
1011 1005          return (xfer_size);
1012 1006  }
1013 1007  
1014 1008  
1015 1009  /*
1016 1010   * ndmp_lbr_init
1017 1011   *
1018 1012   * Initialize the LBR/NDMP backup parameters
1019 1013   *
1020 1014   * Parameters:
1021 1015   *   session (input) - session pointer.
1022 1016   *
1023 1017   * Returns:
1024 1018   *   0: on success
1025 1019   *  -1: otherwise
1026 1020   */
1027 1021  int
1028 1022  ndmp_lbr_init(ndmpd_session_t *session)
1029 1023  {
1030 1024          if (session->ns_ndmp_lbr_params != NULL) {
1031      -                NDMP_LOG(LOG_DEBUG, "ndmp_lbr_params already allocated.");
     1025 +                syslog(LOG_DEBUG, "ndmp_lbr_params already allocated.");
1032 1026                  return (0);
1033 1027          }
1034 1028  
1035 1029          session->ns_ndmp_lbr_params = ndmp_malloc(sizeof (ndmp_lbr_params_t));
1036 1030          if (session->ns_ndmp_lbr_params == NULL)
1037 1031                  return (-1);
1038 1032  
1039 1033          session->ns_ndmp_lbr_params->nlp_bkmap = -1;
1040 1034          session->ns_ndmp_lbr_params->nlp_session = session;
1041 1035          (void) cond_init(&session->ns_ndmp_lbr_params->nlp_cv, 0, NULL);
↓ open down ↓ 52 lines elided ↑ open up ↑
1094 1088  {
1095 1089          ndmp_lbr_params_t *nlp;
1096 1090          tlm_cmd_t *lcmd;
1097 1091  
1098 1092          if ((nlp = ndmp_get_nlp(session)) == NULL)
1099 1093                  return (-1);
1100 1094  
1101 1095          (void) mutex_lock(&nlp->nlp_mtx);
1102 1096          while (session->ns_mover.md_state == NDMP_MOVER_STATE_PAUSED) {
1103 1097                  if (session->ns_eof) {
1104      -                        NDMP_LOG(LOG_ERR, "EOF detected");
     1098 +                        syslog(LOG_ERR, "EOF detected");
1105 1099                          break;
1106 1100                  }
1107 1101                  if (session->ns_data.dd_abort) {
1108      -                        NDMP_LOG(LOG_DEBUG, "Received data abort");
     1102 +                        syslog(LOG_DEBUG, "Received data abort");
1109 1103                          break;
1110 1104                  }
1111 1105                  if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
1112 1106                          /* remote backup/restore error */
1113 1107                          if (session->ns_mover.md_sock == -1 &&
1114 1108                              session->ns_mover.md_listen_sock == -1) {
1115      -                                NDMP_LOG(LOG_ERR,
     1109 +                                syslog(LOG_ERR,
1116 1110                                      "Remote data connection terminated");
1117 1111                                  break;
1118 1112                          }
1119 1113                  } else {
1120 1114                          /* local backup/restore error */
1121 1115                          if ((lcmd = nlp->nlp_cmds.tcs_command) != NULL) {
1122 1116                                  if (lcmd->tc_reader == TLM_STOP ||
1123 1117                                      lcmd->tc_reader == TLM_ABORT ||
1124 1118                                      lcmd->tc_writer == TLM_STOP ||
1125 1119                                      lcmd->tc_writer == TLM_ABORT) {
1126      -                                        NDMP_LOG(LOG_ERR,
     1120 +                                        syslog(LOG_ERR,
1127 1121                                              "Local data connection terminated");
1128 1122                                          break;
1129 1123                                  }
1130 1124                          }
1131 1125                  }
1132 1126  
1133 1127                  (void) cond_wait(&nlp->nlp_cv, &nlp->nlp_mtx);
1134 1128          }
1135 1129          (void) mutex_unlock(&nlp->nlp_mtx);
1136 1130  
↓ open down ↓ 12 lines elided ↑ open up ↑
1149 1143   */
1150 1144  boolean_t
1151 1145  is_buffer_erroneous(tlm_buffer_t *buf)
1152 1146  {
1153 1147          boolean_t rv;
1154 1148  
1155 1149          rv = (buf == NULL || buf->tb_eot || buf->tb_eof ||
1156 1150              buf->tb_errno != 0);
1157 1151          if (rv) {
1158 1152                  if (buf == NULL) {
1159      -                        NDMP_LOG(LOG_DEBUG, "buf == NULL");
     1153 +                        syslog(LOG_DEBUG, "buf == NULL");
1160 1154                  } else {
1161      -                        NDMP_LOG(LOG_DEBUG, "eot: %u, eof: %u, errno: %d",
     1155 +                        syslog(LOG_DEBUG, "eot: %u, eof: %u, errno: %d",
1162 1156                              buf->tb_eot, buf->tb_eof, buf->tb_errno);
1163 1157                  }
1164 1158          }
1165 1159  
1166 1160          return (rv);
1167 1161  }
1168 1162  
1169 1163  /*
1170 1164   * ndmp_execute_cdb
1171 1165   *
↓ open down ↓ 31 lines elided ↑ open up ↑
1203 1197          (void) memset((void *)&reply, 0, sizeof (reply));
1204 1198          (void) memset((void *)rq_buf, 0, sizeof (rq_buf));
1205 1199  
1206 1200          if (request->flags == NDMP_SCSI_DATA_IN) {
1207 1201                  cmd.uscsi_flags = USCSI_READ | USCSI_RQENABLE;
1208 1202                  if ((cmd.uscsi_bufaddr =
1209 1203                      ndmp_malloc(request->datain_len)) == 0) {
1210 1204                          reply.error = NDMP_NO_MEM_ERR;
1211 1205                          if (ndmp_send_response(session->ns_connection,
1212 1206                              NDMP_NO_ERR, (void *)&reply) < 0)
1213      -                                NDMP_LOG(LOG_DEBUG, "error sending"
     1207 +                                syslog(LOG_DEBUG, "error sending"
1214 1208                                      " scsi_execute_cdb reply.");
1215 1209                          return;
1216 1210                  }
1217 1211  
1218 1212                  cmd.uscsi_buflen = request->datain_len;
1219 1213          } else if (request->flags == NDMP_SCSI_DATA_OUT) {
1220 1214                  cmd.uscsi_flags = USCSI_WRITE | USCSI_RQENABLE;
1221 1215                  cmd.uscsi_bufaddr = request->dataout.dataout_val;
1222 1216                  cmd.uscsi_buflen = request->dataout.dataout_len;
1223 1217          } else {
↓ open down ↓ 3 lines elided ↑ open up ↑
1227 1221          }
1228 1222          cmd.uscsi_rqlen = sizeof (rq_buf);
1229 1223          cmd.uscsi_rqbuf = rq_buf;
1230 1224  
1231 1225          cmd.uscsi_timeout = (request->timeout < 1000) ?
1232 1226              1 : (request->timeout / 1000);
1233 1227  
1234 1228          cmd.uscsi_cdb = (caddr_t)request->cdb.cdb_val;
1235 1229          cmd.uscsi_cdblen = request->cdb.cdb_len;
1236 1230  
1237      -        NDMP_LOG(LOG_DEBUG, "cmd: 0x%x, len: %d, flags: %d, datain_len: %d",
1238      -            request->cdb.cdb_val[0] & 0xff, request->cdb.cdb_len,
1239      -            request->flags, request->datain_len);
1240      -        NDMP_LOG(LOG_DEBUG, "dataout_len: %d, timeout: %d",
1241      -            request->dataout.dataout_len, request->timeout);
1242      -
1243 1231          if (request->cdb.cdb_len > 12) {
1244 1232                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1245 1233                  ndmp_send_reply(session->ns_connection, (void *) &reply,
1246 1234                      "sending execute_cdb reply");
1247 1235                  if (request->flags == NDMP_SCSI_DATA_IN)
1248 1236                          free(cmd.uscsi_bufaddr);
1249 1237                  return;
1250 1238          }
1251 1239  
1252 1240          reply.error = NDMP_NO_ERR;
↓ open down ↓ 3 lines elided ↑ open up ↑
1256 1244          } else {
1257 1245                  reply.error = NDMP_DEV_NOT_OPEN_ERR;
1258 1246                  ndmp_send_reply(session->ns_connection, (void *) &reply,
1259 1247                      "sending execute_cdb reply");
1260 1248                  if (request->flags == NDMP_SCSI_DATA_IN)
1261 1249                          free(cmd.uscsi_bufaddr);
1262 1250                  return;
1263 1251          }
1264 1252  
1265 1253          if (ioctl(fd, USCSICMD, &cmd) < 0) {
1266      -                if (errno != EIO && errno != 0)
1267      -                        NDMP_LOG(LOG_ERR,
     1254 +                if (errno != EIO && errno != 0) {
     1255 +                        syslog(LOG_ERR,
1268 1256                              "Failed to send command to device: %m");
1269      -                NDMP_LOG(LOG_DEBUG, "ioctl(USCSICMD) error: %m");
     1257 +                }
1270 1258                  if (cmd.uscsi_status == 0)
1271 1259                          reply.error = NDMP_IO_ERR;
1272 1260          }
1273 1261  
1274 1262          reply.status = cmd.uscsi_status;
1275 1263  
1276 1264          if (request->flags == NDMP_SCSI_DATA_IN) {
1277 1265                  reply.datain.datain_len = cmd.uscsi_buflen;
1278 1266                  reply.datain.datain_val = cmd.uscsi_bufaddr;
1279 1267          } else {
1280 1268                  reply.dataout_len = request->dataout.dataout_len;
1281 1269          }
1282 1270  
1283 1271          reply.ext_sense.ext_sense_len = cmd.uscsi_rqlen - cmd.uscsi_rqresid;
1284 1272          reply.ext_sense.ext_sense_val = rq_buf;
1285 1273  
1286 1274          if (ndmp_send_response(session->ns_connection, NDMP_NO_ERR,
1287 1275              (void *)&reply) < 0)
1288      -                NDMP_LOG(LOG_DEBUG, "Error sending scsi_execute_cdb reply.");
     1276 +                syslog(LOG_DEBUG, "Error sending scsi_execute_cdb reply.");
1289 1277  
1290 1278          if (request->flags == NDMP_SCSI_DATA_IN)
1291 1279                  free(cmd.uscsi_bufaddr);
1292 1280  }
1293 1281  
1294 1282  
1295 1283  /*
1296 1284   * ndmp_stop_local_reader
1297 1285   *
1298 1286   * Stops a mover reader thread (for local backup only)
↓ open down ↓ 3 lines elided ↑ open up ↑
1302 1290   *   cmds (input) - reader/writer command struct
1303 1291   *
1304 1292   * Returns:
1305 1293   *   void
1306 1294   */
1307 1295  void
1308 1296  ndmp_stop_local_reader(ndmpd_session_t *session, tlm_commands_t *cmds)
1309 1297  {
1310 1298          ndmp_lbr_params_t *nlp;
1311 1299  
1312      -        if (session != NULL && session->ns_data.dd_sock == -1) {
1313      -                /* 2-way restore */
     1300 +        if (session != NULL) {
1314 1301                  if (cmds != NULL && cmds->tcs_reader_count > 0) {
1315 1302                          if ((nlp = ndmp_get_nlp(session)) != NULL) {
1316 1303                                  (void) mutex_lock(&nlp->nlp_mtx);
1317 1304                                  cmds->tcs_command->tc_reader = TLM_STOP;
1318 1305                                  (void) cond_broadcast(&nlp->nlp_cv);
1319 1306                                  (void) mutex_unlock(&nlp->nlp_mtx);
1320 1307                          }
1321 1308                  }
1322 1309          }
1323 1310  }
↓ open down ↓ 10 lines elided ↑ open up ↑
1334 1321   *   void
1335 1322   */
1336 1323  void
1337 1324  ndmp_stop_remote_reader(ndmpd_session_t *session)
1338 1325  {
1339 1326          if (session != NULL) {
1340 1327                  if (session->ns_data.dd_sock >= 0) {
1341 1328                          /*
1342 1329                           * 3-way restore.
1343 1330                           */
1344      -                        NDMP_LOG(LOG_DEBUG,
     1331 +                        syslog(LOG_DEBUG,
1345 1332                              "data.sock: %d", session->ns_data.dd_sock);
1346 1333                          (void) close(session->ns_data.dd_sock);
1347 1334                          session->ns_data.dd_sock = -1;
1348 1335                  }
1349 1336          }
1350 1337  }
1351 1338  
1352 1339  
1353 1340  /*
1354 1341   * ndmp_wait_for_reader
1355 1342   *
1356 1343   * Wait for a reader until get done (busy wait)
1357 1344   */
1358 1345  void
1359 1346  ndmp_wait_for_reader(tlm_commands_t *cmds)
1360 1347  {
1361      -        if (cmds == NULL) {
1362      -                NDMP_LOG(LOG_DEBUG, "cmds == NULL");
1363      -        } else {
1364      -                NDMP_LOG(LOG_DEBUG,
1365      -                    "reader_count: %d", cmds->tcs_reader_count);
1366      -
     1348 +        if (cmds != NULL) {
1367 1349                  while (cmds->tcs_reader_count > 0)
1368 1350                          (void) sleep(1);
1369 1351          }
1370 1352  }
1371 1353  
1372 1354  
1373 1355  /*
1374 1356   * ndmp_open_list_find
1375 1357   *
1376 1358   * Find a specific device in the open list
↓ open down ↓ 6 lines elided ↑ open up ↑
1383 1365   * Returns:
1384 1366   *   pointer to the open list entry
1385 1367   */
1386 1368  struct open_list *
1387 1369  ndmp_open_list_find(char *dev, int sid, int lun)
1388 1370  {
1389 1371          struct ol_head *olhp;
1390 1372          struct open_list *olp;
1391 1373  
1392 1374          if (dev == NULL || *dev == '\0') {
1393      -                NDMP_LOG(LOG_DEBUG, "Invalid argument");
1394 1375                  return (NULL);
1395 1376          }
1396 1377  
1397 1378          (void) mutex_lock(&ol_mutex);
1398 1379          olhp = &ol_head;
1399 1380          for (olp = LIST_FIRST(olhp); olp != NULL; olp = LIST_NEXT(olp, ol_q))
1400 1381                  if (strcmp(olp->ol_devnm, dev) == 0 && olp->ol_sid == sid &&
1401 1382                      olp->ol_lun == lun) {
1402 1383                          (void) mutex_unlock(&ol_mutex);
1403 1384                          return (olp);
↓ open down ↓ 20 lines elided ↑ open up ↑
1424 1405   *   errno
1425 1406   */
1426 1407  int
1427 1408  ndmp_open_list_add(ndmp_connection_t *conn, char *dev, int sid, int lun, int fd)
1428 1409  {
1429 1410          int err;
1430 1411          struct ol_head *olhp;
1431 1412          struct open_list *olp;
1432 1413  
1433 1414          if (dev == NULL || *dev == '\0') {
1434      -                NDMP_LOG(LOG_DEBUG, "Invalid argument");
1435 1415                  return (EINVAL);
1436 1416          }
1437      -        NDMP_LOG(LOG_DEBUG,
1438      -            "conn: 0x%08x, dev: %s, sid: %d, lun: %d", conn, dev, sid, lun);
1439 1417  
1440 1418          err = 0;
1441 1419          olhp = &ol_head;
1442 1420  
1443 1421          if ((olp = ndmp_open_list_find(dev, sid, lun)) != NULL) {
1444      -                NDMP_LOG(LOG_DEBUG, "already in list");
1445 1422                  /*
1446 1423                   * The adapter handle can be opened many times by the clients.
1447 1424                   * Only when the target is set, we must check and reject the
1448 1425                   * open request if the device is already being used by another
1449 1426                   * session.
1450 1427                   */
1451 1428                  if (sid == -1)
1452 1429                          olp->ol_nref++;
1453 1430                  else
1454 1431                          err = EBUSY;
1455 1432          } else if ((olp = ndmp_malloc(sizeof (struct open_list))) == NULL) {
1456 1433                  err = ENOMEM;
1457 1434          } else if ((olp->ol_devnm = strdup(dev)) == NULL) {
1458      -                NDMP_LOG(LOG_ERR, "Out of memory.");
     1435 +                syslog(LOG_ERR, "Out of memory.");
1459 1436                  free(olp);
1460 1437                  err = ENOMEM;
1461 1438          } else {
1462 1439                  olp->cl_conn = conn;
1463 1440                  olp->ol_nref = 1;
1464 1441                  olp->ol_sid = sid;
1465 1442                  olp->ol_lun = lun;
1466 1443                  if (fd > 0)
1467 1444                          olp->ol_fd = fd;
1468 1445                  else
↓ open down ↓ 19 lines elided ↑ open up ↑
1488 1465   *
1489 1466   * Returns:
1490 1467   *   errno
1491 1468   */
1492 1469  int
1493 1470  ndmp_open_list_del(char *dev, int sid, int lun)
1494 1471  {
1495 1472          struct open_list *olp;
1496 1473  
1497 1474          if (dev == NULL || *dev == '\0') {
1498      -                NDMP_LOG(LOG_DEBUG, "Invalid argument");
     1475 +                syslog(LOG_DEBUG, "Invalid argument");
1499 1476                  return (EINVAL);
1500 1477          }
1501 1478          if ((olp = ndmp_open_list_find(dev, sid, lun)) == NULL) {
1502      -                NDMP_LOG(LOG_DEBUG, "%s not found", dev);
     1479 +                syslog(LOG_DEBUG, "%s not found", dev);
1503 1480                  return (ENOENT);
1504 1481          }
1505 1482  
1506 1483          (void) mutex_lock(&ol_mutex);
1507 1484          if (--olp->ol_nref <= 0) {
1508      -                NDMP_LOG(LOG_DEBUG,
1509      -                    "Removed dev: %s, sid: %d, lun: %d", dev, sid, lun);
1510 1485                  LIST_REMOVE(olp, ol_q);
1511 1486                  free(olp->ol_devnm);
1512 1487                  free(olp);
1513 1488          }
1514 1489          (void) mutex_unlock(&ol_mutex);
1515 1490  
1516 1491          return (0);
1517 1492  }
1518 1493  
1519 1494  
↓ open down ↓ 12 lines elided ↑ open up ↑
1532 1507  ndmp_open_list_release(ndmp_connection_t *conn)
1533 1508  {
1534 1509          struct ol_head *olhp = &ol_head;
1535 1510          struct open_list *olp;
1536 1511          struct open_list *next;
1537 1512  
1538 1513          (void) mutex_lock(&ol_mutex);
1539 1514          olp = LIST_FIRST(olhp);
1540 1515          while (olp != NULL) {
1541 1516                  next = LIST_NEXT(olp, ol_q);
1542      -                NDMP_LOG(LOG_DEBUG, "olp->conn 0x%08x", olp->cl_conn);
1543 1517                  if (olp->cl_conn == conn) {
1544      -                        NDMP_LOG(LOG_DEBUG,
1545      -                            "Removed dev: %s, sid: %d, lun: %d",
1546      -                            olp->ol_devnm, olp->ol_sid, olp->ol_lun);
1547 1518                          LIST_REMOVE(olp, ol_q);
1548 1519                          if (olp->ol_fd > 0)
1549 1520                                  (void) close(olp->ol_fd);
1550 1521                          free(olp->ol_devnm);
1551 1522                          free(olp);
1552 1523                  }
1553 1524                  olp = next;
1554 1525          }
1555 1526          (void) mutex_unlock(&ol_mutex);
1556 1527  }
↓ open down ↓ 11 lines elided ↑ open up ↑
1568 1539   *   void
1569 1540   */
1570 1541  void
1571 1542  ndmp_stop_buffer_worker(ndmpd_session_t *session)
1572 1543  {
1573 1544          ndmp_lbr_params_t *nlp;
1574 1545          tlm_commands_t *cmds;
1575 1546  
1576 1547          session->ns_tape.td_pos = 0;
1577 1548          if ((nlp = ndmp_get_nlp(session)) == NULL) {
1578      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
     1549 +                syslog(LOG_DEBUG, "nlp == NULL");
1579 1550          } else {
1580 1551                  cmds = &nlp->nlp_cmds;
1581      -                if (cmds->tcs_command == NULL) {
1582      -                        NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL");
1583      -                } else {
     1552 +                if (cmds->tcs_command != NULL) {
1584 1553                          cmds->tcs_reader = cmds->tcs_writer = TLM_ABORT;
1585 1554                          cmds->tcs_command->tc_reader = TLM_ABORT;
1586 1555                          cmds->tcs_command->tc_writer = TLM_ABORT;
1587 1556                          while (cmds->tcs_reader_count > 0 ||
1588 1557                              cmds->tcs_writer_count > 0) {
1589      -                                NDMP_LOG(LOG_DEBUG,
     1558 +                                syslog(LOG_DEBUG,
1590 1559                                      "trying to stop buffer worker");
1591 1560                                  (void) sleep(1);
1592 1561                          }
1593 1562                  }
1594 1563          }
1595 1564  }
1596 1565  
1597 1566  
1598 1567  /*
1599 1568   * ndmp_stop_reader_thread
↓ open down ↓ 6 lines elided ↑ open up ↑
1606 1575   * Returns:
1607 1576   *   void
1608 1577   */
1609 1578  void
1610 1579  ndmp_stop_reader_thread(ndmpd_session_t *session)
1611 1580  {
1612 1581          ndmp_lbr_params_t *nlp;
1613 1582          tlm_commands_t *cmds;
1614 1583  
1615 1584          if ((nlp = ndmp_get_nlp(session)) == NULL) {
1616      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
     1585 +                syslog(LOG_DEBUG, "nlp == NULL");
1617 1586          } else {
1618 1587                  cmds = &nlp->nlp_cmds;
1619      -                if (cmds->tcs_command == NULL) {
1620      -                        NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL");
1621      -                } else {
     1588 +                if (cmds->tcs_command != NULL) {
1622 1589                          cmds->tcs_reader = TLM_ABORT;
1623 1590                          cmds->tcs_command->tc_reader = TLM_ABORT;
1624 1591                          while (cmds->tcs_reader_count > 0) {
1625      -                                NDMP_LOG(LOG_DEBUG,
     1592 +                                syslog(LOG_DEBUG,
1626 1593                                      "trying to stop reader thread");
1627 1594                                  (void) sleep(1);
1628 1595                          }
1629 1596                  }
1630 1597          }
1631 1598  }
1632 1599  
1633 1600  
1634 1601  /*
1635 1602   * ndmp_stop_reader_thread
↓ open down ↓ 6 lines elided ↑ open up ↑
1642 1609   * Returns:
1643 1610   *   void
1644 1611   */
1645 1612  void
1646 1613  ndmp_stop_writer_thread(ndmpd_session_t *session)
1647 1614  {
1648 1615          ndmp_lbr_params_t *nlp;
1649 1616          tlm_commands_t *cmds;
1650 1617  
1651 1618          if ((nlp = ndmp_get_nlp(session)) == NULL) {
1652      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
     1619 +                syslog(LOG_DEBUG, "nlp == NULL");
1653 1620          } else {
1654 1621                  cmds = &nlp->nlp_cmds;
1655      -                if (cmds->tcs_command == NULL) {
1656      -                        NDMP_LOG(LOG_DEBUG, "cmds->tcs_command == NULL");
1657      -                } else {
     1622 +                if (cmds->tcs_command != NULL) {
1658 1623                          (void) mutex_lock(&nlp->nlp_mtx);
1659 1624                          cmds->tcs_writer = TLM_ABORT;
1660 1625                          cmds->tcs_command->tc_writer = TLM_ABORT;
1661 1626                          (void) cond_broadcast(&nlp->nlp_cv);
1662 1627                          (void) mutex_unlock(&nlp->nlp_mtx);
1663 1628                          while (cmds->tcs_writer_count > 0) {
1664      -                                NDMP_LOG(LOG_DEBUG,
     1629 +                                syslog(LOG_DEBUG,
1665 1630                                      "trying to stop writer thread");
1666 1631                                  (void) sleep(1);
1667 1632                          }
1668 1633                  }
1669 1634          }
1670 1635  }
1671 1636  
1672 1637  
1673 1638  /*
1674 1639   * ndmp_free_reader_writer_ipc
↓ open down ↓ 9 lines elided ↑ open up ↑
1684 1649   */
1685 1650  void
1686 1651  ndmp_free_reader_writer_ipc(ndmpd_session_t *session)
1687 1652  {
1688 1653          ndmp_lbr_params_t *nlp;
1689 1654          tlm_commands_t *cmds;
1690 1655  
1691 1656          if ((nlp = ndmp_get_nlp(session)) != NULL) {
1692 1657                  cmds = &nlp->nlp_cmds;
1693 1658                  if (cmds->tcs_command != NULL) {
1694      -                        NDMP_LOG(LOG_DEBUG, "cmds->tcs_command->tc_ref: %d",
     1659 +                        syslog(LOG_DEBUG, "cmds->tcs_command->tc_ref: %d",
1695 1660                              cmds->tcs_command->tc_ref);
1696 1661                          tlm_release_reader_writer_ipc(cmds->tcs_command);
1697 1662                  }
1698 1663          }
1699 1664  }
1700 1665  
1701 1666  
1702 1667  /*
1703 1668   * ndmp_waitfor_op
1704 1669   *
↓ open down ↓ 4 lines elided ↑ open up ↑
1709 1674   *
1710 1675   * Returns:
1711 1676   *   void
1712 1677   */
1713 1678  void
1714 1679  ndmp_waitfor_op(ndmpd_session_t *session)
1715 1680  {
1716 1681          if (session != NULL) {
1717 1682                  while (session->ns_nref > 0) {
1718 1683                          (void) sleep(1);
1719      -                        NDMP_LOG(LOG_DEBUG,
1720      -                            "waiting for session nref: %d", session->ns_nref);
1721 1684                  }
1722 1685          }
1723 1686  }
1724 1687  
1725 1688  
1726 1689  /*
1727 1690   * ndmp_session_ref
1728 1691   *
1729 1692   * Increment the reference count of the session
1730 1693   *
↓ open down ↓ 191 lines elided ↑ open up ↑
1922 1885   * Returns:
1923 1886   *   0: on success
1924 1887   *  -1: otherwise
1925 1888   */
1926 1889  int
1927 1890  ndmp_connect_sock_v3(ulong_t addr, ushort_t port)
1928 1891  {
1929 1892          int sock;
1930 1893          struct sockaddr_in sin;
1931 1894  
1932      -        NDMP_LOG(LOG_DEBUG, "addr %s:%d", inet_ntoa(IN_ADDR(addr)), port);
1933 1895  
1934 1896          sock = socket(AF_INET, SOCK_STREAM, 0);
1935 1897          if (sock < 0) {
1936      -                NDMP_LOG(LOG_DEBUG, "Socket error: %m");
     1898 +                syslog(LOG_DEBUG, "Socket error: %m");
1937 1899                  return (-1);
1938 1900          }
1939 1901  
1940 1902          (void) memset((void *) &sin, 0, sizeof (sin));
1941 1903          sin.sin_family = AF_INET;
1942 1904          sin.sin_addr.s_addr = htonl(addr);
1943 1905          sin.sin_port = htons(port);
1944 1906          if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
1945      -                NDMP_LOG(LOG_DEBUG, "Connect error: %m");
     1907 +                syslog(LOG_DEBUG, "Connect error: %m");
1946 1908                  (void) close(sock);
1947 1909                  return (-1);
1948 1910          }
1949 1911  
     1912 +        syslog(LOG_DEBUG, "Remote addr %s:%d", inet_ntoa(IN_ADDR(addr)), port);
     1913 +
1950 1914          set_socket_options(sock);
1951      -        NDMP_LOG(LOG_DEBUG, "sock %d", sock);
1952 1915  
1953 1916          return (sock);
1954 1917  }
1955 1918  
1956 1919  /*
1957 1920   * ndmp_create_socket
1958 1921   *
1959 1922   * Creates a socket for listening for accepting data connections.
1960 1923   *
1961 1924   * Parameters:
↓ open down ↓ 19 lines elided ↑ open up ↑
1981 1944          /* Try host's IP address */
1982 1945          if (!p || *p == 0)
1983 1946                  p = gethostaddr();
1984 1947  
1985 1948          /* Try default NIC's IP address (if DNS failed) */
1986 1949          if (!p)
1987 1950                  p = get_default_nic_addr();
1988 1951  
1989 1952          /* Fail if no IP can be obtained */
1990 1953          if (!p) {
1991      -                NDMP_LOG(LOG_ERR, "Undetermined network port.");
     1954 +                syslog(LOG_ERR, "Undetermined network port.");
1992 1955                  return (-1);
1993 1956          }
1994 1957  
1995 1958          *addr = inet_addr(p);
1996 1959  
1997 1960          sd = socket(AF_INET, SOCK_STREAM, 0);
1998 1961          if (sd < 0) {
1999      -                NDMP_LOG(LOG_DEBUG, "Socket error: %m");
     1962 +                syslog(LOG_DEBUG, "Socket error: %m");
2000 1963                  return (-1);
2001 1964          }
2002 1965          sin.sin_family = AF_INET;
2003 1966          sin.sin_addr.s_addr = INADDR_ANY;
2004 1967          sin.sin_port = 0;
2005 1968          length = sizeof (sin);
2006 1969  
2007 1970          if (bind(sd, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
2008      -                NDMP_LOG(LOG_DEBUG, "Bind error: %m");
     1971 +                syslog(LOG_DEBUG, "Bind error: %m");
2009 1972                  (void) close(sd);
2010 1973                  sd = -1;
2011 1974          } else if (getsockname(sd, (struct sockaddr *)&sin, &length) < 0) {
2012      -                NDMP_LOG(LOG_DEBUG, "getsockname error: %m");
     1975 +                syslog(LOG_DEBUG, "getsockname error: %m");
2013 1976                  (void) close(sd);
2014 1977                  sd = -1;
2015 1978          } else if (listen(sd, 5) < 0) {
2016      -                NDMP_LOG(LOG_DEBUG, "Listen error: %m");
     1979 +                syslog(LOG_DEBUG, "Listen error: %m");
2017 1980                  (void) close(sd);
2018 1981                  sd = -1;
2019 1982          } else
2020 1983                  *port = sin.sin_port;
2021 1984  
2022 1985          return (sd);
2023 1986  }
2024 1987  
2025 1988  
2026 1989  /*
↓ open down ↓ 28 lines elided ↑ open up ↑
2055 2018          if (cp)
2056 2019                  *cp = '\0';
2057 2020  
2058 2021          return (bp);
2059 2022  }
2060 2023  
2061 2024  
2062 2025  /*
2063 2026   * ndmp_new_job_name
2064 2027   *
2065      - * Create a job name for each backup/restore to keep track
     2028 + * Copy, at most, 'n' characters of the current backup
     2029 + * job name to the buffer in parameter 's1'.
2066 2030   *
2067 2031   * Parameters:
2068      - *   jname (output) - job name
2069 2032   *
     2033 + *   s1 (input) - pointer to a user supplied buffer
     2034 + *   n  (input) - number of bytes to copy
     2035 + *
2070 2036   * Returns:
2071      - *   jname
     2037 + *   count of bytes in name
2072 2038   */
2073      -char *
2074      -ndmp_new_job_name(char *jname)
2075      -{
2076      -        if (jname != NULL) {
2077      -                (void) snprintf(jname, TLM_MAX_BACKUP_JOB_NAME, "%s%d",
2078      -                    NDMP_RCF_BASENAME, ndmp_job_cnt++);
2079      -                NDMP_LOG(LOG_DEBUG, "jname: \"%s\"", jname);
2080      -        }
2081 2039  
2082      -        return (jname);
     2040 +int
     2041 +ndmp_new_job_name(char *s1, size_t n) {
     2042 +
     2043 +        if (n >= TLM_MAX_BACKUP_JOB_NAME) {
     2044 +                /*
     2045 +                 * TLM_MAX_BACKUP_JOB_NAME is the fixed length of
     2046 +                 * the encoded job name in the format `NdmpBackup.nnnn\0`,
     2047 +                 * where nnnn is a job sequence number.  A null byte
     2048 +                 * is included. It is okay if the buffer is bigger than that.
     2049 +                 */
     2050 +                return (snprintf(s1, n, "%10s.%04d",
     2051 +                    NDMP_RCF_BASENAME, ndmp_job_cnt++%1000));
     2052 +        }
     2053 +        return (0);
2083 2054  }
2084 2055  
     2056 +/*
     2057 + * Check if the volume is already checkpointed. Assume it is not
     2058 + * by setting nlp_snapname to '\0' at first. It will be filled
     2059 + * in  with the checkpoint (snapshot name) if one is found.
     2060 + */
     2061 +boolean_t
     2062 +fs_is_checkpointed(ndmp_lbr_params_t *nlp)
     2063 +{
     2064 +        zfs_handle_t *zhp;
     2065 +        snap_data_t si;
2085 2066  
     2067 +        (void) mutex_lock(&zlib_mtx);
     2068 +        if ((zhp = zfs_open(zlibh, nlp->nlp_vol, ZFS_TYPE_DATASET)) != NULL) {
     2069 +                nlp->nlp_snapname[0] = '\0';
     2070 +                si.creation_time = (time_t)0;
     2071 +                si.last_snapshot = nlp->nlp_snapname;
     2072 +                if (ndmp_find_latest_autosync(zhp, (void *) &si) != 0) {
     2073 +                        syslog(LOG_ERR,
     2074 +                            "Find AutoSync failed (err=%d): %s",
     2075 +                            errno, libzfs_error_description(zlibh));
     2076 +                        zfs_close(zhp);
     2077 +                        (void) mutex_unlock(&zlib_mtx);
     2078 +                        return (B_FALSE);
     2079 +                }
     2080 +                zfs_close(zhp);
     2081 +                if (strlen(nlp->nlp_snapname) == 0) {
     2082 +                        syslog(LOG_DEBUG, "Apparently not an "
     2083 +                            "Auto-Sync - continue as normal backup");
     2084 +                        (void) mutex_unlock(&zlib_mtx);
     2085 +                        return (B_FALSE);
     2086 +                }
     2087 +        }
     2088 +        (void) mutex_unlock(&zlib_mtx);
     2089 +        syslog(LOG_DEBUG, "It is an autosync:");
     2090 +        syslog(LOG_DEBUG, "nlp->nlp_vol = [%s]", nlp->nlp_vol);
     2091 +        syslog(LOG_DEBUG, "nlp->nlp_snapname = [%s]", nlp->nlp_snapname);
     2092 +        return (B_TRUE);
     2093 +}
     2094 +
2086 2095  /*
2087 2096   * fs_is_valid_logvol
2088 2097   *
2089 2098   * Check if the log path exists
2090 2099   *
2091 2100   * Parameters:
2092 2101   *   path (input) - log path
2093 2102   *
2094 2103   * Returns:
2095 2104   *   FALSE: invalid
2096 2105   *   TRUE: valid
2097 2106   */
2098 2107  boolean_t
2099 2108  fs_is_valid_logvol(char *path)
2100 2109  {
2101 2110          struct stat64 st;
2102 2111  
2103 2112          if (stat64(path, &st) < 0)
2104      -                return (FALSE);
     2113 +                return (B_FALSE);
2105 2114  
2106      -        return (TRUE);
     2115 +        return (B_TRUE);
2107 2116  }
2108 2117  
2109 2118  
2110 2119  /*
2111 2120   * ndmpd_mk_temp
2112 2121   *
2113 2122   * Make a temporary file using the working directory path and the
2114 2123   * jobname
2115 2124   *
2116 2125   * Parameters:
2117 2126   *   buf (output) - the temporary file name path
2118 2127   *
2119 2128   * Returns:
2120 2129   *   buf
2121 2130   */
2122 2131  char *
2123      -ndmpd_mk_temp(char *buf)
     2132 +ndmpd_mk_temp(char * fname, char *buf)
2124 2133  {
2125      -        char fname[TLM_MAX_BACKUP_JOB_NAME];
2126 2134          const char *dir;
2127 2135          char *rv;
2128 2136  
2129 2137          if (!buf)
2130 2138                  return (NULL);
2131 2139  
2132 2140          dir = ndmpd_get_prop(NDMP_DEBUG_PATH);
2133 2141          if (dir == 0 || *dir == '\0') {
2134      -                NDMP_LOG(LOG_DEBUG, "NDMP work path not specified");
     2142 +                syslog(LOG_DEBUG, "NDMP work path not specified");
2135 2143                  return (0);
2136 2144          }
2137 2145  
     2146 +        /*
     2147 +         * Make sure the NDMP work directory exists.
     2148 +         */
     2149 +        if (ndmpd_mkdir(dir) < 0) {
     2150 +                syslog(LOG_DEBUG,
     2151 +                    "Could not create NDMP work path %s", dir);
     2152 +                return (0);
     2153 +        }
     2154 +
2138 2155          if (!fs_is_valid_logvol((char *)dir)) {
2139      -                NDMP_LOG(LOG_ERR,
2140      -                    "Log file path cannot be on system volumes.");
     2156 +                syslog(LOG_ERR,
     2157 +                    "Log file path cannot be on system volumes");
2141 2158                  return (0);
2142 2159          }
2143 2160  
2144 2161          dir += strspn(dir, " \t");
2145 2162          if (!*dir) {
2146      -                NDMP_LOG(LOG_DEBUG, "NDMP work path not specified");
     2163 +                syslog(LOG_DEBUG, "NDMP work path not specified");
2147 2164                  return (0);
2148 2165          }
2149 2166  
2150 2167          rv = buf;
2151      -        (void) ndmp_new_job_name(fname);
     2168 +
2152 2169          (void) tlm_cat_path(buf, (char *)dir, fname);
2153 2170  
2154 2171          return (rv);
2155 2172  }
2156 2173  
     2174 +/*
     2175 + * ndmp_mkdir
     2176 + *
     2177 + * If the temporary bitmap database directory doesn't exist
     2178 + * create it.  This keep from having to create directory
     2179 + * by hand when it is changed with svcadm.
     2180 + *
     2181 + * Parameters:
     2182 + *   dir (input) - the path to create
     2183 + *
     2184 + * Returns:
     2185 + *   0 - success.
     2186 + *  -1 - error.
     2187 + */
     2188 +static int
     2189 +ndmpd_mkdir(const char *dir)
     2190 +{
     2191 +        char tmp[PATH_MAX];
     2192 +        char *p = NULL;
     2193 +        size_t len;
2157 2194  
     2195 +        (void) snprintf(tmp, sizeof (tmp), "%s", dir);
     2196 +        len = strlen(tmp);
     2197 +        if (tmp[len - 1] == '/')
     2198 +                tmp[len - 1] = '\0';
     2199 +        for (p = tmp + 1; *p; p++) {
     2200 +                if (*p == '/') {
     2201 +                        *p = '\0';
     2202 +                        if (mkdir(tmp, S_IRWXU) < 0) {
     2203 +                                if (errno != EEXIST) {
     2204 +                                syslog(LOG_ERR,
     2205 +                                    "failed to create intermediate path %s\n",
     2206 +                                    tmp);
     2207 +                                return (-1);
     2208 +                                }
     2209 +                        }
     2210 +                        *p = '/';
     2211 +                }
     2212 +        }
     2213 +        if (mkdir(tmp, S_IRWXU) < 0) {
     2214 +                if (errno != EEXIST) {
     2215 +                syslog(LOG_ERR,
     2216 +                    "failed to create full path %s\n", tmp);
     2217 +                return (-1);
     2218 +                }
     2219 +        }
     2220 +        return (0);
     2221 +}
     2222 +
2158 2223  /*
2159 2224   * ndmpd_make_bk_dir_path
2160 2225   *
2161 2226   * Make a directory path for temporary files under the NDMP
2162 2227   * working directory.
2163 2228   *
2164 2229   * Parameters:
2165 2230   *   buf (output) - result path
2166 2231   *   fname (input) - the file name
2167 2232   *
↓ open down ↓ 18 lines elided ↑ open up ↑
2186 2251          (void) strlcpy(path, (char *)p, PATH_MAX);
2187 2252          (void) trim_whitespace(path);
2188 2253  
2189 2254          if ((name = strrchr(fname, '/')) == 0)
2190 2255                  name = fname;
2191 2256  
2192 2257          (void) tlm_cat_path(buf, path, name);
2193 2258          return (buf);
2194 2259  }
2195 2260  
     2261 +static int
     2262 +ndmp_match_checkpoint_name(zfs_handle_t *zhp, void *arg)
     2263 +{
     2264 +        snap_data_t *sd = (snap_data_t *)arg;
     2265 +        time_t snap_creation;
     2266 +        nvlist_t *userprops = NULL;
2196 2267  
     2268 +        if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
     2269 +                if ((userprops = zfs_get_user_props(zhp)) != NULL) {
     2270 +                        /*
     2271 +                         * Destination AutoSync snap-shots have
     2272 +                         * 'nms:autosyncmark' property whereas the
     2273 +                         * source dataset snap-shot has has
     2274 +                         * 'nms:service' property. This finds either
     2275 +                         * for use as backup.
     2276 +                         */
     2277 +                        if (nvlist_exists(userprops, "nms:autosyncmark") ||
     2278 +                            nvlist_exists(userprops,
     2279 +                                "com.nexenta.nef:hprsvcid") ||
     2280 +                            nvlist_exists(userprops, "nms:service")) {
     2281 +                                snap_creation = (time_t)zfs_prop_get_int(zhp,
     2282 +                                    ZFS_PROP_CREATION);
     2283 +                                if (snap_creation > sd->creation_time) {
     2284 +                                        (void) strncpy(
     2285 +                                            (char *) sd->last_snapshot,
     2286 +                                            zfs_get_name(zhp),
     2287 +                                            ZFS_MAX_DATASET_NAME_LEN);
     2288 +                                        sd->creation_time = snap_creation;
     2289 +                                }
     2290 +                        }
     2291 +                }
     2292 +        }
     2293 +        zfs_close(zhp);
     2294 +        return (0);
     2295 +}
     2296 +
2197 2297  /*
     2298 + * ndmp_find_latest_autosync
     2299 + *
     2300 + * Given a dataset zfs_handlt_t find the latest "AutoSync" snapshot
     2301 + */
     2302 +int
     2303 +ndmp_find_latest_autosync(zfs_handle_t *zhp, void *arg)
     2304 +{
     2305 +        int err;
     2306 +        snap_data_t *si = (snap_data_t *)arg;
     2307 +
     2308 +        err = zfs_iter_dependents(zhp, B_FALSE,
     2309 +            ndmp_match_checkpoint_name, (void *)si);
     2310 +        if (err) {
     2311 +                syslog(LOG_DEBUG,
     2312 +                    "Trying to find AutoSync zfs_iter_snapshots: %d", err);
     2313 +                si->last_snapshot = '\0';
     2314 +                return (-1);
     2315 +        } else {
     2316 +                syslog(LOG_DEBUG, "Found most recent AutoSync -> [%s]\n",
     2317 +                    si->last_snapshot);
     2318 +        }
     2319 +        return (0);
     2320 +}
     2321 +
     2322 +/*
2198 2323   * ndmp_is_chkpnt_root
2199 2324   *
2200 2325   * Is this a root checkpoint (snapshot) directory.
2201 2326   * Note: a temporary function
2202 2327   */
2203 2328  boolean_t
2204 2329  ndmp_is_chkpnt_root(char *path)
2205 2330  {
2206 2331          struct stat64 st;
2207 2332  
2208 2333          if (stat64(path, &st) != 0) {
2209      -                NDMP_LOG(LOG_DEBUG, "Couldn't stat path \"%s\"", path);
     2334 +                syslog(LOG_DEBUG, "Couldn't stat path \"%s\"", path);
2210 2335                  return (TRUE);
2211 2336          }
2212 2337          return (FALSE);
2213 2338  }
2214 2339  
2215 2340  
2216 2341  /*
2217 2342   * ndmpd_make_exc_list
2218 2343   *
2219 2344   * Make a list of files that should not be backed up.
↓ open down ↓ 33 lines elided ↑ open up ↑
2253 2378   * Get the inode number of the backup directory
2254 2379   */
2255 2380  int
2256 2381  ndmp_get_bk_dir_ino(ndmp_lbr_params_t *nlp)
2257 2382  {
2258 2383          int rv;
2259 2384          struct stat64 st;
2260 2385  
2261 2386          if (stat64(nlp->nlp_backup_path, &st) != 0) {
2262 2387                  rv = -1;
2263      -                NDMP_LOG(LOG_DEBUG, "Getting inode # of \"%s\"",
     2388 +                syslog(LOG_ERR, "Failed to get inode # of \"%s\"",
2264 2389                      nlp->nlp_backup_path);
2265 2390          } else {
2266 2391                  rv = 0;
2267 2392                  nlp->nlp_bkdirino = st.st_ino;
2268      -                NDMP_LOG(LOG_DEBUG, "nlp_bkdirino: %lu",
2269      -                    (uint_t)nlp->nlp_bkdirino);
2270 2393          }
2271 2394  
2272 2395          return (rv);
2273 2396  }
2274 2397  
2275 2398  
2276 2399  /*
2277 2400   * ndmp_check_utf8magic
2278 2401   *
2279 2402   * Check if the magic string for exists in the tar header. This
↓ open down ↓ 2 lines elided ↑ open up ↑
2282 2405   * This checking is always done before all restores except DAR
2283 2406   * restores.
2284 2407   */
2285 2408  boolean_t
2286 2409  ndmp_check_utf8magic(tlm_cmd_t *cmd)
2287 2410  {
2288 2411          char *cp;
2289 2412          int err, len, actual_size;
2290 2413  
2291 2414          if (cmd == NULL) {
2292      -                NDMP_LOG(LOG_DEBUG, "cmd == NULL");
     2415 +                syslog(LOG_DEBUG, "cmd == NULL");
2293 2416                  return (FALSE);
2294 2417          }
2295 2418          if (cmd->tc_buffers == NULL) {
2296      -                NDMP_LOG(LOG_DEBUG, "cmd->tc_buffers == NULL");
     2419 +                syslog(LOG_DEBUG, "cmd->tc_buffers == NULL");
2297 2420                  return (FALSE);
2298 2421          }
2299 2422  
2300 2423          /* wait until the first buffer gets full. */
2301 2424          tlm_buffer_in_buf_wait(cmd->tc_buffers);
2302 2425  
2303 2426          err = actual_size = 0;
2304 2427          cp = tlm_get_read_buffer(RECORDSIZE, &err, cmd->tc_buffers,
2305 2428              &actual_size);
2306 2429          if (cp == NULL) {
2307      -                NDMP_LOG(LOG_DEBUG, "Can't read from buffers, err: %d", err);
     2430 +                syslog(LOG_DEBUG, "Can't read from buffers, err: %d", err);
2308 2431                  return (FALSE);
2309 2432          }
2310 2433          len = strlen(NDMPUTF8MAGIC);
2311 2434          if (actual_size < len) {
2312      -                NDMP_LOG(LOG_DEBUG, "Not enough data in the buffers");
     2435 +                syslog(LOG_DEBUG, "Not enough data in the buffers");
2313 2436                  return (FALSE);
2314 2437          }
2315 2438  
2316 2439          return ((strncmp(cp, NDMPUTF8MAGIC, len) == 0) ? TRUE : FALSE);
2317 2440  }
2318 2441  
2319 2442  
2320 2443  /*
2321 2444   * ndmp_get_cur_bk_time
2322 2445   *
2323 2446   * Get the backup checkpoint time.
2324 2447   */
2325 2448  int
2326      -ndmp_get_cur_bk_time(ndmp_lbr_params_t *nlp, time_t *tp, char *jname)
     2449 +ndmp_get_cur_bk_time(ndmp_lbr_params_t *nlp, time_t *tp)
2327 2450  {
2328 2451          int err;
2329 2452  
2330      -        if (!nlp || !nlp->nlp_backup_path || !tp) {
2331      -                NDMP_LOG(LOG_DEBUG, "Invalid argument");
     2453 +        if (!nlp || !tp) {
     2454 +                syslog(LOG_ERR, "Invalid argument");
2332 2455                  return (-1);
2333 2456          }
2334 2457  
2335      -        if (!fs_is_chkpnt_enabled(nlp->nlp_backup_path)) {
2336      -                NDMP_LOG(LOG_DEBUG, "Not a chkpnt volume %s",
2337      -                    nlp->nlp_backup_path);
2338      -                *tp = time(NULL);
2339      -                return (0);
2340      -        }
2341      -
2342      -        err = tlm_get_chkpnt_time(nlp->nlp_backup_path, !NLP_ISCHKPNTED(nlp),
2343      -            tp, jname);
     2458 +        err = tlm_get_chkpnt_time(nlp->nlp_snapname, tp);
2344 2459          if (err != 0) {
2345      -                NDMP_LOG(LOG_DEBUG, "Can't checkpoint time");
     2460 +                syslog(LOG_ERR, "Can't checkpoint time from [%s]",
     2461 +                    nlp->nlp_snapname);
2346 2462          } else {
2347      -                NDMP_LOG(LOG_DEBUG, "%s", cctime(tp));
     2463 +                syslog(LOG_DEBUG, "Checkpoint time of [%s] is [%s]",
     2464 +                    nlp->nlp_snapname, cctime(tp));
2348 2465          }
2349 2466  
2350 2467          return (err);
2351 2468  }
2352 2469  
2353 2470  
2354 2471  /*
2355 2472   * get_relative_path
2356 2473   */
2357 2474  char *
↓ open down ↓ 51 lines elided ↑ open up ↑
2409 2526  
2410 2527          try = TUR_MAX_TRY;
2411 2528          if (dev_id <= 0) {
2412 2529                  if ((fd = open(adptnm, O_RDONLY | O_NDELAY)) < 0)
2413 2530                          return (FALSE);
2414 2531          } else {
2415 2532                  fd = dev_id;
2416 2533          }
2417 2534          do {
2418 2535                  if (scsi_test_unit_ready(fd) >= 0) {
2419      -                        NDMP_LOG(LOG_DEBUG, "Unit is ready");
     2536 +                        syslog(LOG_DEBUG, "Unit is ready");
2420 2537  
2421 2538                          if (dev_id <= 0)
2422 2539                                  (void) close(fd);
2423 2540  
2424 2541                          return (TRUE);
2425 2542                  }
2426 2543  
2427      -                NDMP_LOG(LOG_DEBUG, "Unit not ready");
     2544 +                syslog(LOG_DEBUG, "Unit not ready");
2428 2545                  (void) usleep(TUR_WAIT);
2429 2546  
2430 2547          } while (--try > 0);
2431 2548  
2432 2549          if (dev_id <= 0)
2433 2550                  (void) close(fd);
2434 2551  
2435      -        NDMP_LOG(LOG_DEBUG, "Unit didn't get ready");
     2552 +        syslog(LOG_DEBUG, "Unit didn't get ready");
2436 2553          return (FALSE);
2437 2554  }
2438 2555  
2439 2556  
2440 2557  /*
2441 2558   * scsi_test_unit_ready
2442 2559   *
2443 2560   * This is for Test Unit Read, without this function, the only
2444 2561   * impact is getting EBUSY's before each operation which we have
2445 2562   * busy waiting loops checking EBUSY error code.
↓ open down ↓ 9 lines elided ↑ open up ↑
2455 2572          (void) memset(&cdb, 0, sizeof (union scsi_cdb));
2456 2573          cdb.scc_cmd = SCMD_TEST_UNIT_READY;
2457 2574          ucmd.uscsi_cdb = (caddr_t)&cdb;
2458 2575          ucmd.uscsi_cdblen = CDB_GROUP0;
2459 2576          ucmd.uscsi_flags |= USCSI_SILENT;
2460 2577          ucmd.uscsi_timeout = 60;        /* Allow maximum 1 min */
2461 2578  
2462 2579          retval = ioctl(dev_id, USCSICMD, &ucmd);
2463 2580  
2464 2581          if (retval != 0 && errno != EIO) {
2465      -                NDMP_LOG(LOG_ERR,
     2582 +                syslog(LOG_ERR,
2466 2583                      "Failed to send inquiry request to device: %m.");
2467      -                NDMP_LOG(LOG_DEBUG, "Inquiry request failed for"
     2584 +                syslog(LOG_DEBUG, "Inquiry request failed for"
2468 2585                      " dev_id:%d err=%d -%m", dev_id, errno);
2469 2586                  retval = -errno;
2470 2587          } else
2471 2588                  retval = -(ucmd.uscsi_status);
2472 2589  
2473 2590          return (retval);
2474 2591  }
2475 2592  
2476 2593  
2477 2594  /*
↓ open down ↓ 21 lines elided ↑ open up ↑
2499 2616          ndmp_max_tok_seq = atoi(ndmpd_get_prop_default(NDMP_MAXSEQ_ENV, "9"));
2500 2617  
2501 2618          ndmp_full_restore_path = ndmpd_get_prop_yorn(NDMP_FULL_RESTORE_PATH) ?
2502 2619              TRUE : FALSE;
2503 2620  
2504 2621          ndmp_fhinode = ndmpd_get_prop_yorn(NDMP_FHIST_INCR_ENV) ? TRUE : FALSE;
2505 2622  
2506 2623          /* Get the value from ndmp SMF property. */
2507 2624          ndmp_dar_support = ndmpd_get_prop_yorn(NDMP_DAR_SUPPORT);
2508 2625  
     2626 +        ndmp_autosync_support = ndmpd_get_prop_yorn(NDMP_AUTOSYNC_SUPPORT);
     2627 +        ndmp_hpr_support = ndmpd_get_prop_yorn(NDMP_HPR_SUPPORT);
     2628 +        /*
     2629 +         * The HPR snapshot feature superscedes autosync and the two can't be
     2630 +         * active together on the same system.
     2631 +         */
     2632 +        if (ndmp_hpr_support) {
     2633 +                ndmp_autosync_support = 0;
     2634 +                syslog(LOG_DEBUG, "NDMP_HPR_SUPPORT set to [%d]",
     2635 +                    ndmp_hpr_support);
     2636 +        }
     2637 +
     2638 +        if (ndmp_autosync_support) {
     2639 +                syslog(LOG_DEBUG, "NDMP_AUTOSYNC_SUPPORT set to [%d]",
     2640 +                    ndmp_autosync_support);
     2641 +        }
     2642 +
2509 2643          if ((ndmp_ver = atoi(ndmpd_get_prop(NDMP_VERSION_ENV))) == 0)
2510 2644                  ndmp_ver = NDMPVER;
2511 2645  }
2512 2646  
2513 2647  /*
2514 2648   * randomize
2515 2649   *
2516 2650   * Randomize the contents of a buffer
2517 2651   *
2518 2652   * Parameter:
↓ open down ↓ 90 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX