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