Print this page
    
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-559 NDMP cannot backup/restore a file which spans multiple tapes
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/ndmpd/ndmp/ndmpd_callbacks.c
          +++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_callbacks.c
   1    1  /*
   2    2   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
        3 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
   3    4   */
   4    5  
   5    6  /*
   6    7   * BSD 3 Clause License
   7    8   *
   8    9   * Copyright (c) 2007, The Storage Networking Industry Association.
   9   10   *
  10   11   * Redistribution and use in source and binary forms, with or without
  11   12   * modification, are permitted provided that the following conditions
  12   13   * are met:
  13   14   *      - Redistributions of source code must retain the above copyright
  14   15   *        notice, this list of conditions and the following disclaimer.
  15   16   *
  16   17   *      - Redistributions in binary form must reproduce the above copyright
  17   18   *        notice, this list of conditions and the following disclaimer in
  18   19   *        the documentation and/or other materials provided with the
  19   20   *        distribution.
  20   21   *
  21   22   *      - Neither the name of The Storage Networking Industry Association (SNIA)
  22   23   *        nor the names of its contributors may be used to endorse or promote
  23   24   *        products derived from this software without specific prior written
  24   25   *        permission.
  25   26   *
  26   27   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27   28   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28   29   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29   30   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30   31   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31   32   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32   33   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
  33   34   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34   35   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35   36   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36   37   * POSSIBILITY OF SUCH DAMAGE.
  37   38   */
  38   39  /* Copyright (c) 2007, The Storage Networking Industry Association. */
  39   40  /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
  40   41  /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
  41   42  
  42   43  #include <sys/types.h>
       44 +#include <syslog.h>
  43   45  #include <stdlib.h>
  44   46  #include <errno.h>
  45   47  #include <stdarg.h>
  46   48  #include <stdio.h>
  47   49  #include <string.h>
  48   50  #include "ndmpd.h"
  49   51  
  50   52  
  51   53  /*
  52   54   * Message Id counter.  This number is increased by MOD_LOGV3 macro.
  53   55   * MOD_LOGCONTV3 macro uses the number generated by the last MOD_LOGV3.
  54   56   *
  55   57   */
  56   58  int ndmp_log_msg_id = 0;
  57   59  
  58   60  
  59   61  /*
  60   62   * ************************************************************************
  61   63   * NDMP V2 CALLBACKS
  62   64   * ************************************************************************
  63   65   */
  64   66  
  65   67  /*
  66   68   * ndmpd_api_done_v2
  67   69   *
  68   70   * Called when dump/restore has completed.
  69   71   * Sends a notify_halt request to the NDMP client.
  70   72   *
  71   73   * Parameters:
  72   74   *   session (input) - session pointer.
  73   75   *   err     (input) - UNIX error code.
  74   76   *
  75   77   * Returns:
  76   78   *   void
  77   79   */
  78   80  void
  79   81  ndmpd_api_done_v2(void *cookie, int err)
  80   82  {
  
    | 
      ↓ open down ↓ | 
    28 lines elided | 
    
      ↑ open up ↑ | 
  
  81   83          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
  82   84          ndmp_notify_data_halted_request req_v2;
  83   85  
  84   86          if (session == NULL)
  85   87                  return;
  86   88  
  87   89          if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
  88   90              session->ns_data.dd_state == NDMP_DATA_STATE_HALTED)
  89   91                  return;
  90   92  
  91      -        NDMP_LOG(LOG_DEBUG, "data.operation: %d",
       93 +        syslog(LOG_DEBUG, "data.operation: %d",
  92   94              session->ns_data.dd_operation);
  93   95  
  94   96          if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) {
  95   97                  /*
  96   98                   * Send/discard any buffered file history data.
  97   99                   */
  98  100                  ndmpd_file_history_cleanup(session, (err == 0 ? TRUE : FALSE));
  99  101  
 100  102                  /*
 101  103                   * If mover local and successfull backup, write any
 102  104                   * remaining buffered data to tape.
 103  105                   */
 104  106                  if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_LOCAL &&
 105  107                      err == 0) {
 106  108                          if (ndmpd_local_write(session, 0, 0) < 0)
 107  109                                  err = EIO;
 108  110                  }
 109  111          }
 110  112  
 111  113          session->ns_data.dd_state = NDMP_DATA_STATE_HALTED;
 112  114  
 113  115          switch (err) {
 114  116          case 0:
 115  117                  session->ns_data.dd_halt_reason = NDMP_DATA_HALT_SUCCESSFUL;
 116  118                  break;
 117  119          case EINTR:
 118  120                  session->ns_data.dd_halt_reason = NDMP_DATA_HALT_ABORTED;
 119  121                  break;
  
    | 
      ↓ open down ↓ | 
    18 lines elided | 
    
      ↑ open up ↑ | 
  
 120  122          case EIO:
 121  123                  session->ns_data.dd_halt_reason = NDMP_DATA_HALT_CONNECT_ERROR;
 122  124                  break;
 123  125          default:
 124  126                  session->ns_data.dd_halt_reason = NDMP_DATA_HALT_INTERNAL_ERROR;
 125  127          }
 126  128  
 127  129          req_v2.reason = session->ns_data.dd_halt_reason;
 128  130          req_v2.text_reason = "";
 129  131  
 130      -        NDMP_LOG(LOG_DEBUG, "ndmp_send_request(NDMP_NOTIFY_DATA_HALTED)");
      132 +        syslog(LOG_DEBUG, "ndmp_send_request(NDMP_NOTIFY_DATA_HALTED)");
 131  133  
 132  134          if (ndmp_send_request_lock(session->ns_connection,
 133  135              NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, (void *)&req_v2, 0) < 0)
 134      -                NDMP_LOG(LOG_DEBUG, "Sending notify_data_halted request");
      136 +                syslog(LOG_DEBUG, "Sending notify_data_halted request");
 135  137  
 136  138          if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
 137  139  
 138  140                  if (session->ns_mover.md_sock != session->ns_data.dd_sock) {
 139  141                          (void) close(session->ns_data.dd_sock);
 140  142                  } else {
 141      -                        NDMP_LOG(LOG_DEBUG, "Not closing as used by mover");
      143 +                        syslog(LOG_DEBUG, "Not closing as used by mover");
 142  144                  }
 143  145  
 144  146                  session->ns_data.dd_sock = -1;
 145  147          } else {
 146  148                  ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
 147  149          }
 148  150  }
 149  151  
 150  152  
 151  153  /*
 152  154   * ndmpd_api_log_v2
 153  155   *
 154  156   * Sends a log request to the NDMP client.
 155  157   *
 156  158   * Parameters:
 157  159   *   cookie (input) - session pointer.
 158  160   *   str    (input) - null terminated string
 159  161   *   format (input) - printf style format.
 160  162   *   ...    (input) - format arguments.
 161  163   *
 162  164   * Returns:
 163  165   *   0 - success.
 164  166   *  -1 - error.
 165  167   */
 166  168  /*ARGSUSED*/
 167  169  int
 168  170  ndmpd_api_log_v2(void *cookie, char *format, ...)
 169  171  {
 170  172          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 171  173          ndmp_log_log_request request;
 172  174          static char buf[1024];
 173  175          va_list ap;
 174  176  
 175  177          if (session == NULL)
 176  178                  return (-1);
 177  179  
 178  180          va_start(ap, format);
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
 179  181  
 180  182          /*LINTED variable format specifier */
 181  183          (void) vsnprintf(buf, sizeof (buf), format, ap);
 182  184          va_end(ap);
 183  185  
 184  186          request.entry = buf;
 185  187  
 186  188  
 187  189          if (ndmp_send_request(session->ns_connection, _NDMP_LOG_LOG,
 188  190              NDMP_NO_ERR, (void *)&request, 0) < 0) {
 189      -                NDMP_LOG(LOG_DEBUG, "Sending log request");
      191 +                syslog(LOG_ERR, "Sending log request");
 190  192                  return (-1);
 191  193          }
 192  194          return (0);
 193  195  
 194  196  }
 195  197  
 196  198  
 197  199  /*
 198  200   * ndmpd_api_read_v2
 199  201   *
 200  202   * Callback function called by the backup/recover module.
 201  203   * Reads data from the mover.
 202  204   * If the mover is remote, the data is read from the data connection.
 203  205   * If the mover is local, the data is read from the tape device.
 204  206   *
 205  207   * Parameters:
 206  208   *   client_data (input) - session pointer.
 207  209   *   data       (input) - data to be written.
 208  210   *   length     (input) - data length.
 209  211   *
 210  212   * Returns:
 211  213   *   0 - data successfully read.
 212  214   *  -1 - error.
 213  215   *   1 - session terminated or operation aborted.
 214  216   */
 215  217  int
 216  218  ndmpd_api_read_v2(void *client_data, char *data, ulong_t length)
 217  219  {
 218  220          ndmpd_session_t *session = (ndmpd_session_t *)client_data;
 219  221  
 220  222          if (session == NULL)
 221  223                  return (-1);
 222  224  
 223  225          /*
 224  226           * Read the data from the data connection if the mover is remote.
 225  227           */
 226  228          if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
 227  229                  return (ndmpd_remote_read(session, data, length));
 228  230          else
 229  231                  return (ndmpd_local_read(session, data, length));
 230  232  }
 231  233  
 232  234  
 233  235  /*
 234  236   * ndmpd_api_seek_v2
 235  237   *
 236  238   * Seek to the specified position in the data stream and start a
 237  239   * read for the specified amount of data.
 238  240   *
 239  241   * Parameters:
 240  242   *   cookie (input) - session pointer.
 241  243   *   offset (input) - stream position to seek to.
 242  244   *   length (input) - amount of data that will be read using ndmpd_api_read
 243  245   *
 244  246   * Returns:
 245  247   *   0 - seek successful.
 246  248   *  -1 - error.
 247  249   */
 248  250  int
 249  251  ndmpd_api_seek_v2(void *cookie, u_longlong_t offset, u_longlong_t length)
 250  252  {
 251  253          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 252  254          int err;
 253  255  
 254  256          if (session == NULL)
 255  257                  return (-1);
 256  258  
 257  259          session->ns_data.dd_read_offset = offset;
 258  260          session->ns_data.dd_read_length = length;
 259  261  
 260  262          /*
 261  263           * Send a notify_data_read request if the mover is remote.
 262  264           */
 263  265          if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
 264  266                  ndmp_notify_data_read_request request;
 265  267  
 266  268                  session->ns_mover.md_discard_length =
 267  269                      session->ns_mover.md_bytes_left_to_read;
  
    | 
      ↓ open down ↓ | 
    68 lines elided | 
    
      ↑ open up ↑ | 
  
 268  270                  session->ns_mover.md_bytes_left_to_read = length;
 269  271                  session->ns_mover.md_position = offset;
 270  272  
 271  273                  request.offset = long_long_to_quad(offset);
 272  274                  request.length = long_long_to_quad(length);
 273  275  
 274  276                  if (ndmp_send_request_lock(session->ns_connection,
 275  277                      NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
 276  278                      (void *)&request, 0) < 0) {
 277  279  
 278      -                        NDMP_LOG(LOG_DEBUG,
      280 +                        syslog(LOG_ERR,
 279  281                              "Sending notify_data_read request");
 280  282                          return (-1);
 281  283                  }
 282  284                  return (0);
 283  285          }
 284  286          /* Mover is local. */
 285  287  
 286  288          err = ndmpd_mover_seek(session, offset, length);
 287  289          if (err < 0) {
 288  290                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
 289  291                  return (-1);
 290  292          }
 291  293          if (err == 0)
 292  294                  return (0);
 293  295  
 294  296          /*
 295  297           * NDMP client intervention is required to perform the seek.
 296  298           * Wait for the client to either do the seek and send a continue
 297  299           * request or send an abort request.
 298  300           */
 299  301          return (ndmp_wait_for_mover(session));
 300  302  }
 301  303  
 302  304  
 303  305  /*
 304  306   * ndmpd_api_file_recovered_v2
 305  307   *
 306  308   * Notify the NDMP client that the specified file was recovered.
 307  309   *
 308  310   * Parameters:
 309  311   *   cookie (input) - session pointer.
 310  312   *   name   (input) - name of recovered file.
 311  313   *   error  (input) - 0 if file successfully recovered.
 312  314   *                  otherwise, error code indicating why recovery failed.
 313  315   *
 314  316   * Returns:
 315  317   *   void.
 316  318   */
 317  319  int
 318  320  ndmpd_api_file_recovered_v2(void *cookie, char *name, int error)
 319  321  {
 320  322          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 321  323          ndmp_log_file_request_v2 request;
 322  324  
 323  325          if (session == NULL)
 324  326                  return (-1);
 325  327  
 326  328          request.name = name;
 327  329          request.ssid = 0;
 328  330  
 329  331          switch (error) {
 330  332          case 0:
 331  333                  request.error = NDMP_NO_ERR;
  
    | 
      ↓ open down ↓ | 
    43 lines elided | 
    
      ↑ open up ↑ | 
  
 332  334                  break;
 333  335          case ENOENT:
 334  336                  request.error = NDMP_FILE_NOT_FOUND_ERR;
 335  337                  break;
 336  338          default:
 337  339                  request.error = NDMP_PERMISSION_ERR;
 338  340          }
 339  341  
 340  342          if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
 341  343              NDMP_NO_ERR, (void *)&request, 0) < 0) {
 342      -                NDMP_LOG(LOG_DEBUG, "Sending log file request");
      344 +                syslog(LOG_ERR, "Sending log file request");
 343  345                  return (-1);
 344  346          }
 345  347          return (0);
 346  348  }
 347  349  
 348  350  
 349  351  /*
 350  352   * ndmpd_api_write_v2
 351  353   *
 352  354   * Callback function called by the backup/restore module.
 353  355   * Writes data to the mover.
 354  356   * If the mover is remote, the data is written to the data connection.
 355  357   * If the mover is local, the data is buffered and written to the
 356  358   * tape device after a full record has been buffered.
 357  359   *
 358  360   * Parameters:
 359  361   *   client_data (input) - session pointer.
 360  362   *   data       (input) - data to be written.
 361  363   *   length     (input) - data length.
 362  364   *
 363  365   * Returns:
 364  366   *   0 - data successfully written.
 365  367   *  -1 - error.
 366  368   */
 367  369  int
 368  370  ndmpd_api_write_v2(void *client_data, char *data, ulong_t length)
 369  371  {
 370  372          ndmpd_session_t *session = (ndmpd_session_t *)client_data;
 371  373  
 372  374          if (session == NULL)
 373  375                  return (-1);
 374  376  
 375  377          /*
 376  378           * Write the data to the data connection if the mover is remote.
 377  379           */
 378  380          if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP)
 379  381                  return (ndmpd_remote_write(session, data, length));
 380  382          else
 381  383                  return (ndmpd_local_write(session, data, length));
 382  384  }
 383  385  
 384  386  
 385  387  /*
 386  388   * ************************************************************************
 387  389   * NDMP V3 CALLBACKS
 388  390   * ************************************************************************
 389  391   */
 390  392  
 391  393  /*
 392  394   * ndmpd_api_done_v3
 393  395   *
 394  396   * Called when the data module has completed.
 395  397   * Sends a notify_halt request to the NDMP client.
 396  398   *
 397  399   * Parameters:
 398  400   *   session (input) - session pointer.
 399  401   *   err     (input) - UNIX error code.
 400  402   *
 401  403   * Returns:
 402  404   *   void
 403  405   */
 404  406  void
 405  407  ndmpd_api_done_v3(void *cookie, int err)
 406  408  {
 407  409          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 408  410          ndmp_data_halt_reason reason;
 409  411  
 410  412          switch (err) {
 411  413          case 0:
 412  414                  reason = NDMP_DATA_HALT_SUCCESSFUL;
 413  415                  break;
 414  416  
 415  417          case EINTR:
 416  418                  reason = NDMP_DATA_HALT_ABORTED;
 417  419                  break;
 418  420  
 419  421          case EIO:
 420  422                  reason = NDMP_DATA_HALT_CONNECT_ERROR;
 421  423                  break;
 422  424  
 423  425          default:
 424  426                  reason = NDMP_DATA_HALT_INTERNAL_ERROR;
 425  427          }
 426  428  
 427  429          ndmpd_data_error(session, reason);
 428  430  }
 429  431  
 430  432  /*
 431  433   * ndmpd_api_log_v3
 432  434   *
 433  435   * Sends a log request to the NDMP client.
 434  436   *
 435  437   * Parameters:
 436  438   *   cookie (input) - session pointer.
 437  439   *   format (input) - printf style format.
 438  440   *   ...    (input) - format arguments.
 439  441   *
 440  442   * Returns:
 441  443   *   0 - success.
 442  444   *  -1 - error.
 443  445   */
 444  446  /*ARGSUSED*/
 445  447  int
 446  448  ndmpd_api_log_v3(void *cookie, ndmp_log_type type, ulong_t msg_id,
 447  449      char *format, ...)
 448  450  {
 449  451          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 450  452          ndmp_log_message_request_v3 request;
 451  453          static char buf[1024];
 452  454          va_list ap;
 453  455  
 454  456          if (session == NULL)
 455  457                  return (-1);
 456  458  
 457  459          va_start(ap, format);
 458  460  
  
    | 
      ↓ open down ↓ | 
    106 lines elided | 
    
      ↑ open up ↑ | 
  
 459  461          /*LINTED variable format specifier */
 460  462          (void) vsnprintf(buf, sizeof (buf), format, ap);
 461  463          va_end(ap);
 462  464  
 463  465          request.entry = buf;
 464  466          request.log_type = type;
 465  467          request.message_id = msg_id;
 466  468  
 467  469          if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
 468  470              NDMP_NO_ERR, (void *)&request, 0) < 0) {
 469      -                NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
      471 +                syslog(LOG_ERR, "Error sending log message request.");
 470  472                  return (-1);
 471  473          }
 472  474          return (0);
 473  475  }
 474  476  
 475  477  
 476  478  /*
 477  479   * ndmpd_api_write_v3
 478  480   *
 479  481   * Callback function called by the backup/restore module.
 480  482   * Writes data to the mover.
 481  483   * If the mover is remote, the data is written to the data connection.
 482  484   * If the mover is local, the data is buffered and written to the
 483  485   * tape device after a full record has been buffered.
 484  486   *
 485  487   * Parameters:
 486  488   *   client_data (input) - session pointer.
 487  489   *   data       (input) - data to be written.
 488  490   *   length     (input) - data length.
 489  491   *
 490  492   * Returns:
 491  493   *   0 - data successfully written.
 492  494   *  -1 - error.
 493  495   */
 494  496  int
 495  497  ndmpd_api_write_v3(void *client_data, char *data, ulong_t length)
 496  498  {
 497  499          ndmpd_session_t *session = (ndmpd_session_t *)client_data;
 498  500  
 499  501          if (session == NULL)
 500  502                  return (-1);
 501  503  
 502  504          /*
 503  505           * Write the data to the tape if the mover is local, otherwise,
 504  506           * write the data to the data connection.
 505  507           *
 506  508           * The same write function for of v2 can be used in V3
 507  509           * for writing data to the data connection to the mover.
 508  510           * So we don't need ndmpd_remote_write_v3().
 509  511           */
 510  512          if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
 511  513                  return (ndmpd_local_write_v3(session, data, length));
 512  514          else
 513  515                  return (ndmpd_remote_write(session, data, length));
 514  516  }
 515  517  
 516  518  
 517  519  /*
 518  520   * ndmpd_api_read_v3
 519  521   *
 520  522   * Callback function called by the backup/recover module.
 521  523   * Reads data from the mover.
 522  524   * If the mover is remote, the data is read from the data connection.
 523  525   * If the mover is local, the data is read from the tape device.
 524  526   *
 525  527   * Parameters:
 526  528   *   client_data (input) - session pointer.
 527  529   *   data       (input) - data to be written.
 528  530   *   length     (input) - data length.
 529  531   *
 530  532   * Returns:
 531  533   *   0 - data successfully read.
 532  534   *  -1 - error.
 533  535   *   1 - session terminated or operation aborted.
 534  536   */
 535  537  int
 536  538  ndmpd_api_read_v3(void *client_data, char *data, ulong_t length)
 537  539  {
 538  540          ndmpd_session_t *session = (ndmpd_session_t *)client_data;
 539  541  
 540  542          if (session == NULL)
 541  543                  return (-1);
 542  544  
 543  545          /*
 544  546           * Read the data from the data connection if the mover is remote.
 545  547           */
 546  548          if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL)
 547  549                  return (ndmpd_local_read_v3(session, data, length));
 548  550          else
 549  551                  return (ndmpd_remote_read_v3(session, data, length));
 550  552  }
 551  553  
 552  554  
 553  555  /*
 554  556   * ndmpd_api_get_name_v3
 555  557   *
 556  558   * Return the name entry at the specified index from the
 557  559   * recover file name list.
 558  560   *
 559  561   * Parameters:
 560  562   *       cookie    (input) - NDMP session pointer.
 561  563   *       name_index (input) - index of entry to be returned.
 562  564   *
 563  565   * Returns:
 564  566   *   Pointer to name entry.
 565  567   *   0 if requested entry does not exist.
 566  568   */
 567  569  void *
 568  570  ndmpd_api_get_name_v3(void *cookie, ulong_t name_index)
 569  571  {
 570  572          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 571  573  
 572  574          if (session == NULL)
 573  575                  return (NULL);
 574  576  
 575  577          if (name_index >= session->ns_data.dd_nlist_len)
 576  578                  return (NULL);
 577  579  
 578  580          return (&session->ns_data.dd_nlist_v3[name_index]);
 579  581  }
 580  582  
 581  583  
 582  584  /*
 583  585   * ndmpd_api_file_recovered_v3
 584  586   *
 585  587   * Notify the NDMP client that the specified file was recovered.
 586  588   *
 587  589   * Parameters:
 588  590   *   cookie (input) - session pointer.
 589  591   *   name   (input) - name of recovered file.
 590  592   *   ssid   (input) - selection set id.
 591  593   *   error  (input) - 0 if file successfully recovered.
 592  594   *                  otherwise, error code indicating why recovery failed.
 593  595   *
 594  596   * Returns:
 595  597   *   0 - success.
 596  598   *  -1 - error.
 597  599   */
 598  600  int
 599  601  ndmpd_api_file_recovered_v3(void *cookie, char *name, int error)
 600  602  {
 601  603          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 602  604          ndmp_log_file_request_v3 request;
 603  605  
 604  606          if (session == NULL)
 605  607                  return (-1);
 606  608  
 607  609          request.name  = name;
 608  610  
 609  611          switch (error) {
 610  612          case 0:
 611  613                  request.error = NDMP_NO_ERR;
  
    | 
      ↓ open down ↓ | 
    132 lines elided | 
    
      ↑ open up ↑ | 
  
 612  614                  break;
 613  615          case ENOENT:
 614  616                  request.error = NDMP_FILE_NOT_FOUND_ERR;
 615  617                  break;
 616  618          default:
 617  619                  request.error = NDMP_PERMISSION_ERR;
 618  620          }
 619  621  
 620  622          if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
 621  623              NDMP_NO_ERR, (void *)&request, 0) < 0) {
 622      -                NDMP_LOG(LOG_DEBUG, "Error sending log file request");
      624 +                syslog(LOG_ERR, "Error sending log file request");
 623  625                  return (-1);
 624  626          }
 625  627  
 626  628          return (0);
 627  629  }
 628  630  
 629  631  
 630  632  /*
 631  633   * ndmpd_api_seek_v3
 632  634   *
 633  635   * Seek to the specified position in the data stream and start a
 634  636   * read for the specified amount of data.
 635  637   *
 636  638   * Parameters:
 637  639   *   cookie (input) - session pointer.
 638  640   *   offset (input) - stream position to seek to.
 639  641   *   length (input) - amount of data that will be read using ndmpd_api_read
 640  642   *
 641  643   * Returns:
 642  644   *   0 - seek successful.
 643  645   *   1 - seek needed DMA(client) intervention.
 644  646   *  -1 - error.
 645  647   */
 646  648  int
 647  649  ndmpd_api_seek_v3(void *cookie, u_longlong_t offset, u_longlong_t length)
 648  650  {
 649  651          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 650  652          int err;
 651  653          ndmp_notify_data_read_request request;
 652  654  
 653  655          if (session == NULL)
 654  656                  return (-1);
 655  657  
 656  658          session->ns_data.dd_read_offset = offset;
 657  659          session->ns_data.dd_read_length = length;
 658  660  
 659  661          /*
 660  662           * Send a notify_data_read request if the mover is remote.
 661  663           */
 662  664          if (session->ns_data.dd_data_addr.addr_type != NDMP_ADDR_LOCAL) {
 663  665                  session->ns_data.dd_discard_length =
  
    | 
      ↓ open down ↓ | 
    31 lines elided | 
    
      ↑ open up ↑ | 
  
 664  666                      session->ns_data.dd_bytes_left_to_read;
 665  667                  session->ns_data.dd_bytes_left_to_read = length;
 666  668                  session->ns_data.dd_position = offset;
 667  669  
 668  670                  request.offset = long_long_to_quad(offset);
 669  671                  request.length = long_long_to_quad(length);
 670  672  
 671  673                  if (ndmp_send_request_lock(session->ns_connection,
 672  674                      NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
 673  675                      (void *)&request, 0) < 0) {
 674      -                        NDMP_LOG(LOG_DEBUG,
      676 +                        syslog(LOG_ERR,
 675  677                              "Sending notify_data_read request");
 676  678                          return (-1);
 677  679                  }
 678  680  
 679  681                  return (0);
 680  682          }
 681  683  
 682  684          /* Mover is local. */
 683  685  
 684  686          err = ndmpd_mover_seek(session, offset, length);
 685  687          if (err < 0) {
 686  688                  ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
 687  689                  return (-1);
 688  690          }
 689  691  
 690  692          if (err == 0)
 691  693                  return (0);
 692  694  
 693  695          /*
 694  696           * NDMP client intervention is required to perform the seek.
 695  697           * Wait for the client to either do the seek and send a continue
 696  698           * request or send an abort request.
 697  699           */
 698  700          err = ndmp_wait_for_mover(session);
 699  701  
 700  702          /*
 701  703           * If we needed a client intervention, then we should be able to
 702  704           * detect this in DAR.
 703  705           */
 704  706          if (err == 0)
 705  707                  err = 1;
 706  708          return (err);
 707  709  }
 708  710  
 709  711  
 710  712  /*
 711  713   * ************************************************************************
 712  714   * NDMP V4 CALLBACKS
 713  715   * ************************************************************************
 714  716   */
 715  717  
 716  718  /*
 717  719   * ndmpd_api_log_v4
 718  720   *
 719  721   * Sends a log request to the NDMP client.
 720  722   * No message association is supported now, but can be added later on
 721  723   * in this function.
 722  724   *
 723  725   * Parameters:
 724  726   *   cookie (input) - session pointer.
 725  727   *   format (input) - printf style format.
 726  728   *   ...    (input) - format arguments.
 727  729   *
 728  730   * Returns:
 729  731   *   0 - success.
 730  732   *  -1 - error.
 731  733   */
 732  734  /*ARGSUSED*/
 733  735  int
 734  736  ndmpd_api_log_v4(void *cookie, ndmp_log_type type, ulong_t msg_id,
 735  737      char *format, ...)
 736  738  {
 737  739          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 738  740          ndmp_log_message_request_v4 request;
 739  741          static char buf[1024];
 740  742          va_list ap;
 741  743  
 742  744          if (session == NULL)
 743  745                  return (-1);
 744  746  
 745  747          va_start(ap, format);
 746  748  
 747  749          /*LINTED variable format specifier */
 748  750          (void) vsnprintf(buf, sizeof (buf), format, ap);
  
    | 
      ↓ open down ↓ | 
    64 lines elided | 
    
      ↑ open up ↑ | 
  
 749  751          va_end(ap);
 750  752  
 751  753          request.entry = buf;
 752  754          request.log_type = type;
 753  755          request.message_id = msg_id;
 754  756          request.associated_message_valid = NDMP_NO_ASSOCIATED_MESSAGE;
 755  757          request.associated_message_sequence = 0;
 756  758  
 757  759          if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
 758  760              NDMP_NO_ERR, (void *)&request, 0) < 0) {
 759      -                NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
      761 +                syslog(LOG_ERR, "Error sending log message request.");
 760  762                  return (-1);
 761  763          }
 762  764          return (0);
 763  765  }
 764  766  
 765  767  
 766  768  /*
 767  769   * ndmpd_api_file_recovered_v4
 768  770   *
 769  771   * Notify the NDMP client that the specified file was recovered.
 770  772   *
 771  773   * Parameters:
 772  774   *   cookie (input) - session pointer.
 773  775   *   name   (input) - name of recovered file.
 774  776   *   ssid   (input) - selection set id.
 775  777   *   error  (input) - 0 if file successfully recovered.
 776  778   *                  otherwise, error code indicating why recovery failed.
 777  779   *
 778  780   * Returns:
 779  781   *   void.
 780  782   */
 781  783  int
 782  784  ndmpd_api_file_recovered_v4(void *cookie, char *name, int error)
 783  785  {
 784  786          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 785  787          ndmp_log_file_request_v4 request;
 786  788  
 787  789          if (session == NULL)
 788  790                  return (-1);
 789  791  
 790  792          request.name  = name;
 791  793  
 792  794          switch (error) {
 793  795          case 0:
 794  796                  request.recovery_status = NDMP_RECOVERY_SUCCESSFUL;
 795  797                  break;
 796  798          case EPERM:
 797  799                  request.recovery_status = NDMP_RECOVERY_FAILED_PERMISSION;
 798  800                  break;
 799  801          case ENOENT:
 800  802                  request.recovery_status = NDMP_RECOVERY_FAILED_NOT_FOUND;
 801  803                  break;
 802  804          case ENOTDIR:
 803  805                  request.recovery_status = NDMP_RECOVERY_FAILED_NO_DIRECTORY;
 804  806                  break;
 805  807          case ENOMEM:
 806  808                  request.recovery_status = NDMP_RECOVERY_FAILED_OUT_OF_MEMORY;
 807  809                  break;
 808  810          case EIO:
 809  811                  request.recovery_status = NDMP_RECOVERY_FAILED_IO_ERROR;
 810  812                  break;
  
    | 
      ↓ open down ↓ | 
    41 lines elided | 
    
      ↑ open up ↑ | 
  
 811  813          case EEXIST:
 812  814                  request.recovery_status = NDMP_RECOVERY_FAILED_FILE_PATH_EXISTS;
 813  815                  break;
 814  816          default:
 815  817                  request.recovery_status = NDMP_RECOVERY_FAILED_UNDEFINED_ERROR;
 816  818                  break;
 817  819          }
 818  820  
 819  821          if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
 820  822              NDMP_NO_ERR, (void *)&request, 0) < 0) {
 821      -                NDMP_LOG(LOG_DEBUG, "Error sending log file request");
      823 +                syslog(LOG_ERR, "Error sending log file request");
 822  824                  return (-1);
 823  825          }
 824  826  
 825  827          return (0);
 826  828  }
 827  829  
 828  830  
 829  831  /*
 830  832   * ************************************************************************
 831  833   * LOCALS
 832  834   * ************************************************************************
 833  835   */
 834  836  
 835  837  /*
 836  838   * ndmpd_api_find_env
 837  839   *
 838  840   * Return the pointer of the environment variable from the variable
 839  841   * array for the spcified environment variable.
 840  842   *
 841  843   * Parameters:
 842  844   *       cookie (input) - NDMP session pointer.
 843  845   *       name   (input) - name of variable.
 844  846   *
 845  847   * Returns:
 846  848   *   Pointer to variable.
 847  849   *   NULL if variable not found.
 848  850   *
 849  851   */
 850  852  ndmp_pval *
 851  853  ndmpd_api_find_env(void *cookie, char *name)
 852  854  {
 853  855          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
 854  856          ulong_t i;
 855  857          ndmp_pval *envp;
 856  858  
 857  859          if (session == NULL)
 858  860                  return (NULL);
 859  861  
 860  862          envp = session->ns_data.dd_env;
 861  863          for (i = 0; envp && i < session->ns_data.dd_env_len; envp++, i++)
 862  864                  if (strcmp(name, envp->name) == NULL)
 863  865                          return (envp);
 864  866  
 865  867          return (NULL);
 866  868  }
 867  869  
 868  870  
 869  871  /*
 870  872   * ndmpd_api_get_env
 871  873   *
 872  874   * Return the value of an environment variable from the variable array.
 873  875   *
 874  876   * Parameters:
 875  877   *       cookie (input) - NDMP session pointer.
 876  878   *       name   (input) - name of variable.
 877  879   *
 878  880   * Returns:
 879  881   *   Pointer to variable value.
 880  882   *   0 if variable not found.
 881  883   *
 882  884   */
 883  885  char *
 884  886  ndmpd_api_get_env(void *cookie, char *name)
 885  887  {
 886  888          ndmp_pval *envp;
 887  889  
 888  890          envp = ndmpd_api_find_env(cookie, name);
 889  891          if (envp)
 890  892                  return (envp->value);
 891  893  
 892  894          return (NULL);
 893  895  }
 894  896  
 895  897  
 896  898  /*
 897  899   * ndmpd_api_add_env
 898  900   *
 899  901   * Adds an environment variable name/value pair to the environment
 900  902   * variable list.
 901  903   *
 902  904   * Parameters:
 903  905   *   session (input) - session pointer.
 904  906   *   name    (input) - variable name.
 905  907   *   val     (input) - value.
 906  908   *
 907  909   * Returns:
 908  910   *   0 - success.
 909  911   *  -1 - error.
 910  912   */
 911  913  int
 912  914  ndmpd_api_add_env(void *cookie, char *name, char *value)
 913  915  {
 914  916          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
  
    | 
      ↓ open down ↓ | 
    83 lines elided | 
    
      ↑ open up ↑ | 
  
 915  917          char *namebuf;
 916  918          char *valbuf;
 917  919  
 918  920          if (session == NULL)
 919  921                  return (-1);
 920  922  
 921  923          session->ns_data.dd_env = realloc((void *)session->ns_data.dd_env,
 922  924              sizeof (ndmp_pval) * (session->ns_data.dd_env_len + 1));
 923  925  
 924  926          if (session->ns_data.dd_env == NULL) {
 925      -                NDMP_LOG(LOG_ERR, "Out of memory.");
      927 +                syslog(LOG_ERR, "Out of memory.");
 926  928                  return (-1);
 927  929          }
 928  930          namebuf = strdup(name);
 929  931          if (namebuf == NULL)
 930  932                  return (-1);
 931  933  
 932  934          valbuf = strdup(value);
 933  935          if (valbuf == NULL) {
 934  936                  free(namebuf);
 935  937                  return (-1);
 936  938          }
 937  939  
 938  940          (void) mutex_lock(&session->ns_lock);
 939  941          session->ns_data.dd_env[session->ns_data.dd_env_len].name = namebuf;
 940  942          session->ns_data.dd_env[session->ns_data.dd_env_len].value = valbuf;
 941  943          session->ns_data.dd_env_len++;
 942  944          (void) mutex_unlock(&session->ns_lock);
 943  945  
 944  946          return (0);
 945  947  }
 946  948  
 947  949  
 948  950  /*
 949  951   * ndmpd_api_set_env
 950  952   *
 951  953   * Sets an environment variable name/value pair in the environment
 952  954   * variable list.  If the variable exists, it gets the new value,
 953  955   * otherwise it's added as a new variable.
 954  956   *
 955  957   * Parameters:
 956  958   *   session (input) - session pointer.
 957  959   *   name    (input) - variable name.
 958  960   *   val     (input) - value.
 959  961   *
 960  962   * Returns:
 961  963   *   0 - success.
 962  964   *  -1 - error.
 963  965   */
 964  966  int
 965  967  ndmpd_api_set_env(void *cookie, char *name, char *value)
 966  968  {
 967  969          char *valbuf;
 968  970          int rv;
 969  971          ndmp_pval *envp;
 970  972  
 971  973          envp = ndmpd_api_find_env(cookie, name);
 972  974          if (!envp) {
 973  975                  rv = ndmpd_api_add_env(cookie, name, value);
 974  976          } else if (!(valbuf = strdup(value))) {
 975  977                  rv = -1;
 976  978          } else {
 977  979                  rv = 0;
 978  980                  free(envp->value);
 979  981                  envp->value = valbuf;
 980  982          }
 981  983  
 982  984          return (rv);
 983  985  }
 984  986  
 985  987  
 986  988  /*
 987  989   * ndmpd_api_get_name
 988  990   *
 989  991   * Return the name entry at the specified index from the
 990  992   * recover file name list.
 991  993   *
 992  994   * Parameters:
 993  995   *   cookie    (input) - NDMP session pointer.
 994  996   *   name_index (input) - index of entry to be returned.
 995  997   *
 996  998   * Returns:
 997  999   *   Pointer to name entry.
 998 1000   *   0 if requested entry does not exist.
 999 1001   */
