Print this page
    
NEX-13374 NDMP should be able to backup unmounted ZFS filesystems
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Revert "NEX-5801 Snapshots left over after failed backups"
This reverts commit f182fb95f09036db71fbfc6f0a6b90469b761f21.
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-894 Default location of NDMP log file should be under /var/log
NEX-727 Netbackup Catalog verification hangs waiting for NDMP server
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c
          +++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c
   1    1  /*
   2    2   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
   3      - * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
        3 + * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
   4    4   */
   5    5  
   6    6  /*
   7    7   * BSD 3 Clause License
   8    8   *
   9    9   * Copyright (c) 2007, The Storage Networking Industry Association.
  10   10   *
  11   11   * Redistribution and use in source and binary forms, with or without
  12   12   * modification, are permitted provided that the following conditions
  13   13   * are met:
  14   14   *      - Redistributions of source code must retain the above copyright
  15   15   *        notice, this list of conditions and the following disclaimer.
  16   16   *
  17   17   *      - Redistributions in binary form must reproduce the above copyright
  18   18   *        notice, this list of conditions and the following disclaimer in
  19   19   *        the documentation and/or other materials provided with the
  20   20   *        distribution.
  21   21   *
  22   22   *      - Neither the name of The Storage Networking Industry Association (SNIA)
  23   23   *        nor the names of its contributors may be used to endorse or promote
  24   24   *        products derived from this software without specific prior written
  25   25   *        permission.
  26   26   *
  27   27   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28   28   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29   29   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30   30   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  31   31   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  32   32   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33   33   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34   34   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35   35   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
  36   36   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37   37   * POSSIBILITY OF SUCH DAMAGE.
  38   38   */
  39   39  /* Copyright (c) 2007, The Storage Networking Industry Association. */
  40   40  /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
  41   41  
  42   42  #include <sys/types.h>
  43   43  #include <sys/socket.h>
  44   44  #include <sys/time.h>
  45   45  #include <sys/uio.h>
       46 +#include <syslog.h>
  46   47  #include <unistd.h>
  47   48  #include <string.h>
  48   49  #include <stdlib.h>
  49   50  #include <errno.h>
  50   51  #include <netdb.h>
  51   52  #include <netinet/in.h>
  52   53  #include <arpa/inet.h>
  53   54  #include <libinetutil.h>
  54   55  #include "ndmpd.h"
  55   56  #include "ndmpd_common.h"
  56   57  
  57   58  #define NDMP_PROC_ERR   -1
  58   59  #define NDMP_PROC_MSG   1
  59   60  #define NDMP_PROC_REP   0
  60   61  #define NDMP_PROC_REP_ERR       2
  61   62  
  62   63  /*
  63   64   * The ndmp connection version can be set through command line. If command line
  64   65   * is not specified it will be set from the ndmp SMF version property.
  65   66   */
  66   67  int ndmp_ver = 0;
  67   68  
  68   69  /*
  69   70   * The NDMP listening port number
  70   71   */
  71   72  int ndmp_port = 0;
  72   73  
  73   74  /*
  74   75   * Restore path mechanism definition
  75   76   * 0 means partial path restore and
  76   77   * 1 means full path restore.
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
  77   78   * Refer to NDMP_FULL_RESTORE_PATH for partial path and full path definition.
  78   79   */
  79   80  int ndmp_full_restore_path = 1;
  80   81  
  81   82  /*
  82   83   * Do we support Direct Access Restore?
  83   84   */
  84   85  int ndmp_dar_support = 0;
  85   86  
  86   87  /*
       88 + * Is autosync enabled?
       89 + */
       90 +int ndmp_autosync_support = 0;
       91 +
       92 +/*
       93 + * Is HPR snapshot enabled?
       94 + */
       95 +int ndmp_hpr_support = 0;
       96 +
       97 +/*
  87   98   * ndmp_connection_t handler function
  88   99   */
  89  100  static ndmpd_file_handler_func_t connection_file_handler;
  90  101  
  91  102  extern ndmp_handler_t ndmp_msghdl_tab[];
  92  103  
  93  104  static int ndmp_readit(void *connection_handle,
  94  105      caddr_t buf,
  95  106      int len);
  96  107  static int ndmp_writeit(void *connection_handle,
  97  108      caddr_t buf,
  98  109      int len);
  99  110  static int ndmp_recv_msg(ndmp_connection_t *connection);
 100  111  static int ndmp_process_messages(ndmp_connection_t *connection,
 101  112      boolean_t reply_expected);
 102  113  static ndmp_msg_handler_t *ndmp_get_handler(ndmp_connection_t *connection,
 103  114      ndmp_message message);
 104  115  static boolean_t ndmp_check_auth_required(ndmp_message message);
 105  116  static ndmp_handler_t *ndmp_get_interface(ndmp_message message);
 106  117  void *ndmpd_worker(void *ptarg);
 107  118  
 108  119  #ifdef  lint
 109  120  bool_t
 110  121  xdr_ndmp_header(XDR *xdrs, ndmp_header *objp)
 111  122  {
 112  123          xdrs = xdrs;
 113  124          objp = objp;
 114  125          return (0);
 115  126  }
 116  127  #endif  /* lint */
 117  128  
 118  129  /*
 119  130   * ndmp_create_connection
 120  131   *
 121  132   * Allocate and initialize a connection structure.
 122  133   *
 123  134   * Parameters:
 124  135   *   handler_tbl (input) - message handlers.
 125  136   *
 126  137   * Returns:
 127  138   *   NULL - error
 128  139   *   connection pointer
 129  140   *
 130  141   * Notes:
 131  142   *   The returned connection should be destroyed using
 132  143   *   ndmp_destroy_connection().
 133  144   */
 134  145  ndmp_connection_t *
 135  146  ndmp_create_connection(void)
 136  147  {
 137  148          ndmp_connection_t *connection;
 138  149  
 139  150          connection = ndmp_malloc(sizeof (ndmp_connection_t));
 140  151          if (connection == NULL)
 141  152                  return (NULL);
 142  153  
 143  154          connection->conn_sock = -1;
 144  155          connection->conn_my_sequence = 0;
 145  156          connection->conn_authorized = FALSE;
 146  157          connection->conn_eof = FALSE;
  
    | 
      ↓ open down ↓ | 
    50 lines elided | 
    
      ↑ open up ↑ | 
  
 147  158          connection->conn_msginfo.mi_body = 0;
 148  159          connection->conn_version = ndmp_ver;
 149  160          connection->conn_client_data = 0;
 150  161          (void) mutex_init(&connection->conn_lock, 0, NULL);
 151  162          connection->conn_xdrs.x_ops = 0;
 152  163  
 153  164          xdrrec_create(&connection->conn_xdrs, 0, 0, (caddr_t)connection,
 154  165              ndmp_readit, ndmp_writeit);
 155  166  
 156  167          if (connection->conn_xdrs.x_ops == 0) {
 157      -                NDMP_LOG(LOG_DEBUG, "xdrrec_create failed");
      168 +                syslog(LOG_ERR, "xdrrec_create failed");
 158  169                  (void) mutex_destroy(&connection->conn_lock);
 159  170                  (void) close(connection->conn_sock);
 160  171                  free(connection);
 161  172                  return (0);
 162  173          }
 163  174          return ((ndmp_connection_t *)connection);
 164  175  }
 165  176  
 166  177  /*
 167  178   * ndmp_destroy_connection
 168  179   *
 169  180   * Shutdown a connection and release allocated resources.
 170  181   *
 171  182   * Parameters:
 172  183   *   connection_handle (Input) - connection handle.
 173  184   *
 174  185   * Returns:
 175  186   *   void
 176  187   */
 177  188  void
 178  189  ndmp_destroy_connection(ndmp_connection_t *connection_handle)
 179  190  {
 180  191          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 181  192  
 182  193          if (connection->conn_sock >= 0) {
 183  194                  (void) mutex_destroy(&connection->conn_lock);
 184  195                  (void) close(connection->conn_sock);
 185  196                  connection->conn_sock = -1;
 186  197          }
 187  198          xdr_destroy(&connection->conn_xdrs);
 188  199          free(connection);
 189  200  }
 190  201  
 191  202  
 192  203  /*
 193  204   * ndmp_close
 194  205   *
 195  206   * Close a connection.
 196  207   *
 197  208   * Parameters:
 198  209   *   connection_handle (Input) - connection handle.
 199  210   *
 200  211   * Returns:
 201  212   *   void
 202  213   */
 203  214  void
 204  215  ndmp_close(ndmp_connection_t *connection_handle)
 205  216  {
 206  217          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 207  218  
 208  219          ndmpd_audit_disconnect(connection);
 209  220          if (connection->conn_sock >= 0) {
 210  221                  (void) mutex_destroy(&connection->conn_lock);
 211  222                  (void) close(connection->conn_sock);
 212  223                  connection->conn_sock = -1;
 213  224          }
 214  225          connection->conn_eof = TRUE;
 215  226  
 216  227          /*
 217  228           * We should close all the tapes that are used by this connection.
 218  229           * In some cases the ndmp client opens a tape, but does not close the
 219  230           * tape and closes the connection.
 220  231           */
 221  232          ndmp_open_list_release(connection_handle);
 222  233  }
 223  234  
 224  235  /*
 225  236   * ndmp_start_worker
 226  237   *
 227  238   * Initializes and starts a ndmp_worker thread
 228  239   */
 229  240  int
 230  241  ndmp_start_worker(ndmpd_worker_arg_t *argp)
 231  242  {
 232  243          pthread_attr_t tattr;
 233  244          int rc;
 234  245  
 235  246          (void) pthread_attr_init(&tattr);
 236  247          (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
 237  248          rc = pthread_create(NULL, &tattr, ndmpd_worker, (void *)argp);
 238  249          (void) pthread_attr_destroy(&tattr);
 239  250          return (rc);
 240  251  }
 241  252  
 242  253  /*
 243  254   * ndmp_run
 244  255   *
 245  256   * Creates a socket for listening and accepting connections
 246  257   * from NDMP clients.
 247  258   * Accepts connections and passes each connection to the connection
 248  259   * handler.
 249  260   *
 250  261   * Parameters:
 251  262   *   port (input)   -  NDMP server port.
 252  263   *                   If 0, the port number will be retrieved from
 253  264   *                   the network service database. If not found there,
 254  265   *                   the default NDMP port number (from ndmp.x)
 255  266   *                   will be used.
 256  267   *   handler (input) - connection handler function.
 257  268   *
 258  269   * Returns:
 259  270   *   This function normally never returns unless there's error.
 260  271   *   -1 : error
 261  272   *
 262  273   * Notes:
 263  274   *   This function does not return unless encountering an error
 264  275   *   related to the listen socket.
 265  276   */
 266  277  int
 267  278  ndmp_run(ulong_t port, ndmp_con_handler_func_t con_handler_func)
 268  279  {
 269  280          int ns;
 270  281          int on;
  
    | 
      ↓ open down ↓ | 
    103 lines elided | 
    
      ↑ open up ↑ | 
  
 271  282          int server_socket;
 272  283          unsigned int ipaddr;
 273  284          struct sockaddr_in sin;
 274  285          ndmpd_worker_arg_t *argp;
 275  286  
 276  287          sin.sin_family = AF_INET;
 277  288          sin.sin_addr.s_addr = INADDR_ANY;
 278  289          sin.sin_port = htons(port);
 279  290  
 280  291          if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 281      -                NDMP_LOG(LOG_DEBUG, "Socket error: %m");
      292 +                syslog(LOG_ERR, "Socket error: %m");
 282  293                  return (-1);
 283  294          }
 284  295  
 285  296          on = 1;
 286  297          (void) setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,
 287  298              (char *)&on, sizeof (on));
 288  299  
 289  300  
 290  301          if (bind(server_socket, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
 291      -                NDMP_LOG(LOG_DEBUG, "bind error: %m");
      302 +                syslog(LOG_ERR, "bind error: %m");
 292  303                  (void) close(server_socket);
 293  304                  return (-1);
 294  305          }
 295  306          if (listen(server_socket, 5) < 0) {
 296      -                NDMP_LOG(LOG_DEBUG, "listen error: %m");
      307 +                syslog(LOG_ERR, "listen error: %m");
 297  308                  (void) close(server_socket);
 298  309                  return (-1);
 299  310          }
 300  311  
 301  312          for (; ; ) {
 302  313                  if ((ns = tcp_accept(server_socket, &ipaddr)) < 0) {
 303      -                        NDMP_LOG(LOG_DEBUG, "tcp_accept error: %m");
      314 +                        syslog(LOG_ERR, "tcp_accept error: %m");
 304  315                          continue;
 305  316                  }
 306      -                NDMP_LOG(LOG_DEBUG, "connection fd: %d", ns);
 307  317                  set_socket_options(ns);
 308  318  
 309  319                  if ((argp = ndmp_malloc(sizeof (ndmpd_worker_arg_t))) != NULL) {
 310  320                          argp->nw_sock = ns;
 311  321                          argp->nw_ipaddr = ipaddr;
 312  322                          argp->nw_con_handler_func = con_handler_func;
 313  323                          (void) ndmp_start_worker(argp);
 314  324                  }
 315  325          }
 316  326  }
 317  327  
 318  328  /*
 319  329   * ndmpd_worker thread
 320  330   *
 321  331   * Parameters:
 322  332   *   argp (input) - structure containing socket and handler function
 323  333   *
 324  334   * Returns:
 325  335   *   0 - successful connection.
 326  336   *  -1 - error.
 327  337   */
 328  338  void *
 329  339  ndmpd_worker(void *ptarg)
 330  340  {
 331  341          int sock;
 332  342          ndmp_connection_t *connection;
 333  343          ndmpd_worker_arg_t *argp = (ndmpd_worker_arg_t *)ptarg;
 334  344  
 335  345          if (!argp)
 336  346                  return ((void *)-1);
 337  347  
 338  348          NS_INC(trun);
 339  349          sock = argp->nw_sock;
 340  350  
 341  351          if ((connection = ndmp_create_connection()) == NULL) {
 342  352                  (void) close(sock);
 343  353                  free(argp);
 344  354                  exit(1);
 345  355          }
 346  356  
 347  357          /* initialize auditing session */
 348  358          if (adt_start_session(&connection->conn_ah, NULL, 0) != 0) {
 349  359                  free(argp);
 350  360                  return ((void *)-1);
 351  361          }
 352  362  
 353  363          ((ndmp_connection_t *)connection)->conn_sock = sock;
 354  364          (*argp->nw_con_handler_func)(connection);
 355  365          (void) adt_end_session(connection->conn_ah);
 356  366          ndmp_destroy_connection(connection);
 357  367          NS_DEC(trun);
 358  368  
 359  369          free(argp);
 360  370          return (NULL);
 361  371  }
 362  372  
 363  373  /*
 364  374   * ndmp_process_requests
 365  375   *
 366  376   * Reads the next request message into the stream buffer.
 367  377   * Processes messages until the stream buffer is empty.
 368  378   *
 369  379   * Parameters:
 370  380   *   connection_handle (input) - connection handle.
 371  381   *
 372  382   * Returns:
 373  383   *   0 - 1 or more messages successfully processed.
 374  384   *  -1 - error; connection no longer established.
 375  385   */
 376  386  int
 377  387  ndmp_process_requests(ndmp_connection_t *connection_handle)
 378  388  {
 379  389          int rv;
 380  390          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 381  391  
 382  392          (void) mutex_lock(&connection->conn_lock);
 383  393          rv = 0;
 384  394          if (ndmp_process_messages(connection, FALSE) < 0)
 385  395                  rv = -1;
 386  396  
 387  397          (void) mutex_unlock(&connection->conn_lock);
 388  398          return (rv);
 389  399  }
 390  400  
 391  401  
 392  402  /*
 393  403   * ndmp_send_request
 394  404   *
 395  405   * Send an NDMP request message.
 396  406   *
 397  407   * Parameters:
 398  408   *   connection_handle (input) - connection pointer.
 399  409   *   message (input) - message number.
 400  410   *   err (input)  - error code to place in header.
 401  411   *   request_data (input) - message body.
 402  412   *   reply (output) - reply message. If 0, reply will be
 403  413   *                              discarded.
 404  414   *
 405  415   * Returns:
 406  416   *   0  - successful send.
 407  417   *  -1  - error.
 408  418   *   otherwise - error from reply header.
 409  419   *
 410  420   * Notes:
 411  421   *   - The reply body is only returned if the error code is NDMP_NO_ERR.
 412  422   */
 413  423  int
 414  424  ndmp_send_request(ndmp_connection_t *connection_handle, ndmp_message message,
  
    | 
      ↓ open down ↓ | 
    98 lines elided | 
    
      ↑ open up ↑ | 
  
 415  425      ndmp_error err, void *request_data, void **reply)
 416  426  {
 417  427          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 418  428          ndmp_header header;
 419  429          ndmp_msg_handler_t *handler;
 420  430          int r;
 421  431          struct timeval time;
 422  432  
 423  433          /* Lookup info necessary for processing this request. */
 424  434          if (!(handler = ndmp_get_handler(connection, message))) {
 425      -                NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: not supported",
      435 +                syslog(LOG_ERR, "Sending message 0x%x: not supported",
 426  436                      message);
 427  437                  return (-1);
 428  438          }
 429  439          (void) gettimeofday(&time, 0);
 430  440  
 431  441          header.sequence = ++(connection->conn_my_sequence);
 432  442          header.time_stamp = time.tv_sec;
 433  443          header.message_type = NDMP_MESSAGE_REQUEST;
 434  444          header.message = message;
 435  445          header.reply_sequence = 0;
 436  446          header.error = err;
 437  447  
 438  448          connection->conn_xdrs.x_op = XDR_ENCODE;
 439  449          if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
 440      -                NDMP_LOG(LOG_DEBUG,
      450 +                syslog(LOG_ERR,
 441  451                      "Sending message 0x%x: encoding request header", message);
 442  452                  (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
 443  453                  return (-1);
 444  454          }
 445  455          if (err == NDMP_NO_ERR && handler->mh_xdr_request && request_data) {
 446  456                  if (!(*handler->mh_xdr_request)(&connection->conn_xdrs,
 447  457                      request_data)) {
 448      -                        NDMP_LOG(LOG_DEBUG,
      458 +                        syslog(LOG_ERR,
 449  459                              "Sending message 0x%x: encoding request body",
 450  460                              message);
 451  461                          (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
 452  462                          return (-1);
 453  463                  }
 454  464          }
 455  465          (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
 456  466  
 457  467          if (handler->mh_xdr_reply == 0) {
 458      -                NDMP_LOG(LOG_DEBUG, "handler->mh_xdr_reply == 0");
 459  468                  return (0);
 460  469          }
 461  470  
 462  471          /*
 463  472           * Process messages until the reply to this request has been
 464  473           * processed.
 465  474           */
 466  475          for (; ; ) {
 467  476                  r = ndmp_process_messages(connection, TRUE);
 468  477  
 469  478                  /* connection error? */
 470  479                  if (r < 0)
  
    | 
      ↓ open down ↓ | 
    2 lines elided | 
    
      ↑ open up ↑ | 
  
 471  480                          return (-1);
 472  481  
 473  482                  /* no reply received? */
 474  483                  if (r == 0)
 475  484                          continue;
 476  485  
 477  486                  /* reply received? */
 478  487                  if (r == 1) {
 479  488                          if (message !=
 480  489                              connection->conn_msginfo.mi_hdr.message) {
 481      -                                NDMP_LOG(LOG_DEBUG,
      490 +                                syslog(LOG_ERR,
 482  491                                      "Received unexpected reply 0x%x",
 483  492                                      connection->conn_msginfo.mi_hdr.message);
 484  493                                  ndmp_free_message(connection_handle);
 485  494                                  return (-1);
 486  495                          }
 487  496                          if (reply != NULL)
 488  497                                  *reply = connection->conn_msginfo.mi_body;
 489  498                          else
 490  499                                  ndmp_free_message(connection_handle);
 491  500  
 492  501                          return (connection->conn_msginfo.mi_hdr.error);
 493  502                  }
 494  503                  /* error handling reply */
 495  504  
 496  505                  return (-1);
 497  506          }
 498  507  }
 499  508  
 500  509  
 501  510  /*
 502  511   * ndmp_send_request_lock
 503  512   *
 504  513   * A wrapper for ndmp_send_request with locks.
 505  514   *
 506  515   * Parameters:
 507  516   *   connection_handle (input) - connection pointer.
 508  517   *   message (input) - message number.
 509  518   *   err (input) - error code to place in header.
 510  519   *   request_data (input) - message body.
 511  520   *   reply (output) - reply message. If 0, reply will be
 512  521   *                              discarded.
 513  522   *
 514  523   * Returns:
 515  524   *   0  - successful send.
 516  525   *  -1  - error.
 517  526   *   otherwise - error from reply header.
 518  527   *
 519  528   * Notes:
 520  529   *   - The reply body is only returned if the error code is NDMP_NO_ERR.
 521  530   */
 522  531  int
 523  532  ndmp_send_request_lock(ndmp_connection_t *connection_handle,
 524  533      ndmp_message message, ndmp_error err, void *request_data, void **reply)
 525  534  {
 526  535          int rv;
 527  536          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 528  537  
 529  538          (void) mutex_lock(&connection->conn_lock);
 530  539  
 531  540          rv = ndmp_send_request(connection_handle, message, err, request_data,
 532  541              reply);
 533  542          (void) mutex_unlock(&connection->conn_lock);
 534  543          return (rv);
 535  544  }
 536  545  
 537  546  
 538  547  /*
 539  548   * ndmp_send_response
 540  549   *
 541  550   * Send an NDMP reply message.
 542  551   *
 543  552   * Parameters:
 544  553   *   connection_handle  (input)  - connection pointer.
 545  554   *   err               (input)  - error code to place in header.
 546  555   *   reply           (input)  - reply message body.
 547  556   *
 548  557   * Returns:
 549  558   *   0 - successful send.
 550  559   *  -1 - error.
 551  560   *
 552  561   * Notes:
 553  562   *   - The body is only sent if the error code is NDMP_NO_ERR.
 554  563   */
 555  564  int
 556  565  ndmp_send_response(ndmp_connection_t *connection_handle, ndmp_error err,
 557  566      void *reply)
 558  567  {
 559  568          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 560  569          ndmp_header header;
 561  570          struct timeval time;
 562  571  
 563  572          (void) gettimeofday(&time, 0);
  
    | 
      ↓ open down ↓ | 
    72 lines elided | 
    
      ↑ open up ↑ | 
  
 564  573  
 565  574          header.sequence = ++(connection->conn_my_sequence);
 566  575          header.time_stamp = time.tv_sec;
 567  576          header.message_type = NDMP_MESSAGE_REPLY;
 568  577          header.message = connection->conn_msginfo.mi_hdr.message;
 569  578          header.reply_sequence = connection->conn_msginfo.mi_hdr.sequence;
 570  579          header.error = err;
 571  580  
 572  581          connection->conn_xdrs.x_op = XDR_ENCODE;
 573  582          if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
 574      -                NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: "
      583 +                syslog(LOG_ERR, "Sending message 0x%x: "
 575  584                      "encoding reply header",
 576  585                      header.message);
 577  586                  (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
 578  587                  return (-1);
 579  588          }
 580  589          if (err == NDMP_NO_ERR &&
 581  590              connection->conn_msginfo.mi_handler->mh_xdr_reply &&
 582  591              reply) {
 583  592                  if (!(*connection->conn_msginfo.mi_handler->mh_xdr_reply)(
 584  593                      &connection->conn_xdrs, reply)) {
 585      -                        NDMP_LOG(LOG_DEBUG,
      594 +                        syslog(LOG_ERR,
 586  595                              "Sending message 0x%x: encoding reply body",
 587  596                              header.message);
 588  597                          (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
 589  598                          return (-1);
 590  599          }
 591  600          }
 592  601          (void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
 593  602          return (0);
 594  603  }
 595  604  
 596  605  /*
 597  606   * ndmp_free_message
 598  607   *
 599  608   * Free the memory of NDMP message body.
 600  609   *
 601  610   * Parameters:
 602  611   *   connection_handle  (input)  - connection pointer.
 603  612   *
 604  613   * Returns:
 605  614   *   void
 606  615   *
 607  616   */
 608  617  void
 609  618  ndmp_free_message(ndmp_connection_t *connection_handle)
 610  619  {
 611  620          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 612  621  
 613  622          if (connection->conn_msginfo.mi_handler == NULL ||
 614  623              connection->conn_msginfo.mi_body == NULL)
 615  624                  return;
 616  625  
 617  626          connection->conn_xdrs.x_op = XDR_FREE;
 618  627          if (connection->conn_msginfo.mi_hdr.message_type ==
 619  628              NDMP_MESSAGE_REQUEST) {
 620  629                  if (connection->conn_msginfo.mi_handler->mh_xdr_request)
 621  630                          (*connection->conn_msginfo.mi_handler->mh_xdr_request)(
 622  631                              &connection->conn_xdrs,
 623  632                              connection->conn_msginfo.mi_body);
 624  633          } else {
 625  634                  if (connection->conn_msginfo.mi_handler->mh_xdr_reply)
 626  635                          (*connection->conn_msginfo.mi_handler->mh_xdr_reply)(
 627  636                              &connection->conn_xdrs,
 628  637                              connection->conn_msginfo.mi_body);
 629  638          }
 630  639  
 631  640          (void) free(connection->conn_msginfo.mi_body);
 632  641          connection->conn_msginfo.mi_body = 0;
 633  642  }
 634  643  
 635  644  /*
 636  645   * ndmp_get_fd
 637  646   *
 638  647   * Returns the connection file descriptor.
 639  648   *
 640  649   * Parameters:
 641  650   *   connection_handle (input) - connection handle
 642  651   *
 643  652   * Returns:
 644  653   *   >=0 - file descriptor.
 645  654   *   -1  - connection not open.
 646  655   */
 647  656  int
 648  657  ndmp_get_fd(ndmp_connection_t *connection_handle)
 649  658  {
 650  659          return (((ndmp_connection_t *)connection_handle)->conn_sock);
 651  660  }
 652  661  
 653  662  
 654  663  /*
 655  664   * ndmp_set_client_data
 656  665   *
 657  666   * This function provides a means for the library client to provide
 658  667   * a pointer to some user data structure that is retrievable by
 659  668   * each message handler via ndmp_get_client_data.
 660  669   *
 661  670   * Parameters:
 662  671   *   connection_handle  (input) - connection handle.
 663  672   *   client_data        (input) - user data pointer.
 664  673   *
 665  674   * Returns:
 666  675   *   void
 667  676   */
 668  677  void
 669  678  ndmp_set_client_data(ndmp_connection_t *connection_handle, void *client_data)
 670  679  {
 671  680          ((ndmp_connection_t *)connection_handle)->conn_client_data =
 672  681              client_data;
 673  682  }
 674  683  
 675  684  
 676  685  /*
 677  686   * ndmp_get_client_data
 678  687   *
 679  688   * This function provides a means for the library client to provide
 680  689   * a pointer to some user data structure that is retrievable by
 681  690   * each message handler via ndmp_get_client_data.
 682  691   *
 683  692   * Parameters:
 684  693   *   connection_handle (input) - connection handle.
 685  694   *
 686  695   * Returns:
 687  696   *   client data pointer.
 688  697   */
 689  698  void *
 690  699  ndmp_get_client_data(ndmp_connection_t *connection_handle)
 691  700  {
 692  701          return (((ndmp_connection_t *)connection_handle)->conn_client_data);
 693  702  }
 694  703  
 695  704  
 696  705  /*
 697  706   * ndmp_set_version
 698  707   *
 699  708   * Sets the NDMP protocol version to be used on the connection.
 700  709   *
 701  710   * Parameters:
 702  711   *   connection_handle  (input) - connection handle.
 703  712   *   version       (input) - protocol version.
 704  713   *
 705  714   * Returns:
 706  715   *   void
 707  716   */
 708  717  void
 709  718  ndmp_set_version(ndmp_connection_t *connection_handle, ushort_t version)
 710  719  {
 711  720          ((ndmp_connection_t *)connection_handle)->conn_version = version;
 712  721  }
 713  722  
 714  723  
 715  724  /*
 716  725   * ndmp_get_version
 717  726   *
 718  727   * Gets the NDMP protocol version in use on the connection.
 719  728   *
 720  729   * Parameters:
 721  730   *   connection_handle  (input) - connection handle.
 722  731   *   version       (input) - protocol version.
 723  732   *
 724  733   * Returns:
 725  734   *   void
 726  735   */
 727  736  ushort_t
 728  737  ndmp_get_version(ndmp_connection_t *connection_handle)
 729  738  {
 730  739          return (((ndmp_connection_t *)connection_handle)->conn_version);
 731  740  }
 732  741  
 733  742  
 734  743  /*
 735  744   * ndmp_set_authorized
 736  745   *
 737  746   * Mark the connection as either having been authorized or not.
 738  747   *
 739  748   * Parameters:
 740  749   *   connection_handle  (input) - connection handle.
 741  750   *   authorized (input) - TRUE or FALSE.
 742  751   *
 743  752   * Returns:
 744  753   *   void
 745  754   */
 746  755  void
 747  756  ndmp_set_authorized(ndmp_connection_t *connection_handle, boolean_t authorized)
 748  757  {
 749  758          ((ndmp_connection_t *)connection_handle)->conn_authorized = authorized;
 750  759  }
 751  760  
 752  761  
 753  762  /*
 754  763   * ndmpd_main
 755  764   *
 756  765   * NDMP main function called from main().
 757  766   *
 758  767   * Parameters:
 759  768   *   void
 760  769   *
 761  770   * Returns:
 762  771   *   void
 763  772   */
 764  773  void
 765  774  ndmpd_main(void)
 766  775  {
 767  776          char *propval;
 768  777  
 769  778          ndmp_load_params();
 770  779  
 771  780          /*
 772  781           * Find ndmp port number to be used. If ndmpd is run as command line
 773  782           * and port number is supplied, use that port number. If port number is
 774  783           * is not supplied, find out if ndmp port property is set. If ndmp
 775  784           * port property is set, use that port number otherwise use the defaule
 776  785           * port number.
 777  786           */
 778  787          if (ndmp_port == 0) {
 779  788                  if ((propval = ndmpd_get_prop(NDMP_TCP_PORT)) == NULL ||
 780  789                      *propval == 0)
 781  790                          ndmp_port = NDMPPORT;
 782  791                  else
 783  792                          ndmp_port = strtol(propval, 0, 0);
 784  793          }
 785  794  
 786  795          if (ndmp_run(ndmp_port, connection_handler) == -1)
 787  796                  perror("ndmp_run ERROR");
 788  797  }
 789  798  
 790  799  /*
 791  800   * connection_handler
 792  801   *
 793  802   * NDMP connection handler.
 794  803   * Waits for, reads, and processes NDMP requests on a connection.
 795  804   *
 796  805   * Parameters:
 797  806   *   connection (input) - connection handle.
 798  807   *
 799  808   * Return:
 800  809   *   void
 801  810   */
 802  811  void
 803  812  connection_handler(ndmp_connection_t *connection)
 804  813  {
 805  814          static int conn_id = 1;
 806  815          ndmpd_session_t session;
 807  816          ndmp_notify_connected_request req;
 808  817          int connection_fd;
 809  818  
 810  819          (void) memset(&session, 0, sizeof (session));
 811  820          session.ns_connection = connection;
 812  821          session.ns_eof = FALSE;
 813  822          /*
 814  823           * The 'protocol_version' must be 1 at first, since the client talks
 815  824           * to the server in version 1 then they can move to a higher
 816  825           * protocol version.
 817  826           */
 818  827          session.ns_protocol_version = ndmp_ver;
 819  828  
 820  829          session.ns_scsi.sd_is_open = -1;
 821  830          session.ns_scsi.sd_devid = -1;
 822  831  
 823  832          session.ns_scsi.sd_sid = 0;
 824  833          session.ns_scsi.sd_lun = 0;
 825  834          session.ns_scsi.sd_valid_target_set = 0;
 826  835          (void) memset(session.ns_scsi.sd_adapter_name, 0,
 827  836              sizeof (session.ns_scsi.sd_adapter_name));
 828  837  
 829  838          session.ns_tape.td_fd = -1;
 830  839          session.ns_tape.td_sid = 0;
 831  840          session.ns_tape.td_lun = 0;
 832  841          (void) memset(session.ns_tape.td_adapter_name, 0,
 833  842              sizeof (session.ns_tape.td_adapter_name));
 834  843          session.ns_tape.td_pos = 0;
 835  844          session.ns_tape.td_record_count = 0;
 836  845          session.ns_file_handler_list = 0;
 837  846  
 838  847          (void) ndmpd_data_init(&session);
 839  848          ndmpd_file_history_init(&session);
 840  849          if (ndmpd_mover_init(&session) < 0)
 841  850                  return;
 842  851  
 843  852          if (ndmp_lbr_init(&session) < 0)
 844  853                  return;
 845  854  
 846  855          /*
 847  856           * Setup defaults here. The init functions can not set defaults
 848  857           * since the init functions are called by the stop request handlers
 849  858           * and client set variables need to persist across data operations.
 850  859           */
  
    | 
      ↓ open down ↓ | 
    255 lines elided | 
    
      ↑ open up ↑ | 
  
 851  860          session.ns_mover.md_record_size = MAX_RECORD_SIZE;
 852  861  
 853  862          ndmp_set_client_data(connection, (void *)&session);
 854  863  
 855  864          req.reason = NDMP_CONNECTED;
 856  865          req.protocol_version = ndmp_ver;
 857  866          req.text_reason = "";
 858  867  
 859  868          if (ndmp_send_request_lock(connection, NDMP_NOTIFY_CONNECTION_STATUS,
 860  869              NDMP_NO_ERR, (void *)&req, 0) < 0) {
 861      -                NDMP_LOG(LOG_DEBUG, "Connection terminated");
      870 +                syslog(LOG_DEBUG, "Send CONNECTION STATUS failed");
 862  871                  return;
 863  872          }
 864  873          connection_fd = ndmp_get_fd(connection);
 865  874  
 866      -        NDMP_LOG(LOG_DEBUG, "connection_fd: %d", connection_fd);
 867      -
 868  875          /*
 869  876           * Add the handler function for the connection to the DMA.
 870  877           */
 871  878          if (ndmpd_add_file_handler(&session, (void *)&session, connection_fd,
 872  879              NDMPD_SELECT_MODE_READ, HC_CLIENT, connection_file_handler) != 0) {
 873      -                NDMP_LOG(LOG_DEBUG, "Could not register session handler.");
      880 +                syslog(LOG_ERR, "Could not register session handler.");
 874  881                  return;
 875  882          }
 876  883  
 877  884          /*
 878  885           * Register the connection in the list of active connections.
 879  886           */
 880  887          if (ndmp_connect_list_add(connection, &conn_id) != 0) {
 881      -                NDMP_LOG(LOG_ERR,
      888 +                syslog(LOG_ERR,
 882  889                      "Could not register the session to the server.");
 883  890                  (void) ndmpd_remove_file_handler(&session, connection_fd);
 884  891                  return;
 885  892          }
 886  893  
 887  894          session.hardlink_q = hardlink_q_init();
 888  895  
 889  896          while (session.ns_eof == FALSE)
 890  897                  (void) ndmpd_select(&session, TRUE, HC_ALL);
 891  898  
 892  899          hardlink_q_cleanup(session.hardlink_q);
 893  900  
 894      -        NDMP_LOG(LOG_DEBUG, "Connection terminated");
 895      -
 896  901          (void) ndmpd_remove_file_handler(&session, connection_fd);
 897  902  
 898  903          if (session.ns_scsi.sd_is_open != -1) {
 899      -                NDMP_LOG(LOG_DEBUG, "scsi.is_open: %d",
      904 +                syslog(LOG_ERR, "scsi.is_open: %d",
 900  905                      session.ns_scsi.sd_is_open);
 901  906                  (void) ndmp_open_list_del(session.ns_scsi.sd_adapter_name,
 902  907                      session.ns_scsi.sd_sid, session.ns_scsi.sd_lun);
 903  908          }
 904  909          if (session.ns_tape.td_fd != -1) {
 905      -                NDMP_LOG(LOG_DEBUG, "tape.fd: %d", session.ns_tape.td_fd);
      910 +                syslog(LOG_ERR, "tape.fd: %d", session.ns_tape.td_fd);
 906  911                  (void) close(session.ns_tape.td_fd);
 907  912                  (void) ndmp_open_list_del(session.ns_tape.td_adapter_name,
 908  913                      session.ns_tape.td_sid, session.ns_tape.td_lun);
 909  914          }
 910  915          ndmpd_mover_shut_down(&session);
 911  916          ndmp_lbr_cleanup(&session);
 912  917          ndmpd_data_cleanup(&session);
 913  918          ndmpd_file_history_cleanup(&session, FALSE);
 914  919          ndmpd_mover_cleanup(&session);
 915  920  
 916  921          (void) ndmp_connect_list_del(connection);
 917  922  }
 918  923  
 919  924  
 920  925  /*
 921  926   * connection_file_handler
 922  927   *
 923  928   * ndmp_connection_t file handler function.
 924  929   * Called by ndmpd_select when data is available to be read on the
 925  930   * NDMP connection.
 926  931   *
 927  932   * Parameters:
 928  933   *   cookie (input) - session pointer.
 929  934   *   fd      (input) - connection file descriptor.
 930  935   *   mode    (input) - select mode.
 931  936   *
 932  937   * Returns:
 933  938   *   void.
 934  939   */
 935  940  /*ARGSUSED*/
 936  941  static void
 937  942  connection_file_handler(void *cookie, int fd, ulong_t mode)
 938  943  {
 939  944          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 940  945  
 941  946          if (ndmp_process_requests(session->ns_connection) < 0)
 942  947                  session->ns_eof = TRUE;
 943  948  }
 944  949  
 945  950  
 946  951  /* ************* private functions *************************************** */
 947  952  
 948  953  /*
 949  954   * ndmp_readit
 950  955   *
 951  956   * Low level read routine called by the xdrrec library.
 952  957   *
 953  958   * Parameters:
 954  959   *   connection (input) - connection pointer.
 955  960   *   buf        (input) - location to store received data.
 956  961   *   len        (input) - max number of bytes to read.
 957  962   *
 958  963   * Returns:
 959  964   *   >0 - number of bytes received.
 960  965   *   -1 - error.
 961  966   */
 962  967  static int
 963  968  ndmp_readit(void *connection_handle, caddr_t buf, int len)
 964  969  {
 965  970          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 966  971  
 967  972          len = read(connection->conn_sock, buf, len);
 968  973          if (len <= 0) {
 969  974                  /* ndmp_connection_t has been closed. */
 970  975                  connection->conn_eof = TRUE;
 971  976                  return (-1);
 972  977          }
 973  978          return (len);
 974  979  }
 975  980  
 976  981  /*
 977  982   * ndmp_writeit
 978  983   *
 979  984   * Low level write routine called by the xdrrec library.
 980  985   *
 981  986   * Parameters:
 982  987   *   connection (input) - connection pointer.
 983  988   *   buf        (input) - location to store received data.
 984  989   *   len        (input) - max number of bytes to read.
 985  990   *
 986  991   * Returns:
 987  992   *   >0 - number of bytes sent.
 988  993   *   -1 - error.
 989  994   */
 990  995  static int
 991  996  ndmp_writeit(void *connection_handle, caddr_t buf, int len)
 992  997  {
 993  998          ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
 994  999          register int n;
 995 1000          register int cnt;
 996 1001  
 997 1002          for (cnt = len; cnt > 0; cnt -= n, buf += n) {
 998 1003                  if ((n = write(connection->conn_sock, buf, cnt)) < 0) {
 999 1004                          connection->conn_eof = TRUE;
1000 1005                          return (-1);
1001 1006                  }
1002 1007          }
1003 1008  
1004 1009          return (len);
1005 1010  }
1006 1011  
1007 1012  
1008 1013  /*
1009 1014   * ndmp_recv_msg
1010 1015   *
1011 1016   * Read the next message.
1012 1017   *
1013 1018   * Parameters:
1014 1019   *   connection (input)  - connection pointer.
1015 1020   *   msg        (output) - received message.
1016 1021   *
1017 1022   * Returns:
1018 1023   *   0 - Message successfully received.
1019 1024   *   error number - Message related error.
1020 1025   *  -1 - Error decoding the message header.
1021 1026   */
1022 1027  static int
1023 1028  ndmp_recv_msg(ndmp_connection_t *connection)
1024 1029  {
1025 1030          bool_t(*xdr_func) (XDR *, ...) = NULL;
1026 1031  
  
    | 
      ↓ open down ↓ | 
    111 lines elided | 
    
      ↑ open up ↑ | 
  
1027 1032          /* Decode the header. */
1028 1033          connection->conn_xdrs.x_op = XDR_DECODE;
1029 1034          (void) xdrrec_skiprecord(&connection->conn_xdrs);
1030 1035          if (!xdr_ndmp_header(&connection->conn_xdrs,
1031 1036              &connection->conn_msginfo.mi_hdr))
1032 1037                  return (-1);
1033 1038  
1034 1039          /* Lookup info necessary for processing this message. */
1035 1040          if ((connection->conn_msginfo.mi_handler = ndmp_get_handler(connection,
1036 1041              connection->conn_msginfo.mi_hdr.message)) == 0) {
1037      -                NDMP_LOG(LOG_DEBUG, "Message 0x%x not supported",
     1042 +                syslog(LOG_DEBUG, "Message 0x%x not supported",
1038 1043                      connection->conn_msginfo.mi_hdr.message);
1039 1044                  return (NDMP_NOT_SUPPORTED_ERR);
1040 1045          }
1041 1046          connection->conn_msginfo.mi_body = 0;
1042 1047  
1043 1048          if (connection->conn_msginfo.mi_hdr.error != NDMP_NO_ERR)
1044 1049                  return (0);
1045 1050  
1046 1051          /* Determine body type */
1047 1052          if (connection->conn_msginfo.mi_hdr.message_type ==
1048 1053              NDMP_MESSAGE_REQUEST) {
1049 1054                  if (ndmp_check_auth_required(
1050 1055                      connection->conn_msginfo.mi_hdr.message) &&
1051 1056                      !connection->conn_authorized) {
1052      -                        NDMP_LOG(LOG_DEBUG,
     1057 +                        syslog(LOG_ERR,
1053 1058                              "Processing request 0x%x:connection not authorized",
1054 1059                              connection->conn_msginfo.mi_hdr.message);
1055 1060                          return (NDMP_NOT_AUTHORIZED_ERR);
1056 1061                  }
1057 1062                  if (connection->conn_msginfo.mi_handler->mh_sizeof_request >
1058 1063                      0) {
1059 1064                          xdr_func =
1060 1065                              connection->conn_msginfo.mi_handler->mh_xdr_request;
1061 1066                          if (xdr_func == NULL) {
1062      -                                NDMP_LOG(LOG_DEBUG,
     1067 +                                syslog(LOG_ERR,
1063 1068                                      "Processing request 0x%x: no xdr function "
1064 1069                                      "in handler table",
1065 1070                                      connection->conn_msginfo.mi_hdr.message);
1066 1071                                  return (NDMP_NOT_SUPPORTED_ERR);
1067 1072                          }
1068 1073                          connection->conn_msginfo.mi_body = ndmp_malloc(
1069 1074                              connection->conn_msginfo.mi_handler->
1070 1075                              mh_sizeof_request);
1071 1076                          if (connection->conn_msginfo.mi_body == NULL)
1072 1077                                  return (NDMP_NO_MEM_ERR);
1073 1078  
1074 1079                          (void) memset(connection->conn_msginfo.mi_body, 0,
1075 1080                              connection->conn_msginfo.mi_handler->
1076 1081                              mh_sizeof_request);
1077 1082                  }
1078 1083          } else {
1079 1084                  if (connection->conn_msginfo.mi_handler->mh_sizeof_reply > 0) {
1080 1085                          xdr_func =
1081 1086                              connection->conn_msginfo.mi_handler->mh_xdr_reply;
1082 1087                          if (xdr_func == NULL) {
1083      -                                NDMP_LOG(LOG_DEBUG,
     1088 +                                syslog(LOG_ERR,
1084 1089                                      "Processing reply 0x%x: no xdr function "
1085 1090                                      "in handler table",
1086 1091                                      connection->conn_msginfo.mi_hdr.message);
1087 1092                                  return (NDMP_NOT_SUPPORTED_ERR);
1088 1093                          }
1089 1094                          connection->conn_msginfo.mi_body = ndmp_malloc(
1090 1095                              connection->conn_msginfo.mi_handler->
1091 1096                              mh_sizeof_reply);
1092 1097                          if (connection->conn_msginfo.mi_body == NULL)
1093 1098                                  return (NDMP_NO_MEM_ERR);
1094 1099  
  
    | 
      ↓ open down ↓ | 
    1 lines elided | 
    
      ↑ open up ↑ | 
  
1095 1100                          (void) memset(connection->conn_msginfo.mi_body, 0,
1096 1101                              connection->conn_msginfo.mi_handler->
1097 1102                              mh_sizeof_reply);
1098 1103                  }
1099 1104          }
1100 1105  
1101 1106          /* Decode message arguments if needed */
1102 1107          if (xdr_func) {
1103 1108                  if (!(*xdr_func)(&connection->conn_xdrs,
1104 1109                      connection->conn_msginfo.mi_body)) {
1105      -                        NDMP_LOG(LOG_DEBUG,
1106      -                            "Processing message 0x%x: error decoding arguments",
     1110 +                        syslog(LOG_ERR,
     1111 +                            "Processing %s message 0x%x: "
     1112 +                            "error decoding arguments",
     1113 +                            connection->conn_msginfo.mi_hdr.message_type ==
     1114 +                            NDMP_MESSAGE_REQUEST ?
     1115 +                            "Request" : "Reply",
1107 1116                              connection->conn_msginfo.mi_hdr.message);
1108 1117                          free(connection->conn_msginfo.mi_body);
1109 1118                          connection->conn_msginfo.mi_body = 0;
1110 1119                          return (NDMP_XDR_DECODE_ERR);
1111 1120                  }
1112 1121          }
1113 1122          return (0);
1114 1123  }
1115 1124  
1116 1125  /*
1117 1126   * ndmp_process_messages
1118 1127   *
1119 1128   * Reads the next message into the stream buffer.
1120 1129   * Processes messages until the stream buffer is empty.
1121 1130   *
1122 1131   * This function processes all data in the stream buffer before returning.
1123 1132   * This allows functions like poll() to be used to determine when new
1124 1133   * messages have arrived. If only some of the messages in the stream buffer
1125 1134   * were processed and then poll was called, poll() could block waiting for
1126 1135   * a message that had already been received and read into the stream buffer.
1127 1136   *
1128 1137   * This function processes both request and reply messages.
1129 1138   * Request messages are dispatched using the appropriate function from the
1130 1139   * message handling table.
1131 1140   * Only one reply messages may be pending receipt at a time.
1132 1141   * A reply message, if received, is placed in connection->conn_msginfo
1133 1142   * before returning to the caller.
1134 1143   * Errors are reported if a reply is received but not expected or if
1135 1144   * more than one reply message is received
1136 1145   *
1137 1146   * Parameters:
1138 1147   *   connection     (input)  - connection pointer.
1139 1148   *   reply_expected (output) - TRUE  - a reply message is expected.
1140 1149   *                           FALSE - no reply message is expected and
1141 1150   *                           an error will be reported if a reply
1142 1151   *                           is received.
1143 1152   *
1144 1153   * Returns:
1145 1154   *   NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
1146 1155   *      error processing reply message.
1147 1156   *   NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
1148 1157   *      reply seen.
1149 1158   *   NDMP_PROC_REP_ERR - 1 or more messages successfully processed,
1150 1159   *      no reply seen.
1151 1160   *   NDMP_PROC_REP_ERR - error; connection no longer established.
1152 1161   *
1153 1162   * Notes:
1154 1163   *   If the peer is generating a large number of requests, a caller
1155 1164   *   looking for a reply will be blocked while the requests are handled.
1156 1165   *   This is because this function does not return until the stream
1157 1166   *   buffer is empty.
1158 1167   *   Code needs to be added to allow a return if the stream buffer
1159 1168   *   is not empty but there is data available on the socket. This will
1160 1169   *   prevent poll() from blocking and prevent a caller looking for a reply
  
    | 
      ↓ open down ↓ | 
    44 lines elided | 
    
      ↑ open up ↑ | 
  
1161 1170   *   from getting blocked by a bunch of requests.
1162 1171   */
1163 1172  static int
1164 1173  ndmp_process_messages(ndmp_connection_t *connection, boolean_t reply_expected)
1165 1174  {
1166 1175          msg_info_t reply_msginfo;
1167 1176          boolean_t reply_read = FALSE;
1168 1177          boolean_t reply_error = FALSE;
1169 1178          int err;
1170 1179  
1171      -        NDMP_LOG(LOG_DEBUG, "reply_expected: %s",
1172      -            reply_expected == TRUE ? "TRUE" : "FALSE");
1173      -
1174 1180          (void) memset((void *)&reply_msginfo, 0, sizeof (msg_info_t));
1175 1181  
1176 1182          do {
1177 1183                  (void) memset((void *)&connection->conn_msginfo, 0,
1178 1184                      sizeof (msg_info_t));
1179 1185  
1180 1186                  if ((err = ndmp_recv_msg(connection)) != NDMP_NO_ERR) {
1181 1187                          if (connection->conn_eof) {
1182      -                                NDMP_LOG(LOG_DEBUG, "detected eof");
1183 1188                                  return (NDMP_PROC_ERR);
1184 1189                          }
1185 1190                          if (err < 1) {
1186      -                                NDMP_LOG(LOG_DEBUG, "error decoding header");
     1191 +                                syslog(LOG_ERR, "error decoding header");
1187 1192  
1188 1193                                  /*
1189 1194                                   * Error occurred decoding the header.
1190 1195                                   * Don't send a reply since we don't know
1191 1196                                   * the message or if the message was even
1192 1197                                   * a request message.  To be safe, assume
1193 1198                                   * that the message was a reply if a reply
1194 1199                                   * was expected. Need to do this to prevent
1195 1200                                   * hanging ndmp_send_request() waiting for a
1196 1201                                   * reply.  Don't set reply_read so that the
1197 1202                                   * reply will be processed if it is received
1198 1203                                   * later.
1199 1204                                   */
1200 1205                                  if (reply_read == FALSE)
1201 1206                                          reply_error = TRUE;
1202 1207  
1203 1208                                  continue;
1204 1209                          }
1205 1210                          if (connection->conn_msginfo.mi_hdr.message_type
1206 1211                              != NDMP_MESSAGE_REQUEST) {
1207      -                                NDMP_LOG(LOG_DEBUG, "received reply: 0x%x",
     1212 +                                syslog(LOG_DEBUG, "received reply: 0x%x",
1208 1213                                      connection->conn_msginfo.mi_hdr.message);
1209 1214  
1210 1215                                  if (reply_expected == FALSE ||
1211 1216                                      reply_read == TRUE)
1212      -                                        NDMP_LOG(LOG_DEBUG,
     1217 +                                        syslog(LOG_DEBUG,
1213 1218                                              "Unexpected reply message: 0x%x",
1214 1219                                              connection->conn_msginfo.mi_hdr.
1215 1220                                              message);
1216 1221  
1217 1222                                  ndmp_free_message((ndmp_connection_t *)
1218 1223                                      connection);
1219 1224  
1220 1225                                  if (reply_read == FALSE) {
1221 1226                                          reply_read = TRUE;
1222 1227                                          reply_error = TRUE;
1223 1228                                  }
1224 1229                                  continue;
1225 1230                          }
1226      -                        NDMP_LOG(LOG_DEBUG, "received request: 0x%x",
1227      -                            connection->conn_msginfo.mi_hdr.message);
1228 1231  
1229 1232                          (void) ndmp_send_response((ndmp_connection_t *)
1230 1233                              connection, err, NULL);
1231 1234                          ndmp_free_message((ndmp_connection_t *)connection);
1232 1235                          continue;
1233 1236                  }
1234 1237                  if (connection->conn_msginfo.mi_hdr.message_type
1235 1238                      != NDMP_MESSAGE_REQUEST) {
1236      -                        NDMP_LOG(LOG_DEBUG, "received reply: 0x%x",
     1239 +                        syslog(LOG_DEBUG, "received reply: 0x%x",
1237 1240                              connection->conn_msginfo.mi_hdr.message);
1238 1241  
1239 1242                          if (reply_expected == FALSE || reply_read == TRUE) {
1240      -                                NDMP_LOG(LOG_DEBUG,
     1243 +                                syslog(LOG_DEBUG,
1241 1244                                      "Unexpected reply message: 0x%x",
1242 1245                                      connection->conn_msginfo.mi_hdr.message);
1243 1246                                  ndmp_free_message((ndmp_connection_t *)
1244 1247                                      connection);
1245 1248                                  continue;
1246 1249                          }
1247 1250                          reply_read = TRUE;
1248 1251                          reply_msginfo = connection->conn_msginfo;
1249 1252                          continue;
1250 1253                  }
1251      -                NDMP_LOG(LOG_DEBUG, "received request: 0x%x",
1252      -                    connection->conn_msginfo.mi_hdr.message);
1253      -
1254 1254                  /*
1255 1255                   * The following is needed to catch an improperly constructed
1256 1256                   * handler table or to deal with an NDMP client that is not
1257 1257                   * conforming to the negotiated protocol version.
1258 1258                   */
1259 1259                  if (connection->conn_msginfo.mi_handler->mh_func == NULL) {
1260      -                        NDMP_LOG(LOG_DEBUG, "No handler for message 0x%x",
     1260 +                        syslog(LOG_DEBUG, "No handler for message 0x%x",
1261 1261                              connection->conn_msginfo.mi_hdr.message);
1262 1262  
1263 1263                          (void) ndmp_send_response((ndmp_connection_t *)
1264 1264                              connection, NDMP_NOT_SUPPORTED_ERR, NULL);
1265 1265                          ndmp_free_message((ndmp_connection_t *)connection);
1266 1266                          continue;
1267 1267                  }
1268 1268                  /*
1269 1269                   * Call the handler function.
1270 1270                   * The handler will send any necessary reply.
1271 1271                   */
1272 1272                  (*connection->conn_msginfo.mi_handler->mh_func) (connection,
1273 1273                      connection->conn_msginfo.mi_body);
1274 1274  
1275 1275                  ndmp_free_message((ndmp_connection_t *)connection);
1276 1276  
1277 1277          } while (xdrrec_eof(&connection->conn_xdrs) == FALSE &&
1278 1278              connection->conn_eof == FALSE);
1279 1279  
1280      -        NDMP_LOG(LOG_DEBUG, "no more messages in stream buffer");
1281      -
1282 1280          if (connection->conn_eof == TRUE) {
1283 1281                  if (reply_msginfo.mi_body)
1284 1282                          free(reply_msginfo.mi_body);
1285 1283                  return (NDMP_PROC_ERR);
1286 1284          }
1287 1285          if (reply_error) {
1288 1286                  if (reply_msginfo.mi_body)
1289 1287                          free(reply_msginfo.mi_body);
1290 1288                  return (NDMP_PROC_REP_ERR);
1291 1289          }
1292 1290          if (reply_read) {
1293 1291                  connection->conn_msginfo = reply_msginfo;
1294 1292                  return (NDMP_PROC_MSG);
1295 1293          }
1296 1294          return (NDMP_PROC_REP);
1297 1295  }
1298 1296  
1299 1297  
1300 1298  /*
1301 1299   * ndmp_get_interface
1302 1300   *
1303 1301   * Return the NDMP interface (e.g. config, scsi, tape) for the
1304 1302   * specific message.
1305 1303   *
1306 1304   * Parameters:
1307 1305   *   message (input) - message number.
1308 1306   *
1309 1307   * Returns:
1310 1308   *   NULL - message not found.
1311 1309   *   pointer to handler info.
1312 1310   */
1313 1311  static ndmp_handler_t *
1314 1312  ndmp_get_interface(ndmp_message message)
1315 1313  {
1316 1314          ndmp_handler_t *ni = &ndmp_msghdl_tab[(message >> 8) % INT_MAXCMD];
1317 1315  
1318 1316          if ((message & 0xff) >= ni->hd_cnt)
1319 1317                  return (NULL);
1320 1318  
1321 1319          /* Sanity check */
1322 1320          if (ni->hd_msgs[message & 0xff].hm_message != message)
1323 1321                  return (NULL);
1324 1322  
1325 1323          return (ni);
1326 1324  }
1327 1325  
1328 1326  /*
1329 1327   * ndmp_get_handler
1330 1328   *
1331 1329   * Return the handler info for the specified NDMP message.
1332 1330   *
1333 1331   * Parameters:
1334 1332   *   connection (input) - connection pointer.
1335 1333   *   message (input) - message number.
1336 1334   *
1337 1335   * Returns:
1338 1336   *   NULL - message not found.
1339 1337   *   pointer to handler info.
1340 1338   */
1341 1339  static ndmp_msg_handler_t *
1342 1340  ndmp_get_handler(ndmp_connection_t *connection, ndmp_message message)
1343 1341  {
1344 1342          ndmp_msg_handler_t *handler = NULL;
1345 1343  
1346 1344          ndmp_handler_t *ni = ndmp_get_interface(message);
1347 1345          int ver = connection->conn_version;
1348 1346  
1349 1347          if (ni)
1350 1348                  handler = &ni->hd_msgs[message & 0xff].hm_msg_v[ver - 2];
1351 1349  
1352 1350          return (handler);
1353 1351  }
1354 1352  
1355 1353  /*
1356 1354   * ndmp_check_auth_required
1357 1355   *
1358 1356   * Check if the connection needs to be authenticated before
1359 1357   * this message is being processed.
1360 1358   *
1361 1359   * Parameters:
1362 1360   *   message (input) - message number.
1363 1361   *
1364 1362   * Returns:
1365 1363   *   TRUE - required
1366 1364   *   FALSE - not required
1367 1365   */
1368 1366  static boolean_t
1369 1367  ndmp_check_auth_required(ndmp_message message)
1370 1368  {
1371 1369          boolean_t auth_req = FALSE;
1372 1370          ndmp_handler_t *ni = ndmp_get_interface(message);
1373 1371  
1374 1372          if (ni)
1375 1373                  auth_req = ni->hd_msgs[message & 0xff].hm_auth_required;
1376 1374  
1377 1375          return (auth_req);
1378 1376  }
1379 1377  
1380 1378  /*
1381 1379   * tcp_accept
1382 1380   *
1383 1381   * A wrapper around accept for retrying and getting the IP address
1384 1382   *
1385 1383   * Parameters:
1386 1384   *   listen_sock (input) - the socket for listening
1387 1385   *   inaddr_p (output) - the IP address of peer connection
1388 1386   *
1389 1387   * Returns:
1390 1388   *   socket for the accepted connection
1391 1389   *   -1: error
1392 1390   */
1393 1391  int
1394 1392  tcp_accept(int listen_sock, unsigned int *inaddr_p)
1395 1393  {
1396 1394          struct sockaddr_in      sin;
1397 1395          int                     sock, i;
1398 1396          int                     try;
1399 1397  
1400 1398          for (try = 0; try < 3; try++) {
1401 1399                  i = sizeof (sin);
1402 1400                  sock = accept(listen_sock, (struct sockaddr *)&sin, &i);
1403 1401                  if (sock < 0) {
1404 1402                          continue;
1405 1403                  }
1406 1404                  *inaddr_p = sin.sin_addr.s_addr;
1407 1405                  return (sock);
1408 1406          }
1409 1407          return (-1);
1410 1408  }
1411 1409  
1412 1410  
1413 1411  /*
1414 1412   * tcp_get_peer
1415 1413   *
1416 1414   * Get the peer IP address for a connection
1417 1415   *
1418 1416   * Parameters:
1419 1417   *   sock (input) - the active socket
1420 1418   *   inaddr_p (output) - the IP address of peer connection
1421 1419   *   port_p (output) - the port number of peer connection
1422 1420   *
1423 1421   * Returns:
1424 1422   *   socket for the accepted connection
1425 1423   *   -1: error
1426 1424   */
1427 1425  int
1428 1426  tcp_get_peer(int sock, unsigned int *inaddr_p, int *port_p)
1429 1427  {
1430 1428          struct sockaddr_in sin;
1431 1429          int i, rc;
1432 1430  
1433 1431          i = sizeof (sin);
1434 1432          rc = getpeername(sock, (struct sockaddr *)&sin, &i);
1435 1433          if (rc != 0)
1436 1434                  return (-1);
1437 1435  
1438 1436          if (inaddr_p)
1439 1437                  *inaddr_p = sin.sin_addr.s_addr;
1440 1438  
1441 1439          if (port_p)
1442 1440                  *port_p = ntohs(sin.sin_port);
1443 1441  
1444 1442          return (sock);
1445 1443  
1446 1444  }
1447 1445  
1448 1446  /*
1449 1447   * gethostaddr
1450 1448   *
1451 1449   * Get the IP address string of the current host
1452 1450   *
1453 1451   * Parameters:
1454 1452   *   void
1455 1453   *
1456 1454   * Returns:
1457 1455   *   IP address
1458 1456   *   NULL: error
1459 1457   */
1460 1458  char *
1461 1459  gethostaddr(void)
1462 1460  {
1463 1461          static char s[MAXHOSTNAMELEN];
1464 1462          struct hostent *h;
1465 1463          struct in_addr in;
1466 1464          char *p;
1467 1465  
1468 1466          if (gethostname(s, sizeof (s)) == -1)
1469 1467                  return (NULL);
1470 1468  
1471 1469          if ((h = gethostbyname(s)) == NULL)
1472 1470                  return (NULL);
1473 1471  
1474 1472          p = h->h_addr_list[0];
1475 1473          (void) memcpy(&in.s_addr, p, sizeof (in.s_addr));
1476 1474          return (inet_ntoa(in));
1477 1475  }
1478 1476  
1479 1477  
1480 1478  /*
1481 1479   * get_default_nic_addr
1482 1480   *
1483 1481   * Get the IP address of the default NIC
1484 1482   */
1485 1483  char *
1486 1484  get_default_nic_addr(void)
1487 1485  {
1488 1486          struct ifaddrlist *al = NULL;
1489 1487          char errmsg[ERRBUFSIZE];
1490 1488          struct in_addr addr;
1491 1489          int nifs;
1492 1490  
1493 1491          nifs = ifaddrlist(&al, AF_INET, LIFC_EXTERNAL_SOURCE, errmsg);
1494 1492          if (nifs <= 0)
1495 1493                  return (NULL);
1496 1494  
1497 1495          /* pick the first interface's address */
1498 1496          addr = al[0].addr.addr;
1499 1497          free(al);
1500 1498  
1501 1499          return (inet_ntoa(IN_ADDR(addr.s_addr)));
1502 1500  }
1503 1501  
1504 1502  
1505 1503  /*
1506 1504   * ndmpd_audit_backup
1507 1505   *
  
    | 
      ↓ open down ↓ | 
    216 lines elided | 
    
      ↑ open up ↑ | 
  
1508 1506   * Generate AUE_ndmp_backup audit record
1509 1507   */
1510 1508  /*ARGSUSED*/
1511 1509  void
1512 1510  ndmpd_audit_backup(ndmp_connection_t *conn,
1513 1511      char *path, int dest, char *local_path, int result)
1514 1512  {
1515 1513          adt_event_data_t *event;
1516 1514  
1517 1515          if ((event = adt_alloc_event(conn->conn_ah, ADT_ndmp_backup)) == NULL) {
1518      -                NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1516 +                syslog(LOG_ERR, "Audit failure: %m.");
1519 1517                  return;
1520 1518          }
1521 1519          event->adt_ndmp_backup.source = path;
1522 1520  
1523 1521          if (dest == NDMP_ADDR_LOCAL) {
1524 1522                  event->adt_ndmp_backup.local_dest = local_path;
1525 1523          } else {
1526 1524                  event->adt_ndmp_backup.remote_dest = conn->conn_sock;
1527 1525          }
1528 1526  
1529 1527          if (result == 0) {
1530 1528                  if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
1531      -                        NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1529 +                        syslog(LOG_ERR, "Audit failure: %m.");
1532 1530          } else {
1533 1531                  if (adt_put_event(event, ADT_FAILURE, result) != 0)
1534      -                        NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1532 +                        syslog(LOG_ERR, "Audit failure: %m.");
1535 1533          }
1536 1534  
1537 1535          adt_free_event(event);
1538 1536  }
1539 1537  
1540 1538  
1541 1539  /*
1542 1540   * ndmpd_audit_restore
1543 1541   *
1544 1542   * Generate AUE_ndmp_restore audit record
1545 1543   */
1546 1544  /*ARGSUSED*/
1547 1545  void
1548 1546  ndmpd_audit_restore(ndmp_connection_t *conn,
1549 1547      char *path, int dest, char *local_path, int result)
1550 1548  {
1551 1549          adt_event_data_t *event;
1552 1550  
1553 1551          if ((event = adt_alloc_event(conn->conn_ah,
1554 1552              ADT_ndmp_restore)) == NULL) {
1555      -                NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1553 +                syslog(LOG_ERR, "Audit failure: %m.");
1556 1554                  return;
1557 1555          }
1558 1556          event->adt_ndmp_restore.destination = path;
1559 1557  
1560 1558          if (dest == NDMP_ADDR_LOCAL) {
1561 1559                  event->adt_ndmp_restore.local_source = local_path;
1562 1560          } else {
1563 1561                  event->adt_ndmp_restore.remote_source = conn->conn_sock;
1564 1562          }
1565 1563  
1566 1564          if (result == 0) {
1567 1565                  if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
1568      -                        NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1566 +                        syslog(LOG_ERR, "Audit failure: %m.");
1569 1567          } else {
1570 1568                  if (adt_put_event(event, ADT_FAILURE, result) != 0)
1571      -                        NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1569 +                        syslog(LOG_ERR, "Audit failure: %m.");
1572 1570          }
1573 1571  
1574 1572          adt_free_event(event);
1575 1573  }
1576 1574  
1577 1575  
1578 1576  /*
1579 1577   * ndmpd_audit_connect
1580 1578   *
1581 1579   * Generate AUE_ndmp_connect audit record
1582 1580   */
1583 1581  /*ARGSUSED*/
1584 1582  void
1585 1583  ndmpd_audit_connect(ndmp_connection_t *conn, int result)
1586 1584  {
1587 1585          adt_event_data_t *event;
1588 1586          adt_termid_t *termid;
1589 1587  
1590 1588          if (adt_load_termid(conn->conn_sock, &termid) != 0) {
1591      -                NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1589 +                syslog(LOG_ERR, "Audit failure: %m.");
1592 1590                  return;
1593 1591          }
1594 1592  
1595 1593          if (adt_set_user(conn->conn_ah, ADT_NO_ATTRIB, ADT_NO_ATTRIB,
1596 1594              ADT_NO_ATTRIB, ADT_NO_ATTRIB, termid, ADT_NEW) != 0) {
1597      -                NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1595 +                syslog(LOG_ERR, "Audit failure: %m.");
1598 1596                  free(termid);
1599 1597                  return;
1600 1598          }
1601 1599          free(termid);
1602 1600  
1603 1601          if ((event = adt_alloc_event(conn->conn_ah,
1604 1602              ADT_ndmp_connect)) == NULL) {
1605      -                NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1603 +                syslog(LOG_ERR, "Audit failure: %m.");
1606 1604                  return;
1607 1605          }
1608 1606  
1609 1607          if (result == 0) {
1610 1608                  if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
1611      -                        NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1609 +                        syslog(LOG_ERR, "Audit failure: %m.");
1612 1610          } else {
1613 1611                  if (adt_put_event(event, ADT_FAILURE, result) != 0)
1614      -                        NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1612 +                        syslog(LOG_ERR, "Audit failure: %m.");
1615 1613          }
1616 1614  
1617 1615          adt_free_event(event);
1618 1616  }
1619 1617  
1620 1618  
1621 1619  /*
1622 1620   * ndmpd_audit_disconnect
1623 1621   *
1624 1622   * Generate AUE_ndmp_disconnect audit record
1625 1623   */
1626 1624  /*ARGSUSED*/
1627 1625  void
1628 1626  ndmpd_audit_disconnect(ndmp_connection_t *conn)
1629 1627  {
1630 1628          adt_event_data_t *event;
1631 1629  
1632 1630          if ((event = adt_alloc_event(conn->conn_ah,
1633 1631              ADT_ndmp_disconnect)) == NULL) {
1634      -                NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1632 +                syslog(LOG_ERR, "Audit failure: %m.");
1635 1633                  return;
1636 1634          }
1637 1635          if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
1638      -                NDMP_LOG(LOG_ERR, "Audit failure: %m.");
     1636 +                syslog(LOG_ERR, "Audit failure: %m.");
1639 1637  
1640 1638          adt_free_event(event);
1641 1639  }
1642 1640  
1643 1641  void *
1644 1642  ndmp_malloc(size_t size)
1645 1643  {
1646 1644          void *data;
1647 1645  
1648 1646          if ((data = calloc(1, size)) == NULL) {
1649      -                NDMP_LOG(LOG_ERR, "Out of memory.");
     1647 +                syslog(LOG_ERR, "Out of memory.");
1650 1648          }
1651 1649  
1652 1650          return (data);
1653 1651  }
1654 1652  
1655 1653  /*
1656 1654   * get_backup_path_v3
1657 1655   *
1658 1656   * Get the backup path from the NDMP environment variables.
1659 1657   *
1660 1658   * Parameters:
1661 1659   *   params (input) - pointer to the parameters structure.
1662 1660   *
1663 1661   * Returns:
1664 1662   *   The backup path: if anything is specified
1665 1663   *   NULL: Otherwise
1666 1664   */
1667 1665  char *
1668 1666  get_backup_path_v3(ndmpd_module_params_t *params)
1669 1667  {
1670 1668          char *bkpath;
  
    | 
      ↓ open down ↓ | 
    11 lines elided | 
    
      ↑ open up ↑ | 
  
1671 1669  
1672 1670          bkpath = MOD_GETENV(params, "PREFIX");
1673 1671          if (!bkpath)
1674 1672                  bkpath = MOD_GETENV(params, "FILESYSTEM");
1675 1673  
1676 1674  
1677 1675          if (!bkpath) {
1678 1676                  MOD_LOGV3(params, NDMP_LOG_ERROR,
1679 1677                      "Backup path not defined.\n");
1680 1678          } else {
1681      -                NDMP_LOG(LOG_DEBUG, "bkpath: \"%s\"", bkpath);
     1679 +                syslog(LOG_DEBUG, "bkpath: \"%s\"", bkpath);
1682 1680          }
1683 1681  
1684 1682          return (bkpath);
1685 1683  }
1686 1684  
1687 1685  /*
1688 1686   * get_backup_path
1689 1687   *
1690 1688   * Find the backup path from the environment variables (v2)
1691 1689   */
1692 1690  char *
1693 1691  get_backup_path_v2(ndmpd_module_params_t *params)
1694 1692  {
1695 1693          char *bkpath;
1696 1694  
1697 1695          bkpath = MOD_GETENV(params, "PREFIX");
1698 1696          if (bkpath == NULL)
1699 1697                  bkpath = MOD_GETENV(params, "FILESYSTEM");
1700 1698  
1701 1699          if (bkpath == NULL) {
1702 1700                  MOD_LOG(params, "Error: restore path not specified.\n");
1703 1701                  return (NULL);
1704 1702          }
1705 1703  
1706 1704          if (*bkpath != '/') {
1707 1705                  MOD_LOG(params, "Error: relative backup path not allowed.\n");
1708 1706                  return (NULL);
1709 1707          }
1710 1708  
1711 1709          return (bkpath);
1712 1710  }
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX