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-2690 NDMP V4 required to have Record size is persistent between mover connections and state transitions
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-727 Netbackup Catalog verification hangs waiting for NDMP server
NEX-799 past last file mark returned NDMP_IO_ERR, should be NDMP_EOM_ERR (V4+)
NEX-812 NDMP backup terminate after hit the EOM in Netbackup backup
NEX-559 NDMP cannot backup/restore a file which spans multiple tapes
SUP-484 NDMP backup jobs error out when reaching the end of media (EOM)
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
          +++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
   1    1  /*
   2    2   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
   3    3   */
   4    4  
   5    5  /*
   6    6   * BSD 3 Clause License
   7    7   *
   8    8   * Copyright (c) 2007, The Storage Networking Industry Association.
   9    9   *
  10   10   * Redistribution and use in source and binary forms, with or without
  11   11   * modification, are permitted provided that the following conditions
  12   12   * are met:
  13   13   *      - Redistributions of source code must retain the above copyright
  14   14   *        notice, this list of conditions and the following disclaimer.
  15   15   *
  16   16   *      - Redistributions in binary form must reproduce the above copyright
  17   17   *        notice, this list of conditions and the following disclaimer in
  18   18   *        the documentation and/or other materials provided with the
  19   19   *        distribution.
  20   20   *
  21   21   *      - Neither the name of The Storage Networking Industry Association (SNIA)
  22   22   *        nor the names of its contributors may be used to endorse or promote
  23   23   *        products derived from this software without specific prior written
  24   24   *        permission.
  25   25   *
  26   26   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27   27   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28   28   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29   29   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  
    | 
      ↓ 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/ioctl.h>
  43   43  #include <sys/types.h>
  44   44  #include <sys/socket.h>
  45   45  #include <sys/socketvar.h>
       46 +#include <syslog.h>
  46   47  #include <netinet/in.h>
  47   48  #include <arpa/inet.h>
  48   49  #include <net/if.h>
  49   50  #include <errno.h>
  50   51  #include <fcntl.h>
  51   52  #include <netdb.h>
  52   53  #include <stdlib.h>
  53   54  #include <unistd.h>
  54   55  #include <string.h>
  55   56  #include "ndmpd_common.h"
  56   57  #include "ndmpd.h"
  57   58  #include <sys/mtio.h>
  58   59  
  59   60  /*
  60   61   * Maximum mover record size
  61   62   */
  62   63  #define MAX_MOVER_RECSIZE       (512*KILOBYTE)
  63   64  
  64   65  static int create_listen_socket_v2(ndmpd_session_t *session, ulong_t *addr,
  65   66      ushort_t *port);
  66   67  static int tape_read(ndmpd_session_t *session, char *data);
  67   68  static int change_tape(ndmpd_session_t *session);
  68   69  static int discard_data(ndmpd_session_t *session, ulong_t length);
  69   70  static int mover_tape_read_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf);
  70   71  static int mover_socket_write_one_buf(ndmpd_session_t *session,
  71   72      tlm_buffer_t *buf);
  72   73  static int start_mover_for_restore(ndmpd_session_t *session);
  73   74  static int mover_socket_read_one_buf(ndmpd_session_t *session,
  74   75      tlm_buffer_t *buf, long read_size);
  75   76  static int mover_tape_write_one_buf(ndmpd_session_t *session,
  76   77      tlm_buffer_t *buf);
  77   78  static int start_mover_for_backup(ndmpd_session_t *session);
  78   79  static boolean_t is_writer_running_v3(ndmpd_session_t *session);
  79   80  static int mover_pause_v3(ndmpd_session_t *session,
  80   81      ndmp_mover_pause_reason reason);
  81   82  static int mover_tape_write_v3(ndmpd_session_t *session, char *data,
  82   83      ssize_t length);
  83   84  static int mover_tape_flush_v3(ndmpd_session_t *session);
  84   85  static int mover_tape_read_v3(ndmpd_session_t *session, char *data);
  85   86  static int create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr,
  86   87      ushort_t *port);
  87   88  static void mover_data_read_v3(void *cookie, int fd, ulong_t mode);
  88   89  static void accept_connection(void *cookie, int fd, ulong_t mode);
  89   90  static void mover_data_write_v3(void *cookie, int fd, ulong_t mode);
  90   91  static void accept_connection_v3(void *cookie, int fd, ulong_t mode);
  91   92  static ndmp_error mover_connect_sock(ndmpd_session_t *session,
  92   93      ndmp_mover_mode mode, ulong_t addr, ushort_t port);
  93   94  static boolean_t is_writer_running(ndmpd_session_t *session);
  94   95  static int set_socket_nonblock(int sock);
  95   96  
  96   97  
  97   98  int ndmp_max_mover_recsize = MAX_MOVER_RECSIZE; /* patchable */
  98   99  
  99  100  #define TAPE_READ_ERR           -1
 100  101  #define TAPE_NO_WRITER_ERR      -2
 101  102  
 102  103  /*
 103  104   * Set non-blocking mode for socket.
 104  105   */
 105  106  static int
 106  107  set_socket_nonblock(int sock)
 107  108  {
 108  109          int flags;
 109  110  
 110  111          flags = fcntl(sock, F_GETFL, 0);
 111  112          if (flags < 0)
 112  113                  return (0);
 113  114          return (fcntl(sock, F_SETFL, flags|O_NONBLOCK) == 0);
 114  115  }
 115  116  
 116  117  /*
 117  118   * ************************************************************************
 118  119   * NDMP V2 HANDLERS
 119  120   * ************************************************************************
 120  121   */
 121  122  
 122  123  /*
 123  124   * ndmpd_mover_get_state_v2
 124  125   *
 125  126   * This handler handles the mover_get_state request.
 126  127   * Status information for the mover state machine is returned.
 127  128   *
 128  129   * Parameters:
 129  130   *   connection (input) - connection handle.
 130  131   *   body       (input) - request message body.
 131  132   *
 132  133   * Returns:
 133  134   *   void
 134  135   */
 135  136  /*ARGSUSED*/
 136  137  void
 137  138  ndmpd_mover_get_state_v2(ndmp_connection_t *connection, void *body)
 138  139  {
 139  140          ndmp_mover_get_state_reply_v2 reply;
 140  141          ndmpd_session_t *session = ndmp_get_client_data(connection);
 141  142  
 142  143          reply.error = NDMP_NO_ERR;
 143  144          reply.state = session->ns_mover.md_state;
 144  145          reply.pause_reason = session->ns_mover.md_pause_reason;
 145  146          reply.halt_reason = session->ns_mover.md_halt_reason;
 146  147          reply.record_size = session->ns_mover.md_record_size;
 147  148          reply.record_num = session->ns_mover.md_record_num;
 148  149          reply.data_written =
 149  150              long_long_to_quad(session->ns_mover.md_data_written);
 150  151          reply.seek_position =
 151  152              long_long_to_quad(session->ns_mover.md_seek_position);
 152  153          reply.bytes_left_to_read =
 153  154              long_long_to_quad(session->ns_mover.md_bytes_left_to_read);
 154  155          reply.window_offset =
 155  156              long_long_to_quad(session->ns_mover.md_window_offset);
 156  157          reply.window_length =
 157  158              long_long_to_quad(session->ns_mover.md_window_length);
 158  159  
 159  160          ndmp_send_reply(connection, (void *) &reply,
 160  161              "sending tape_get_state reply");
 161  162  }
 162  163  
 163  164  
 164  165  /*
 165  166   * ndmpd_mover_listen_v2
 166  167   *
 167  168   * This handler handles mover_listen requests.
 168  169   *
 169  170   * Parameters:
 170  171   *   connection (input) - connection handle.
 171  172   *   body       (input) - request message body.
 172  173   *
 173  174   * Returns:
 174  175   *   void
 175  176   */
 176  177  void
 177  178  ndmpd_mover_listen_v2(ndmp_connection_t *connection, void *body)
 178  179  {
  
    | 
      ↓ open down ↓ | 
    123 lines elided | 
    
      ↑ open up ↑ | 
  
 179  180          ndmp_mover_listen_request_v2 *request;
 180  181          ndmp_mover_listen_reply_v2 reply;
 181  182          ndmpd_session_t *session = ndmp_get_client_data(connection);
 182  183          ulong_t addr;
 183  184          ushort_t port;
 184  185  
 185  186          request = (ndmp_mover_listen_request_v2 *)body;
 186  187  
 187  188          if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE ||
 188  189              session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
 189      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 190  190                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 191  191                  ndmp_send_reply(connection, (void *) &reply,
 192  192                      "sending mover_listen reply");
 193  193                  return;
 194  194          }
 195  195          session->ns_mover.md_mode = request->mode;
 196  196  
 197  197          if (request->addr_type == NDMP_ADDR_LOCAL) {
 198  198                  reply.mover.addr_type = NDMP_ADDR_LOCAL;
 199  199          } else {
 200  200                  if (create_listen_socket_v2(session, &addr, &port) < 0) {
 201  201                          reply.error = NDMP_IO_ERR;
 202  202                          ndmp_send_reply(connection, (void *) &reply,
 203  203                              "sending mover_listen reply");
 204  204                          return;
 205  205                  }
 206  206                  reply.mover.addr_type = NDMP_ADDR_TCP;
 207  207                  reply.mover.ndmp_mover_addr_u.addr.ip_addr = htonl(addr);
 208  208                  reply.mover.ndmp_mover_addr_u.addr.port = htons(port);
 209  209          }
 210  210  
 211  211          session->ns_mover.md_state = NDMP_MOVER_STATE_LISTEN;
 212  212  
 213  213          /*
 214  214           * ndmp window should always set by client during restore
 215  215           */
 216  216  
 217  217          /* Set the default window. */
 218  218          session->ns_mover.md_window_offset = 0;
 219  219          session->ns_mover.md_window_length = MAX_WINDOW_SIZE;
 220  220          session->ns_mover.md_position = 0;
 221  221  
 222  222          reply.error = NDMP_NO_ERR;
 223  223          ndmp_send_reply(connection, (void *) &reply,
 224  224              "sending mover_listen reply");
 225  225  }
 226  226  
 227  227  
 228  228  /*
 229  229   * ndmpd_mover_continue_v2
 230  230   *
 231  231   * This handler handles mover_continue requests.
 232  232   *
 233  233   * Parameters:
 234  234   *   connection (input) - connection handle.
 235  235   *   body       (input) - request message body.
 236  236   *
 237  237   * Returns:
  
    | 
      ↓ open down ↓ | 
    38 lines elided | 
    
      ↑ open up ↑ | 
  
 238  238   *   void
 239  239   */
 240  240  /*ARGSUSED*/
 241  241  void
 242  242  ndmpd_mover_continue_v2(ndmp_connection_t *connection, void *body)
 243  243  {
 244  244          ndmp_mover_continue_reply reply;
 245  245          ndmpd_session_t *session = ndmp_get_client_data(connection);
 246  246  
 247  247          if (session->ns_mover.md_state != NDMP_MOVER_STATE_PAUSED) {
 248      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 249  248  
 250  249                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 251  250                  ndmp_send_reply(connection, (void *) &reply,
 252  251                      "sending mover_continue reply");
 253  252                  return;
 254  253          }
 255  254          session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
 256  255          reply.error = NDMP_NO_ERR;
 257  256          ndmp_send_reply(connection, (void *) &reply,
 258  257              "sending mover_continue reply");
 259  258  }
 260  259  
 261  260  
 262  261  /*
 263  262   * ndmpd_mover_abort_v2
 264  263   *
 265  264   * This handler handles mover_abort requests.
 266  265   *
 267  266   * Parameters:
 268  267   *   connection (input) - connection handle.
 269  268   *   body       (input) - request message body.
 270  269   *
 271  270   * Returns:
 272  271   *   void
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
 273  272   */
 274  273  /*ARGSUSED*/
 275  274  void
 276  275  ndmpd_mover_abort_v2(ndmp_connection_t *connection, void *body)
 277  276  {
 278  277          ndmp_mover_abort_reply reply;
 279  278          ndmpd_session_t *session = ndmp_get_client_data(connection);
 280  279  
 281  280          if (session->ns_mover.md_state == NDMP_MOVER_STATE_IDLE ||
 282  281              session->ns_mover.md_state == NDMP_MOVER_STATE_HALTED) {
 283      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 284  282  
 285  283                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 286  284                  ndmp_send_reply(connection, (void *) &reply,
 287  285                      "sending mover_abort reply");
 288  286                  return;
 289  287          }
 290  288  
 291  289          reply.error = NDMP_NO_ERR;
 292  290          ndmp_send_reply(connection, (void *) &reply,
 293  291              "sending mover_abort reply");
 294  292  
 295  293          ndmpd_mover_error(session, NDMP_MOVER_HALT_ABORTED);
 296  294          ndmp_stop_buffer_worker(session);
 297  295  }
 298  296  
 299  297  
 300  298  /*
 301  299   * ndmpd_mover_stop_v2
 302  300   *
 303  301   * This handler handles mover_stop requests.
 304  302   *
 305  303   * Parameters:
 306  304   *   connection (input) - connection handle.
 307  305   *   body       (input) - request message body.
 308  306   *
 309  307   * Returns:
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
 310  308   *   void
 311  309   */
 312  310  /*ARGSUSED*/
 313  311  void
 314  312  ndmpd_mover_stop_v2(ndmp_connection_t *connection, void *body)
 315  313  {
 316  314          ndmp_mover_stop_reply reply;
 317  315          ndmpd_session_t *session = ndmp_get_client_data(connection);
 318  316  
 319  317          if (session->ns_mover.md_state != NDMP_MOVER_STATE_HALTED) {
 320      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 321  318  
 322  319                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 323  320                  ndmp_send_reply(connection, (void *) &reply,
 324  321                      "sending mover_stop reply");
 325  322                  return;
 326  323          }
 327  324  
 328  325          ndmp_waitfor_op(session);
 329  326          reply.error = NDMP_NO_ERR;
 330  327          ndmp_send_reply(connection, (void *) &reply,
 331  328              "sending mover_stop reply");
 332  329  
 333  330          ndmp_lbr_cleanup(session);
 334  331          ndmpd_mover_cleanup(session);
 335  332          (void) ndmpd_mover_init(session);
 336  333          (void) ndmp_lbr_init(session);
 337  334  }
 338  335  
 339  336  
 340  337  /*
 341  338   * ndmpd_mover_set_window_v2
 342  339   *
 343  340   * This handler handles mover_set_window requests.
 344  341   *
 345  342   *
 346  343   * Parameters:
 347  344   *   connection (input) - connection handle.
 348  345   *   body       (input) - request message body.
 349  346   *
 350  347   * Returns:
 351  348   *   void
 352  349   */
 353  350  void
 354  351  ndmpd_mover_set_window_v2(ndmp_connection_t *connection, void *body)
 355  352  {
 356  353          ndmp_mover_set_window_request *request;
 357  354          ndmp_mover_set_window_reply reply;
 358  355          ndmpd_session_t *session = ndmp_get_client_data(connection);
 359  356  
 360  357          request = (ndmp_mover_set_window_request *) body;
 361  358  
 362  359          /*
  
    | 
      ↓ open down ↓ | 
    32 lines elided | 
    
      ↑ open up ↑ | 
  
 363  360           * The NDMPv2 specification states that "a window can be set only
 364  361           * when in the listen or paused state."
 365  362           *
 366  363           * See the comment in ndmpd_mover_set_window_v3 regarding the reason for
 367  364           * allowing it in the idle state as well.
 368  365           */
 369  366          if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE &&
 370  367              session->ns_mover.md_state != NDMP_MOVER_STATE_PAUSED &&
 371  368              session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN) {
 372  369                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 373      -                NDMP_LOG(LOG_DEBUG, "Invalid state %d",
 374      -                    session->ns_mover.md_state);
 375  370          } else {
 376  371                  if (quad_to_long_long(request->length) == 0) {
 377  372                          reply.error = NDMP_ILLEGAL_ARGS_ERR;
 378      -                        NDMP_LOG(LOG_DEBUG, "Invalid window size %d",
      373 +                        syslog(LOG_ERR, "Illegal window size %d",
 379  374                              quad_to_long_long(request->length));
 380  375                  } else {
 381  376                          reply.error = NDMP_NO_ERR;
 382  377                          session->ns_mover.md_window_offset =
 383  378                              quad_to_long_long(request->offset);
 384  379                          session->ns_mover.md_window_length =
 385  380                              quad_to_long_long(request->length);
 386  381                          session->ns_mover.md_position =
 387  382                              session->ns_mover.md_window_offset;
 388  383                  }
 389  384          }
 390  385  
 391  386          ndmp_send_reply(connection, (void *) &reply,
 392  387              "sending mover_set_window reply");
 393  388  }
 394  389  
 395  390  
 396  391  /*
 397  392   * ndmpd_mover_read_v2
 398  393   *
 399  394   * This handler handles mover_read requests. If the requested offset is
 400  395   * outside of the current window, the mover is paused and a notify_mover_paused
 401  396   * request is sent notifying the client that a seek is required. If the
 402  397   * requested offest is within the window but not within the current record,
 403  398   * then the tape is positioned to the record containing the requested offest.
 404  399   * The requested amount of data is then read from the tape device and written
 405  400   * to the data connection.
 406  401   *
 407  402   * Parameters:
 408  403   *   connection (input) - connection handle.
 409  404   *   body       (input) - request message body.
 410  405   *
 411  406   * Returns:
 412  407   *   void
 413  408   */
 414  409  void
  
    | 
      ↓ open down ↓ | 
    26 lines elided | 
    
      ↑ open up ↑ | 
  
 415  410  ndmpd_mover_read_v2(ndmp_connection_t *connection, void *body)
 416  411  {
 417  412          ndmp_mover_read_request *request = (ndmp_mover_read_request *) body;
 418  413          ndmp_mover_read_reply reply;
 419  414          ndmpd_session_t *session = ndmp_get_client_data(connection);
 420  415          int err;
 421  416  
 422  417          if (session->ns_mover.md_state != NDMP_MOVER_STATE_ACTIVE ||
 423  418              session->ns_mover.md_bytes_left_to_read != 0 ||
 424  419              session->ns_mover.md_mode != NDMP_MOVER_MODE_WRITE) {
 425      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 426  420                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 427  421                  ndmp_send_reply(connection, &reply,
 428  422                      "sending mover_read reply");
 429  423                  return;
 430  424          }
 431  425          if (session->ns_tape.td_fd == -1) {
 432      -                NDMP_LOG(LOG_DEBUG, "Tape device is not open");
      426 +                syslog(LOG_ERR, "Tape device is not open");
 433  427                  reply.error = NDMP_DEV_NOT_OPEN_ERR;
 434  428                  ndmp_send_reply(connection, &reply,
 435  429                      "sending mover_read reply");
 436  430                  return;
 437  431          }
 438  432  
 439  433          reply.error = NDMP_NO_ERR;
 440  434          ndmp_send_reply(connection, &reply, "sending mover_read reply");
 441  435  
 442  436          err = ndmpd_mover_seek(session, quad_to_long_long(request->offset),
 443  437              quad_to_long_long(request->length));
 444  438          if (err < 0) {
 445  439                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
 446  440                  return;
 447  441          }
 448  442          /*
 449  443           * Just return if we are waiting for the NDMP client to
 450  444           * complete the seek.
 451  445           */
 452  446          if (err == 1)
 453  447                  return;
 454  448  
 455  449          /*
 456  450           * Start the mover for restore in the 3-way backups.
 457  451           */
 458  452          if (start_mover_for_restore(session) < 0)
 459  453                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
 460  454  }
 461  455  
 462  456  
 463  457  /*
 464  458   * ndmpd_mover_close_v2
 465  459   *
 466  460   * This handler handles mover_close requests.
 467  461   *
 468  462   * Parameters:
 469  463   *   connection (input) - connection handle.
 470  464   *   body       (input) - request message body.
 471  465   *
 472  466   * Returns:
  
    | 
      ↓ open down ↓ | 
    30 lines elided | 
    
      ↑ open up ↑ | 
  
 473  467   *   void
 474  468   */
 475  469  /*ARGSUSED*/
 476  470  void
 477  471  ndmpd_mover_close_v2(ndmp_connection_t *connection, void *body)
 478  472  {
 479  473          ndmp_mover_close_reply reply;
 480  474          ndmpd_session_t *session = ndmp_get_client_data(connection);
 481  475  
 482  476          if (session->ns_mover.md_state != NDMP_MOVER_STATE_PAUSED) {
 483      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 484  477  
 485  478                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 486  479                  ndmp_send_reply(connection, &reply,
 487  480                      "sending mover_close reply");
 488  481                  return;
 489  482          }
 490  483          free(session->ns_mover.md_data_addr_v4.tcp_addr_v4);
 491  484  
 492  485          reply.error = NDMP_NO_ERR;
 493  486          ndmp_send_reply(connection, &reply, "sending mover_close reply");
 494  487  
 495  488          ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
 496  489  }
 497  490  
 498  491  
 499  492  /*
 500  493   * ndmpd_mover_set_record_size_v2
 501  494   *
 502  495   * This handler handles mover_set_record_size requests.
 503  496   *
 504  497   * Parameters:
 505  498   *   connection (input) - connection handle.
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
 506  499   *   body       (input) - request message body.
 507  500   *
 508  501   * Returns:
 509  502   *   void
 510  503   */
 511  504  void
 512  505  ndmpd_mover_set_record_size_v2(ndmp_connection_t *connection, void *body)
 513  506  {
 514  507          ndmp_mover_set_record_size_request *request;
 515  508          ndmp_mover_set_record_size_reply reply;
      509 +
 516  510          ndmpd_session_t *session = ndmp_get_client_data(connection);
 517  511  
 518  512          request = (ndmp_mover_set_record_size_request *) body;
 519  513  
 520  514          session->ns_mover.md_record_size = request->len;
 521  515          session->ns_mover.md_buf = realloc(session->ns_mover.md_buf,
 522  516              request->len);
 523  517  
 524  518          reply.error = NDMP_NO_ERR;
 525  519          ndmp_send_reply(connection, &reply,
 526  520              "sending mover_set_record_size reply");
 527  521  }
 528  522  
 529  523  
 530  524  /*
 531  525   * ************************************************************************
 532  526   * NDMP V3 HANDLERS
 533  527   * ************************************************************************
 534  528   */
 535  529  
 536  530  /*
 537  531   * ndmpd_mover_get_state_v3
 538  532   *
 539  533   * This handler handles the ndmp_mover_get_state_request.
 540  534   * Status information for the mover state machine is returned.
 541  535   *
 542  536   * Parameters:
 543  537   *   connection (input) - connection handle.
 544  538   *   body       (input) - request message body.
 545  539   *
 546  540   * Returns:
 547  541   *   void
 548  542   */
 549  543  /*ARGSUSED*/
 550  544  void
 551  545  ndmpd_mover_get_state_v3(ndmp_connection_t *connection, void *body)
 552  546  {
 553  547          ndmp_mover_get_state_reply_v3 reply;
 554  548          ndmpd_session_t *session = ndmp_get_client_data(connection);
 555  549  
 556  550          (void) memset((void*)&reply, 0, sizeof (reply));
 557  551  
 558  552          reply.error = NDMP_NO_ERR;
 559  553          reply.state = session->ns_mover.md_state;
 560  554          reply.pause_reason = session->ns_mover.md_pause_reason;
 561  555          reply.halt_reason = session->ns_mover.md_halt_reason;
 562  556          reply.record_size = session->ns_mover.md_record_size;
 563  557          reply.record_num = session->ns_mover.md_record_num;
 564  558          reply.data_written =
 565  559              long_long_to_quad(session->ns_mover.md_data_written);
 566  560          reply.seek_position =
 567  561              long_long_to_quad(session->ns_mover.md_seek_position);
 568  562          reply.bytes_left_to_read =
 569  563              long_long_to_quad(session->ns_mover.md_bytes_left_to_read);
 570  564          reply.window_offset =
 571  565              long_long_to_quad(session->ns_mover.md_window_offset);
 572  566          reply.window_length =
 573  567              long_long_to_quad(session->ns_mover.md_window_length);
 574  568          if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE)
 575  569                  ndmp_copy_addr_v3(&reply.data_connection_addr,
 576  570                      &session->ns_mover.md_data_addr);
 577  571  
 578  572          ndmp_send_reply(connection, &reply,
 579  573              "sending ndmp_mover_get_state reply");
 580  574  }
 581  575  
 582  576  
 583  577  /*
 584  578   * ndmpd_mover_listen_v3
 585  579   *
 586  580   * This handler handles ndmp_mover_listen_requests.
 587  581   * A TCP/IP socket is created that is used to listen for
 588  582   * and accept data connections initiated by a remote
 589  583   * data server.
 590  584   *
 591  585   * Parameters:
 592  586   *   connection (input) - connection handle.
 593  587   *   body       (input) - request message body.
 594  588   *
 595  589   * Returns:
 596  590   *   void
 597  591   */
 598  592  void
 599  593  ndmpd_mover_listen_v3(ndmp_connection_t *connection, void *body)
 600  594  {
 601  595          ndmp_mover_listen_request_v3 *request;
 602  596          ndmp_mover_listen_reply_v3 reply;
 603  597          ndmpd_session_t *session = ndmp_get_client_data(connection);
 604  598          ulong_t addr;
  
    | 
      ↓ open down ↓ | 
    79 lines elided | 
    
      ↑ open up ↑ | 
  
 605  599          ushort_t port;
 606  600  
 607  601          request = (ndmp_mover_listen_request_v3 *)body;
 608  602  
 609  603          (void) memset((void*)&reply, 0, sizeof (reply));
 610  604          reply.error = NDMP_NO_ERR;
 611  605  
 612  606          if (request->mode != NDMP_MOVER_MODE_READ &&
 613  607              request->mode != NDMP_MOVER_MODE_WRITE) {
 614  608                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
 615      -                NDMP_LOG(LOG_DEBUG, "Invalid mode %d", request->mode);
 616  609          } else if (!ndmp_valid_v3addr_type(request->addr_type)) {
 617  610                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
 618      -                NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
 619      -                    request->addr_type);
 620  611          } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) {
 621  612                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 622      -                NDMP_LOG(LOG_DEBUG,
 623      -                    "Invalid mover state to process listen request");
 624  613          } else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
 625  614                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 626      -                NDMP_LOG(LOG_DEBUG,
 627      -                    "Invalid data state to process listen request");
 628  615          } else if (session->ns_tape.td_fd == -1) {
 629  616                  reply.error = NDMP_DEV_NOT_OPEN_ERR;
 630      -                NDMP_LOG(LOG_DEBUG, "No tape device open");
      617 +                syslog(LOG_ERR, "No tape device open");
 631  618          } else if (request->mode == NDMP_MOVER_MODE_READ &&
 632  619              session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
 633  620                  reply.error = NDMP_PERMISSION_ERR;
 634      -                NDMP_LOG(LOG_ERR, "Write protected device.");
      621 +                syslog(LOG_ERR, "Write protected device.");
 635  622          }
 636  623  
 637  624          if (reply.error != NDMP_NO_ERR) {
 638  625                  ndmp_send_reply(connection, &reply,
 639  626                      "error sending ndmp_mover_listen reply");
 640  627                  return;
 641  628          }
 642  629  
 643  630          switch (request->addr_type) {
 644  631          case NDMP_ADDR_LOCAL:
 645  632                  reply.data_connection_addr.addr_type = NDMP_ADDR_LOCAL;
 646  633                  session->ns_mover.md_data_addr.addr_type = NDMP_ADDR_LOCAL;
 647  634                  reply.error = NDMP_NO_ERR;
 648  635                  break;
 649  636          case NDMP_ADDR_TCP:
 650  637                  if (create_listen_socket_v3(session, &addr, &port) < 0) {
  
    | 
      ↓ open down ↓ | 
    6 lines elided | 
    
      ↑ open up ↑ | 
  
 651  638                          reply.error = NDMP_IO_ERR;
 652  639                          break;
 653  640                  }
 654  641                  reply.error = NDMP_NO_ERR;
 655  642                  reply.data_connection_addr.addr_type = NDMP_ADDR_TCP;
 656  643                  reply.data_connection_addr.tcp_ip_v3 = htonl(addr);
 657  644                  reply.data_connection_addr.tcp_port_v3 = htons(port);
 658  645                  session->ns_mover.md_data_addr.addr_type = NDMP_ADDR_TCP;
 659  646                  session->ns_mover.md_data_addr.tcp_ip_v3 = addr;
 660  647                  session->ns_mover.md_data_addr.tcp_port_v3 = ntohs(port);
 661      -                NDMP_LOG(LOG_DEBUG, "listen_socket: %d",
      648 +                syslog(LOG_DEBUG, "listen_socket: %d",
 662  649                      session->ns_mover.md_listen_sock);
 663  650                  break;
 664  651          default:
 665  652                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
 666      -                NDMP_LOG(LOG_DEBUG, "Invalid address type: %d",
 667      -                    request->addr_type);
 668  653          }
 669  654  
 670  655          if (reply.error == NDMP_NO_ERR) {
 671  656                  session->ns_mover.md_mode = request->mode;
 672  657                  session->ns_mover.md_state = NDMP_MOVER_STATE_LISTEN;
 673  658          }
 674  659  
 675  660          ndmp_send_reply(connection, &reply,
 676  661              "error sending ndmp_mover_listen reply");
 677  662  }
 678  663  
 679  664  
 680  665  /*
 681  666   * ndmpd_mover_continue_v3
 682  667   *
 683  668   * This handler handles ndmp_mover_continue_requests.
 684  669   *
 685  670   * Parameters:
 686  671   *   connection (input) - connection handle.
 687  672   *   body       (input) - request message body.
 688  673   *
 689  674   * Returns:
 690  675   *   void
 691  676   */
 692  677  /*ARGSUSED*/
 693  678  void
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
 694  679  ndmpd_mover_continue_v3(ndmp_connection_t *connection, void *body)
 695  680  {
 696  681          ndmp_mover_continue_reply reply;
 697  682          ndmpd_session_t *session = ndmp_get_client_data(connection);
 698  683          ndmp_lbr_params_t *nlp = ndmp_get_nlp(session);
 699  684          int ret;
 700  685  
 701  686          (void) memset((void*)&reply, 0, sizeof (reply));
 702  687  
 703  688          if (session->ns_mover.md_state != NDMP_MOVER_STATE_PAUSED) {
 704      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 705  689                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 706  690                  ndmp_send_reply(connection, (void *) &reply,
 707  691                      "sending mover_continue reply");
 708  692                  return;
 709  693          }
 710  694  
 711  695          if (session->ns_protocol_version == NDMPV4 &&
 712  696              !session->ns_mover.md_pre_cond) {
 713      -                NDMP_LOG(LOG_DEBUG, "Precondition check");
      697 +                syslog(LOG_DEBUG, "Precondition check");
 714  698                  reply.error = NDMP_PRECONDITION_ERR;
 715  699                  ndmp_send_reply(connection, (void *) &reply,
 716  700                      "sending mover_continue reply");
 717  701                  return;
 718  702          }
 719  703          /*
 720  704           * Restore the file handler if the mover is remote to the data
 721  705           * server and the handler was removed pending the continuation of a
 722  706           * seek request. The handler is removed in mover_data_write().
 723  707           */
 724  708          if (session->ns_mover.md_pause_reason == NDMP_MOVER_PAUSE_SEEK &&
 725  709              session->ns_mover.md_sock != -1) {
 726  710                  /*
 727  711                   * If we are here, it means that we needed DMA interference
 728  712                   * for seek. We should be on the right window, so we do not
 729  713                   * need the DMA interference anymore.
 730  714                   * We do another seek inside the Window to move to the
 731  715                   * exact position on the tape.
 732  716                   * If the resore is running without DAR the pause reason should
 733  717                   * not be seek.
 734  718                   */
 735  719                  ret = ndmpd_mover_seek(session,
 736  720                      session->ns_mover.md_seek_position,
 737  721                      session->ns_mover.md_bytes_left_to_read);
 738  722                  if (ret < 0) {
 739  723                          ndmpd_mover_error(session,
 740  724                              NDMP_MOVER_HALT_INTERNAL_ERROR);
 741  725                          return;
 742  726                  }
 743  727  
 744  728                  if (!ret) {
 745  729                          if (ndmpd_add_file_handler(session, (void*) session,
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
 746  730                              session->ns_mover.md_sock, NDMPD_SELECT_MODE_WRITE,
 747  731                              HC_MOVER, mover_data_write_v3) < 0)
 748  732                                  ndmpd_mover_error(session,
 749  733                                      NDMP_MOVER_HALT_INTERNAL_ERROR);
 750  734                  } else {
 751  735                          /*
 752  736                           * This should not happen because we should be in the
 753  737                           * right window. This means that DMA does not follow
 754  738                           * the V3 spec.
 755  739                           */
 756      -                        NDMP_LOG(LOG_DEBUG, "DMA Error.");
 757  740                          ndmpd_mover_error(session,
 758  741                              NDMP_MOVER_HALT_INTERNAL_ERROR);
 759  742                          return;
 760  743                  }
 761  744          }
 762  745  
 763  746          (void) mutex_lock(&nlp->nlp_mtx);
 764  747          session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
 765  748          session->ns_mover.md_pause_reason = NDMP_MOVER_PAUSE_NA;
 766  749          /* The tape has been likely exchanged, reset tape block counter */
 767  750          session->ns_tape.td_record_count = 0;
 768  751          (void) cond_broadcast(&nlp->nlp_cv);
 769  752          (void) mutex_unlock(&nlp->nlp_mtx);
 770  753  
 771  754          reply.error = NDMP_NO_ERR;
 772  755          ndmp_send_reply(connection, (void *) &reply,
 773  756              "sending mover_continue reply");
 774  757  }
 775  758  
 776  759  
 777  760  /*
 778  761   * ndmpd_mover_abort_v3
 779  762   *
 780  763   * This handler handles mover_abort requests.
 781  764   *
 782  765   * Parameters:
 783  766   *   connection (input) - connection handle.
 784  767   *   body       (input) - request message body.
 785  768   *
 786  769   * Returns:
 787  770   *   void
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
 788  771   */
 789  772  /*ARGSUSED*/
 790  773  void
 791  774  ndmpd_mover_abort_v3(ndmp_connection_t *connection, void *body)
 792  775  {
 793  776          ndmp_mover_abort_reply reply;
 794  777          ndmpd_session_t *session = ndmp_get_client_data(connection);
 795  778  
 796  779          if (session->ns_mover.md_state == NDMP_MOVER_STATE_IDLE ||
 797  780              session->ns_mover.md_state == NDMP_MOVER_STATE_HALTED) {
 798      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 799  781  
 800  782                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 801  783                  ndmp_send_reply(connection, (void *) &reply,
 802  784                      "sending mover_abort reply");
 803  785                  return;
 804  786          }
 805  787  
 806  788          reply.error = NDMP_NO_ERR;
 807  789          ndmp_send_reply(connection, (void *) &reply,
 808  790              "sending mover_abort reply");
 809  791  
 810  792          ndmpd_mover_error(session, NDMP_MOVER_HALT_ABORTED);
 811  793  }
 812  794  
 813  795  
 814  796  /*
 815  797   * ndmpd_mover_set_window_v3
 816  798   *
 817  799   * This handler handles mover_set_window requests.
 818  800   *
 819  801   *
 820  802   * Parameters:
 821  803   *   connection (input) - connection handle.
 822  804   *   body       (input) - request message body.
 823  805   *
 824  806   * Returns:
 825  807   *   void
 826  808   */
 827  809  void
 828  810  ndmpd_mover_set_window_v3(ndmp_connection_t *connection, void *body)
 829  811  {
 830  812          ndmp_mover_set_window_request *request;
 831  813          ndmp_mover_set_window_reply reply;
 832  814          ndmpd_session_t *session = ndmp_get_client_data(connection);
 833  815  
 834  816          request = (ndmp_mover_set_window_request *) body;
 835  817  
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
 836  818          /*
 837  819           * Note: The spec says that the window can be set only in the listen
 838  820           * and paused states.  We let this happen when mover is in the idle
 839  821           * state as well.  I can't rememebr which NDMP client (net_backup 4.5
 840  822           * or net_worker 6.1.1) forced us to do this!
 841  823           */
 842  824          if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE &&
 843  825              session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN &&
 844  826              session->ns_mover.md_state != NDMP_MOVER_STATE_PAUSED) {
 845  827                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 846      -                NDMP_LOG(LOG_DEBUG, "Invalid state %d",
 847      -                    session->ns_mover.md_state);
 848  828          } else if (session->ns_mover.md_record_size == 0) {
 849  829                  if (session->ns_protocol_version == NDMPV4)
 850  830                          reply.error = NDMP_PRECONDITION_ERR;
 851  831                  else
 852  832                          reply.error = NDMP_ILLEGAL_ARGS_ERR;
 853      -                NDMP_LOG(LOG_DEBUG, "Invalid record size 0");
 854  833          } else
 855  834                  reply.error = NDMP_NO_ERR;
 856  835  
 857  836          if (quad_to_long_long(request->length) == 0) {
 858  837                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
 859      -                NDMP_LOG(LOG_DEBUG, "Invalid window size %d",
 860      -                    quad_to_long_long(request->length));
 861  838          }
 862  839  
 863  840          if (reply.error != NDMP_NO_ERR) {
 864  841                  ndmp_send_reply(connection, (void *) &reply,
 865  842                      "sending mover_set_window_v3 reply");
 866  843                  return;
 867  844          }
 868  845  
 869  846          session->ns_mover.md_pre_cond = TRUE;
 870  847          session->ns_mover.md_window_offset = quad_to_long_long(request->offset);
 871  848          session->ns_mover.md_window_length = quad_to_long_long(request->length);
 872  849  
 873  850          /*
 874  851           * We have to update the position for DAR. DAR needs this
 875  852           * information to position to the right index on tape,
 876  853           * especially when we span the tapes.
 877  854           */
 878  855  #ifdef  NO_POSITION_CHANGE
 879  856          /*
 880  857           * Do not change the mover position if we are reading from
 881  858           * the tape.  In this way, we can use the position+window_length
 882  859           * to know how much we can write to a tape before pausing with
 883  860           * EOW reason.
 884  861           */
 885  862          if (session->ns_mover.md_mode != NDMP_MOVER_MODE_WRITE)
 886  863  #endif  /* NO_POSITION_CHANGE */
 887  864                  session->ns_mover.md_position =
 888  865                      session->ns_mover.md_window_offset;
 889  866  
 890  867          ndmp_send_reply(connection, (void *) &reply,
 891  868              "sending mover_set_window_v3 reply");
 892  869  }
 893  870  
 894  871  
 895  872  /*
 896  873   * ndmpd_mover_read_v3
 897  874   *
 898  875   * This handler handles ndmp_mover_read_requests.
 899  876   * If the requested offset is outside of the current window, the mover
 900  877   * is paused and a notify_mover_paused request is sent notifying the
 901  878   * client that a seek is required. If the requested offest is within
 902  879   * the window but not within the current record, then the tape is
 903  880   * positioned to the record containing the requested offest. The requested
 904  881   * amount of data is then read from the tape device and written to the
 905  882   * data connection.
 906  883   *
 907  884   * Parameters:
 908  885   *   connection (input) - connection handle.
 909  886   *   body       (input) - request message body.
 910  887   *
 911  888   * Returns:
 912  889   *   void
 913  890   */
 914  891  void
 915  892  ndmpd_mover_read_v3(ndmp_connection_t *connection, void *body)
 916  893  {
  
    | 
      ↓ open down ↓ | 
    46 lines elided | 
    
      ↑ open up ↑ | 
  
 917  894          ndmp_mover_read_request *request = (ndmp_mover_read_request *)body;
 918  895          ndmp_mover_read_reply reply;
 919  896          ndmpd_session_t *session = ndmp_get_client_data(connection);
 920  897          int err;
 921  898  
 922  899          (void) memset((void*)&reply, 0, sizeof (reply));
 923  900  
 924  901          if (session->ns_mover.md_state != NDMP_MOVER_STATE_ACTIVE ||
 925  902              session->ns_mover.md_mode != NDMP_MOVER_MODE_WRITE) {
 926  903                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 927      -                NDMP_LOG(LOG_DEBUG, "Invalid state");
 928  904          } else if (session->ns_mover.md_bytes_left_to_read != 0) {
 929  905                  reply.error = NDMP_READ_IN_PROGRESS_ERR;
 930      -                NDMP_LOG(LOG_DEBUG, "In progress");
 931  906          } else if (session->ns_tape.td_fd == -1) {
 932  907                  reply.error = NDMP_DEV_NOT_OPEN_ERR;
 933      -                NDMP_LOG(LOG_DEBUG, "Tape device is not open");
      908 +                syslog(LOG_ERR, "Tape device is not open");
 934  909          } else if (quad_to_long_long(request->length) == 0 ||
 935  910              (quad_to_long_long(request->length) == MAX_WINDOW_SIZE &&
 936  911              quad_to_long_long(request->offset) != 0)) {
 937  912                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
 938      -                NDMP_LOG(LOG_DEBUG, "Illegal args");
 939  913          } else {
 940  914                  reply.error = NDMP_NO_ERR;
 941  915          }
 942  916  
 943  917          ndmp_send_reply(connection, (void *) &reply,
 944  918              "sending ndmp_mover_read_reply");
 945  919          if (reply.error != NDMP_NO_ERR)
 946  920                  return;
 947  921  
 948  922          err = ndmpd_mover_seek(session, quad_to_long_long(request->offset),
 949  923              quad_to_long_long(request->length));
 950  924          if (err < 0) {
 951  925                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
 952  926                  return;
 953  927          }
 954  928  
 955  929          /*
 956  930           * Just return if we are waiting for the DMA to complete the seek.
 957  931           */
 958  932          if (err == 1)
 959  933                  return;
 960  934  
 961  935          /*
 962  936           * Setup a handler function that will be called when
 963  937           * data can be written to the data connection without blocking.
 964  938           */
 965  939          if (ndmpd_add_file_handler(session, (void*)session,
 966  940              session->ns_mover.md_sock, NDMPD_SELECT_MODE_WRITE, HC_MOVER,
 967  941              mover_data_write_v3) < 0) {
 968  942                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
 969  943                  return;
 970  944          }
 971  945  }
 972  946  
 973  947  
 974  948  /*
 975  949   * ndmpd_mover_set_record_size_v3
 976  950   *
 977  951   * This handler handles mover_set_record_size requests.
 978  952   *
 979  953   * Parameters:
 980  954   *   connection (input) - connection handle.
 981  955   *   body       (input) - request message body.
 982  956   *
 983  957   * Returns:
 984  958   *   void
 985  959   */
 986  960  void
 987  961  ndmpd_mover_set_record_size_v3(ndmp_connection_t *connection, void *body)
  
    | 
      ↓ open down ↓ | 
    39 lines elided | 
    
      ↑ open up ↑ | 
  
 988  962  {
 989  963          ndmp_mover_set_record_size_request *request;
 990  964          ndmp_mover_set_record_size_reply reply;
 991  965          ndmpd_session_t *session = ndmp_get_client_data(connection);
 992  966          char *cp;
 993  967  
 994  968          request = (ndmp_mover_set_record_size_request *) body;
 995  969  
 996  970          if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) {
 997  971                  reply.error = NDMP_ILLEGAL_STATE_ERR;
 998      -                NDMP_LOG(LOG_DEBUG, "Invalid mover state %d",
 999      -                    session->ns_mover.md_state);
1000  972          } else if (request->len > (unsigned int)ndmp_max_mover_recsize) {
1001  973                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1002      -                NDMP_LOG(LOG_DEBUG,
1003      -                    "Invalid argument %d, should be > 0 and <= %d",
1004      -                    request->len, ndmp_max_mover_recsize);
1005      -        } else if (request->len == session->ns_mover.md_record_size)
      974 +        } else if (request->len == session->ns_mover.md_record_size) {
1006  975                  reply.error = NDMP_NO_ERR;
1007      -        else if (!(cp = realloc(session->ns_mover.md_buf, request->len))) {
      976 +                session->ns_mover.md_pre_cond = TRUE;
      977 +        } else if (!(cp = realloc(session->ns_mover.md_buf, request->len))) {
1008  978                  reply.error = NDMP_NO_MEM_ERR;
1009  979          } else {
1010  980                  reply.error = NDMP_NO_ERR;
1011  981                  session->ns_mover.md_buf = cp;
1012  982                  session->ns_mover.md_record_size = request->len;
1013  983                  session->ns_mover.md_window_offset = 0;
1014  984                  session->ns_mover.md_window_length = 0;
1015  985          }
1016  986  
1017  987          ndmp_send_reply(connection, (void *) &reply,
1018  988              "sending mover_set_record_size reply");
1019  989  }
1020  990  
1021  991  
1022  992  /*
1023  993   * ndmpd_mover_connect_v3
1024  994   *   Request handler. Connects the mover to either a local
1025  995   *   or remote data server.
1026  996   *
1027  997   * Parameters:
1028  998   *   connection (input) - connection handle.
1029  999   *   body       (input) - request message body.
1030 1000   *
1031 1001   * Returns:
1032 1002   *   void
1033 1003   */
1034 1004  void
1035 1005  ndmpd_mover_connect_v3(ndmp_connection_t *connection, void *body)
1036 1006  {
1037 1007          ndmp_mover_connect_request_v3 *request;
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
1038 1008          ndmp_mover_connect_reply_v3 reply;
1039 1009          ndmpd_session_t *session = ndmp_get_client_data(connection);
1040 1010  
1041 1011          request = (ndmp_mover_connect_request_v3*)body;
1042 1012  
1043 1013          (void) memset((void*)&reply, 0, sizeof (reply));
1044 1014  
1045 1015          if (request->mode != NDMP_MOVER_MODE_READ &&
1046 1016              request->mode != NDMP_MOVER_MODE_WRITE) {
1047 1017                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1048      -                NDMP_LOG(LOG_DEBUG, "Invalid mode %d", request->mode);
1049 1018          } else if (!ndmp_valid_v3addr_type(request->addr.addr_type)) {
1050 1019                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1051      -                NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
1052      -                    request->addr.addr_type);
1053 1020          } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) {
1054 1021                  reply.error = NDMP_ILLEGAL_STATE_ERR;
1055      -                NDMP_LOG(LOG_DEBUG, "Invalid state %d: mover is not idle",
1056      -                    session->ns_mover.md_state);
1057 1022          } else if (session->ns_tape.td_fd == -1) {
1058 1023                  reply.error = NDMP_DEV_NOT_OPEN_ERR;
1059      -                NDMP_LOG(LOG_DEBUG, "No tape device open");
     1024 +                syslog(LOG_ERR, "No tape device open");
1060 1025          } else if (request->mode == NDMP_MOVER_MODE_READ &&
1061 1026              session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
1062 1027                  reply.error = NDMP_WRITE_PROTECT_ERR;
1063      -                NDMP_LOG(LOG_ERR, "Write protected device.");
     1028 +                syslog(LOG_ERR, "Write protected device.");
1064 1029          } else
1065 1030                  reply.error = NDMP_NO_ERR;
1066 1031  
1067 1032          if (reply.error != NDMP_NO_ERR) {
1068 1033                  ndmp_send_reply(connection, (void *) &reply,
1069 1034                      "sending ndmp_mover_connect reply");
1070 1035                  return;
1071 1036          }
1072 1037  
1073 1038          switch (request->addr.addr_type) {
1074 1039          case NDMP_ADDR_LOCAL:
1075 1040                  /*
1076 1041                   * Verify that the data server is listening for a
1077 1042                   * local connection.
1078 1043                   */
1079 1044                  if (session->ns_data.dd_state != NDMP_DATA_STATE_LISTEN ||
1080 1045                      session->ns_data.dd_listen_sock != -1) {
1081      -                        NDMP_LOG(LOG_DEBUG,
1082      -                            "Data server is not in local listen state");
1083 1046                          reply.error = NDMP_ILLEGAL_STATE_ERR;
1084 1047                  } else
1085 1048                          session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED;
1086 1049                  break;
1087 1050  
1088 1051          case NDMP_ADDR_TCP:
1089 1052                  reply.error = mover_connect_sock(session, request->mode,
1090 1053                      request->addr.tcp_ip_v3, request->addr.tcp_port_v3);
1091 1054                  break;
1092 1055  
1093 1056          default:
1094 1057                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1095      -                NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
1096      -                    request->addr.addr_type);
1097 1058          }
1098 1059  
1099 1060          if (reply.error == NDMP_NO_ERR) {
1100 1061                  session->ns_mover.md_data_addr.addr_type =
1101 1062                      request->addr.addr_type;
1102 1063                  session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
1103 1064                  session->ns_mover.md_mode = request->mode;
1104 1065          }
1105 1066  
1106 1067          ndmp_send_reply(connection, (void *) &reply,
1107 1068              "sending ndmp_mover_connect reply");
1108 1069  }
1109 1070  
1110 1071  
1111 1072  /*
1112 1073   * ************************************************************************
1113 1074   * NDMP V4 HANDLERS
1114 1075   * ************************************************************************
1115 1076   */
1116 1077  
1117 1078  /*
1118 1079   * ndmpd_mover_get_state_v4
1119 1080   *
1120 1081   * This handler handles the ndmp_mover_get_state_request.
1121 1082   * Status information for the mover state machine is returned.
1122 1083   *
1123 1084   * Parameters:
1124 1085   *   connection (input) - connection handle.
1125 1086   *   body       (input) - request message body.
1126 1087   *
1127 1088   * Returns:
1128 1089   *   void
1129 1090   */
1130 1091  /*ARGSUSED*/
1131 1092  void
1132 1093  ndmpd_mover_get_state_v4(ndmp_connection_t *connection, void *body)
1133 1094  {
1134 1095          ndmp_mover_get_state_reply_v4 reply;
1135 1096          ndmpd_session_t *session = ndmp_get_client_data(connection);
1136 1097  
1137 1098          (void) memset((void*)&reply, 0, sizeof (reply));
1138 1099  
1139 1100          reply.error = NDMP_NO_ERR;
1140 1101          reply.state = session->ns_mover.md_state;
1141 1102          reply.mode = session->ns_mover.md_mode;
1142 1103          reply.pause_reason = session->ns_mover.md_pause_reason;
1143 1104          reply.halt_reason = session->ns_mover.md_halt_reason;
1144 1105          reply.record_size = session->ns_mover.md_record_size;
1145 1106          reply.record_num = session->ns_mover.md_record_num;
1146 1107          reply.bytes_moved =
1147 1108              long_long_to_quad(session->ns_mover.md_data_written);
1148 1109          reply.seek_position =
1149 1110              long_long_to_quad(session->ns_mover.md_seek_position);
1150 1111          reply.bytes_left_to_read =
1151 1112              long_long_to_quad(session->ns_mover.md_bytes_left_to_read);
1152 1113          reply.window_offset =
1153 1114              long_long_to_quad(session->ns_mover.md_window_offset);
1154 1115          reply.window_length =
1155 1116              long_long_to_quad(session->ns_mover.md_window_length);
1156 1117          if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE)
1157 1118                  ndmp_copy_addr_v4(&reply.data_connection_addr,
1158 1119                      &session->ns_mover.md_data_addr_v4);
1159 1120  
1160 1121          ndmp_send_reply(connection, (void *) &reply,
1161 1122              "sending ndmp_mover_get_state reply");
1162 1123          free(reply.data_connection_addr.tcp_addr_v4);
1163 1124  }
1164 1125  
1165 1126  
1166 1127  /*
1167 1128   * ndmpd_mover_listen_v4
1168 1129   *
1169 1130   * This handler handles ndmp_mover_listen_requests.
1170 1131   * A TCP/IP socket is created that is used to listen for
1171 1132   * and accept data connections initiated by a remote
1172 1133   * data server.
1173 1134   *
1174 1135   * Parameters:
1175 1136   *   connection (input) - connection handle.
1176 1137   *   body       (input) - request message body.
1177 1138   *
1178 1139   * Returns:
1179 1140   *   void
1180 1141   */
1181 1142  void
1182 1143  ndmpd_mover_listen_v4(ndmp_connection_t *connection, void *body)
1183 1144  {
1184 1145          ndmp_mover_listen_request_v4 *request;
1185 1146  
1186 1147          ndmp_mover_listen_reply_v4 reply;
1187 1148          ndmpd_session_t *session = ndmp_get_client_data(connection);
1188 1149          ulong_t addr;
  
    | 
      ↓ open down ↓ | 
    82 lines elided | 
    
      ↑ open up ↑ | 
  
1189 1150          ushort_t port;
1190 1151  
1191 1152          request = (ndmp_mover_listen_request_v4 *)body;
1192 1153  
1193 1154          (void) memset((void*)&reply, 0, sizeof (reply));
1194 1155          reply.error = NDMP_NO_ERR;
1195 1156  
1196 1157          if (request->mode != NDMP_MOVER_MODE_READ &&
1197 1158              request->mode != NDMP_MOVER_MODE_WRITE) {
1198 1159                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1199      -                NDMP_LOG(LOG_DEBUG, "Invalid mode %d", request->mode);
1200 1160          } else if (!ndmp_valid_v3addr_type(request->addr_type)) {
1201 1161                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1202      -                NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
1203      -                    request->addr_type);
1204 1162          } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) {
1205 1163                  reply.error = NDMP_ILLEGAL_STATE_ERR;
1206      -                NDMP_LOG(LOG_DEBUG,
1207      -                    "Invalid mover state to process listen request");
1208 1164          } else if (session->ns_data.dd_state != NDMP_DATA_STATE_IDLE) {
1209 1165                  reply.error = NDMP_ILLEGAL_STATE_ERR;
1210      -                NDMP_LOG(LOG_DEBUG,
1211      -                    "Invalid data state to process listen request");
1212 1166          } else if (session->ns_tape.td_fd == -1) {
1213 1167                  reply.error = NDMP_DEV_NOT_OPEN_ERR;
1214      -                NDMP_LOG(LOG_DEBUG, "No tape device open");
     1168 +                syslog(LOG_ERR, "No tape device open");
1215 1169          } else if (session->ns_mover.md_record_size == 0) {
1216 1170                  reply.error = NDMP_PRECONDITION_ERR;
1217      -                NDMP_LOG(LOG_DEBUG, "Invalid record size 0");
1218 1171          } else if (request->mode == NDMP_MOVER_MODE_READ &&
1219 1172              session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
1220 1173                  reply.error = NDMP_PERMISSION_ERR;
1221      -                NDMP_LOG(LOG_ERR, "Write protected device.");
     1174 +                syslog(LOG_ERR, "Write protected device.");
1222 1175          }
1223 1176  
1224 1177          if (reply.error != NDMP_NO_ERR) {
1225 1178                  ndmp_send_reply(connection, (void *) &reply,
1226 1179                      "error sending ndmp_mover_listen reply");
1227 1180                  return;
1228 1181          }
1229 1182  
1230 1183          switch (request->addr_type) {
1231 1184          case NDMP_ADDR_LOCAL:
1232 1185                  reply.connect_addr.addr_type = NDMP_ADDR_LOCAL;
1233 1186                  session->ns_mover.md_data_addr.addr_type = NDMP_ADDR_LOCAL;
1234 1187                  reply.error = NDMP_NO_ERR;
1235 1188                  break;
1236 1189          case NDMP_ADDR_TCP:
1237 1190                  if (create_listen_socket_v3(session, &addr, &port) < 0) {
1238 1191                          reply.error = NDMP_IO_ERR;
1239 1192                          break;
1240 1193                  }
1241 1194                  reply.error = NDMP_NO_ERR;
1242 1195  
1243 1196                  session->ns_mover.md_data_addr_v4.addr_type = NDMP_ADDR_TCP;
1244 1197                  session->ns_mover.md_data_addr_v4.tcp_len_v4 = 1;
1245 1198                  session->ns_mover.md_data_addr_v4.tcp_addr_v4 =
1246 1199                      ndmp_malloc(sizeof (ndmp_tcp_addr_v4));
1247 1200  
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
1248 1201                  session->ns_mover.md_data_addr_v4.tcp_ip_v4(0) = addr;
1249 1202                  session->ns_mover.md_data_addr_v4.tcp_port_v4(0) = ntohs(port);
1250 1203  
1251 1204                  ndmp_copy_addr_v4(&reply.connect_addr,
1252 1205                      &session->ns_mover.md_data_addr_v4);
1253 1206  
1254 1207                  /* For compatibility with V3 */
1255 1208                  session->ns_mover.md_data_addr.addr_type = NDMP_ADDR_TCP;
1256 1209                  session->ns_mover.md_data_addr.tcp_ip_v3 = addr;
1257 1210                  session->ns_mover.md_data_addr.tcp_port_v3 = ntohs(port);
1258      -                NDMP_LOG(LOG_DEBUG, "listen_socket: %d",
     1211 +                syslog(LOG_DEBUG, "listen_socket: %d",
1259 1212                      session->ns_mover.md_listen_sock);
1260 1213                  break;
1261 1214          default:
1262 1215                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1263      -                NDMP_LOG(LOG_DEBUG, "Invalid address type: %d",
1264      -                    request->addr_type);
1265 1216          }
1266 1217  
1267 1218          if (reply.error == NDMP_NO_ERR) {
1268 1219                  session->ns_mover.md_mode = request->mode;
1269 1220                  session->ns_mover.md_state = NDMP_MOVER_STATE_LISTEN;
1270 1221          }
1271 1222  
1272 1223          ndmp_send_reply(connection, (void *) &reply,
1273 1224              "error sending ndmp_mover_listen reply");
1274 1225          free(reply.connect_addr.tcp_addr_v4);
1275 1226  }
1276 1227  
1277 1228  /*
1278 1229   * ndmpd_mover_connect_v4
1279 1230   *   Request handler. Connects the mover to either a local
1280 1231   *   or remote data server.
1281 1232   *
1282 1233   * Parameters:
1283 1234   *   connection (input) - connection handle.
1284 1235   *   body       (input) - request message body.
1285 1236   *
1286 1237   * Returns:
1287 1238   *   void
1288 1239   */
1289 1240  void
1290 1241  ndmpd_mover_connect_v4(ndmp_connection_t *connection, void *body)
1291 1242  {
  
    | 
      ↓ open down ↓ | 
    17 lines elided | 
    
      ↑ open up ↑ | 
  
1292 1243          ndmp_mover_connect_request_v4 *request;
1293 1244          ndmp_mover_connect_reply_v4 reply;
1294 1245          ndmpd_session_t *session = ndmp_get_client_data(connection);
1295 1246  
1296 1247          request = (ndmp_mover_connect_request_v4 *)body;
1297 1248          (void) memset((void*)&reply, 0, sizeof (reply));
1298 1249  
1299 1250          if (request->mode != NDMP_MOVER_MODE_READ &&
1300 1251              request->mode != NDMP_MOVER_MODE_WRITE) {
1301 1252                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1302      -                NDMP_LOG(LOG_DEBUG, "Invalid mode %d", request->mode);
1303 1253          } else if (!ndmp_valid_v3addr_type(request->addr.addr_type)) {
1304 1254                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1305      -                NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
1306      -                    request->addr.addr_type);
1307 1255          } else if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE) {
1308 1256                  reply.error = NDMP_ILLEGAL_STATE_ERR;
1309      -                NDMP_LOG(LOG_DEBUG, "Invalid state %d: mover is not idle",
1310      -                    session->ns_mover.md_state);
1311 1257          } else if (session->ns_tape.td_fd == -1) {
1312 1258                  reply.error = NDMP_DEV_NOT_OPEN_ERR;
1313      -                NDMP_LOG(LOG_DEBUG, "No tape device open");
     1259 +                syslog(LOG_ERR, "No tape device open");
1314 1260          } else if (request->mode == NDMP_MOVER_MODE_READ &&
1315 1261              session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
1316 1262                  reply.error = NDMP_PERMISSION_ERR;
1317      -                NDMP_LOG(LOG_ERR, "Write protected device.");
     1263 +                syslog(LOG_ERR, "Write protected device.");
1318 1264          } else if (session->ns_mover.md_record_size == 0) {
1319 1265                  reply.error = NDMP_PRECONDITION_ERR;
1320      -                NDMP_LOG(LOG_DEBUG, "Invalid record size 0");
1321 1266          } else
1322 1267                  reply.error = NDMP_NO_ERR;
1323 1268  
1324 1269          if (reply.error != NDMP_NO_ERR) {
1325 1270                  ndmp_send_reply(connection, (void *) &reply,
1326 1271                      "sending ndmp_mover_connect reply");
1327 1272                  return;
1328 1273          }
1329 1274  
1330 1275          switch (request->addr.addr_type) {
1331 1276          case NDMP_ADDR_LOCAL:
1332 1277                  /*
1333 1278                   * Verify that the data server is listening for a
1334 1279                   * local connection.
1335 1280                   */
1336 1281                  if (session->ns_data.dd_state != NDMP_DATA_STATE_LISTEN ||
1337 1282                      session->ns_data.dd_listen_sock != -1) {
1338      -                        NDMP_LOG(LOG_DEBUG,
1339      -                            "Data server is not in local listen state");
1340 1283                          reply.error = NDMP_ILLEGAL_STATE_ERR;
1341 1284                  } else
1342 1285                          session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED;
1343 1286                  break;
1344 1287  
1345 1288          case NDMP_ADDR_TCP:
1346 1289                  reply.error = mover_connect_sock(session, request->mode,
1347 1290                      request->addr.tcp_ip_v4(0), request->addr.tcp_port_v4(0));
1348 1291                  break;
1349 1292  
1350 1293          default:
1351 1294                  reply.error = NDMP_ILLEGAL_ARGS_ERR;
1352      -                NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
1353      -                    request->addr.addr_type);
1354 1295          }
1355 1296  
1356 1297          if (reply.error == NDMP_NO_ERR) {
1357 1298                  session->ns_mover.md_data_addr.addr_type =
1358 1299                      request->addr.addr_type;
1359 1300                  session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
1360 1301                  session->ns_mover.md_mode = request->mode;
1361 1302          }
1362 1303  
1363 1304          ndmp_send_reply(connection, (void *) &reply,
1364 1305              "sending ndmp_mover_connect reply");
1365 1306  }
1366 1307  
1367 1308  
1368 1309  
1369 1310  /*
1370 1311   * ************************************************************************
1371 1312   * LOCALS
1372 1313   * ************************************************************************
1373 1314   */
1374 1315  
1375 1316  /*
1376 1317   * ndmpd_local_write
1377 1318   *
1378 1319   * Writes data to the mover.
1379 1320   * Buffers and write data to the tape device.
1380 1321   * A full tape record is buffered before being written.
1381 1322   *
1382 1323   * Parameters:
1383 1324   *   session    (input) - session pointer.
1384 1325   *   data       (input) - data to be written.
1385 1326   *   length     (input) - data length.
1386 1327   *
1387 1328   * Returns:
1388 1329   *   0 - data successfully written.
1389 1330   *  -1 - error.
1390 1331   */
1391 1332  int
1392 1333  ndmpd_local_write(ndmpd_session_t *session, char *data, ulong_t length)
1393 1334  {
1394 1335          ulong_t count = 0;
1395 1336          ssize_t n;
1396 1337          ulong_t len;
1397 1338  
1398 1339          /*
1399 1340           * A length of 0 indicates that any buffered data should be
1400 1341           * flushed to tape.
1401 1342           */
1402 1343          if (length == 0) {
1403 1344                  if (session->ns_mover.md_w_index == 0)
1404 1345                          return (0);
1405 1346  
1406 1347                  (void) memset(
1407 1348                      &session->ns_mover.md_buf[session->ns_mover.md_w_index],
1408 1349                      0, session->ns_mover.md_record_size -
1409 1350                      session->ns_mover.md_w_index);
1410 1351  
1411 1352                  n = mover_tape_write_v3(session, session->ns_mover.md_buf,
1412 1353                      session->ns_mover.md_record_size);
1413 1354                  if (n <= 0) {
1414 1355                          ndmpd_mover_error(session,
1415 1356                              (n == 0 ? NDMP_MOVER_HALT_ABORTED :
1416 1357                              NDMP_MOVER_HALT_INTERNAL_ERROR));
1417 1358                          return (-1);
1418 1359                  }
1419 1360                  session->ns_mover.md_position += n;
1420 1361                  session->ns_mover.md_data_written +=
1421 1362                      session->ns_mover.md_w_index;
1422 1363                  session->ns_mover.md_record_num++;
1423 1364                  session->ns_mover.md_w_index = 0;
1424 1365                  return (0);
1425 1366          }
1426 1367          /* Break the data into records. */
1427 1368          while (count < length) {
1428 1369                  /*
1429 1370                   * Determine if data needs to be buffered or
1430 1371                   * can be written directly from user supplied location.
1431 1372                   * We can fast path the write if there is no pending
1432 1373                   * buffered data and there is at least a full record's worth
1433 1374                   * of data to be written.
1434 1375                   */
1435 1376                  if (session->ns_mover.md_w_index == 0 &&
1436 1377                      length - count >= session->ns_mover.md_record_size) {
1437 1378                          n = mover_tape_write_v3(session, &data[count],
1438 1379                              session->ns_mover.md_record_size);
1439 1380                          if (n <= 0) {
1440 1381                                  ndmpd_mover_error(session,
1441 1382                                      (n == 0 ? NDMP_MOVER_HALT_ABORTED :
1442 1383                                      NDMP_MOVER_HALT_INTERNAL_ERROR));
1443 1384                                  return (-1);
1444 1385                          }
1445 1386                          session->ns_mover.md_position += n;
1446 1387                          session->ns_mover.md_data_written += n;
1447 1388                          session->ns_mover.md_record_num++;
1448 1389                          count += n;
1449 1390                          continue;
1450 1391                  }
1451 1392                  /* Buffer the data */
1452 1393                  len = length - count;
1453 1394                  if (len > session->ns_mover.md_record_size -
1454 1395                      session->ns_mover.md_w_index)
1455 1396                          len = session->ns_mover.md_record_size -
1456 1397                              session->ns_mover.md_w_index;
1457 1398  
1458 1399                  (void) memcpy(
1459 1400                      &session->ns_mover.md_buf[session->ns_mover.md_w_index],
1460 1401                      &data[count], len);
1461 1402                  session->ns_mover.md_w_index += len;
1462 1403                  count += len;
1463 1404  
1464 1405                  /* Write the buffer if its full */
1465 1406                  if (session->ns_mover.md_w_index ==
1466 1407                      session->ns_mover.md_record_size) {
1467 1408                          n = mover_tape_write_v3(session,
1468 1409                              session->ns_mover.md_buf,
1469 1410                              session->ns_mover.md_record_size);
1470 1411                          if (n <= 0) {
1471 1412                                  ndmpd_mover_error(session,
1472 1413                                      (n == 0 ? NDMP_MOVER_HALT_ABORTED :
1473 1414                                      NDMP_MOVER_HALT_INTERNAL_ERROR));
1474 1415                                  return (-1);
1475 1416                          }
1476 1417                          session->ns_mover.md_position += n;
1477 1418                          session->ns_mover.md_data_written += n;
1478 1419                          session->ns_mover.md_record_num++;
1479 1420                          session->ns_mover.md_w_index = 0;
1480 1421                  }
1481 1422          }
1482 1423  
1483 1424          return (0);
1484 1425  }
1485 1426  
1486 1427  
1487 1428  /*
1488 1429   * ndmpd_remote_write
1489 1430   *
1490 1431   * Writes data to the remote mover.
1491 1432   *
1492 1433   * Parameters:
1493 1434   *   session    (input) - session pointer.
1494 1435   *   data       (input) - data to be written.
1495 1436   *   length     (input) - data length.
1496 1437   *
1497 1438   * Returns:
1498 1439   *   0 - data successfully written.
1499 1440   *  -1 - error.
1500 1441   */
1501 1442  int
1502 1443  ndmpd_remote_write(ndmpd_session_t *session, char *data, ulong_t length)
1503 1444  {
  
    | 
      ↓ open down ↓ | 
    140 lines elided | 
    
      ↑ open up ↑ | 
  
1504 1445          ssize_t n;
1505 1446          ulong_t count = 0;
1506 1447  
1507 1448          while (count < length) {
1508 1449                  if (session->ns_eof == TRUE ||
1509 1450                      session->ns_data.dd_abort == TRUE)
1510 1451                          return (-1);
1511 1452  
1512 1453                  if ((n = write(session->ns_data.dd_sock, &data[count],
1513 1454                      length - count)) < 0) {
1514      -                        NDMP_LOG(LOG_ERR, "Socket write error: %m.");
     1455 +                        syslog(LOG_ERR, "Socket write error: %m.");
1515 1456                          return (-1);
1516 1457                  }
1517 1458                  count += n;
1518 1459          }
1519 1460  
1520 1461          return (0);
1521 1462  }
1522 1463  
1523 1464  /*
1524 1465   * ndmpd_local_read
1525 1466   *
1526 1467   * Reads data from the local tape device.
1527 1468   * Full tape records are read and buffered.
1528 1469   *
1529 1470   * Parameters:
1530 1471   *   session (input) - session pointer.
1531 1472   *   data    (input) - location to store data.
1532 1473   *   length  (input) - data length.
1533 1474   *
1534 1475   * Returns:
1535 1476   *   0 - data successfully read.
1536 1477   *  -1 - error.
1537 1478   *   1 - session terminated or operation aborted.
1538 1479   */
1539 1480  int
1540 1481  ndmpd_local_read(ndmpd_session_t *session, char *data, ulong_t length)
1541 1482  {
1542 1483          ulong_t count = 0;
1543 1484          ssize_t n;
1544 1485          ulong_t len;
1545 1486          ndmp_notify_mover_paused_request pause_request;
1546 1487  
1547 1488          /*
1548 1489           * Automatically increase the seek window if necessary.
1549 1490           * This is needed in the event the module attempts to read
1550 1491           * past a seek window set via a prior call to ndmpd_seek() or
1551 1492           * the module has not issued a seek. If no seek was issued then
1552 1493           * pretend that a seek was issued to read the entire tape.
1553 1494           */
1554 1495          if (length > session->ns_mover.md_bytes_left_to_read) {
1555 1496                  /* ndmpd_seek() never called? */
1556 1497                  if (session->ns_data.dd_read_length == 0) {
1557 1498                          session->ns_mover.md_bytes_left_to_read = ~0LL;
1558 1499                          session->ns_data.dd_read_offset = 0LL;
1559 1500                          session->ns_data.dd_read_length = ~0LL;
1560 1501                  } else {
1561 1502                          session->ns_mover.md_bytes_left_to_read = length;
1562 1503                          session->ns_data.dd_read_offset =
1563 1504                              session->ns_mover.md_position;
1564 1505                          session->ns_data.dd_read_length = length;
1565 1506                  }
1566 1507          }
1567 1508          /*
1568 1509           * Read as many records as necessary to satisfy the request.
1569 1510           */
1570 1511          while (count < length) {
1571 1512                  /*
1572 1513                   * If the end of the mover window has been reached,
1573 1514                   * then notify the client that a new data window is needed.
1574 1515                   */
1575 1516                  if (session->ns_mover.md_position >=
1576 1517                      session->ns_mover.md_window_offset +
1577 1518                      session->ns_mover.md_window_length) {
1578 1519  
  
    | 
      ↓ open down ↓ | 
    54 lines elided | 
    
      ↑ open up ↑ | 
  
1579 1520                          session->ns_mover.md_state = NDMP_MOVER_STATE_PAUSED;
1580 1521                          session->ns_mover.md_pause_reason =
1581 1522                              NDMP_MOVER_PAUSE_SEEK;
1582 1523                          pause_request.reason = NDMP_MOVER_PAUSE_SEEK;
1583 1524                          pause_request.seek_position =
1584 1525                              long_long_to_quad(session->ns_mover.md_position);
1585 1526  
1586 1527                          if (ndmp_send_request(session->ns_connection,
1587 1528                              NDMP_NOTIFY_MOVER_PAUSED, NDMP_NO_ERR,
1588 1529                              (void *) &pause_request, 0) < 0) {
1589      -                                NDMP_LOG(LOG_DEBUG,
1590      -                                    "Sending notify_mover_paused request");
1591 1530                                  ndmpd_mover_error(session,
1592 1531                                      NDMP_MOVER_HALT_INTERNAL_ERROR);
1593 1532                                  return (-1);
1594 1533                          }
1595 1534                          /*
1596 1535                           * Wait until the state is changed by
1597 1536                           * an abort or continue request.
1598 1537                           */
1599 1538                          if (ndmp_wait_for_mover(session) != 0)
1600 1539                                  return (1);
1601 1540                  }
1602 1541                  len = length - count;
1603 1542  
1604 1543                  /*
1605 1544                   * Prevent reading past the end of the window.
1606 1545                   */
1607 1546                  if (len >
1608 1547                      session->ns_mover.md_window_offset +
1609 1548                      session->ns_mover.md_window_length -
1610 1549                      session->ns_mover.md_position)
1611 1550                          len = session->ns_mover.md_window_offset +
1612 1551                              session->ns_mover.md_window_length -
1613 1552                              session->ns_mover.md_position;
1614 1553  
1615 1554                  /*
1616 1555                   * Copy from the data buffer first.
1617 1556                   */
1618 1557                  if (session->ns_mover.md_w_index -
1619 1558                      session->ns_mover.md_r_index != 0) {
1620 1559                          /*
1621 1560                           * Limit the copy to the amount of data in the buffer.
1622 1561                           */
1623 1562                          if (len > session->ns_mover.md_w_index -
1624 1563                              session->ns_mover.md_r_index)
1625 1564                                  len = session->ns_mover.md_w_index
1626 1565                                      - session->ns_mover.md_r_index;
1627 1566  
1628 1567                          (void) memcpy((void *) &data[count],
1629 1568                              &session->ns_mover.md_buf[session->
1630 1569                              ns_mover.md_r_index], len);
1631 1570                          count += len;
1632 1571                          session->ns_mover.md_r_index += len;
1633 1572                          session->ns_mover.md_bytes_left_to_read -= len;
1634 1573                          session->ns_mover.md_position += len;
1635 1574                          continue;
1636 1575                  }
1637 1576                  /*
1638 1577                   * Determine if data needs to be buffered or
1639 1578                   * can be read directly to user supplied location.
1640 1579                   * We can fast path the read if at least a full record
1641 1580                   * needs to be read and there is no seek pending.
1642 1581                   * This is done to eliminate a buffer copy.
1643 1582                   */
1644 1583                  if (len >= session->ns_mover.md_record_size &&
1645 1584                      session->ns_mover.md_position >=
1646 1585                      session->ns_mover.md_seek_position) {
1647 1586                          n = tape_read(session, &data[count]);
1648 1587                          if (n <= 0) {
1649 1588                                  if (n == TAPE_NO_WRITER_ERR)
1650 1589                                          return (1);
1651 1590  
1652 1591                                  ndmpd_mover_error(session,
1653 1592                                      (n == 0 ? NDMP_MOVER_HALT_ABORTED :
1654 1593                                      NDMP_MOVER_HALT_INTERNAL_ERROR));
1655 1594                                  return (n == 0) ? (1) : (-1);
1656 1595                          }
1657 1596                          count += n;
1658 1597                          session->ns_mover.md_bytes_left_to_read -= n;
1659 1598                          session->ns_mover.md_position += n;
1660 1599                          continue;
1661 1600                  }
1662 1601                  /* Read the next record into the buffer. */
1663 1602                  n = tape_read(session, session->ns_mover.md_buf);
1664 1603                  if (n <= 0) {
1665 1604                          if (n == TAPE_NO_WRITER_ERR)
  
    | 
      ↓ open down ↓ | 
    65 lines elided | 
    
      ↑ open up ↑ | 
  
1666 1605                                  return (1);
1667 1606  
1668 1607                          ndmpd_mover_error(session,
1669 1608                              (n == 0 ? NDMP_MOVER_HALT_ABORTED :
1670 1609                              NDMP_MOVER_HALT_INTERNAL_ERROR));
1671 1610                          return (n == 0) ? (1) : (-1);
1672 1611                  }
1673 1612                  session->ns_mover.md_w_index = n;
1674 1613                  session->ns_mover.md_r_index = 0;
1675 1614  
1676      -                NDMP_LOG(LOG_DEBUG, "n: %d", n);
1677      -
1678 1615                  /*
1679 1616                   * Discard data if the current data stream position is
1680 1617                   * prior to the seek position. This is necessary if a seek
1681 1618                   * request set the seek pointer to a position that is not a
1682 1619                   * record boundary. The seek request handler can only position
1683 1620                   * to the start of a record.
1684 1621                   */
1685 1622                  if (session->ns_mover.md_position <
1686 1623                      session->ns_mover.md_seek_position) {
1687 1624                          session->ns_mover.md_r_index =
1688 1625                              session->ns_mover.md_seek_position -
1689 1626                              session->ns_mover.md_position;
1690 1627                          session->ns_mover.md_position =
1691 1628                              session->ns_mover.md_seek_position;
1692 1629                  }
1693 1630          }
1694 1631  
1695 1632          return (0);
1696 1633  }
1697 1634  
1698 1635  
1699 1636  /*
1700 1637   * ndmpd_remote_read
1701 1638   *
1702 1639   * Reads data from the remote mover.
1703 1640   *
1704 1641   * Parameters:
1705 1642   *   session (input) - session pointer.
1706 1643   *   data    (input) - data to be written.
1707 1644   *   length  (input) - data length.
1708 1645   *
1709 1646   * Returns:
1710 1647   *   0 - data successfully read.
1711 1648   *  -1 - error.
1712 1649   *   1 - session terminated or operation aborted.
1713 1650   */
1714 1651  int
1715 1652  ndmpd_remote_read(ndmpd_session_t *session, char *data, ulong_t length)
1716 1653  {
1717 1654          ulong_t count = 0;
1718 1655          ssize_t n;
1719 1656          ulong_t len;
1720 1657          ndmp_notify_data_read_request request;
1721 1658  
1722 1659          while (count < length) {
1723 1660                  len = length - count;
1724 1661  
1725 1662                  /*
1726 1663                   * If the end of the seek window has been reached then
1727 1664                   * send an ndmp_read request to the client.
1728 1665                   * The NDMP client will then send a mover_data_read request to
1729 1666                   * the remote mover and the mover will send more data.
1730 1667                   * This condition can occur if the module attempts to read past
1731 1668                   * a seek window set via a prior call to ndmpd_seek() or
1732 1669                   * the module has not issued a seek. If no seek was issued then
1733 1670                   * pretend that a seek was issued to read the entire tape.
1734 1671                   */
1735 1672                  if (session->ns_mover.md_bytes_left_to_read == 0) {
1736 1673                          /* ndmpd_seek() never called? */
1737 1674                          if (session->ns_data.dd_read_length == 0) {
1738 1675                                  session->ns_mover.md_bytes_left_to_read = ~0LL;
1739 1676                                  session->ns_data.dd_read_offset = 0LL;
1740 1677                                  session->ns_data.dd_read_length = ~0LL;
1741 1678                          } else {
1742 1679                                  session->ns_mover.md_bytes_left_to_read = len;
1743 1680                                  session->ns_data.dd_read_offset =
1744 1681                                      session->ns_mover.md_position;
1745 1682                                  session->ns_data.dd_read_length = len;
  
    | 
      ↓ open down ↓ | 
    58 lines elided | 
    
      ↑ open up ↑ | 
  
1746 1683                          }
1747 1684  
1748 1685                          request.offset =
1749 1686                              long_long_to_quad(session->ns_data.dd_read_offset);
1750 1687                          request.length =
1751 1688                              long_long_to_quad(session->ns_data.dd_read_length);
1752 1689  
1753 1690                          if (ndmp_send_request_lock(session->ns_connection,
1754 1691                              NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
1755 1692                              (void *) &request, 0) < 0) {
1756      -                                NDMP_LOG(LOG_DEBUG,
1757      -                                    "Sending notify_data_read request");
1758 1693                                  return (-1);
1759 1694                          }
1760 1695                  }
1761 1696                  if (session->ns_eof == TRUE ||
1762 1697                      session->ns_data.dd_abort == TRUE)
1763 1698                          return (1);
1764 1699  
1765 1700                  /*
1766 1701                   * If the module called ndmpd_seek() prior to reading all of the
1767 1702                   * data that the remote mover was requested to send, then the
1768 1703                   * excess data from the seek has to be discardd.
1769 1704                   */
1770 1705                  if (session->ns_mover.md_discard_length != 0) {
1771 1706                          n = discard_data(session,
1772 1707                              (ulong_t)session->ns_mover.md_discard_length);
1773 1708                          if (n < 0)
  
    | 
      ↓ open down ↓ | 
    6 lines elided | 
    
      ↑ open up ↑ | 
  
1774 1709                                  return (-1);
1775 1710                          session->ns_mover.md_discard_length -= n;
1776 1711                          continue;
1777 1712                  }
1778 1713                  /*
1779 1714                   * Don't attempt to read more data than the remote is sending.
1780 1715                   */
1781 1716                  if (len > session->ns_mover.md_bytes_left_to_read)
1782 1717                          len = session->ns_mover.md_bytes_left_to_read;
1783 1718  
1784      -                NDMP_LOG(LOG_DEBUG, "len: %u", len);
1785      -
1786 1719                  if ((n = read(session->ns_data.dd_sock, &data[count],
1787 1720                      len)) < 0) {
1788      -                        NDMP_LOG(LOG_ERR, "Socket read error: %m.");
     1721 +                        syslog(LOG_ERR, "Socket read error: %m.");
1789 1722                          return (-1);
1790 1723                  }
1791 1724                  /* read returns 0 if the connection was closed */
1792 1725                  if (n == 0)
1793 1726                          return (-1);
1794 1727  
1795 1728                  count += n;
1796 1729                  session->ns_mover.md_bytes_left_to_read -= n;
1797 1730                  session->ns_mover.md_position += n;
1798 1731          }
1799 1732  
1800 1733          return (0);
1801 1734  }
1802 1735  
1803 1736  /* *** ndmpd internal functions ***************************************** */
1804 1737  
1805 1738  /*
1806 1739   * ndmpd_mover_init
1807 1740   *
1808 1741   * Initialize mover specific session variables.
1809 1742   * Don't initialize variables such as record_size that need to
1810 1743   * persist across data operations. A client may open a connection and
1811 1744   * do multiple backups after setting the record_size.
1812 1745   *
1813 1746   * Parameters:
1814 1747   *   session (input) - session pointer.
1815 1748   *
1816 1749   * Returns:
1817 1750   *   0 - success.
1818 1751   *  -1 - error.
1819 1752   */
1820 1753  int
1821 1754  ndmpd_mover_init(ndmpd_session_t *session)
1822 1755  {
1823 1756          session->ns_mover.md_state = NDMP_MOVER_STATE_IDLE;
1824 1757          session->ns_mover.md_pause_reason = NDMP_MOVER_PAUSE_NA;
1825 1758          session->ns_mover.md_halt_reason = NDMP_MOVER_HALT_NA;
1826 1759          session->ns_mover.md_data_written = 0LL;
1827 1760          session->ns_mover.md_seek_position = 0LL;
1828 1761          session->ns_mover.md_bytes_left_to_read = 0LL;
1829 1762          session->ns_mover.md_window_offset = 0LL;
1830 1763          session->ns_mover.md_window_length = MAX_WINDOW_SIZE;
1831 1764          session->ns_mover.md_position = 0LL;
1832 1765          session->ns_mover.md_discard_length = 0;
1833 1766          session->ns_mover.md_record_num = 0;
1834 1767          session->ns_mover.md_record_size = 0;
1835 1768          session->ns_mover.md_listen_sock = -1;
1836 1769          session->ns_mover.md_pre_cond = FALSE;
1837 1770          session->ns_mover.md_sock = -1;
1838 1771          session->ns_mover.md_r_index = 0;
1839 1772          session->ns_mover.md_w_index = 0;
1840 1773          session->ns_mover.md_buf = ndmp_malloc(MAX_RECORD_SIZE);
1841 1774          if (!session->ns_mover.md_buf)
1842 1775                  return (-1);
1843 1776  
1844 1777          if (ndmp_get_version(session->ns_connection) == NDMPV3) {
1845 1778                  session->ns_mover.md_mode = NDMP_MOVER_MODE_READ;
1846 1779                  (void) memset(&session->ns_mover.md_data_addr, 0,
1847 1780                      sizeof (ndmp_addr_v3));
1848 1781          }
1849 1782          return (0);
1850 1783  }
1851 1784  
1852 1785  
1853 1786  /*
1854 1787   * ndmpd_mover_shut_down
1855 1788   *
1856 1789   * Shutdown the mover. It closes all the sockets.
1857 1790   *
1858 1791   * Parameters:
1859 1792   *   session (input) - session pointer.
1860 1793   *
1861 1794   * Returns:
1862 1795   *   void
1863 1796   */
  
    | 
      ↓ open down ↓ | 
    65 lines elided | 
    
      ↑ open up ↑ | 
  