1000 1002  void *
1001 1003  ndmpd_api_get_name(void *cookie, ulong_t name_index)
1002 1004  {
1003 1005          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1004 1006  
1005 1007          if (session == NULL)
1006 1008                  return (NULL);
1007 1009  
1008 1010          if (name_index >= session->ns_data.dd_nlist_len)
1009 1011                  return (NULL);
1010 1012  
1011 1013          return (&session->ns_data.dd_nlist[name_index]);
1012 1014  }
1013 1015  
1014 1016  
1015 1017  /*
1016 1018   * ndmpd_api_dispatch
1017 1019   *
1018 1020   * Process pending NDMP client requests and check registered files for
1019 1021   * data availability.
1020 1022   *
1021 1023   * Parameters:
1022 1024   *   cookie (input) - session pointer.
1023 1025   *   block  (input) -
1024 1026   *              TRUE    block until a request has been processed or
1025 1027   *                      until a file handler has been called.
1026 1028   *              FALSE   don't block.
1027 1029   *
1028 1030   * Returns:
1029 1031   *  -1 - abort request received or connection closed.
1030 1032   *   0 - success.
1031 1033   */
1032 1034  int
1033 1035  ndmpd_api_dispatch(void *cookie, boolean_t block)
1034 1036  {
1035 1037          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1036 1038          int err;
1037 1039  
1038 1040          if (session == NULL)
1039 1041                  return (-1);
1040 1042  
1041 1043          for (; ; ) {
1042 1044                  err = ndmpd_select(session, block, HC_ALL);
1043 1045                  if (err < 0 || session->ns_data.dd_abort == TRUE ||
1044 1046                      session->ns_eof)
1045 1047                          return (-1);
1046 1048  
1047 1049                  if (err == 0)
1048 1050                          return (0);
1049 1051  
1050 1052                  /*
1051 1053                   * Something was processed.
1052 1054                   * Set the block flag to false so that we will return as
1053 1055                   * soon as everything available to be processed has been
1054 1056                   * processed.
1055 1057                   */
1056 1058                  block = FALSE;
1057 1059          }
1058 1060  }
1059 1061  
1060 1062  
1061 1063  /*
1062 1064   * ndmpd_api_add_file_handler
1063 1065   *
1064 1066   * Adds a file handler to the file handler list.
1065 1067   * The file handler list is used by ndmpd_api_dispatch.
1066 1068   *
1067 1069   * Parameters:
1068 1070   *   daemon_cookie (input) - session pointer.
1069 1071   *   cookie  (input) - opaque data to be passed to file hander when called.
1070 1072   *   fd      (input) - file descriptor.
1071 1073   *   mode    (input) - bitmask of the following:
1072 1074   *      NDMP_SELECT_MODE_READ = watch file for ready for reading
1073 1075   *      NDMP_SELECT_MODE_WRITE = watch file for ready for writing
1074 1076   *      NDMP_SELECT_MODE_EXCEPTION = watch file for exception
1075 1077   *   func    (input) - function to call when the file meets one of the
1076 1078   *                   conditions specified by mode.
1077 1079   *
1078 1080   * Returns:
1079 1081   *   0 - success.
1080 1082   *  -1 - error.
1081 1083   */
1082 1084  int
1083 1085  ndmpd_api_add_file_handler(void *daemon_cookie, void *cookie, int fd,
1084 1086      ulong_t mode, ndmpd_file_handler_func_t *func)
1085 1087  {
1086 1088          ndmpd_session_t *session = (ndmpd_session_t *)daemon_cookie;
1087 1089  
1088 1090          return (ndmpd_add_file_handler(session, cookie, fd, mode, HC_MODULE,
1089 1091              func));
1090 1092  }
1091 1093  
1092 1094  
1093 1095  /*
1094 1096   * ndmpd_api_remove_file_handler
1095 1097   *
1096 1098   * Removes a file handler from the file handler list.
1097 1099   *
1098 1100   * Parameters:
1099 1101   *   cookie  (input) - session pointer.
1100 1102   *   fd      (input) - file descriptor.
1101 1103   *
1102 1104   * Returns:
1103 1105   *   0 - success.
1104 1106   *  -1 - error.
1105 1107   */
1106 1108  int
1107 1109  ndmpd_api_remove_file_handler(void *cookie, int fd)
1108 1110  {
1109 1111          ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1110 1112  
1111 1113          return (ndmpd_remove_file_handler(session, fd));
1112 1114  }
  
    | 
      ↓ open down ↓ | 
    177 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX