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