1864 1797  void
1865 1798  ndmpd_mover_shut_down(ndmpd_session_t *session)
1866 1799  {
1867 1800          ndmp_lbr_params_t *nlp;
1868 1801  
1869 1802          if ((nlp = ndmp_get_nlp(session)) == NULL)
1870 1803                  return;
1871 1804  
1872 1805          (void) mutex_lock(&nlp->nlp_mtx);
1873 1806          if (session->ns_mover.md_listen_sock != -1) {
1874      -                NDMP_LOG(LOG_DEBUG, "mover.listen_sock: %d",
1875      -                    session->ns_mover.md_listen_sock);
1876 1807                  (void) ndmpd_remove_file_handler(session,
1877 1808                      session->ns_mover.md_listen_sock);
1878 1809                  (void) close(session->ns_mover.md_listen_sock);
1879 1810                  session->ns_mover.md_listen_sock = -1;
1880 1811          }
1881 1812          if (session->ns_mover.md_sock != -1) {
1882      -                NDMP_LOG(LOG_DEBUG, "mover.sock: %d",
1883      -                    session->ns_mover.md_sock);
1884 1813                  (void) ndmpd_remove_file_handler(session,
1885 1814                      session->ns_mover.md_sock);
1886 1815                  (void) close(session->ns_mover.md_sock);
1887 1816                  session->ns_mover.md_sock = -1;
1888 1817          }
1889 1818          (void) cond_broadcast(&nlp->nlp_cv);
1890 1819          (void) mutex_unlock(&nlp->nlp_mtx);
1891 1820  }
1892 1821  
1893 1822  
1894 1823  /*
1895 1824   * ndmpd_mover_cleanup
1896 1825   *
1897 1826   * Parameters:
1898 1827   *   session (input) - session pointer.
1899 1828   *
1900 1829   * Returns:
1901 1830   *   void
1902 1831   */
1903 1832  void
1904 1833  ndmpd_mover_cleanup(ndmpd_session_t *session)
1905 1834  {
1906 1835          NDMP_FREE(session->ns_mover.md_buf);
1907 1836  }
1908 1837  
1909 1838  
1910 1839  /*
1911 1840   * ndmpd_mover_connect
1912 1841   *   Create a connection to the specified mover.
1913 1842   *
1914 1843   * Parameters:
1915 1844   *   session (input) - session pointer
1916 1845   *
1917 1846   * Returns:
1918 1847   *   error code.
1919 1848   */
1920 1849  ndmp_error
1921 1850  ndmpd_mover_connect(ndmpd_session_t *session, ndmp_mover_mode mover_mode)
1922 1851  {
1923 1852          ndmp_mover_addr *mover = &session->ns_data.dd_mover;
1924 1853          struct sockaddr_in sin;
1925 1854          int sock = -1;
1926 1855  
1927 1856          if (mover->addr_type == NDMP_ADDR_TCP) {
1928 1857                  if (mover->ndmp_mover_addr_u.addr.ip_addr) {
1929 1858                          (void) memset((void *) &sin, 0, sizeof (sin));
1930 1859                          sin.sin_family = AF_INET;
1931 1860                          sin.sin_addr.s_addr =
1932 1861                              htonl(mover->ndmp_mover_addr_u.addr.ip_addr);
1933 1862                          sin.sin_port =
1934 1863                              htons(mover->ndmp_mover_addr_u.addr.port);
1935 1864  
1936 1865                          /*
1937 1866                           * If the address type is TCP but both the address and
1938 1867                           * the port number are zero, we have to use a different
1939 1868                           * socket than the mover socket. This can happen when
1940 1869                           * using NDMP disk to disk copy (AKA D2D copy).
  
    | 
      ↓ open down ↓ | 
    47 lines elided | 
    
      ↑ open up ↑ | 
  
1941 1870                           * The NDMPCopy client will send a zero address to
1942 1871                           * direct the server to use the mover socket as the
1943 1872                           * data socket to receive the recovery data.
1944 1873                           */
1945 1874                          if (sin.sin_addr.s_addr == 0 && sin.sin_port == 0) {
1946 1875                                  session->ns_data.dd_sock =
1947 1876                                      session->ns_mover.md_sock;
1948 1877                                  return (NDMP_NO_ERR);
1949 1878                          }
1950 1879  
1951      -                        NDMP_LOG(LOG_DEBUG, "addr: %u port: %u",
     1880 +                        syslog(LOG_DEBUG, "addr: %u port: %u",
1952 1881                              mover->ndmp_mover_addr_u.addr.ip_addr,
1953 1882                              (ulong_t)sin.sin_port);
1954 1883  
1955 1884                          if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1956      -                                NDMP_LOG(LOG_DEBUG, "Socket error: %m");
     1885 +                                syslog(LOG_ERR, "Socket error: %m");
1957 1886                                  return (NDMP_IO_ERR);
1958 1887                          }
1959 1888                          if (connect(sock, (struct sockaddr *)&sin,
1960 1889                              sizeof (sin)) < 0) {
1961      -                                NDMP_LOG(LOG_DEBUG, "Connect error: %m");
     1890 +                                syslog(LOG_ERR, "Connect error: %m");
1962 1891                                  (void) close(sock);
1963 1892                                  return (NDMP_IO_ERR);
1964 1893                          }
1965 1894                          set_socket_options(sock);
1966 1895                  } else {
1967 1896                          if ((session->ns_mover.md_state !=
1968 1897                              NDMP_MOVER_STATE_ACTIVE) ||
1969 1898                              (session->ns_mover.md_sock == -1)) {
1970 1899  
1971      -                                NDMP_LOG(LOG_DEBUG,
     1900 +                                syslog(LOG_DEBUG,
1972 1901                                      "Not in active  state mover"
1973      -                                    "  state = %d or Invalid mover sock=%d",
     1902 +                                    "  state = %d or Illegal mover sock=%d",
1974 1903                                      session->ns_mover.md_state,
1975 1904                                      session->ns_mover.md_sock);
1976 1905                                  return (NDMP_ILLEGAL_STATE_ERR);
1977 1906                          }
1978 1907  
1979 1908                          sock = session->ns_mover.md_sock;
1980      -                        NDMP_LOG(LOG_DEBUG,
     1909 +                        syslog(LOG_DEBUG,
1981 1910                              "session: 0x%x setting data sock fd: %d to be"
1982 1911                              " same as listen_sock", session, sock);
1983 1912                  }
1984 1913  
1985      -                NDMP_LOG(LOG_DEBUG, "sock fd: %d", sock);
1986      -
1987 1914                  session->ns_data.dd_sock = sock;
1988 1915  
1989      -                NDMP_LOG(LOG_DEBUG, "data.mover_sock: %u", sock);
1990      -
1991 1916                  return (NDMP_NO_ERR);
1992 1917          }
1993 1918          /* Local mover connection. */
1994 1919  
1995 1920          if (session->ns_mover.md_state != NDMP_MOVER_STATE_LISTEN) {
1996      -                NDMP_LOG(LOG_DEBUG, "Mover is not in listen state");
1997 1921                  return (NDMP_ILLEGAL_STATE_ERR);
1998 1922          }
1999 1923          if (session->ns_tape.td_fd == -1) {
2000      -                NDMP_LOG(LOG_DEBUG, "Tape device not open");
     1924 +                syslog(LOG_ERR, "Tape device not open");
2001 1925                  return (NDMP_DEV_NOT_OPEN_ERR);
2002 1926          }
2003 1927          if (mover_mode == NDMP_MOVER_MODE_READ &&
2004 1928              session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
2005      -                NDMP_LOG(LOG_ERR, "Write protected device.");
     1929 +                syslog(LOG_ERR, "Write protected device.");
2006 1930                  return (NDMP_WRITE_PROTECT_ERR);
2007 1931          }
2008 1932          session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
2009 1933          session->ns_mover.md_mode = mover_mode;
2010 1934  
2011 1935          return (NDMP_NO_ERR);
2012 1936  }
2013 1937  
2014 1938  
2015 1939  
2016 1940  /*
2017 1941   * ndmpd_mover_seek
2018 1942   *
2019 1943   * Seek to the requested data stream position.
2020 1944   * If the requested offset is outside of the current window,
2021 1945   * the mover is paused and a notify_mover_paused request is sent
2022 1946   * notifying the client that a seek is required.
2023 1947   * If the requested offest is within the window but not within the
2024 1948   * current record, then the tape is positioned to the record containing
2025 1949   * the requested offest.
2026 1950   * The requested amount of data is then read from the tape device and
2027 1951   * written to the data connection.
2028 1952   *
2029 1953   * Parameters:
2030 1954   *   session (input) - session pointer.
2031 1955   *   offset  (input) - data stream position to seek to.
2032 1956   *   length  (input) - amount of data that will be read.
2033 1957   *
2034 1958   * Returns:
2035 1959   *   1 - seek pending completion by the NDMP client.
2036 1960   *   0 - seek successfully completed.
2037 1961   *  -1 - error.
2038 1962   */
2039 1963  int
2040 1964  ndmpd_mover_seek(ndmpd_session_t *session, u_longlong_t offset,
2041 1965      u_longlong_t length)
2042 1966  {
2043 1967          int ctlcmd;
2044 1968          int ctlcnt;
2045 1969          u_longlong_t tape_position;
2046 1970          u_longlong_t buf_position;
2047 1971          ndmp_notify_mover_paused_request pause_request;
2048 1972  
2049 1973          session->ns_mover.md_seek_position = offset;
2050 1974          session->ns_mover.md_bytes_left_to_read = length;
  
    | 
      ↓ open down ↓ | 
    35 lines elided | 
    
      ↑ open up ↑ | 
  
2051 1975  
2052 1976          /*
2053 1977           * If the requested position is outside of the window,
2054 1978           * notify the client that a seek is required.
2055 1979           */
2056 1980          if (session->ns_mover.md_seek_position <
2057 1981              session->ns_mover.md_window_offset ||
2058 1982              session->ns_mover.md_seek_position >=
2059 1983              session->ns_mover.md_window_offset +
2060 1984              session->ns_mover.md_window_length) {
2061      -                NDMP_LOG(LOG_DEBUG, "MOVER_PAUSE_SEEK(%llu)",
2062      -                    session->ns_mover.md_seek_position);
2063 1985  
2064 1986                  session->ns_mover.md_w_index = 0;
2065 1987                  session->ns_mover.md_r_index = 0;
2066 1988  
2067 1989                  session->ns_mover.md_state = NDMP_MOVER_STATE_PAUSED;
2068 1990                  session->ns_mover.md_pause_reason = NDMP_MOVER_PAUSE_SEEK;
2069 1991                  pause_request.reason = NDMP_MOVER_PAUSE_SEEK;
2070 1992                  pause_request.seek_position = long_long_to_quad(offset);
2071 1993  
2072 1994                  if (ndmp_send_request(session->ns_connection,
2073 1995                      NDMP_NOTIFY_MOVER_PAUSED, NDMP_NO_ERR,
2074 1996                      (void *) &pause_request, 0) < 0) {
2075      -                        NDMP_LOG(LOG_DEBUG,
2076      -                            "Sending notify_mover_paused request");
2077 1997                          return (-1);
2078 1998                  }
2079 1999                  return (1);
2080 2000          }
2081 2001          /*
2082 2002           * Determine the data stream position of the first byte in the
2083 2003           * data buffer.
2084 2004           */
2085 2005          buf_position = session->ns_mover.md_position -
2086 2006              (session->ns_mover.md_position % session->ns_mover.md_record_size);
2087 2007  
2088 2008          /*
2089 2009           * Determine the data stream position of the next byte that
2090 2010           * will be read from tape.
2091 2011           */
2092 2012          tape_position = buf_position;
2093 2013          if (session->ns_mover.md_w_index != 0)
  
    | 
      ↓ open down ↓ | 
    7 lines elided | 
    
      ↑ open up ↑ | 
  
2094 2014                  tape_position += session->ns_mover.md_record_size;
2095 2015  
2096 2016          /*
2097 2017           * Check if requested position is for data that has been read and is
2098 2018           * in the buffer.
2099 2019           */
2100 2020          if (offset >= buf_position && offset < tape_position) {
2101 2021                  session->ns_mover.md_position = offset;
2102 2022                  session->ns_mover.md_r_index = session->ns_mover.md_position -
2103 2023                      buf_position;
2104      -
2105      -                NDMP_LOG(LOG_DEBUG, "pos %llu r_index %u",
2106      -                    session->ns_mover.md_position,
2107      -                    session->ns_mover.md_r_index);
2108      -
2109 2024                  return (0);
2110 2025          }
2111 2026  
2112 2027          ctlcmd = 0;
2113 2028          if (tape_position > session->ns_mover.md_seek_position) {
2114 2029                  /* Need to seek backward. */
2115 2030                  ctlcmd = MTBSR;
2116 2031                  ctlcnt = (int)((tape_position - offset - 1)
2117 2032                      / session->ns_mover.md_record_size) + 1;
2118 2033                  tape_position -= ((u_longlong_t)(((tape_position - offset - 1) /
2119 2034                      session->ns_mover.md_record_size) + 1) *
2120 2035                      (u_longlong_t)session->ns_mover.md_record_size);
2121 2036  
2122 2037          } else if (offset >= tape_position + session->ns_mover.md_record_size) {
  
    | 
      ↓ open down ↓ | 
    4 lines elided | 
    
      ↑ open up ↑ | 
  
2123 2038                  /* Need to seek forward. */
2124 2039                  ctlcmd = MTFSR;
2125 2040                  ctlcnt = (int)((offset - tape_position)
2126 2041                      / session->ns_mover.md_record_size);
2127 2042                  tape_position += ((u_longlong_t)(((offset - tape_position) /
2128 2043                      session->ns_mover.md_record_size)) *
2129 2044                      (u_longlong_t)session->ns_mover.md_record_size);
2130 2045          }
2131 2046          /* Reposition the tape if necessary. */
2132 2047          if (ctlcmd) {
2133      -                NDMP_LOG(LOG_DEBUG, "cmd %d count %d",
2134      -                    ctlcmd, ctlcnt);
2135 2048                  (void) ndmp_mtioctl(session->ns_tape.td_fd, ctlcmd, ctlcnt);
2136 2049          }
2137 2050  
2138 2051          session->ns_mover.md_position = tape_position;
2139 2052          session->ns_mover.md_r_index = 0;
2140 2053          session->ns_mover.md_w_index = 0;
2141 2054  
2142      -        NDMP_LOG(LOG_DEBUG, "pos %llu", session->ns_mover.md_position);
2143      -
2144 2055          return (0);
2145 2056  }
2146 2057  
2147 2058  
2148 2059  /* ** static functions ************************************************** */
2149 2060  
2150 2061  /*
2151 2062   * create_listen_socket_v2
2152 2063   *
2153 2064   * Creates a socket for listening for accepting data connections.
2154 2065   *
2155 2066   * Parameters:
2156 2067   *   session (input)  - session pointer.
2157 2068   *   addr    (output) - location to store address of socket.
2158 2069   *   port    (output) - location to store port of socket.
2159 2070   *
2160 2071   * Returns:
2161 2072   *   0 - success.
2162 2073   *  -1 - error.
2163 2074   */
2164 2075  static int
2165 2076  create_listen_socket_v2(ndmpd_session_t *session, ulong_t *addr, ushort_t *port)
2166 2077  {
2167 2078          session->ns_mover.md_listen_sock = ndmp_create_socket(addr, port);
2168 2079          if (session->ns_mover.md_listen_sock < 0)
2169 2080                  return (-1);
2170 2081  
2171 2082          /*
2172 2083           * Add a file handler for the listen socket.
2173 2084           * ndmpd_select will call accept_connection when a
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
2174 2085           * connection is ready to be accepted.
2175 2086           */
2176 2087          if (ndmpd_add_file_handler(session, (void *) session,
2177 2088              session->ns_mover.md_listen_sock, NDMPD_SELECT_MODE_READ, HC_MOVER,
2178 2089              accept_connection) < 0) {
2179 2090                  (void) close(session->ns_mover.md_listen_sock);
2180 2091                  session->ns_mover.md_listen_sock = -1;
2181 2092                  return (-1);
2182 2093          }
2183 2094  
2184      -        NDMP_LOG(LOG_DEBUG, "addr: 0x%x, port: %d", *addr, *port);
2185 2095          return (0);
2186 2096  }
2187 2097  
2188 2098  /*
2189 2099   * accept_connection
2190 2100   *
2191 2101   * Accept a data connection from a data server.
2192 2102   * Called by ndmpd_select when a connection is pending on
2193 2103   * the mover listen socket.
2194 2104   *
2195 2105   * Parameters:
2196 2106   *   cookie  (input) - session pointer.
2197 2107   *   fd      (input) - file descriptor.
2198 2108   *   mode    (input) - select mode.
2199 2109   *
2200 2110   * Returns:
2201 2111   *   void.
2202 2112   */
2203 2113  /*ARGSUSED*/
2204 2114  static void
2205 2115  accept_connection(void *cookie, int fd, ulong_t mode)
2206 2116  {
2207 2117          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
2208 2118          struct sockaddr_in from;
2209 2119          int from_len;
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
2210 2120  
2211 2121          from_len = sizeof (from);
2212 2122          session->ns_mover.md_sock = accept(fd, (struct sockaddr *)&from,
2213 2123              &from_len);
2214 2124  
2215 2125          (void) ndmpd_remove_file_handler(session, fd);
2216 2126          (void) close(session->ns_mover.md_listen_sock);
2217 2127          session->ns_mover.md_listen_sock = -1;
2218 2128  
2219 2129          if (session->ns_mover.md_sock < 0) {
2220      -                NDMP_LOG(LOG_DEBUG, "Accept error: %m");
     2130 +                syslog(LOG_ERR, "Accept error: %m");
2221 2131                  ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_ERROR);
2222 2132                  return;
2223 2133          }
2224 2134          set_socket_options(session->ns_mover.md_sock);
2225 2135  
2226      -        NDMP_LOG(LOG_DEBUG, "sock fd: %d", session->ns_mover.md_sock);
2227      -
2228 2136          if (session->ns_mover.md_mode == NDMP_MOVER_MODE_READ) {
2229 2137                  if (start_mover_for_backup(session) < 0) {
2230 2138                          ndmpd_mover_error(session,
2231 2139                              NDMP_MOVER_HALT_INTERNAL_ERROR);
2232 2140                          return;
2233 2141                  }
2234      -                NDMP_LOG(LOG_DEBUG, "Backup connection established by %s:%d",
     2142 +                syslog(LOG_DEBUG, "Backup connection established by %s:%d",
2235 2143                      inet_ntoa(IN_ADDR(from.sin_addr.s_addr)),
2236 2144                      ntohs(from.sin_port));
2237 2145          } else {
2238      -                NDMP_LOG(LOG_DEBUG, "Restore connection established by %s:%d",
     2146 +                syslog(LOG_DEBUG, "Restore connection established by %s:%d",
2239 2147                      inet_ntoa(IN_ADDR(from.sin_addr.s_addr)),
2240 2148                      ntohs(from.sin_port));
2241 2149          }
2242 2150  
2243      -        NDMP_LOG(LOG_DEBUG, "Received connection");
2244      -
2245 2151          session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
2246 2152  }
2247 2153  
2248 2154  /*
2249 2155   * tape_read
2250 2156   *
2251 2157   * Reads a data record from tape. Detects and handles EOT conditions.
2252 2158   *
2253 2159   * Parameters:
2254 2160   *   session (input) - session pointer.
2255 2161   *   data    (input) - location to read data to.
2256 2162   *
2257 2163   * Returns:
2258 2164   *    0 - operation aborted.
2259 2165   *   -1 - tape read error.
2260 2166   *   otherwise - number of bytes read.
2261 2167   */
  
    | 
      ↓ open down ↓ | 
    7 lines elided | 
    
      ↑ open up ↑ | 
  
2262 2168  static int
2263 2169  tape_read(ndmpd_session_t *session, char *data)
2264 2170  {
2265 2171          ssize_t n;
2266 2172          int err;
2267 2173          int count = session->ns_mover.md_record_size;
2268 2174  
2269 2175          for (; ; ) {
2270 2176                  n = read(session->ns_tape.td_fd, data, count);
2271 2177                  if (n < 0) {
2272      -                        NDMP_LOG(LOG_ERR, "Tape read error: %m.");
     2178 +                        syslog(LOG_ERR, "Tape read error: %m.");
2273 2179                          return (TAPE_READ_ERR);
2274 2180                  }
2275 2181                  NS_ADD(rtape, n);
2276 2182  
2277 2183                  if (n == 0) {
2278 2184                          if (!is_writer_running(session))
2279 2185                                  return (TAPE_NO_WRITER_ERR);
2280 2186  
2281 2187                          /*
2282 2188                           * End of media reached.
2283 2189                           * Notify client and wait for the client to
2284 2190                           * either abort the data operation or continue the
2285 2191                           * operation after changing the tape.
2286 2192                           */
2287 2193                          NDMP_APILOG((void*)session, NDMP_LOG_NORMAL,
2288 2194                              ++ndmp_log_msg_id,
2289 2195                              "End of tape reached. Load next tape");
2290 2196  
2291      -                        NDMP_LOG(LOG_DEBUG,
     2197 +                        syslog(LOG_DEBUG,
2292 2198                              "End of tape reached. Load next tape");
2293 2199  
2294 2200                          err = change_tape(session);
2295 2201  
2296 2202                          /* Operation aborted or connection terminated? */
2297 2203                          if (err < 0) {
2298 2204                                  /*
2299 2205                                   * K.L. Go back one record if it is read
2300 2206                                   * but not used.
2301 2207                                   */
2302 2208  
2303 2209                                  if (count != session->ns_mover.md_record_size) {
2304 2210                                          (void) ndmp_mtioctl(
2305 2211                                              session->ns_tape.td_fd, MTBSR, 1);
2306 2212                                  }
2307 2213                                  return (0);
2308 2214                          }
2309 2215                          /* Retry the read from the new tape. */
2310 2216                          continue;
2311 2217                  }
2312 2218  
2313 2219                  /* Change to pass Veritas Netbackup prequal test. */
2314 2220                  data += n;
2315 2221                  count -= n;
2316 2222                  if (count <= 0) {
2317 2223                          session->ns_mover.md_record_num++;
2318 2224                          session->ns_tape.td_record_count++;
2319 2225                          return (n);
2320 2226                  }
2321 2227          }
2322 2228  }
2323 2229  
2324 2230  /*
2325 2231   * change_tape
2326 2232   *
2327 2233   * Send a notify_pause request (protocol version 1) or
2328 2234   * notify_mover_pause request (protocol version 2) to the
2329 2235   * NDMP client to inform
2330 2236   * the client that a tape volume change is required.
2331 2237   * Process messages until the data/mover operation is either aborted
2332 2238   * or continued.
2333 2239   *
2334 2240   * Parameters:
2335 2241   *   client_data (input) - session pointer.
2336 2242   *
2337 2243   * Returns:
2338 2244   *   0 - operation has been continued.
2339 2245   *  -1 - operation has been aborted.
2340 2246   */
2341 2247  static int
2342 2248  change_tape(ndmpd_session_t *session)
2343 2249  {
2344 2250          ndmp_notify_mover_paused_request request;
2345 2251  
  
    | 
      ↓ open down ↓ | 
    44 lines elided | 
    
      ↑ open up ↑ | 
  
2346 2252          session->ns_mover.md_state = NDMP_MOVER_STATE_PAUSED;
2347 2253  
2348 2254          if (session->ns_mover.md_mode == NDMP_MOVER_MODE_READ)
2349 2255                  session->ns_mover.md_pause_reason = NDMP_MOVER_PAUSE_EOM;
2350 2256          else
2351 2257                  session->ns_mover.md_pause_reason = NDMP_MOVER_PAUSE_EOF;
2352 2258  
2353 2259          request.reason = session->ns_mover.md_pause_reason;
2354 2260          request.seek_position = long_long_to_quad(0LL);
2355 2261  
2356      -        NDMP_LOG(LOG_DEBUG, "ndmp_send_request: MOVER_PAUSED, reason: %d",
     2262 +        syslog(LOG_DEBUG, "ndmp_send_request: MOVER_PAUSED, reason: %d",
2357 2263              session->ns_mover.md_pause_reason);
2358 2264  
2359 2265          if (ndmp_send_request(session->ns_connection,
2360 2266              NDMP_NOTIFY_MOVER_PAUSED, NDMP_NO_ERR,
2361 2267              (void *) &request, 0) < 0) {
2362      -                NDMP_LOG(LOG_DEBUG,
2363      -                    "Sending notify_mover_paused request");
2364 2268                  return (-1);
2365 2269          }
2366 2270          /*
2367 2271           * Wait for until the state is changed by
2368 2272           * an abort or continue request.
2369 2273           */
2370 2274          return (ndmp_wait_for_mover(session));
2371 2275  }
2372 2276  
2373 2277  
2374 2278  /*
2375 2279   * discard_data
2376 2280   *
2377 2281   * Read and discard data from the data connection.
2378 2282   * Called when a module has called ndmpd_seek() prior to
2379 2283   * reading all of the data from the previous seek.
2380 2284   *
2381 2285   * Parameters:
2382 2286   *   session (input) - session pointer.
2383 2287   *
2384 2288   * Returns:
2385 2289   *   number of bytes read and discarded.
2386 2290   *  -1 - error.
2387 2291   */
2388 2292  static int
2389 2293  discard_data(ndmpd_session_t *session, ulong_t length)
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
2390 2294  {
2391 2295          int n;
2392 2296          char *addr;
2393 2297  
2394 2298          if ((addr = ndmp_malloc(length)) == NULL)
2395 2299                  return (-1);
2396 2300  
2397 2301          /* Read and discard the data. */
2398 2302          n = read(session->ns_mover.md_sock, addr, length);
2399 2303          if (n < 0) {
2400      -                NDMP_LOG(LOG_ERR, "Socket read error: %m.");
     2304 +                syslog(LOG_ERR, "Socket read error: %m.");
2401 2305                  free(addr);
2402 2306                  return (-1);
2403 2307          }
2404 2308  
2405 2309          free(addr);
2406 2310          return (n);
2407 2311  }
2408 2312  
2409 2313  
2410 2314  /*
2411 2315   * mover_tape_read_one_buf
2412 2316   *
2413 2317   * Read one buffer from the tape. This is used by mover_tape_reader
2414 2318   *
2415 2319   * Parameters:
2416 2320   *   session (input) - session pointer.
2417 2321   *   buf (input) - buffer read
2418 2322   *
2419 2323   * Returns:
2420 2324   *   0: on success
2421 2325   *  -1: otherwise
2422 2326   */
2423 2327  static int
2424 2328  mover_tape_read_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf)
2425 2329  {
2426 2330          int n;
2427 2331  
2428 2332          tlm_buffer_mark_empty(buf);
2429 2333  
2430 2334          /*
2431 2335           * If the end of the mover window has been reached,
2432 2336           * then notify the client that a seek is needed.
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
2433 2337           * Remove the file handler to prevent this function from
2434 2338           * being called. The handler will be reinstalled in
2435 2339           * ndmpd_mover_continue.
2436 2340           */
2437 2341  
2438 2342          if (session->ns_mover.md_position >=
2439 2343              session->ns_mover.md_window_offset +
2440 2344              session->ns_mover.md_window_length) {
2441 2345                  ndmp_notify_mover_paused_request pause_request;
2442 2346  
2443      -                NDMP_LOG(LOG_DEBUG, "end of mover window");
2444      -
2445 2347                  session->ns_mover.md_state = NDMP_MOVER_STATE_PAUSED;
2446 2348                  session->ns_mover.md_pause_reason = NDMP_MOVER_PAUSE_SEEK;
2447 2349                  pause_request.reason = NDMP_MOVER_PAUSE_SEEK;
2448 2350                  pause_request.seek_position =
2449 2351                      long_long_to_quad(session->ns_mover.md_position);
2450 2352  
2451 2353                  if (ndmp_send_request(session->ns_connection,
2452 2354                      NDMP_NOTIFY_MOVER_PAUSED, NDMP_NO_ERR,
2453 2355                      (void *) &pause_request, 0) < 0) {
2454      -                        NDMP_LOG(LOG_DEBUG,
2455      -                            "Sending notify_mover_paused request");
2456 2356                          ndmpd_mover_error(session,
2457 2357                              NDMP_MOVER_HALT_INTERNAL_ERROR);
2458 2358                  }
2459 2359                  buf->tb_errno = EIO;
2460 2360                  return (TAPE_READ_ERR);
2461 2361          }
2462 2362  
2463 2363          n = tape_read(session, buf->tb_buffer_data);
2464 2364  
2465      -        NDMP_LOG(LOG_DEBUG, "read %d bytes from tape", n);
2466      -
2467 2365          if (n <= 0) {
2468 2366                  if (n < 0)
2469 2367                          ndmpd_mover_error(session,
2470 2368                              (n == 0 ? NDMP_MOVER_HALT_ABORTED :
2471 2369                              NDMP_MOVER_HALT_INTERNAL_ERROR));
2472 2370                  return (TAPE_READ_ERR);
2473 2371          }
2474 2372  
2475 2373          buf->tb_full = TRUE;
2476 2374          buf->tb_buffer_size = session->ns_mover.md_record_size;
2477 2375  
2478 2376          /*
2479 2377           * Discard data if the current data stream position is
2480 2378           * prior to the seek position. This is necessary if a seek
2481 2379           * request set the seek pointer to a position that is not a
2482 2380           * record boundary. The seek request handler can only position
2483 2381           * to the start of a record.
2484 2382           */
2485 2383          if (session->ns_mover.md_position < session->ns_mover.md_seek_position)
2486 2384                  session->ns_mover.md_position =
2487 2385                      session->ns_mover.md_seek_position;
2488 2386  
2489 2387          return (0);
2490 2388  }
2491 2389  
2492 2390  
2493 2391  /*
2494 2392   * mover_tape_reader
2495 2393   *
2496 2394   * Mover tape reader thread. It is launched when the mover is started
2497 2395   * for restore.
2498 2396   *
2499 2397   * Parameters:
2500 2398   *   session (input) - session pointer.
2501 2399   *
2502 2400   * Returns:
2503 2401   *   0: on success
2504 2402   *  -1: otherwise
2505 2403   */
2506 2404  int
2507 2405  mover_tape_reader(ndmpd_session_t *session)
  
    | 
      ↓ open down ↓ | 
    31 lines elided | 
    
      ↑ open up ↑ | 
  
2508 2406  {
2509 2407          int bidx;       /* buffer index */
2510 2408          int rv;
2511 2409          ndmp_lbr_params_t *nlp;
2512 2410          tlm_buffer_t *buf;
2513 2411          tlm_buffers_t *bufs;
2514 2412          tlm_cmd_t *lcmd;        /* Local command */
2515 2413          tlm_commands_t *cmds;   /* Commands structure */
2516 2414  
2517 2415          if ((nlp = ndmp_get_nlp(session)) == NULL) {
2518      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
2519 2416                  return (-1);
2520 2417          }
2521 2418  
2522 2419          cmds = &nlp->nlp_cmds;
2523 2420          lcmd = cmds->tcs_command;
2524 2421          bufs = lcmd->tc_buffers;
2525 2422  
2526 2423          lcmd->tc_ref++;
2527 2424          cmds->tcs_reader_count++;
2528 2425  
2529 2426          /*
  
    | 
      ↓ open down ↓ | 
    1 lines elided | 
    
      ↑ open up ↑ | 
  
2530 2427           * Let our parent thread know that we are running.
2531 2428           */
2532 2429          tlm_cmd_signal(cmds->tcs_command, TLM_TAPE_READER);
2533 2430  
2534 2431          buf = tlm_buffer_in_buf(bufs, &bidx);
2535 2432          while (cmds->tcs_reader == TLM_RESTORE_RUN &&
2536 2433              lcmd->tc_reader == TLM_RESTORE_RUN) {
2537 2434                  buf = tlm_buffer_in_buf(bufs, NULL);
2538 2435  
2539 2436                  if (buf->tb_full) {
2540      -                        NDMP_LOG(LOG_DEBUG, "R%d", bidx);
     2437 +                        syslog(LOG_DEBUG, "R%d", bidx);
2541 2438                          /*
2542 2439                           * The buffer is still full, wait for the consumer
2543 2440                           * thread to use it.
2544 2441                           */
2545 2442                          tlm_buffer_out_buf_timed_wait(bufs, 100);
2546 2443  
2547 2444                  } else {
2548      -                        NDMP_LOG(LOG_DEBUG, "r%d", bidx);
     2445 +                        syslog(LOG_DEBUG, "r%d", bidx);
2549 2446  
2550 2447                          rv = mover_tape_read_one_buf(session, buf);
2551 2448                          /*
2552 2449                           * If there was an error while reading, such as
2553 2450                           * end of stream.
2554 2451                           */
2555 2452                          if (rv < 0) {
2556      -                                NDMP_LOG(LOG_DEBUG, "Exiting, rv: %d", rv);
     2453 +                                syslog(LOG_DEBUG, "Exiting, rv: %d", rv);
2557 2454                                  break;
2558 2455                          }
2559 2456  
2560 2457                          /*
2561 2458                           * Can we do more buffering?
2562 2459                           */
2563 2460                          if (is_buffer_erroneous(buf)) {
2564      -                                NDMP_LOG(LOG_DEBUG,
     2461 +                                syslog(LOG_DEBUG,
2565 2462                                      "Exiting, errno: %d, eot: %d, eof: %d",
2566 2463                                      buf->tb_errno, buf->tb_eot, buf->tb_eof);
2567 2464                                  break;
2568 2465                          }
2569 2466  
2570 2467                          (void) tlm_buffer_advance_in_idx(bufs);
2571 2468                          tlm_buffer_release_in_buf(bufs);
2572 2469                          bidx = bufs->tbs_buffer_in;
2573 2470                  }
2574 2471          }
2575 2472  
2576 2473          /* If the consumer is waiting for us, wake it up. */
2577 2474          tlm_buffer_release_in_buf(bufs);
2578 2475  
2579 2476          /*
2580 2477           * Clean up.
2581 2478           */
2582 2479          cmds->tcs_reader_count--;
2583 2480          lcmd->tc_ref--;
2584 2481          lcmd->tc_writer = TLM_STOP;
2585 2482          return (0);
2586 2483  }
2587 2484  
2588 2485  
2589 2486  /*
2590 2487   * mover_socket_write_one_buf
2591 2488   *
2592 2489   * Write one buffer to the network socket. This is used by mover_socket_writer
2593 2490   *
2594 2491   * Parameters:
2595 2492   *   session (input) - session pointer.
2596 2493   *   buf (input) - buffer read
2597 2494   *
2598 2495   * Returns:
2599 2496   *   0: on success
2600 2497   *  -1: otherwise
2601 2498   */
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
2602 2499  static int
2603 2500  mover_socket_write_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf)
2604 2501  {
2605 2502          int n;
2606 2503  
2607 2504          /* Write the data to the data connection. */
2608 2505          errno = 0;
2609 2506          n = write(session->ns_mover.md_sock, buf->tb_buffer_data,
2610 2507              buf->tb_buffer_size);
2611 2508  
2612      -        NDMP_LOG(LOG_DEBUG, "n: %d, len: %d", n, buf->tb_buffer_size);
2613      -
2614 2509          if (n < 0) {
2615      -                NDMP_LOG(LOG_DEBUG, "n: %d, errno: %m", n);
2616 2510                  ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
2617 2511                  return (-1);
2618 2512          }
2619 2513  
2620 2514          session->ns_mover.md_position += n;
2621 2515          session->ns_mover.md_bytes_left_to_read -= n;
2622 2516          tlm_buffer_mark_empty(buf);
2623 2517  
2624 2518          /*
2625 2519           * If the read limit has been reached,
2626 2520           * then remove the file handler to prevent this
2627 2521           * function from getting called. The next mover_read request
2628 2522           * will reinstall the handler.
2629 2523           */
2630 2524          if (session->ns_mover.md_bytes_left_to_read == 0) {
2631      -                NDMP_LOG(LOG_DEBUG, "bytes_left_to_read == 0");
2632 2525                  (void) ndmpd_remove_file_handler(session,
2633 2526                      session->ns_mover.md_sock);
2634 2527                  return (-1);
2635 2528          }
2636 2529  
2637 2530          return (0);
2638 2531  }
2639 2532  
2640 2533  
2641 2534  
2642 2535  /*
2643 2536   * mover_socket_writer
2644 2537   *
2645 2538   * Mover's socket writer thread. This thread sends the read buffer
2646 2539   * from the tape to the data server through the network socket.
2647 2540   *
2648 2541   * Parameters:
2649 2542   *   session (input) - session pointer.
2650 2543   *
2651 2544   * Returns:
2652 2545   *   0: on success
2653 2546   *  -1: otherwise
2654 2547   */
2655 2548  int
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
2656 2549  mover_socket_writer(ndmpd_session_t *session)
2657 2550  {
2658 2551          int bidx;       /* buffer index */
2659 2552          ndmp_lbr_params_t *nlp;
2660 2553          tlm_buffer_t *buf;
2661 2554          tlm_buffers_t *bufs;
2662 2555          tlm_cmd_t *lcmd;        /* Local command */
2663 2556          tlm_commands_t *cmds;   /* Commands structure */
2664 2557  
2665 2558          if ((nlp = ndmp_get_nlp(session)) == NULL) {
2666      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
2667 2559                  return (-1);
2668 2560          }
2669 2561  
2670 2562          cmds = &nlp->nlp_cmds;
2671 2563          lcmd = cmds->tcs_command;
2672 2564          bufs = lcmd->tc_buffers;
2673 2565  
2674 2566          lcmd->tc_ref++;
2675 2567          cmds->tcs_writer_count++;
2676 2568  
2677 2569          /*
  
    | 
      ↓ open down ↓ | 
    1 lines elided | 
    
      ↑ open up ↑ | 
  
2678 2570           * Let our parent thread know that we are running.
2679 2571           */
2680 2572          tlm_cmd_signal(cmds->tcs_command, TLM_SOCK_WRITER);
2681 2573  
2682 2574          bidx = bufs->tbs_buffer_out;
2683 2575          while (cmds->tcs_writer != (int)TLM_ABORT &&
2684 2576              lcmd->tc_writer != (int)TLM_ABORT) {
2685 2577                  buf = &bufs->tbs_buffer[bidx];
2686 2578  
2687 2579                  if (buf->tb_full) {
2688      -                        NDMP_LOG(LOG_DEBUG, "w%d", bidx);
     2580 +                        syslog(LOG_DEBUG, "w%d", bidx);
2689 2581  
2690 2582                          if (mover_socket_write_one_buf(session, buf) < 0) {
2691      -                                NDMP_LOG(LOG_DEBUG,
2692      -                                    "mover_socket_write_one_buf() < 0");
2693 2583                                  break;
2694 2584                          }
2695 2585  
2696 2586                          (void) tlm_buffer_advance_out_idx(bufs);
2697 2587                          tlm_buffer_release_out_buf(bufs);
2698 2588                          bidx = bufs->tbs_buffer_out;
2699 2589                  } else {
2700 2590                          if (lcmd->tc_writer != TLM_RESTORE_RUN) {
2701 2591                                  /* No more data is coming, time to exit */
2702      -                                NDMP_LOG(LOG_DEBUG, "Time to exit");
2703 2592                                  break;
2704 2593                          }
2705      -                        NDMP_LOG(LOG_DEBUG, "W%d", bidx);
     2594 +                        syslog(LOG_DEBUG, "W%d", bidx);
2706 2595                          /*
2707 2596                           * The buffer is not full, wait for the producer
2708 2597                           * thread to fill it.
2709 2598                           */
2710 2599                          tlm_buffer_in_buf_timed_wait(bufs, 100);
2711 2600                  }
2712 2601          }
2713 2602  
2714 2603          if (cmds->tcs_writer == (int)TLM_ABORT)
2715      -                NDMP_LOG(LOG_DEBUG, "cmds->tcs_writer == (int)TLM_ABORT");
     2604 +                syslog(LOG_DEBUG, "cmds->tcs_writer == (int)TLM_ABORT");
2716 2605          if (lcmd->tc_writer == (int)TLM_ABORT)
2717      -                NDMP_LOG(LOG_DEBUG, "lcmd->tc_writer == TLM_ABORT");
     2606 +                syslog(LOG_DEBUG, "lcmd->tc_writer == TLM_ABORT");
2718 2607  
2719 2608          /* If the producer is waiting for us, wake it up. */
2720 2609          tlm_buffer_release_out_buf(bufs);
2721 2610  
2722 2611          /*
2723 2612           * Clean up.
2724 2613           */
2725 2614          cmds->tcs_writer_count--;
2726 2615          lcmd->tc_ref--;
2727 2616          lcmd->tc_reader = TLM_STOP;
2728 2617          return (0);
2729 2618  }
2730 2619  
2731 2620  
2732 2621  /*
2733 2622   * start_mover_for_restore
2734 2623   *
2735 2624   * Creates the mover tape reader and network writer threads for
2736 2625   * the mover to perform the 3-way restore.
2737 2626   *
2738 2627   * Parameters:
2739 2628   *   session (input) - session pointer.
2740 2629   *
2741 2630   * Returns:
2742 2631   *   0: on success
2743 2632   *  -1: otherwise
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
2744 2633   */
2745 2634  static int
2746 2635  start_mover_for_restore(ndmpd_session_t *session)
2747 2636  {
2748 2637          ndmp_lbr_params_t *nlp;
2749 2638          tlm_commands_t *cmds;
2750 2639          long xfer_size;
2751 2640          int rc;
2752 2641  
2753 2642          if ((nlp = ndmp_get_nlp(session)) == NULL) {
2754      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
2755 2643                  return (-1);
2756 2644          }
2757 2645  
2758 2646          cmds = &nlp->nlp_cmds;
2759 2647          (void) memset(cmds, 0, sizeof (*cmds));
2760 2648          cmds->tcs_reader = cmds->tcs_writer = TLM_RESTORE_RUN;
2761 2649          xfer_size = ndmp_buffer_get_size(session);
2762 2650          cmds->tcs_command = tlm_create_reader_writer_ipc(FALSE, xfer_size);
2763 2651          if (cmds->tcs_command == NULL)
2764 2652                  return (-1);
2765 2653  
2766 2654          cmds->tcs_command->tc_reader = TLM_RESTORE_RUN;
2767 2655          cmds->tcs_command->tc_writer = TLM_RESTORE_RUN;
2768 2656  
  
    | 
      ↓ open down ↓ | 
    4 lines elided | 
    
      ↑ open up ↑ | 
  
2769 2657          /*
2770 2658           * We intentionnally don't wait for the threads to start since the
2771 2659           * reply of the request (which resulted in calling this function)
2772 2660           * must be sent to the client before probable errors are sent
2773 2661           * to the client.
2774 2662           */
2775 2663          rc = pthread_create(NULL, NULL, (funct_t)mover_tape_reader, session);
2776 2664          if (rc == 0) {
2777 2665                  tlm_cmd_wait(cmds->tcs_command, TLM_TAPE_READER);
2778 2666          } else {
2779      -                NDMP_LOG(LOG_DEBUG, "Launch mover_tape_reader: %s",
2780      -                    strerror(rc));
2781 2667                  return (-1);
2782 2668          }
2783 2669  
2784 2670          rc = pthread_create(NULL, NULL, (funct_t)mover_socket_writer, session);
2785 2671          if (rc == 0) {
2786 2672                  tlm_cmd_wait(cmds->tcs_command, TLM_SOCK_WRITER);
2787 2673          } else {
2788      -                NDMP_LOG(LOG_DEBUG, "Launch mover_socket_writer: %s",
2789      -                    strerror(rc));
2790 2674                  return (-1);
2791 2675          }
2792 2676  
2793 2677          tlm_release_reader_writer_ipc(cmds->tcs_command);
2794 2678          return (0);
2795 2679  }
2796 2680  
2797 2681  
2798 2682  /*
2799 2683   * mover_socket_read_one_buf
2800 2684   *
2801 2685   * Read one buffer from the network socket for the mover. This is used
2802 2686   * by mover_socket_reader
2803 2687   *
2804 2688   * Parameters:
2805 2689   *   session (input) - session pointer.
2806 2690   *   buf (input) - buffer read
2807 2691   *   read_size (input) - size to be read
2808 2692   *
2809 2693   * Returns:
2810 2694   *   0: on success
2811 2695   *  -1: otherwise
2812 2696   */
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
2813 2697  static int
2814 2698  mover_socket_read_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf,
2815 2699      long read_size)
2816 2700  {
2817 2701          int n, index;
2818 2702          long toread;
2819 2703  
2820 2704          tlm_buffer_mark_empty(buf);
2821 2705          for (index = 0, toread = read_size; toread > 0; ) {
2822 2706                  errno = 0;
2823      -                NDMP_LOG(LOG_DEBUG, "index: %d, toread: %d", index, toread);
2824      -
2825 2707                  n = read(session->ns_mover.md_sock, &buf->tb_buffer_data[index],
2826 2708                      toread);
2827 2709                  if (n == 0) {
2828      -                        NDMP_LOG(LOG_DEBUG, "n: %d", n);
2829 2710                          break;
2830 2711                  } else if (n > 0) {
2831      -                        NDMP_LOG(LOG_DEBUG, "n: %d", n);
2832 2712                          index += n;
2833 2713                          toread -= n;
2834 2714                  } else {
2835 2715                          buf->tb_eof = TRUE;
2836 2716                          buf->tb_errno = errno;
2837 2717                          buf->tb_buffer_size = 0;
2838      -                        NDMP_LOG(LOG_DEBUG, "n: %d, errno: %m", n);
2839 2718                          return (-1);
2840 2719                  }
2841 2720          }
2842 2721  
2843 2722          if (index > 0) {
2844 2723                  buf->tb_full = TRUE;
2845 2724                  buf->tb_buffer_size = read_size;
2846 2725                  if (read_size > 0)
2847 2726                          (void) memset(&buf->tb_buffer_data[index], 0,
2848 2727                              read_size - index);
2849 2728          } else {
2850 2729                  buf->tb_eof = TRUE;
2851 2730                  buf->tb_buffer_size = 0;
2852 2731          }
2853 2732  
2854      -        NDMP_LOG(LOG_DEBUG, "full: %d, eot: %d, eof: %d,"
     2733 +        syslog(LOG_DEBUG, "full: %d, eot: %d, eof: %d,"
2855 2734              " errno: %d, size: %d, data: 0x%x",
2856 2735              buf->tb_full, buf->tb_eot, buf->tb_eof, buf->tb_errno,
2857 2736              buf->tb_buffer_size, buf->tb_buffer_data);
2858 2737  
2859 2738          return (0);
2860 2739  }
2861 2740  
2862 2741  
2863 2742  
2864 2743  /*
2865 2744   * mover_socket_reader
2866 2745   *
2867 2746   * Mover socket reader thread. This is used when reading data from the
2868 2747   * network socket for performing remote backups.
2869 2748   *
2870 2749   * Parameters:
2871 2750   *   session (input) - session pointer.
2872 2751   *
2873 2752   * Returns:
2874 2753   *   0: on success
2875 2754   *  -1: otherwise
2876 2755   */
2877 2756  int
2878 2757  mover_socket_reader(ndmpd_session_t *session)
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
2879 2758  {
2880 2759          int bidx;       /* buffer index */
2881 2760          ndmp_lbr_params_t *nlp;
2882 2761          tlm_buffer_t *buf;
2883 2762          tlm_buffers_t *bufs;
2884 2763          tlm_cmd_t *lcmd;        /* Local command */
2885 2764          tlm_commands_t *cmds;   /* Commands structure */
2886 2765          static int nr = 0;
2887 2766  
2888 2767          if ((nlp = ndmp_get_nlp(session)) == NULL) {
2889      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
2890 2768                  return (-1);
2891 2769          }
2892 2770  
2893 2771          cmds = &nlp->nlp_cmds;
2894 2772          lcmd = cmds->tcs_command;
2895 2773          bufs = lcmd->tc_buffers;
2896 2774  
2897 2775          lcmd->tc_ref++;
2898 2776          cmds->tcs_reader_count++;
2899 2777  
2900 2778          /*
  
    | 
      ↓ open down ↓ | 
    1 lines elided | 
    
      ↑ open up ↑ | 
  
2901 2779           * Let our parent thread know that we are running.
2902 2780           */
2903 2781          tlm_cmd_signal(cmds->tcs_command, TLM_SOCK_READER);
2904 2782  
2905 2783          bidx = bufs->tbs_buffer_in;
2906 2784          while (cmds->tcs_reader == TLM_BACKUP_RUN &&
2907 2785              lcmd->tc_reader == TLM_BACKUP_RUN) {
2908 2786                  buf = &bufs->tbs_buffer[bidx];
2909 2787  
2910 2788                  if (buf->tb_full) {
2911      -                        NDMP_LOG(LOG_DEBUG, "R%d", bidx);
     2789 +                        syslog(LOG_DEBUG, "R%d", bidx);
2912 2790                          /*
2913 2791                           * The buffer is still full, wait for the consumer
2914 2792                           * thread to use it.
2915 2793                           */
2916 2794                          tlm_buffer_out_buf_timed_wait(bufs, 100);
2917 2795                  } else {
2918      -                        NDMP_LOG(LOG_DEBUG, "r%d, nr: %d", bidx, ++nr);
     2796 +                        syslog(LOG_DEBUG, "r%d, nr: %d", bidx, ++nr);
2919 2797  
2920 2798                          (void) mover_socket_read_one_buf(session, buf,
2921 2799                              bufs->tbs_data_transfer_size);
2922 2800  
2923 2801                          /*
2924 2802                           * Can we do more buffering?
2925 2803                           */
2926 2804                          if (is_buffer_erroneous(buf)) {
2927      -                                NDMP_LOG(LOG_DEBUG,
     2805 +                                syslog(LOG_DEBUG,
2928 2806                                      "Exiting, errno: %d, eot: %d, eof: %d",
2929 2807                                      buf->tb_errno, buf->tb_eot, buf->tb_eof);
2930 2808                                  break;
2931 2809                          }
2932 2810  
2933 2811                          (void) tlm_buffer_advance_in_idx(bufs);
2934 2812                          tlm_buffer_release_in_buf(bufs);
2935 2813                          bidx = bufs->tbs_buffer_in;
2936 2814                  }
2937 2815          }
2938 2816  
2939 2817          if (cmds->tcs_reader != TLM_BACKUP_RUN)
2940      -                NDMP_LOG(LOG_DEBUG, "cmds->tcs_reader != TLM_BACKUP_RUN");
     2818 +                syslog(LOG_DEBUG, "cmds->tcs_reader != TLM_BACKUP_RUN");
2941 2819          if (lcmd->tc_reader != TLM_BACKUP_RUN)
2942      -                NDMP_LOG(LOG_DEBUG, "lcmd->tc_reader != TLM_BACKUP_RUN");
2943      -        NDMP_LOG(LOG_DEBUG, "nr: %d", nr);
     2820 +                syslog(LOG_DEBUG, "lcmd->tc_reader != TLM_BACKUP_RUN");
     2821 +        syslog(LOG_DEBUG, "nr: %d", nr);
2944 2822  
2945 2823          /* If the consumer is waiting for us, wake it up. */
2946 2824          tlm_buffer_release_in_buf(bufs);
2947 2825  
2948 2826          /*
2949 2827           * Clean up.
2950 2828           */
2951 2829          cmds->tcs_reader_count--;
2952 2830          lcmd->tc_ref--;
2953 2831          lcmd->tc_writer = TLM_STOP;
2954 2832          return (0);
2955 2833  }
2956 2834  
2957 2835  
2958 2836  /*
2959 2837   * mover_tape_writer_one_buf
2960 2838   *
2961 2839   * Write one buffer for the mover to the local tape device. This is
2962 2840   * used by mover_tape_writer thread.
2963 2841   *
2964 2842   * Parameters:
2965 2843   *   session (input) - session pointer.
2966 2844   *   buf (input) - buffer read
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
2967 2845   *
2968 2846   * Returns:
2969 2847   *   0: on success
2970 2848   *  -1: otherwise
2971 2849   */
2972 2850  static int
2973 2851  mover_tape_write_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf)
2974 2852  {
2975 2853          int n;
2976 2854  
2977      -        NDMP_LOG(LOG_DEBUG, "full: %d, eot: %d, eof: %d,"
     2855 +        syslog(LOG_DEBUG, "full: %d, eot: %d, eof: %d,"
2978 2856              " errno: %d, size: %d, data: 0x%x",
2979 2857              buf->tb_full, buf->tb_eot, buf->tb_eof, buf->tb_errno,
2980 2858              buf->tb_buffer_size, buf->tb_buffer_data);
2981 2859  
2982 2860          n = mover_tape_write_v3(session, buf->tb_buffer_data,
2983 2861              buf->tb_buffer_size);
2984 2862  
2985      -        NDMP_LOG(LOG_DEBUG, "n: %d", n);
2986      -
2987 2863          if (n <= 0) {
2988 2864                  ndmpd_mover_error(session, (n == 0 ? NDMP_MOVER_HALT_ABORTED
2989 2865                      : NDMP_MOVER_HALT_INTERNAL_ERROR));
2990 2866                  return (-1);
2991 2867          }
2992 2868          session->ns_mover.md_position += n;
2993 2869          session->ns_mover.md_data_written += n;
2994 2870          session->ns_mover.md_record_num++;
2995 2871  
2996      -        NDMP_LOG(LOG_DEBUG, "Calling tlm_buffer_mark_empty(buf)");
2997 2872          tlm_buffer_mark_empty(buf);
2998 2873  
2999 2874          return (0);
3000 2875  }
3001 2876  
3002 2877  
3003 2878  /*
3004 2879   * mover_tape_writer
3005 2880   *
3006 2881   * Mover tape writer thread. This is used for performing remote backups
3007 2882   * in a 3-way configuration. It writes the data from network socket to
3008 2883   * the locally attached tape device.
3009 2884   *
3010 2885   * Parameters:
3011 2886   *   session (input) - session pointer.
3012 2887   *
3013 2888   * Returns:
3014 2889   *   0: on success
3015 2890   *  -1: otherwise
3016 2891   */
3017 2892  int
3018 2893  mover_tape_writer(ndmpd_session_t *session)
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
3019 2894  {
3020 2895          int bidx;
3021 2896          ndmp_lbr_params_t *nlp;
3022 2897          tlm_buffer_t *buf;
3023 2898          tlm_buffers_t *bufs;
3024 2899          tlm_cmd_t *lcmd;
3025 2900          tlm_commands_t *cmds;
3026 2901          static int nw = 0;
3027 2902  
3028 2903          if ((nlp = ndmp_get_nlp(session)) == NULL) {
3029      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
3030 2904                  return (-1);
3031 2905          }
3032 2906  
3033 2907          cmds = &nlp->nlp_cmds;
3034 2908          lcmd = cmds->tcs_command;
3035 2909          bufs = lcmd->tc_buffers;
3036 2910  
3037 2911          lcmd->tc_ref++;
3038 2912          cmds->tcs_writer_count++;
3039 2913  
3040 2914          /*
3041 2915           * Let our parent thread know that we are running.
3042 2916           */
3043 2917          tlm_cmd_signal(cmds->tcs_command, TLM_TAPE_WRITER);
3044 2918  
3045 2919          bidx = bufs->tbs_buffer_out;
3046 2920          buf = &bufs->tbs_buffer[bidx];
3047 2921          while (cmds->tcs_writer != (int)TLM_ABORT &&
3048 2922              lcmd->tc_writer != (int)TLM_ABORT) {
3049 2923                  if (buf->tb_full) {
3050      -                        NDMP_LOG(LOG_DEBUG, "w%d, nw: %d", bidx, ++nw);
     2924 +                        syslog(LOG_DEBUG, "w%d, nw: %d", bidx, ++nw);
3051 2925  
3052 2926                          if (mover_tape_write_one_buf(session, buf) < 0) {
3053      -                                NDMP_LOG(LOG_DEBUG,
     2927 +                                syslog(LOG_DEBUG,
3054 2928                                      "mover_tape_write_one_buf() failed");
3055 2929                                  break;
3056 2930                          }
3057 2931  
3058 2932                          (void) tlm_buffer_advance_out_idx(bufs);
3059 2933                          tlm_buffer_release_out_buf(bufs);
3060 2934                          bidx = bufs->tbs_buffer_out;
3061 2935                          buf = &bufs->tbs_buffer[bidx];
3062 2936                  } else {
3063 2937                          if (lcmd->tc_writer != TLM_BACKUP_RUN) {
3064 2938                                  /* No more data is coming, time to exit */
3065      -                                NDMP_LOG(LOG_DEBUG, "Time to exit");
3066 2939                                  break;
3067 2940                          }
3068      -                        NDMP_LOG(LOG_DEBUG, "W%d", bidx);
     2941 +                        syslog(LOG_DEBUG, "W%d", bidx);
3069 2942                          /*
3070 2943                           * The buffer is not full, wait for the producer
3071 2944                           * thread to fill it.
3072 2945                           */
3073 2946                          tlm_buffer_in_buf_timed_wait(bufs, 100);
3074 2947                  }
3075 2948          }
3076 2949  
3077 2950          if (cmds->tcs_writer == (int)TLM_ABORT)
3078      -                NDMP_LOG(LOG_DEBUG, "cmds->tcs_writer == TLM_ABORT");
     2951 +                syslog(LOG_DEBUG, "cmds->tcs_writer == TLM_ABORT");
3079 2952          if (lcmd->tc_writer == (int)TLM_ABORT)
3080      -                NDMP_LOG(LOG_DEBUG, "lcmd->tc_writer == TLM_ABORT");
3081      -        NDMP_LOG(LOG_DEBUG, "nw: %d", nw);
     2953 +                syslog(LOG_DEBUG, "lcmd->tc_writer == TLM_ABORT");
3082 2954  
3083 2955          if (buf->tb_errno == 0) {
3084 2956                  ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
3085 2957          } else {
3086      -                NDMP_LOG(LOG_DEBUG, "buf->tb_errno: %d", buf->tb_errno);
3087 2958                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
3088 2959          }
3089 2960  
3090 2961          /* If the producer is waiting for us, wake it up. */
3091 2962          tlm_buffer_release_out_buf(bufs);
3092 2963  
3093 2964          /*
3094 2965           * Clean up.
3095 2966           */
3096 2967          cmds->tcs_writer_count--;
3097 2968          lcmd->tc_ref--;
3098 2969          lcmd->tc_reader = TLM_STOP;
3099 2970          return (0);
3100 2971  }
3101 2972  
3102 2973  
3103 2974  /*
3104 2975   * start_mover_for_backup
3105 2976   *
3106 2977   * Starts a remote backup by running socket reader and tape
3107 2978   * writer threads. The mover runs a remote backup in a 3-way backup
3108 2979   * configuration.
3109 2980   *
3110 2981   * Parameters:
3111 2982   *   session (input) - session pointer.
3112 2983   *
3113 2984   * Returns:
3114 2985   *   0: on success
  
    | 
      ↓ open down ↓ | 
    18 lines elided | 
    
      ↑ open up ↑ | 
  
3115 2986   *  -1: otherwise
3116 2987   */
3117 2988  static int
3118 2989  start_mover_for_backup(ndmpd_session_t *session)
3119 2990  {
3120 2991          ndmp_lbr_params_t *nlp;
3121 2992          tlm_commands_t *cmds;
3122 2993          int rc;
3123 2994  
3124 2995          if ((nlp = ndmp_get_nlp(session)) == NULL) {
3125      -                NDMP_LOG(LOG_DEBUG, "nlp == NULL");
3126 2996                  return (-1);
3127 2997          }
3128 2998  
3129 2999          cmds = &nlp->nlp_cmds;
3130 3000          (void) memset(cmds, 0, sizeof (*cmds));
3131 3001          cmds->tcs_reader = cmds->tcs_writer = TLM_BACKUP_RUN;
3132 3002          cmds->tcs_command = tlm_create_reader_writer_ipc(TRUE,
3133 3003              session->ns_mover.md_record_size);
3134 3004          if (cmds->tcs_command == NULL)
3135 3005                  return (-1);
3136 3006  
3137 3007          cmds->tcs_command->tc_reader = TLM_BACKUP_RUN;
3138 3008          cmds->tcs_command->tc_writer = TLM_BACKUP_RUN;
3139 3009  
  
    | 
      ↓ open down ↓ | 
    4 lines elided | 
    
      ↑ open up ↑ | 
  
3140 3010          /*
3141 3011           * We intentionally don't wait for the threads to start since the
3142 3012           * reply of the request (which resulted in calling this function)
3143 3013           * must be sent to the client before probable errors are sent
3144 3014           * to the client.
3145 3015           */
3146 3016          rc = pthread_create(NULL, NULL, (funct_t)mover_socket_reader, session);
3147 3017          if (rc == 0) {
3148 3018                  tlm_cmd_wait(cmds->tcs_command, TLM_SOCK_READER);
3149 3019          } else {
3150      -                NDMP_LOG(LOG_DEBUG, "Launch mover_socket_reader: %s",
3151      -                    strerror(rc));
3152 3020                  return (-1);
3153 3021          }
3154 3022  
3155 3023          rc = pthread_create(NULL, NULL, (funct_t)mover_tape_writer, session);
3156 3024          if (rc == 0) {
3157 3025                  tlm_cmd_wait(cmds->tcs_command, TLM_TAPE_WRITER);
3158 3026          } else {
3159      -                NDMP_LOG(LOG_DEBUG, "Launch mover_tape_writer: %s",
3160      -                    strerror(rc));
3161 3027                  return (-1);
3162 3028          }
3163 3029  
3164 3030          tlm_release_reader_writer_ipc(cmds->tcs_command);
3165 3031          return (0);
3166 3032  }
3167 3033  
3168 3034  
3169 3035  /*
3170 3036   * is_writer_running
3171 3037   *
3172 3038   * Find out if the writer thread has started or not.
3173 3039   *
3174 3040   * Parameters:
3175 3041   *   session (input) - session pointer.
3176 3042   *
3177 3043   * Returns:
3178 3044   *   0: not started
3179 3045   *   non-zero: started
3180 3046   *      Note: non-zero is also returned if the backup type is
3181 3047   *              neither TAR nor DUMP.  I.e. the is_writer_running()
3182 3048   *              check does not apply in this case and things should
3183 3049   *              appear successful.
3184 3050   */
3185 3051  static boolean_t
3186 3052  is_writer_running(ndmpd_session_t *session)
3187 3053  {
3188 3054          boolean_t rv;
3189 3055          ndmp_lbr_params_t *nlp;
3190 3056  
3191 3057          if (session && (session->ns_butype > NDMP_BUTYPE_DUMP))
3192 3058                  return (1);
3193 3059  
3194 3060          if (session == NULL)
3195 3061                  rv = 0;
3196 3062          else if ((nlp = ndmp_get_nlp(session)) == NULL)
3197 3063                  rv = 0;
3198 3064          else
3199 3065                  rv = (nlp->nlp_cmds.tcs_writer_count > 0);
3200 3066  
3201 3067          return (rv);
3202 3068  }
3203 3069  
3204 3070  
3205 3071  /*
3206 3072   * is_writer_running_v3
3207 3073   *
3208 3074   * Find out if the writer thread has started or not.
3209 3075   *
3210 3076   * Parameters:
3211 3077   *   session (input) - session pointer.
3212 3078   *
3213 3079   * Returns:
3214 3080   *   0: not started
3215 3081   *   non-zero: started
3216 3082   *      Note: non-zero is also returned if the backup type is
3217 3083   *              neither TAR nor DUMP.  I.e. the is_writer_running()
3218 3084   *              check does not apply in this case and things should
3219 3085   *              appear successful.
3220 3086   */
3221 3087  static boolean_t
3222 3088  is_writer_running_v3(ndmpd_session_t *session)
3223 3089  {
3224 3090          boolean_t rv;
3225 3091          ndmp_lbr_params_t *nlp;
3226 3092  
3227 3093          if (session && (session->ns_butype > NDMP_BUTYPE_DUMP))
3228 3094                  return (1);
3229 3095  
3230 3096          if (session == NULL)
3231 3097                  rv = 0;
3232 3098          else if (session->ns_mover.md_data_addr.addr_type == NDMP_ADDR_TCP)
3233 3099                  rv = 1;
3234 3100          else if ((nlp = ndmp_get_nlp(session)) == NULL)
3235 3101                  rv = 0;
3236 3102          else
3237 3103                  rv = (nlp->nlp_cmds.tcs_writer_count > 0);
3238 3104  
3239 3105          return (rv);
3240 3106  }
3241 3107  
3242 3108  
3243 3109  /*
3244 3110   * ndmpd_mover_error_send
3245 3111   *
3246 3112   * This function sends the notify message to the client.
3247 3113   *
3248 3114   * Parameters:
3249 3115   *   session (input) - session pointer.
3250 3116   *   reason  (input) - halt reason.
3251 3117   *
3252 3118   * Returns:
3253 3119   *   Error code
3254 3120   */
3255 3121  int
3256 3122  ndmpd_mover_error_send(ndmpd_session_t *session, ndmp_mover_halt_reason reason)
3257 3123  {
3258 3124          ndmp_notify_mover_halted_request req;
3259 3125  
3260 3126          req.reason = reason;
3261 3127          req.text_reason = "";
3262 3128  
3263 3129          return (ndmp_send_request(session->ns_connection,
3264 3130              NDMP_NOTIFY_MOVER_HALTED, NDMP_NO_ERR, (void *)&req, 0));
3265 3131  }
3266 3132  
3267 3133  
3268 3134  /*
3269 3135   * ndmpd_mover_error_send_v4
3270 3136   *
3271 3137   * This function sends the notify message to the client.
3272 3138   *
3273 3139   * Parameters:
3274 3140   *   session (input) - session pointer.
3275 3141   *   reason  (input) - halt reason.
3276 3142   *
3277 3143   * Returns:
3278 3144   *   Error code
3279 3145   */
3280 3146  int
3281 3147  ndmpd_mover_error_send_v4(ndmpd_session_t *session,
3282 3148      ndmp_mover_halt_reason reason)
3283 3149  {
3284 3150          ndmp_notify_mover_halted_request_v4 req;
3285 3151  
3286 3152          req.reason = reason;
3287 3153  
3288 3154          return (ndmp_send_request(session->ns_connection,
3289 3155              NDMP_NOTIFY_MOVER_HALTED, NDMP_NO_ERR, (void *)&req, 0));
3290 3156  }
3291 3157  
3292 3158  
3293 3159  /*
3294 3160   * ndmpd_mover_error
3295 3161   *
3296 3162   * This function is called when an unrecoverable mover error
3297 3163   * has been detected. A notify message is sent to the client and the
3298 3164   * mover is placed into the halted state.
3299 3165   *
3300 3166   * Parameters:
3301 3167   *   session (input) - session pointer.
3302 3168   *   reason  (input) - halt reason.
3303 3169   *
3304 3170   * Returns:
3305 3171   *   void.
3306 3172   */
3307 3173  void
3308 3174  ndmpd_mover_error(ndmpd_session_t *session, ndmp_mover_halt_reason reason)
  
    | 
      ↓ open down ↓ | 
    138 lines elided | 
    
      ↑ open up ↑ | 
  
3309 3175  {
3310 3176          ndmp_lbr_params_t *nlp = ndmp_get_nlp(session);
3311 3177  
3312 3178          if (session->ns_mover.md_state == NDMP_MOVER_STATE_HALTED ||
3313 3179              (session->ns_protocol_version > NDMPV2 &&
3314 3180              session->ns_mover.md_state == NDMP_MOVER_STATE_IDLE))
3315 3181                  return;
3316 3182  
3317 3183          if (session->ns_protocol_version == NDMPV4) {
3318 3184                  if (ndmpd_mover_error_send_v4(session, reason) < 0)
3319      -                        NDMP_LOG(LOG_DEBUG,
     3185 +                        syslog(LOG_ERR,
3320 3186                              "Error sending notify_mover_halted request");
3321 3187          } else {
3322 3188                  /* No media error in V3 */
3323 3189                  if (reason == NDMP_MOVER_HALT_MEDIA_ERROR)
3324 3190                          reason = NDMP_MOVER_HALT_INTERNAL_ERROR;
3325 3191                  if (ndmpd_mover_error_send(session, reason) < 0)
3326      -                        NDMP_LOG(LOG_DEBUG,
     3192 +                        syslog(LOG_ERR,
3327 3193                              "Error sending notify_mover_halted request");
3328 3194          }
3329 3195  
3330 3196          (void) mutex_lock(&nlp->nlp_mtx);
3331 3197          if (session->ns_mover.md_listen_sock != -1) {
3332 3198                  (void) ndmpd_remove_file_handler(session,
3333 3199                      session->ns_mover.md_listen_sock);
3334 3200                  (void) close(session->ns_mover.md_listen_sock);
3335 3201                  session->ns_mover.md_listen_sock = -1;
3336 3202          }
3337 3203          if (session->ns_mover.md_sock != -1) {
3338 3204                  (void) ndmpd_remove_file_handler(session,
3339 3205                      session->ns_mover.md_sock);
3340 3206                  (void) close(session->ns_mover.md_sock);
3341 3207                  session->ns_mover.md_sock = -1;
3342 3208          }
3343 3209  
3344 3210          session->ns_mover.md_state = NDMP_MOVER_STATE_HALTED;
3345 3211          session->ns_mover.md_halt_reason = reason;
3346 3212          (void) cond_broadcast(&nlp->nlp_cv);
3347 3213          (void) mutex_unlock(&nlp->nlp_mtx);
3348 3214  }
3349 3215  
3350 3216  
3351 3217  /*
3352 3218   * mover_pause_v3
3353 3219   *
3354 3220   * Send an ndmp_notify_mover_paused request to the
3355 3221   * NDMP client to inform the client that its attention is required.
3356 3222   * Process messages until the data/mover operation is either aborted
3357 3223   * or continued.
3358 3224   *
3359 3225   * Parameters:
3360 3226   *   client_data (input) - session pointer.
3361 3227   *   reason (input) - pause reason.
3362 3228   *
3363 3229   * Returns:
3364 3230   *   0 - operation has been continued.
3365 3231   *  -1 - operation has been aborted.
3366 3232   */
3367 3233  static int
3368 3234  mover_pause_v3(ndmpd_session_t *session, ndmp_mover_pause_reason reason)
3369 3235  {
3370 3236          int rv;
3371 3237          ndmp_notify_mover_paused_request request;
3372 3238  
3373 3239          rv = 0;
  
    | 
      ↓ open down ↓ | 
    37 lines elided | 
    
      ↑ open up ↑ | 
  
3374 3240          session->ns_mover.md_state = NDMP_MOVER_STATE_PAUSED;
3375 3241          session->ns_mover.md_pause_reason = reason;
3376 3242          session->ns_mover.md_pre_cond = FALSE;
3377 3243  
3378 3244          request.reason = session->ns_mover.md_pause_reason;
3379 3245          request.seek_position =
3380 3246              long_long_to_quad(session->ns_mover.md_position);
3381 3247  
3382 3248          if (ndmp_send_request(session->ns_connection, NDMP_NOTIFY_MOVER_PAUSED,
3383 3249              NDMP_NO_ERR, (void *)&request, 0) < 0) {
3384      -                NDMP_LOG(LOG_DEBUG,
     3250 +                syslog(LOG_ERR,
3385 3251                      "Error sending notify_mover_paused_request");
3386 3252                  return (-1);
3387 3253          }
3388 3254  
3389 3255          /*
3390 3256           * 3-way operations are single-thread.  The same thread
3391 3257           * should process the messages.
3392 3258           *
3393 3259           * 2-way operations are multi-thread.  The main thread
3394 3260           * processes the messages.  We just need to wait and
3395 3261           * see if the mover state changes or the operation aborts.
3396 3262           */
3397 3263          if (session->ns_mover.md_data_addr.addr_type == NDMP_ADDR_TCP) {
3398 3264                  /*
3399 3265                   * Process messages until the state is changed by
3400 3266                   * an abort, continue, or close request .
3401 3267                   */
3402 3268                  for (; ; ) {
3403 3269                          if (ndmpd_select(session, TRUE, HC_CLIENT) < 0)
3404 3270                                  return (-1);
3405 3271  
3406 3272                          if (session->ns_eof == TRUE)
3407 3273                                  return (-1);
3408 3274  
3409 3275                          switch (session->ns_mover.md_state) {
3410 3276                          case NDMP_MOVER_STATE_ACTIVE:
3411 3277                                  session->ns_tape.td_record_count = 0;
3412 3278                                  return (0);
3413 3279  
3414 3280                          case NDMP_MOVER_STATE_PAUSED:
3415 3281                                  continue;
3416 3282  
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
3417 3283                          default:
3418 3284                                  return (-1);
3419 3285                          }
3420 3286                  }
3421 3287  
3422 3288          } else {
3423 3289                  if (session->ns_mover.md_data_addr.addr_type ==
3424 3290                      NDMP_ADDR_LOCAL) {
3425 3291                          rv = ndmp_wait_for_mover(session);
3426 3292                  } else {
3427      -                        NDMP_LOG(LOG_DEBUG, "Invalid address type %d",
3428      -                            session->ns_mover.md_data_addr.addr_type);
3429 3293                          rv = -1;
3430 3294                  }
3431 3295          }
3432 3296  
3433 3297          return (rv);
3434 3298  }
3435 3299  
3436 3300  
3437 3301  /*
3438 3302   * mover_tape_write_v3
3439 3303   *
3440 3304   * Writes a data record to tape. Detects and handles EOT conditions.
3441 3305   *
3442 3306   * Parameters:
3443 3307   *   session (input) - session pointer.
3444 3308   *   data    (input) - data to be written.
3445 3309   *   length  (input) - length of data to be written.
3446 3310   *
3447 3311   * Returns:
3448 3312   *    0 - operation aborted by client.
3449 3313   *   -1 - error.
3450 3314   *   otherwise - number of bytes written.
3451 3315   */
3452 3316  static int
3453 3317  mover_tape_write_v3(ndmpd_session_t *session, char *data, ssize_t length)
3454 3318  {
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
3455 3319          ssize_t n;
3456 3320          ssize_t count = length;
3457 3321  
3458 3322          while (count > 0) {
3459 3323                  /*
3460 3324                   * Enforce mover window on write.
3461 3325                   */
3462 3326                  if (session->ns_mover.md_position >=
3463 3327                      session->ns_mover.md_window_offset +
3464 3328                      session->ns_mover.md_window_length) {
3465      -                        NDMP_LOG(LOG_DEBUG, "MOVER_PAUSE_EOW");
     3329 +                        syslog(LOG_DEBUG, "MOVER_PAUSE_EOW");
3466 3330  
3467 3331                          if (mover_pause_v3(session, NDMP_MOVER_PAUSE_EOW) < 0)
3468 3332                                  /* Operation aborted or connection terminated */
3469 3333                                  return (-1);
3470 3334  
3471 3335                  }
3472 3336  
3473 3337                  n = write(session->ns_tape.td_fd, data, count);
3474 3338                  if (n < 0) {
3475      -                        NDMP_LOG(LOG_ERR, "Tape write error: %m.");
     3339 +                        syslog(LOG_ERR, "Tape write error: %m.");
3476 3340                          return (-1);
3477 3341                  } else if (n > 0) {
3478 3342                          NS_ADD(wtape, n);
3479 3343                          count -= n;
3480 3344                          data += n;
3481 3345                          session->ns_tape.td_record_count++;
3482 3346                  }
3483 3347  
3484 3348                  /* EOM handling */
3485 3349                  if (count > 0) {
3486 3350                          struct mtget mtstatus;
3487 3351  
3488 3352                          (void) ioctl(session->ns_tape.td_fd, MTIOCGET,
3489 3353                              &mtstatus);
3490      -                        NDMP_LOG(LOG_DEBUG, "EOM detected (%d written bytes, "
     3354 +                        syslog(LOG_DEBUG, "EOM detected (%d written bytes, "
3491 3355                              "mover record %d, file #%d, block #%d)", n,
3492 3356                              session->ns_tape.td_record_count,
3493 3357                              mtstatus.mt_fileno, mtstatus.mt_blkno);
3494 3358  
3495 3359                          /*
3496 3360                           * Notify the client to either abort the operation
3497 3361                           * or change the tape.
3498 3362                           */
3499 3363                          NDMP_APILOG((void*)session, NDMP_LOG_NORMAL,
3500 3364                              ++ndmp_log_msg_id,
3501 3365                              "End of tape reached. Load next tape");
3502 3366  
3503 3367                          if (mover_pause_v3(session, NDMP_MOVER_PAUSE_EOM) < 0)
3504 3368                                  /* Operation aborted or connection terminated */
3505 3369                                  return (-1);
3506 3370                  }
3507 3371          }
3508 3372  
3509 3373          return (length);
3510 3374  }
3511 3375  
3512 3376  
3513 3377  /*
3514 3378   * mover_tape_flush_v3
3515 3379   *
3516 3380   * Writes all remaining buffered data to tape. A partial record is
3517 3381   * padded out to a full record with zeros.
3518 3382   *
3519 3383   * Parameters:
3520 3384   *   session (input) - session pointer.
3521 3385   *   data    (input) - data to be written.
3522 3386   *   length  (input) - length of data to be written.
3523 3387   *
3524 3388   * Returns:
3525 3389   *   -1 - error.
3526 3390   *   otherwise - number of bytes written.
3527 3391   */
3528 3392  static int
3529 3393  mover_tape_flush_v3(ndmpd_session_t *session)
3530 3394  {
3531 3395          int n;
3532 3396  
  
    | 
      ↓ open down ↓ | 
    32 lines elided | 
    
      ↑ open up ↑ | 
  
3533 3397          if (session->ns_mover.md_w_index == 0)
3534 3398                  return (0);
3535 3399  
3536 3400          (void) memset((void*)&session->ns_mover.md_buf[session->
3537 3401              ns_mover.md_w_index], 0,
3538 3402              session->ns_mover.md_record_size - session->ns_mover.md_w_index);
3539 3403  
3540 3404          n = mover_tape_write_v3(session, session->ns_mover.md_buf,
3541 3405              session->ns_mover.md_record_size);
3542 3406          if (n < 0) {
3543      -                NDMP_LOG(LOG_ERR, "Tape write error: %m.");
     3407 +                syslog(LOG_ERR, "Tape write error: %m.");
3544 3408                  return (-1);
3545 3409          }
3546 3410  
3547 3411          session->ns_mover.md_w_index = 0;
3548 3412          session->ns_mover.md_position += n;
3549 3413          return (n);
3550 3414  }
3551 3415  
3552 3416  
3553 3417  /*
3554 3418   * ndmpd_local_write_v3
3555 3419   *
3556 3420   * Buffers and writes data to the tape device.
3557 3421   * A full tape record is buffered before being written.
3558 3422   *
3559 3423   * Parameters:
3560 3424   *   session    (input) - session pointer.
3561 3425   *   data       (input) - data to be written.
3562 3426   *   length     (input) - data length.
3563 3427   *
3564 3428   * Returns:
3565 3429   *   0 - data successfully written.
3566 3430   *  -1 - error.
3567 3431   */
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
3568 3432  int
3569 3433  ndmpd_local_write_v3(ndmpd_session_t *session, char *data, ulong_t length)
3570 3434  {
3571 3435          ulong_t count = 0;
3572 3436          ssize_t n;
3573 3437          ulong_t len;
3574 3438  
3575 3439          if (session->ns_mover.md_state == NDMP_MOVER_STATE_IDLE ||
3576 3440              session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
3577 3441              session->ns_mover.md_state == NDMP_MOVER_STATE_HALTED) {
3578      -                NDMP_LOG(LOG_DEBUG, "Invalid mover state to write data");
3579 3442                  return (-1);
3580 3443          }
3581 3444  
3582 3445          /*
3583 3446           * A length of 0 indicates that any buffered data should be
3584 3447           * flushed to tape.
3585 3448           */
3586 3449          if (length == 0) {
3587 3450                  if (session->ns_mover.md_w_index == 0)
3588 3451                          return (0);
3589 3452  
3590 3453                  (void) memset((void*)&session->ns_mover.md_buf[session->
3591 3454                      ns_mover.md_w_index], 0, session->ns_mover.md_record_size -
3592 3455                      session->ns_mover.md_w_index);
3593 3456  
3594 3457                  n = mover_tape_write_v3(session, session->ns_mover.md_buf,
3595 3458                      session->ns_mover.md_record_size);
3596 3459                  if (n <= 0) {
3597 3460                          ndmpd_mover_error(session,
3598 3461                              (n == 0 ?  NDMP_MOVER_HALT_ABORTED :
3599 3462                              NDMP_MOVER_HALT_MEDIA_ERROR));
3600 3463                          return (-1);
3601 3464                  }
3602 3465  
3603 3466                  session->ns_mover.md_position += n;
3604 3467                  session->ns_mover.md_data_written +=
3605 3468                      session->ns_mover.md_w_index;
3606 3469                  session->ns_mover.md_record_num++;
3607 3470                  session->ns_mover.md_w_index = 0;
3608 3471                  return (0);
3609 3472          }
3610 3473  
3611 3474          /* Break the data into records. */
3612 3475          while (count < length) {
3613 3476                  /*
3614 3477                   * Determine if data needs to be buffered or
3615 3478                   * can be written directly from user supplied location.
3616 3479                   * We can fast path the write if there is no pending
3617 3480                   * buffered data and there is at least a full records worth
3618 3481                   * of data to be written.
3619 3482                   */
3620 3483                  if (session->ns_mover.md_w_index == 0 &&
3621 3484                      length - count >= session->ns_mover.md_record_size) {
3622 3485                          n = mover_tape_write_v3(session, &data[count],
3623 3486                              session->ns_mover.md_record_size);
3624 3487                          if (n <= 0) {
3625 3488                                  ndmpd_mover_error(session,
3626 3489                                      (n == 0 ?  NDMP_MOVER_HALT_ABORTED :
3627 3490                                      NDMP_MOVER_HALT_MEDIA_ERROR));
3628 3491                                  return (-1);
3629 3492                          }
3630 3493  
3631 3494                          session->ns_mover.md_position += n;
3632 3495                          session->ns_mover.md_data_written += n;
3633 3496                          session->ns_mover.md_record_num++;
3634 3497                          count += n;
3635 3498                          continue;
3636 3499                  }
3637 3500  
3638 3501                  /* Buffer the data */
3639 3502                  len = length - count;
3640 3503                  if (len > session->ns_mover.md_record_size -
3641 3504                      session->ns_mover.md_w_index)
3642 3505                          len = session->ns_mover.md_record_size -
3643 3506                              session->ns_mover.md_w_index;
3644 3507  
3645 3508                  (void) memcpy(&session->ns_mover.md_buf[session->
3646 3509                      ns_mover.md_w_index], &data[count], len);
3647 3510                  session->ns_mover.md_w_index += len;
3648 3511                  count += len;
3649 3512  
3650 3513                  /* Write the buffer if its full */
3651 3514                  if (session->ns_mover.md_w_index ==
3652 3515                      session->ns_mover.md_record_size) {
3653 3516                          n = mover_tape_write_v3(session,
3654 3517                              session->ns_mover.md_buf,
3655 3518                              session->ns_mover.md_record_size);
3656 3519                          if (n <= 0) {
3657 3520                                  ndmpd_mover_error(session,
3658 3521                                      (n == 0 ?  NDMP_MOVER_HALT_ABORTED :
3659 3522                                      NDMP_MOVER_HALT_MEDIA_ERROR));
3660 3523                                  return (-1);
3661 3524                          }
3662 3525  
3663 3526                          session->ns_mover.md_position += n;
3664 3527                          session->ns_mover.md_data_written += n;
3665 3528                          session->ns_mover.md_record_num++;
3666 3529                          session->ns_mover.md_w_index = 0;
3667 3530                  }
3668 3531          }
3669 3532  
3670 3533          return (0);
3671 3534  }
3672 3535  
3673 3536  
3674 3537  /*
3675 3538   * mover_data_read_v3
3676 3539   *
3677 3540   * Reads backup data from the data connection and writes the
3678 3541   * received data to the tape device.
3679 3542   *
3680 3543   * Parameters:
3681 3544   *   cookie  (input) - session pointer.
3682 3545   *   fd      (input) - file descriptor.
3683 3546   *   mode    (input) - select mode.
3684 3547   *
3685 3548   * Returns:
3686 3549   *   void.
3687 3550   */
3688 3551  /*ARGSUSED*/
3689 3552  static void
3690 3553  mover_data_read_v3(void *cookie, int fd, ulong_t mode)
3691 3554  {
3692 3555          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
3693 3556          int n;
3694 3557          ulong_t index;
3695 3558  
  
    | 
      ↓ open down ↓ | 
    107 lines elided | 
    
      ↑ open up ↑ | 
  
3696 3559          n = read(fd, &session->ns_mover.md_buf[session->ns_mover.md_w_index],
3697 3560              session->ns_mover.md_record_size - session->ns_mover.md_w_index);
3698 3561  
3699 3562          /*
3700 3563           * Since this function is only called when select believes data
3701 3564           * is available to be read, a return of zero indicates the
3702 3565           * connection has been closed.
3703 3566           */
3704 3567          if (n <= 0) {
3705 3568                  if (n == 0) {
3706      -                        NDMP_LOG(LOG_DEBUG, "Data connection closed");
     3569 +                        syslog(LOG_DEBUG, "Data connection closed");
3707 3570                          ndmpd_mover_error(session,
3708 3571                              NDMP_MOVER_HALT_CONNECT_CLOSED);
3709 3572                  } else {
3710 3573                          /* Socket is non-blocking, perhaps there are no data */
3711 3574                          if (errno == EAGAIN) {
3712      -                                NDMP_LOG(LOG_ERR, "No data to read");
     3575 +                                syslog(LOG_DEBUG, "No data to read");
3713 3576                                  return;
3714 3577                          }
3715 3578  
3716      -                        NDMP_LOG(LOG_ERR, "Failed to read from socket: %m");
     3579 +                        syslog(LOG_ERR,
     3580 +                            "Failed to read from socket %d: %m", fd);
3717 3581                          ndmpd_mover_error(session,
3718 3582                              NDMP_MOVER_HALT_INTERNAL_ERROR);
3719 3583                  }
3720 3584  
3721 3585                  /* Save the index since mover_tape_flush_v3 resets it. */
3722 3586                  index = session->ns_mover.md_w_index;
3723 3587  
3724 3588                  /* Flush any buffered data to tape. */
3725 3589                  if (mover_tape_flush_v3(session) > 0) {
3726 3590                          session->ns_mover.md_data_written += index;
3727 3591                          session->ns_mover.md_record_num++;
3728 3592                  }
3729 3593  
3730 3594                  return;
3731 3595          }
3732 3596  
3733      -        NDMP_LOG(LOG_DEBUG, "n %d", n);
3734      -
3735 3597          session->ns_mover.md_w_index += n;
3736 3598  
3737 3599          if (session->ns_mover.md_w_index == session->ns_mover.md_record_size) {
3738 3600                  n = mover_tape_write_v3(session, session->ns_mover.md_buf,
3739 3601                      session->ns_mover.md_record_size);
3740 3602                  if (n <= 0) {
3741 3603                          ndmpd_mover_error(session,
3742 3604                              (n == 0 ? NDMP_MOVER_HALT_ABORTED :
3743 3605                              NDMP_MOVER_HALT_MEDIA_ERROR));
3744 3606                          return;
3745 3607                  }
3746 3608  
3747 3609                  session->ns_mover.md_position += n;
3748 3610                  session->ns_mover.md_w_index = 0;
3749 3611                  session->ns_mover.md_data_written += n;
3750 3612                  session->ns_mover.md_record_num++;
3751 3613          }
3752 3614  }
3753 3615  
3754 3616  /*
3755 3617   * mover_tape_read_v3
3756 3618   *
3757 3619   * Reads a data record from tape. Detects and handles EOT conditions.
3758 3620   *
3759 3621   * Parameters:
3760 3622   *   session (input) - session pointer.
3761 3623   *   data    (input) - location to read data to.
3762 3624   *
3763 3625   * Returns:
3764 3626   *   0 - operation aborted.
3765 3627   *   TAPE_READ_ERR - tape read IO error.
3766 3628   *   TAPE_NO_WRITER_ERR - no writer is running during tape read
3767 3629   *   otherwise - number of bytes read.
3768 3630   */
3769 3631  static int
3770 3632  mover_tape_read_v3(ndmpd_session_t *session, char *data)
3771 3633  {
3772 3634          int pause_reason;
3773 3635          ssize_t  n;
3774 3636          int err;
3775 3637          int count;
3776 3638  
3777 3639          count = session->ns_mover.md_record_size;
  
    | 
      ↓ open down ↓ | 
    33 lines elided | 
    
      ↑ open up ↑ | 
  
3778 3640          while (count > 0) {
3779 3641                  pause_reason = NDMP_MOVER_PAUSE_NA;
3780 3642  
3781 3643                  n = read(session->ns_tape.td_fd, data, count);
3782 3644                  if (n < 0) {
3783 3645                          /*
3784 3646                           * If at beginning of file and read fails with EIO,
3785 3647                           * then it's repeated attempt to read at EOT.
3786 3648                           */
3787 3649                          if (errno == EIO && tape_is_at_bof(session)) {
3788      -                                NDMP_LOG(LOG_DEBUG, "Repeated read at EOT");
3789 3650                                  pause_reason = NDMP_MOVER_PAUSE_EOM;
3790 3651                                  NDMP_APILOG((void*)session, NDMP_LOG_NORMAL,
3791 3652                                      ++ndmp_log_msg_id,
3792 3653                                      "End of tape reached. Load next tape");
3793 3654                          }
3794 3655                          /*
3795 3656                           * According to NDMPv4 spec preferred error code when
3796 3657                           * trying to read from blank tape is NDMP_EOM_ERR.
3797 3658                           */
3798 3659                          else if (errno == EIO && tape_is_at_bot(session)) {
3799      -                                NDMP_LOG(LOG_ERR,
     3660 +                                syslog(LOG_ERR,
3800 3661                                      "Blank tape detected, returning EOM");
3801 3662                                  NDMP_APILOG((void*)session, NDMP_LOG_NORMAL,
3802 3663                                      ++ndmp_log_msg_id,
3803 3664                                      "Blank tape. Load another tape");
3804 3665                                  pause_reason = NDMP_MOVER_PAUSE_EOM;
3805 3666                          } else {
3806      -                                NDMP_LOG(LOG_ERR, "Tape read error: %m.");
     3667 +                                syslog(LOG_ERR, "Tape read error: %m.");
3807 3668                                  return (TAPE_READ_ERR);
3808 3669                          }
3809 3670                  } else if (n > 0) {
3810 3671                          NS_ADD(rtape, n);
3811 3672                          data += n;
3812 3673                          count -= n;
3813 3674                          session->ns_tape.td_record_count++;
3814 3675                  } else {
3815 3676                          if (!is_writer_running_v3(session))
3816 3677                                  return (TAPE_NO_WRITER_ERR);
3817 3678  
3818 3679                          /*
3819 3680                           * End of file or media reached. Notify client and
3820 3681                           * wait for the client to either abort the data
3821 3682                           * operation or continue the operation after changing
3822 3683                           * the tape.
3823 3684                           */
3824 3685                          if (tape_is_at_bof(session)) {
3825      -                                NDMP_LOG(LOG_DEBUG, "EOT detected");
     3686 +                                syslog(LOG_DEBUG, "EOT detected");
3826 3687                                  pause_reason = NDMP_MOVER_PAUSE_EOM;
3827 3688                                  NDMP_APILOG((void*)session, NDMP_LOG_NORMAL,
3828 3689                                      ++ndmp_log_msg_id, "End of medium reached");
3829 3690                          } else {
3830      -                                NDMP_LOG(LOG_DEBUG, "EOF detected");
     3691 +                                syslog(LOG_DEBUG, "EOF detected");
3831 3692                                  /* reposition the tape to BOT side of FM */
3832 3693                                  fm_dance(session);
3833 3694                                  pause_reason = NDMP_MOVER_PAUSE_EOF;
3834 3695                                  NDMP_APILOG((void*)session, NDMP_LOG_NORMAL,
3835 3696                                      ++ndmp_log_msg_id, "End of file reached.");
3836 3697                          }
3837 3698                  }
3838 3699  
3839 3700                  if (pause_reason != NDMP_MOVER_PAUSE_NA) {
3840 3701                          err = mover_pause_v3(session, pause_reason);
3841 3702  
3842 3703                          /* Operation aborted or connection terminated? */
3843 3704                          if (err < 0) {
3844 3705                                  return (0);
3845 3706                          }
3846 3707                          /* Retry the read from new location */
3847 3708                  }
3848 3709          }
3849 3710          return (session->ns_mover.md_record_size);
3850 3711  }
3851 3712  
3852 3713  
3853 3714  /*
3854 3715   * mover_data_write_v3
3855 3716   *
3856 3717   * Reads backup data from the tape device and writes the
3857 3718   * data to the data connection.
3858 3719   * This function is called by ndmpd_select when the data connection
3859 3720   * is ready for more data to be written.
3860 3721   *
3861 3722   * Parameters:
3862 3723   *   cookie  (input) - session pointer.
3863 3724   *   fd      (input) - file descriptor.
3864 3725   *   mode    (input) - select mode.
3865 3726   *
3866 3727   * Returns:
3867 3728   *   void.
3868 3729   */
3869 3730  /*ARGSUSED*/
3870 3731  static void
3871 3732  mover_data_write_v3(void *cookie, int fd, ulong_t mode)
3872 3733  {
3873 3734          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
3874 3735          int n;
3875 3736          ulong_t len;
3876 3737          u_longlong_t wlen;
3877 3738          ndmp_notify_mover_paused_request pause_request;
  
    | 
      ↓ open down ↓ | 
    37 lines elided | 
    
      ↑ open up ↑ | 
  
3878 3739  
3879 3740          /*
3880 3741           * If the end of the mover window has been reached,
3881 3742           * then notify the client that a seek is needed.
3882 3743           * Remove the file handler to prevent this function from
3883 3744           * being called. The handler will be reinstalled in
3884 3745           * ndmpd_mover_continue.
3885 3746           */
3886 3747          if (session->ns_mover.md_position >= session->ns_mover.md_window_offset
3887 3748              + session->ns_mover.md_window_length) {
3888      -                NDMP_LOG(LOG_DEBUG,
     3749 +                syslog(LOG_DEBUG,
3889 3750                      "MOVER_PAUSE_SEEK(%llu)", session->ns_mover.md_position);
3890 3751  
3891 3752                  session->ns_mover.md_w_index = 0;
3892 3753                  session->ns_mover.md_r_index = 0;
3893 3754  
3894 3755                  session->ns_mover.md_state = NDMP_MOVER_STATE_PAUSED;
3895 3756                  session->ns_mover.md_pause_reason = NDMP_MOVER_PAUSE_SEEK;
3896 3757                  pause_request.reason = NDMP_MOVER_PAUSE_SEEK;
3897 3758                  pause_request.seek_position =
3898 3759                      long_long_to_quad(session->ns_mover.md_position);
3899 3760                  session->ns_mover.md_seek_position =
3900 3761                      session->ns_mover.md_position;
3901 3762  
3902 3763                  (void) ndmpd_remove_file_handler(session, fd);
3903 3764  
3904 3765                  if (ndmp_send_request(session->ns_connection,
3905 3766                      NDMP_NOTIFY_MOVER_PAUSED, NDMP_NO_ERR,
3906 3767                      (void *)&pause_request, 0) < 0) {
3907      -                        NDMP_LOG(LOG_DEBUG,
     3768 +                        syslog(LOG_DEBUG,
3908 3769                              "Sending notify_mover_paused request");
3909 3770                          ndmpd_mover_error(session,
3910 3771                              NDMP_MOVER_HALT_INTERNAL_ERROR);
3911 3772                  }
3912 3773                  return;
3913 3774          }
3914 3775  
3915 3776          /*
3916 3777           * Read more data into the tape buffer if the buffer is empty.
3917 3778           */
3918 3779          if (session->ns_mover.md_w_index == 0) {
3919 3780                  n = mover_tape_read_v3(session, session->ns_mover.md_buf);
3920 3781  
3921      -                NDMP_LOG(LOG_DEBUG,
     3782 +                syslog(LOG_DEBUG,
3922 3783                      "read %u bytes from tape", n);
3923 3784  
3924 3785                  if (n <= 0) {
3925 3786                          ndmpd_mover_error(session, (n == 0 ?
3926 3787                              NDMP_MOVER_HALT_ABORTED
3927 3788                              : NDMP_MOVER_HALT_MEDIA_ERROR));
3928 3789                          return;
3929 3790                  }
3930 3791  
3931 3792                  /*
3932 3793                   * Discard data if the current data stream position is
3933 3794                   * prior to the seek position. This is necessary if a seek
3934 3795                   * request set the seek pointer to a position that is not a
3935 3796                   * record boundary. The seek request handler can only position
3936 3797                   * to the start of a record.
3937 3798                   */
3938 3799                  if (session->ns_mover.md_position <
3939 3800                      session->ns_mover.md_seek_position) {
3940 3801                          session->ns_mover.md_r_index =
3941 3802                              session->ns_mover.md_seek_position -
3942 3803                              session->ns_mover.md_position;
3943 3804                          session->ns_mover.md_position =
3944 3805                              session->ns_mover.md_seek_position;
3945 3806                  }
3946 3807  
3947 3808                  session->ns_mover.md_w_index = n;
3948 3809                  session->ns_mover.md_record_num++;
3949 3810          }
3950 3811  
3951 3812          /*
3952 3813           * The limit on the total amount of data to be sent can be
3953 3814           * dictated by either the end of the mover window or the end of the
3954 3815           * seek window.
3955 3816           * First determine which window applies and then determine if the
3956 3817           * send length needs to be less than a full record to avoid
3957 3818           * exceeding the window.
3958 3819           */
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
3959 3820          if (session->ns_mover.md_position +
3960 3821              session->ns_mover.md_bytes_left_to_read >
3961 3822              session->ns_mover.md_window_offset +
3962 3823              session->ns_mover.md_window_length)
3963 3824                  wlen = session->ns_mover.md_window_offset +
3964 3825                      session->ns_mover.md_window_length -
3965 3826                      session->ns_mover.md_position;
3966 3827          else
3967 3828                  wlen = session->ns_mover.md_bytes_left_to_read;
3968 3829  
3969      -        NDMP_LOG(LOG_DEBUG, "wlen window restrictions: %llu", wlen);
3970      -
3971 3830          /*
3972 3831           * Now limit the length to the amount of data in the buffer.
3973 3832           */
3974 3833          if (wlen > session->ns_mover.md_w_index - session->ns_mover.md_r_index)
3975 3834                  wlen = session->ns_mover.md_w_index -
3976 3835                      session->ns_mover.md_r_index;
3977 3836  
3978 3837          len = wlen & 0xffffffff;
3979      -        NDMP_LOG(LOG_DEBUG,
3980      -            "buffer restrictions: wlen %llu len %u", wlen, len);
3981 3838  
3982 3839          /*
3983 3840           * Write the data to the data connection.
3984 3841           */
3985 3842          n = write(session->ns_mover.md_sock,
3986 3843              &session->ns_mover.md_buf[session->ns_mover.md_r_index], len);
3987 3844  
3988 3845          if (n < 0) {
3989 3846                  /* Socket is non-blocking, perhaps the write queue is full */
3990 3847                  if (errno == EAGAIN) {
3991      -                        NDMP_LOG(LOG_ERR, "Cannot write to socket");
     3848 +                        syslog(LOG_ERR, "Cannot write to socket");
3992 3849                          return;
3993 3850                  }
3994      -                NDMP_LOG(LOG_ERR, "Failed to write to socket: %m");
     3851 +                syslog(LOG_ERR, "Failed to write to socket: %m");
3995 3852                  ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
3996 3853                  return;
3997 3854          }
3998 3855  
3999      -        NDMP_LOG(LOG_DEBUG,
4000      -            "wrote %u of %u bytes to data connection position %llu r_index %lu",
     3856 +        syslog(LOG_DEBUG,
     3857 +            "wrote %u of %u bytes to data connection position %lu r_index %lu",
4001 3858              n, len, session->ns_mover.md_position,
4002 3859              session->ns_mover.md_r_index);
4003 3860  
4004 3861          session->ns_mover.md_r_index += n;
4005 3862          session->ns_mover.md_position += n;
4006 3863          session->ns_mover.md_bytes_left_to_read -= n;
4007 3864  
4008 3865          /*
4009 3866           * If all data in the buffer has been written,
4010 3867           * zero the buffer indices. The next call to this function
4011 3868           * will read more data from the tape device into the buffer.
4012 3869           */
4013 3870          if (session->ns_mover.md_r_index == session->ns_mover.md_w_index) {
4014 3871                  session->ns_mover.md_r_index = 0;
4015 3872                  session->ns_mover.md_w_index = 0;
4016 3873          }
4017 3874  
4018 3875          /*
4019 3876           * If the read limit has been reached,
4020 3877           * then remove the file handler to prevent this
4021 3878           * function from getting called. The next mover_read request
4022 3879           * will reinstall the handler.
4023 3880           */
4024 3881          if (session->ns_mover.md_bytes_left_to_read == 0)
4025 3882                  (void) ndmpd_remove_file_handler(session, fd);
4026 3883  }
4027 3884  
4028 3885  
4029 3886  /*
4030 3887   * accept_connection_v3
4031 3888   *
4032 3889   * Accept a data connection from a data server.
4033 3890   * Called by ndmpd_select when a connection is pending on
4034 3891   * the mover listen socket.
4035 3892   *
4036 3893   * Parameters:
4037 3894   *   cookie  (input) - session pointer.
4038 3895   *   fd      (input) - file descriptor.
4039 3896   *   mode    (input) - select mode.
4040 3897   *
4041 3898   * Returns:
4042 3899   *   void.
4043 3900   */
4044 3901  /*ARGSUSED*/
4045 3902  static void
  
    | 
      ↓ open down ↓ | 
    35 lines elided | 
    
      ↑ open up ↑ | 
  
4046 3903  accept_connection_v3(void *cookie, int fd, ulong_t mode)
4047 3904  {
4048 3905          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
4049 3906          int from_len;
4050 3907          struct sockaddr_in from;
4051 3908  
4052 3909          from_len = sizeof (from);
4053 3910          session->ns_mover.md_sock = accept(fd, (struct sockaddr *)&from,
4054 3911              &from_len);
4055 3912  
4056      -        NDMP_LOG(LOG_DEBUG, "sin: port %d addr %s", ntohs(from.sin_port),
     3913 +        syslog(LOG_DEBUG, "sin: port %d addr %s", ntohs(from.sin_port),
4057 3914              inet_ntoa(IN_ADDR(from.sin_addr.s_addr)));
4058 3915  
4059 3916          (void) ndmpd_remove_file_handler(session, fd);
4060 3917          (void) close(session->ns_mover.md_listen_sock);
4061 3918          session->ns_mover.md_listen_sock = -1;
4062 3919  
4063 3920          if (session->ns_mover.md_sock < 0) {
4064      -                NDMP_LOG(LOG_DEBUG, "Accept error: %m");
     3921 +                syslog(LOG_DEBUG, "Accept error: %m");
4065 3922                  ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_ERROR);
4066 3923                  return;
4067 3924          }
4068 3925  
4069 3926          /*
4070 3927           * Save the peer address.
4071 3928           */
4072 3929          session->ns_mover.md_data_addr.tcp_ip_v3 = from.sin_addr.s_addr;
4073 3930          session->ns_mover.md_data_addr.tcp_port_v3 = ntohs(from.sin_port);
4074 3931  
4075 3932          /* Set the parameter of the new socket */
4076 3933          set_socket_options(session->ns_mover.md_sock);
4077 3934  
4078 3935          /*
4079 3936           * Backup/restore is handled by a callback called from main event loop,
4080 3937           * which reads/writes data to md_sock socket. IO on socket must be
4081 3938           * non-blocking, otherwise ndmpd would be unable to process other
4082 3939           * incoming requests.
4083 3940           */
4084 3941          if (!set_socket_nonblock(session->ns_mover.md_sock)) {
4085      -                NDMP_LOG(LOG_ERR, "Could not set non-blocking mode "
     3942 +                syslog(LOG_ERR, "Could not set non-blocking mode "
4086 3943                      "on socket: %m");
4087 3944                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
4088 3945                  return;
4089 3946          }
4090 3947  
4091      -        NDMP_LOG(LOG_DEBUG, "sock fd: %d", session->ns_mover.md_sock);
     3948 +        syslog(LOG_DEBUG, "sock fd: %d", session->ns_mover.md_sock);
4092 3949  
4093 3950          if (session->ns_mover.md_mode == NDMP_MOVER_MODE_READ) {
4094 3951                  if (ndmpd_add_file_handler(session, (void*)session,
4095 3952                      session->ns_mover.md_sock, NDMPD_SELECT_MODE_READ,
4096 3953                      HC_MOVER, mover_data_read_v3) < 0) {
4097 3954                          ndmpd_mover_error(session,
4098 3955                              NDMP_MOVER_HALT_INTERNAL_ERROR);
4099 3956                          return;
4100 3957                  }
4101      -                NDMP_LOG(LOG_DEBUG, "Backup connection established by %s:%d",
     3958 +                syslog(LOG_DEBUG, "Backup connection established by %s:%d",
4102 3959                      inet_ntoa(IN_ADDR(from.sin_addr.s_addr)),
4103 3960                      ntohs(from.sin_port));
4104 3961          } else {
4105      -                NDMP_LOG(LOG_DEBUG, "Restore connection established by %s:%d",
     3962 +                syslog(LOG_DEBUG, "Restore connection established by %s:%d",
4106 3963                      inet_ntoa(IN_ADDR(from.sin_addr.s_addr)),
4107 3964                      ntohs(from.sin_port));
4108 3965          }
4109 3966  
4110 3967          session->ns_mover.md_state = NDMP_MOVER_STATE_ACTIVE;
4111 3968  }
4112 3969  
4113 3970  
4114 3971  /*
4115 3972   * create_listen_socket_v3
4116 3973   *
4117 3974   * Creates a socket for listening for accepting data connections.
4118 3975   *
4119 3976   * Parameters:
4120 3977   *   session (input)  - session pointer.
4121 3978   *   addr    (output) - location to store address of socket.
4122 3979   *   port    (output) - location to store port of socket.
4123 3980   *
4124 3981   * Returns:
4125 3982   *   0 - success.
4126 3983   *  -1 - error.
4127 3984   */
4128 3985  static int
4129 3986  create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, ushort_t *port)
4130 3987  {
4131 3988          session->ns_mover.md_listen_sock = ndmp_create_socket(addr, port);
4132 3989          if (session->ns_mover.md_listen_sock < 0)
4133 3990                  return (-1);
4134 3991  
4135 3992          /*
4136 3993           * Add a file handler for the listen socket.
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
4137 3994           * ndmpd_select will call accept_connection when a
4138 3995           * connection is ready to be accepted.
4139 3996           */
4140 3997          if (ndmpd_add_file_handler(session, (void *) session,
4141 3998              session->ns_mover.md_listen_sock, NDMPD_SELECT_MODE_READ, HC_MOVER,
4142 3999              accept_connection_v3) < 0) {
4143 4000                  (void) close(session->ns_mover.md_listen_sock);
4144 4001                  session->ns_mover.md_listen_sock = -1;
4145 4002                  return (-1);
4146 4003          }
4147      -        NDMP_LOG(LOG_DEBUG, "IP %s port %d",
     4004 +        syslog(LOG_DEBUG, "IP %s port %d",
4148 4005              inet_ntoa(*(struct in_addr *)addr), ntohs(*port));
4149 4006          return (0);
4150 4007  }
4151 4008  
4152 4009  
4153 4010  /*
4154 4011   * mover_connect_sock
4155 4012   *
4156 4013   * Connect the mover to the specified address
4157 4014   *
4158 4015   * Parameters:
4159 4016   *   session (input)  - session pointer.
4160 4017   *   mode    (input)  - mover mode.
4161 4018   *   addr    (output) - location to store address of socket.
4162 4019   *   port    (output) - location to store port of socket.
4163 4020   *
4164 4021   * Returns:
4165 4022   *   error code.
4166 4023   */
4167 4024  static ndmp_error
4168 4025  mover_connect_sock(ndmpd_session_t *session, ndmp_mover_mode mode,
4169 4026      ulong_t addr, ushort_t port)
4170 4027  {
4171 4028          int sock;
4172 4029  
4173 4030          sock = ndmp_connect_sock_v3(addr, port);
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
4174 4031          if (sock < 0)
4175 4032                  return (NDMP_CONNECT_ERR);
4176 4033  
4177 4034          /*
4178 4035           * Backup/restore is handled by a callback called from main event loop,
4179 4036           * which reads/writes data to md_sock socket. IO on socket must be
4180 4037           * non-blocking, otherwise ndmpd would be unable to process other
4181 4038           * incoming requests.
4182 4039           */
4183 4040          if (!set_socket_nonblock(sock)) {
4184      -                NDMP_LOG(LOG_ERR, "Could not set non-blocking mode "
     4041 +                syslog(LOG_ERR, "Could not set non-blocking mode "
4185 4042                      "on socket: %m");
4186 4043                  (void) close(sock);
4187 4044                  return (NDMP_CONNECT_ERR);
4188 4045          }
4189 4046  
4190 4047          if (mode == NDMP_MOVER_MODE_READ) {
4191 4048                  if (ndmpd_add_file_handler(session, (void*)session, sock,
4192 4049                      NDMPD_SELECT_MODE_READ, HC_MOVER, mover_data_read_v3) < 0) {
4193 4050                          (void) close(sock);
4194 4051                          return (NDMP_CONNECT_ERR);
4195 4052                  }
4196 4053          }
4197 4054          session->ns_mover.md_sock = sock;
4198 4055          session->ns_mover.md_data_addr.addr_type = NDMP_ADDR_TCP;
4199 4056          session->ns_mover.md_data_addr.tcp_ip_v3 = ntohl(addr);
4200 4057          session->ns_mover.md_data_addr.tcp_port_v3 = port;
4201 4058          return (NDMP_NO_ERR);
4202 4059  }
4203 4060  
4204 4061  
4205 4062  /*
4206 4063   * ndmpd_local_read_v3
4207 4064   *
4208 4065   * Reads data from the local tape device.
4209 4066   * Full tape records are read and buffered.
4210 4067   *
4211 4068   * Parameters:
4212 4069   *   session (input) - session pointer.
4213 4070   *   data    (input) - location to store data.
4214 4071   *   length  (input) - data length.
4215 4072   *
4216 4073   * Returns:
4217 4074   *   1 - no read error but no writer running
4218 4075   *   0 - data successfully read.
4219 4076   *  -1 - error.
4220 4077   */
4221 4078  int
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
4222 4079  ndmpd_local_read_v3(ndmpd_session_t *session, char *data, ulong_t length)
4223 4080  {
4224 4081          ulong_t count;
4225 4082          ulong_t len;
4226 4083          ssize_t n;
4227 4084  
4228 4085          count = 0;
4229 4086          if (session->ns_mover.md_state == NDMP_MOVER_STATE_IDLE ||
4230 4087              session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
4231 4088              session->ns_mover.md_state == NDMP_MOVER_STATE_HALTED) {
4232      -                NDMP_LOG(LOG_DEBUG, "Invalid mover state to read data");
4233 4089                  return (-1);
4234 4090          }
4235 4091  
4236 4092          /*
4237 4093           * Automatically increase the seek window if necessary.
4238 4094           * This is needed in the event the module attempts to read
4239 4095           * past a seek window set via a prior call to ndmpd_seek() or
4240 4096           * the module has not issued a seek. If no seek was issued then
4241 4097           * pretend that a seek was issued to read the entire tape.
4242 4098           */
4243 4099          if (length > session->ns_mover.md_bytes_left_to_read) {
4244 4100                  /* ndmpd_seek() never called? */
4245 4101                  if (session->ns_data.dd_read_length == 0) {
4246 4102                          session->ns_mover.md_bytes_left_to_read = ~0LL;
4247 4103                          session->ns_data.dd_read_offset = 0LL;
4248 4104                          session->ns_data.dd_read_length = ~0LL;
4249 4105                  } else {
4250 4106                          session->ns_mover.md_bytes_left_to_read = length;
4251 4107                          session->ns_data.dd_read_offset =
4252 4108                              session->ns_mover.md_position;
4253 4109                          session->ns_data.dd_read_length = length;
4254 4110                  }
4255 4111          }
4256 4112  
4257 4113          /*
4258 4114           * Read as many records as necessary to satisfy the request.
4259 4115           */
4260 4116          while (count < length) {
4261 4117                  /*
4262 4118                   * If the end of the mover window has been reached,
4263 4119                   * then notify the client that a new data window is needed.
4264 4120                   */
4265 4121                  if (session->ns_mover.md_position >=
4266 4122                      session->ns_mover.md_window_offset +
4267 4123                      session->ns_mover.md_window_length) {
4268 4124                          if (mover_pause_v3(session,
4269 4125                              NDMP_MOVER_PAUSE_SEEK) < 0) {
4270 4126                                  ndmpd_mover_error(session,
4271 4127                                      NDMP_MOVER_HALT_INTERNAL_ERROR);
4272 4128                                  return (-1);
4273 4129                          }
4274 4130                          continue;
4275 4131                  }
4276 4132  
4277 4133                  len = length - count;
4278 4134  
4279 4135                  /*
4280 4136                   * Prevent reading past the end of the window.
4281 4137                   */
4282 4138                  if (len > session->ns_mover.md_window_offset +
4283 4139                      session->ns_mover.md_window_length -
4284 4140                      session->ns_mover.md_position)
4285 4141                          len = session->ns_mover.md_window_offset +
4286 4142                              session->ns_mover.md_window_length -
4287 4143                              session->ns_mover.md_position;
4288 4144  
4289 4145                  /*
4290 4146                   * Copy from the data buffer first.
4291 4147                   */
4292 4148                  if (session->ns_mover.md_w_index -
4293 4149                      session->ns_mover.md_r_index != 0) {
4294 4150                          /*
4295 4151                           * Limit the copy to the amount of data in the buffer.
4296 4152                           */
4297 4153                          if (len > session->ns_mover.md_w_index -
4298 4154                              session->ns_mover.md_r_index)
4299 4155                                  len = session->ns_mover.md_w_index -
4300 4156                                      session->ns_mover.md_r_index;
4301 4157                          (void) memcpy((void*)&data[count],
4302 4158                              &session->ns_mover.md_buf[session->
4303 4159                              ns_mover.md_r_index], len);
4304 4160                          count += len;
4305 4161                          session->ns_mover.md_r_index += len;
4306 4162                          session->ns_mover.md_bytes_left_to_read -= len;
4307 4163                          session->ns_mover.md_position += len;
4308 4164                          continue;
4309 4165                  }
4310 4166  
4311 4167                  /*
4312 4168                   * Determine if data needs to be buffered or
4313 4169                   * can be read directly to user supplied location.
4314 4170                   * We can fast path the read if at least a full record
4315 4171                   * needs to be read and there is no seek pending.
4316 4172                   * This is done to eliminate a buffer copy.
4317 4173                   */
4318 4174                  if (len >= session->ns_mover.md_record_size &&
4319 4175                      session->ns_mover.md_position >=
4320 4176                      session->ns_mover.md_seek_position) {
4321 4177                          n = mover_tape_read_v3(session, &data[count]);
4322 4178                          if (n <= 0) {
4323 4179                                  if (n == TAPE_NO_WRITER_ERR)
4324 4180                                          return (1);
4325 4181  
4326 4182                                  ndmpd_mover_error(session,
4327 4183                                      (n == 0 ? NDMP_MOVER_HALT_ABORTED :
4328 4184                                      NDMP_MOVER_HALT_MEDIA_ERROR));
4329 4185                                  return ((n == 0) ? 1 : -1);
4330 4186                          }
4331 4187  
4332 4188                          count += n;
4333 4189                          session->ns_mover.md_bytes_left_to_read -= n;
4334 4190                          session->ns_mover.md_position += n;
4335 4191                          session->ns_mover.md_record_num++;
4336 4192                          continue;
4337 4193                  }
4338 4194  
4339 4195                  /* Read the next record into the buffer. */
4340 4196                  n = mover_tape_read_v3(session, session->ns_mover.md_buf);
4341 4197                  if (n <= 0) {
4342 4198                          if (n == TAPE_NO_WRITER_ERR)
4343 4199                                  return (1);
4344 4200  
  
    | 
      ↓ open down ↓ | 
    102 lines elided | 
    
      ↑ open up ↑ | 
  
4345 4201                          ndmpd_mover_error(session,
4346 4202                              (n == 0 ? NDMP_MOVER_HALT_ABORTED :
4347 4203                              NDMP_MOVER_HALT_MEDIA_ERROR));
4348 4204                          return ((n == 0) ? 1 : -1);
4349 4205                  }
4350 4206  
4351 4207                  session->ns_mover.md_w_index = n;
4352 4208                  session->ns_mover.md_r_index = 0;
4353 4209                  session->ns_mover.md_record_num++;
4354 4210  
4355      -                NDMP_LOG(LOG_DEBUG, "n: %d", n);
4356      -
4357 4211                  /*
4358 4212                   * Discard data if the current data stream position is
4359 4213                   * prior to the seek position. This is necessary if a seek
4360 4214                   * request set the seek pointer to a position that is not a
4361 4215                   * record boundary. The seek request handler can only position
4362 4216                   * to the start of a record.
4363 4217                   */
4364 4218                  if (session->ns_mover.md_position <
4365 4219                      session->ns_mover.md_seek_position) {
4366 4220                          session->ns_mover.md_r_index =
4367 4221                              session->ns_mover.md_seek_position -
4368 4222                              session->ns_mover.md_position;
4369 4223                          session->ns_mover.md_position =
4370 4224                              session->ns_mover.md_seek_position;
4371 4225                  }
4372 4226          }
4373 4227  
4374 4228          return (0);
4375 4229  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX