1 /*
2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 */
4
5 /*
6 * BSD 3 Clause License
7 *
8 * Copyright (c) 2007, The Storage Networking Industry Association.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * - Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * - Neither the name of The Storage Networking Industry Association (SNIA)
22 * nor the names of its contributors may be used to endorse or promote
23 * products derived from this software without specific prior written
24 * permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38 /* Copyright (c) 2007, The Storage Networking Industry Association. */
39 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
40 /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
41
42 #include <sys/types.h>
43 #include <stdlib.h>
44 #include <errno.h>
45 #include <stdarg.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include "ndmpd.h"
49
50
51 /*
52 * Message Id counter. This number is increased by MOD_LOGV3 macro.
53 * MOD_LOGCONTV3 macro uses the number generated by the last MOD_LOGV3.
54 *
55 */
56 int ndmp_log_msg_id = 0;
57
58
59 /*
60 * ************************************************************************
61 * NDMP V2 CALLBACKS
62 * ************************************************************************
71 * Parameters:
72 * session (input) - session pointer.
73 * err (input) - UNIX error code.
74 *
75 * Returns:
76 * void
77 */
78 void
79 ndmpd_api_done_v2(void *cookie, int err)
80 {
81 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
82 ndmp_notify_data_halted_request req_v2;
83
84 if (session == NULL)
85 return;
86
87 if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
88 session->ns_data.dd_state == NDMP_DATA_STATE_HALTED)
89 return;
90
91 NDMP_LOG(LOG_DEBUG, "data.operation: %d",
92 session->ns_data.dd_operation);
93
94 if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) {
95 /*
96 * Send/discard any buffered file history data.
97 */
98 ndmpd_file_history_cleanup(session, (err == 0 ? TRUE : FALSE));
99
100 /*
101 * If mover local and successfull backup, write any
102 * remaining buffered data to tape.
103 */
104 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_LOCAL &&
105 err == 0) {
106 if (ndmpd_local_write(session, 0, 0) < 0)
107 err = EIO;
108 }
109 }
110
111 session->ns_data.dd_state = NDMP_DATA_STATE_HALTED;
112
113 switch (err) {
114 case 0:
115 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_SUCCESSFUL;
116 break;
117 case EINTR:
118 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_ABORTED;
119 break;
120 case EIO:
121 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_CONNECT_ERROR;
122 break;
123 default:
124 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_INTERNAL_ERROR;
125 }
126
127 req_v2.reason = session->ns_data.dd_halt_reason;
128 req_v2.text_reason = "";
129
130 NDMP_LOG(LOG_DEBUG, "ndmp_send_request(NDMP_NOTIFY_DATA_HALTED)");
131
132 if (ndmp_send_request_lock(session->ns_connection,
133 NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, (void *)&req_v2, 0) < 0)
134 NDMP_LOG(LOG_DEBUG, "Sending notify_data_halted request");
135
136 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
137
138 if (session->ns_mover.md_sock != session->ns_data.dd_sock) {
139 (void) close(session->ns_data.dd_sock);
140 } else {
141 NDMP_LOG(LOG_DEBUG, "Not closing as used by mover");
142 }
143
144 session->ns_data.dd_sock = -1;
145 } else {
146 ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
147 }
148 }
149
150
151 /*
152 * ndmpd_api_log_v2
153 *
154 * Sends a log request to the NDMP client.
155 *
156 * Parameters:
157 * cookie (input) - session pointer.
158 * str (input) - null terminated string
159 * format (input) - printf style format.
160 * ... (input) - format arguments.
161 *
169 {
170 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
171 ndmp_log_log_request request;
172 static char buf[1024];
173 va_list ap;
174
175 if (session == NULL)
176 return (-1);
177
178 va_start(ap, format);
179
180 /*LINTED variable format specifier */
181 (void) vsnprintf(buf, sizeof (buf), format, ap);
182 va_end(ap);
183
184 request.entry = buf;
185
186
187 if (ndmp_send_request(session->ns_connection, _NDMP_LOG_LOG,
188 NDMP_NO_ERR, (void *)&request, 0) < 0) {
189 NDMP_LOG(LOG_DEBUG, "Sending log request");
190 return (-1);
191 }
192 return (0);
193
194 }
195
196
197 /*
198 * ndmpd_api_read_v2
199 *
200 * Callback function called by the backup/recover module.
201 * Reads data from the mover.
202 * If the mover is remote, the data is read from the data connection.
203 * If the mover is local, the data is read from the tape device.
204 *
205 * Parameters:
206 * client_data (input) - session pointer.
207 * data (input) - data to be written.
208 * length (input) - data length.
209 *
258 session->ns_data.dd_read_length = length;
259
260 /*
261 * Send a notify_data_read request if the mover is remote.
262 */
263 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
264 ndmp_notify_data_read_request request;
265
266 session->ns_mover.md_discard_length =
267 session->ns_mover.md_bytes_left_to_read;
268 session->ns_mover.md_bytes_left_to_read = length;
269 session->ns_mover.md_position = offset;
270
271 request.offset = long_long_to_quad(offset);
272 request.length = long_long_to_quad(length);
273
274 if (ndmp_send_request_lock(session->ns_connection,
275 NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
276 (void *)&request, 0) < 0) {
277
278 NDMP_LOG(LOG_DEBUG,
279 "Sending notify_data_read request");
280 return (-1);
281 }
282 return (0);
283 }
284 /* Mover is local. */
285
286 err = ndmpd_mover_seek(session, offset, length);
287 if (err < 0) {
288 ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
289 return (-1);
290 }
291 if (err == 0)
292 return (0);
293
294 /*
295 * NDMP client intervention is required to perform the seek.
296 * Wait for the client to either do the seek and send a continue
297 * request or send an abort request.
298 */
322
323 if (session == NULL)
324 return (-1);
325
326 request.name = name;
327 request.ssid = 0;
328
329 switch (error) {
330 case 0:
331 request.error = NDMP_NO_ERR;
332 break;
333 case ENOENT:
334 request.error = NDMP_FILE_NOT_FOUND_ERR;
335 break;
336 default:
337 request.error = NDMP_PERMISSION_ERR;
338 }
339
340 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
341 NDMP_NO_ERR, (void *)&request, 0) < 0) {
342 NDMP_LOG(LOG_DEBUG, "Sending log file request");
343 return (-1);
344 }
345 return (0);
346 }
347
348
349 /*
350 * ndmpd_api_write_v2
351 *
352 * Callback function called by the backup/restore module.
353 * Writes data to the mover.
354 * If the mover is remote, the data is written to the data connection.
355 * If the mover is local, the data is buffered and written to the
356 * tape device after a full record has been buffered.
357 *
358 * Parameters:
359 * client_data (input) - session pointer.
360 * data (input) - data to be written.
361 * length (input) - data length.
362 *
449 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
450 ndmp_log_message_request_v3 request;
451 static char buf[1024];
452 va_list ap;
453
454 if (session == NULL)
455 return (-1);
456
457 va_start(ap, format);
458
459 /*LINTED variable format specifier */
460 (void) vsnprintf(buf, sizeof (buf), format, ap);
461 va_end(ap);
462
463 request.entry = buf;
464 request.log_type = type;
465 request.message_id = msg_id;
466
467 if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
468 NDMP_NO_ERR, (void *)&request, 0) < 0) {
469 NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
470 return (-1);
471 }
472 return (0);
473 }
474
475
476 /*
477 * ndmpd_api_write_v3
478 *
479 * Callback function called by the backup/restore module.
480 * Writes data to the mover.
481 * If the mover is remote, the data is written to the data connection.
482 * If the mover is local, the data is buffered and written to the
483 * tape device after a full record has been buffered.
484 *
485 * Parameters:
486 * client_data (input) - session pointer.
487 * data (input) - data to be written.
488 * length (input) - data length.
489 *
602 ndmp_log_file_request_v3 request;
603
604 if (session == NULL)
605 return (-1);
606
607 request.name = name;
608
609 switch (error) {
610 case 0:
611 request.error = NDMP_NO_ERR;
612 break;
613 case ENOENT:
614 request.error = NDMP_FILE_NOT_FOUND_ERR;
615 break;
616 default:
617 request.error = NDMP_PERMISSION_ERR;
618 }
619
620 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
621 NDMP_NO_ERR, (void *)&request, 0) < 0) {
622 NDMP_LOG(LOG_DEBUG, "Error sending log file request");
623 return (-1);
624 }
625
626 return (0);
627 }
628
629
630 /*
631 * ndmpd_api_seek_v3
632 *
633 * Seek to the specified position in the data stream and start a
634 * read for the specified amount of data.
635 *
636 * Parameters:
637 * cookie (input) - session pointer.
638 * offset (input) - stream position to seek to.
639 * length (input) - amount of data that will be read using ndmpd_api_read
640 *
641 * Returns:
642 * 0 - seek successful.
654 return (-1);
655
656 session->ns_data.dd_read_offset = offset;
657 session->ns_data.dd_read_length = length;
658
659 /*
660 * Send a notify_data_read request if the mover is remote.
661 */
662 if (session->ns_data.dd_data_addr.addr_type != NDMP_ADDR_LOCAL) {
663 session->ns_data.dd_discard_length =
664 session->ns_data.dd_bytes_left_to_read;
665 session->ns_data.dd_bytes_left_to_read = length;
666 session->ns_data.dd_position = offset;
667
668 request.offset = long_long_to_quad(offset);
669 request.length = long_long_to_quad(length);
670
671 if (ndmp_send_request_lock(session->ns_connection,
672 NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
673 (void *)&request, 0) < 0) {
674 NDMP_LOG(LOG_DEBUG,
675 "Sending notify_data_read request");
676 return (-1);
677 }
678
679 return (0);
680 }
681
682 /* Mover is local. */
683
684 err = ndmpd_mover_seek(session, offset, length);
685 if (err < 0) {
686 ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
687 return (-1);
688 }
689
690 if (err == 0)
691 return (0);
692
693 /*
694 * NDMP client intervention is required to perform the seek.
739 static char buf[1024];
740 va_list ap;
741
742 if (session == NULL)
743 return (-1);
744
745 va_start(ap, format);
746
747 /*LINTED variable format specifier */
748 (void) vsnprintf(buf, sizeof (buf), format, ap);
749 va_end(ap);
750
751 request.entry = buf;
752 request.log_type = type;
753 request.message_id = msg_id;
754 request.associated_message_valid = NDMP_NO_ASSOCIATED_MESSAGE;
755 request.associated_message_sequence = 0;
756
757 if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
758 NDMP_NO_ERR, (void *)&request, 0) < 0) {
759 NDMP_LOG(LOG_DEBUG, "Error sending log message request.");
760 return (-1);
761 }
762 return (0);
763 }
764
765
766 /*
767 * ndmpd_api_file_recovered_v4
768 *
769 * Notify the NDMP client that the specified file was recovered.
770 *
771 * Parameters:
772 * cookie (input) - session pointer.
773 * name (input) - name of recovered file.
774 * ssid (input) - selection set id.
775 * error (input) - 0 if file successfully recovered.
776 * otherwise, error code indicating why recovery failed.
777 *
778 * Returns:
779 * void.
801 break;
802 case ENOTDIR:
803 request.recovery_status = NDMP_RECOVERY_FAILED_NO_DIRECTORY;
804 break;
805 case ENOMEM:
806 request.recovery_status = NDMP_RECOVERY_FAILED_OUT_OF_MEMORY;
807 break;
808 case EIO:
809 request.recovery_status = NDMP_RECOVERY_FAILED_IO_ERROR;
810 break;
811 case EEXIST:
812 request.recovery_status = NDMP_RECOVERY_FAILED_FILE_PATH_EXISTS;
813 break;
814 default:
815 request.recovery_status = NDMP_RECOVERY_FAILED_UNDEFINED_ERROR;
816 break;
817 }
818
819 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
820 NDMP_NO_ERR, (void *)&request, 0) < 0) {
821 NDMP_LOG(LOG_DEBUG, "Error sending log file request");
822 return (-1);
823 }
824
825 return (0);
826 }
827
828
829 /*
830 * ************************************************************************
831 * LOCALS
832 * ************************************************************************
833 */
834
835 /*
836 * ndmpd_api_find_env
837 *
838 * Return the pointer of the environment variable from the variable
839 * array for the spcified environment variable.
840 *
841 * Parameters:
905 * val (input) - value.
906 *
907 * Returns:
908 * 0 - success.
909 * -1 - error.
910 */
911 int
912 ndmpd_api_add_env(void *cookie, char *name, char *value)
913 {
914 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
915 char *namebuf;
916 char *valbuf;
917
918 if (session == NULL)
919 return (-1);
920
921 session->ns_data.dd_env = realloc((void *)session->ns_data.dd_env,
922 sizeof (ndmp_pval) * (session->ns_data.dd_env_len + 1));
923
924 if (session->ns_data.dd_env == NULL) {
925 NDMP_LOG(LOG_ERR, "Out of memory.");
926 return (-1);
927 }
928 namebuf = strdup(name);
929 if (namebuf == NULL)
930 return (-1);
931
932 valbuf = strdup(value);
933 if (valbuf == NULL) {
934 free(namebuf);
935 return (-1);
936 }
937
938 (void) mutex_lock(&session->ns_lock);
939 session->ns_data.dd_env[session->ns_data.dd_env_len].name = namebuf;
940 session->ns_data.dd_env[session->ns_data.dd_env_len].value = valbuf;
941 session->ns_data.dd_env_len++;
942 (void) mutex_unlock(&session->ns_lock);
943
944 return (0);
945 }
|
1 /*
2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
4 */
5
6 /*
7 * BSD 3 Clause License
8 *
9 * Copyright (c) 2007, The Storage Networking Industry Association.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * - Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
22 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 * nor the names of its contributors may be used to endorse or promote
24 * products derived from this software without specific prior written
25 * permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39 /* Copyright (c) 2007, The Storage Networking Industry Association. */
40 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
41 /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
42
43 #include <sys/types.h>
44 #include <syslog.h>
45 #include <stdlib.h>
46 #include <errno.h>
47 #include <stdarg.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include "ndmpd.h"
51
52
53 /*
54 * Message Id counter. This number is increased by MOD_LOGV3 macro.
55 * MOD_LOGCONTV3 macro uses the number generated by the last MOD_LOGV3.
56 *
57 */
58 int ndmp_log_msg_id = 0;
59
60
61 /*
62 * ************************************************************************
63 * NDMP V2 CALLBACKS
64 * ************************************************************************
73 * Parameters:
74 * session (input) - session pointer.
75 * err (input) - UNIX error code.
76 *
77 * Returns:
78 * void
79 */
80 void
81 ndmpd_api_done_v2(void *cookie, int err)
82 {
83 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
84 ndmp_notify_data_halted_request req_v2;
85
86 if (session == NULL)
87 return;
88
89 if (session->ns_data.dd_state == NDMP_DATA_STATE_IDLE ||
90 session->ns_data.dd_state == NDMP_DATA_STATE_HALTED)
91 return;
92
93 syslog(LOG_DEBUG, "data.operation: %d",
94 session->ns_data.dd_operation);
95
96 if (session->ns_data.dd_operation == NDMP_DATA_OP_BACKUP) {
97 /*
98 * Send/discard any buffered file history data.
99 */
100 ndmpd_file_history_cleanup(session, (err == 0 ? TRUE : FALSE));
101
102 /*
103 * If mover local and successfull backup, write any
104 * remaining buffered data to tape.
105 */
106 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_LOCAL &&
107 err == 0) {
108 if (ndmpd_local_write(session, 0, 0) < 0)
109 err = EIO;
110 }
111 }
112
113 session->ns_data.dd_state = NDMP_DATA_STATE_HALTED;
114
115 switch (err) {
116 case 0:
117 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_SUCCESSFUL;
118 break;
119 case EINTR:
120 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_ABORTED;
121 break;
122 case EIO:
123 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_CONNECT_ERROR;
124 break;
125 default:
126 session->ns_data.dd_halt_reason = NDMP_DATA_HALT_INTERNAL_ERROR;
127 }
128
129 req_v2.reason = session->ns_data.dd_halt_reason;
130 req_v2.text_reason = "";
131
132 syslog(LOG_DEBUG, "ndmp_send_request(NDMP_NOTIFY_DATA_HALTED)");
133
134 if (ndmp_send_request_lock(session->ns_connection,
135 NDMP_NOTIFY_DATA_HALTED, NDMP_NO_ERR, (void *)&req_v2, 0) < 0)
136 syslog(LOG_DEBUG, "Sending notify_data_halted request");
137
138 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
139
140 if (session->ns_mover.md_sock != session->ns_data.dd_sock) {
141 (void) close(session->ns_data.dd_sock);
142 } else {
143 syslog(LOG_DEBUG, "Not closing as used by mover");
144 }
145
146 session->ns_data.dd_sock = -1;
147 } else {
148 ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
149 }
150 }
151
152
153 /*
154 * ndmpd_api_log_v2
155 *
156 * Sends a log request to the NDMP client.
157 *
158 * Parameters:
159 * cookie (input) - session pointer.
160 * str (input) - null terminated string
161 * format (input) - printf style format.
162 * ... (input) - format arguments.
163 *
171 {
172 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
173 ndmp_log_log_request request;
174 static char buf[1024];
175 va_list ap;
176
177 if (session == NULL)
178 return (-1);
179
180 va_start(ap, format);
181
182 /*LINTED variable format specifier */
183 (void) vsnprintf(buf, sizeof (buf), format, ap);
184 va_end(ap);
185
186 request.entry = buf;
187
188
189 if (ndmp_send_request(session->ns_connection, _NDMP_LOG_LOG,
190 NDMP_NO_ERR, (void *)&request, 0) < 0) {
191 syslog(LOG_ERR, "Sending log request");
192 return (-1);
193 }
194 return (0);
195
196 }
197
198
199 /*
200 * ndmpd_api_read_v2
201 *
202 * Callback function called by the backup/recover module.
203 * Reads data from the mover.
204 * If the mover is remote, the data is read from the data connection.
205 * If the mover is local, the data is read from the tape device.
206 *
207 * Parameters:
208 * client_data (input) - session pointer.
209 * data (input) - data to be written.
210 * length (input) - data length.
211 *
260 session->ns_data.dd_read_length = length;
261
262 /*
263 * Send a notify_data_read request if the mover is remote.
264 */
265 if (session->ns_data.dd_mover.addr_type == NDMP_ADDR_TCP) {
266 ndmp_notify_data_read_request request;
267
268 session->ns_mover.md_discard_length =
269 session->ns_mover.md_bytes_left_to_read;
270 session->ns_mover.md_bytes_left_to_read = length;
271 session->ns_mover.md_position = offset;
272
273 request.offset = long_long_to_quad(offset);
274 request.length = long_long_to_quad(length);
275
276 if (ndmp_send_request_lock(session->ns_connection,
277 NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
278 (void *)&request, 0) < 0) {
279
280 syslog(LOG_ERR,
281 "Sending notify_data_read request");
282 return (-1);
283 }
284 return (0);
285 }
286 /* Mover is local. */
287
288 err = ndmpd_mover_seek(session, offset, length);
289 if (err < 0) {
290 ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
291 return (-1);
292 }
293 if (err == 0)
294 return (0);
295
296 /*
297 * NDMP client intervention is required to perform the seek.
298 * Wait for the client to either do the seek and send a continue
299 * request or send an abort request.
300 */
324
325 if (session == NULL)
326 return (-1);
327
328 request.name = name;
329 request.ssid = 0;
330
331 switch (error) {
332 case 0:
333 request.error = NDMP_NO_ERR;
334 break;
335 case ENOENT:
336 request.error = NDMP_FILE_NOT_FOUND_ERR;
337 break;
338 default:
339 request.error = NDMP_PERMISSION_ERR;
340 }
341
342 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
343 NDMP_NO_ERR, (void *)&request, 0) < 0) {
344 syslog(LOG_ERR, "Sending log file request");
345 return (-1);
346 }
347 return (0);
348 }
349
350
351 /*
352 * ndmpd_api_write_v2
353 *
354 * Callback function called by the backup/restore module.
355 * Writes data to the mover.
356 * If the mover is remote, the data is written to the data connection.
357 * If the mover is local, the data is buffered and written to the
358 * tape device after a full record has been buffered.
359 *
360 * Parameters:
361 * client_data (input) - session pointer.
362 * data (input) - data to be written.
363 * length (input) - data length.
364 *
451 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
452 ndmp_log_message_request_v3 request;
453 static char buf[1024];
454 va_list ap;
455
456 if (session == NULL)
457 return (-1);
458
459 va_start(ap, format);
460
461 /*LINTED variable format specifier */
462 (void) vsnprintf(buf, sizeof (buf), format, ap);
463 va_end(ap);
464
465 request.entry = buf;
466 request.log_type = type;
467 request.message_id = msg_id;
468
469 if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
470 NDMP_NO_ERR, (void *)&request, 0) < 0) {
471 syslog(LOG_ERR, "Error sending log message request.");
472 return (-1);
473 }
474 return (0);
475 }
476
477
478 /*
479 * ndmpd_api_write_v3
480 *
481 * Callback function called by the backup/restore module.
482 * Writes data to the mover.
483 * If the mover is remote, the data is written to the data connection.
484 * If the mover is local, the data is buffered and written to the
485 * tape device after a full record has been buffered.
486 *
487 * Parameters:
488 * client_data (input) - session pointer.
489 * data (input) - data to be written.
490 * length (input) - data length.
491 *
604 ndmp_log_file_request_v3 request;
605
606 if (session == NULL)
607 return (-1);
608
609 request.name = name;
610
611 switch (error) {
612 case 0:
613 request.error = NDMP_NO_ERR;
614 break;
615 case ENOENT:
616 request.error = NDMP_FILE_NOT_FOUND_ERR;
617 break;
618 default:
619 request.error = NDMP_PERMISSION_ERR;
620 }
621
622 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
623 NDMP_NO_ERR, (void *)&request, 0) < 0) {
624 syslog(LOG_ERR, "Error sending log file request");
625 return (-1);
626 }
627
628 return (0);
629 }
630
631
632 /*
633 * ndmpd_api_seek_v3
634 *
635 * Seek to the specified position in the data stream and start a
636 * read for the specified amount of data.
637 *
638 * Parameters:
639 * cookie (input) - session pointer.
640 * offset (input) - stream position to seek to.
641 * length (input) - amount of data that will be read using ndmpd_api_read
642 *
643 * Returns:
644 * 0 - seek successful.
656 return (-1);
657
658 session->ns_data.dd_read_offset = offset;
659 session->ns_data.dd_read_length = length;
660
661 /*
662 * Send a notify_data_read request if the mover is remote.
663 */
664 if (session->ns_data.dd_data_addr.addr_type != NDMP_ADDR_LOCAL) {
665 session->ns_data.dd_discard_length =
666 session->ns_data.dd_bytes_left_to_read;
667 session->ns_data.dd_bytes_left_to_read = length;
668 session->ns_data.dd_position = offset;
669
670 request.offset = long_long_to_quad(offset);
671 request.length = long_long_to_quad(length);
672
673 if (ndmp_send_request_lock(session->ns_connection,
674 NDMP_NOTIFY_DATA_READ, NDMP_NO_ERR,
675 (void *)&request, 0) < 0) {
676 syslog(LOG_ERR,
677 "Sending notify_data_read request");
678 return (-1);
679 }
680
681 return (0);
682 }
683
684 /* Mover is local. */
685
686 err = ndmpd_mover_seek(session, offset, length);
687 if (err < 0) {
688 ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
689 return (-1);
690 }
691
692 if (err == 0)
693 return (0);
694
695 /*
696 * NDMP client intervention is required to perform the seek.
741 static char buf[1024];
742 va_list ap;
743
744 if (session == NULL)
745 return (-1);
746
747 va_start(ap, format);
748
749 /*LINTED variable format specifier */
750 (void) vsnprintf(buf, sizeof (buf), format, ap);
751 va_end(ap);
752
753 request.entry = buf;
754 request.log_type = type;
755 request.message_id = msg_id;
756 request.associated_message_valid = NDMP_NO_ASSOCIATED_MESSAGE;
757 request.associated_message_sequence = 0;
758
759 if (ndmp_send_request(session->ns_connection, NDMP_LOG_MESSAGE,
760 NDMP_NO_ERR, (void *)&request, 0) < 0) {
761 syslog(LOG_ERR, "Error sending log message request.");
762 return (-1);
763 }
764 return (0);
765 }
766
767
768 /*
769 * ndmpd_api_file_recovered_v4
770 *
771 * Notify the NDMP client that the specified file was recovered.
772 *
773 * Parameters:
774 * cookie (input) - session pointer.
775 * name (input) - name of recovered file.
776 * ssid (input) - selection set id.
777 * error (input) - 0 if file successfully recovered.
778 * otherwise, error code indicating why recovery failed.
779 *
780 * Returns:
781 * void.
803 break;
804 case ENOTDIR:
805 request.recovery_status = NDMP_RECOVERY_FAILED_NO_DIRECTORY;
806 break;
807 case ENOMEM:
808 request.recovery_status = NDMP_RECOVERY_FAILED_OUT_OF_MEMORY;
809 break;
810 case EIO:
811 request.recovery_status = NDMP_RECOVERY_FAILED_IO_ERROR;
812 break;
813 case EEXIST:
814 request.recovery_status = NDMP_RECOVERY_FAILED_FILE_PATH_EXISTS;
815 break;
816 default:
817 request.recovery_status = NDMP_RECOVERY_FAILED_UNDEFINED_ERROR;
818 break;
819 }
820
821 if (ndmp_send_request_lock(session->ns_connection, NDMP_LOG_FILE,
822 NDMP_NO_ERR, (void *)&request, 0) < 0) {
823 syslog(LOG_ERR, "Error sending log file request");
824 return (-1);
825 }
826
827 return (0);
828 }
829
830
831 /*
832 * ************************************************************************
833 * LOCALS
834 * ************************************************************************
835 */
836
837 /*
838 * ndmpd_api_find_env
839 *
840 * Return the pointer of the environment variable from the variable
841 * array for the spcified environment variable.
842 *
843 * Parameters:
907 * val (input) - value.
908 *
909 * Returns:
910 * 0 - success.
911 * -1 - error.
912 */
913 int
914 ndmpd_api_add_env(void *cookie, char *name, char *value)
915 {
916 ndmpd_session_t *session = (ndmpd_session_t *)cookie;
917 char *namebuf;
918 char *valbuf;
919
920 if (session == NULL)
921 return (-1);
922
923 session->ns_data.dd_env = realloc((void *)session->ns_data.dd_env,
924 sizeof (ndmp_pval) * (session->ns_data.dd_env_len + 1));
925
926 if (session->ns_data.dd_env == NULL) {
927 syslog(LOG_ERR, "Out of memory.");
928 return (-1);
929 }
930 namebuf = strdup(name);
931 if (namebuf == NULL)
932 return (-1);
933
934 valbuf = strdup(value);
935 if (valbuf == NULL) {
936 free(namebuf);
937 return (-1);
938 }
939
940 (void) mutex_lock(&session->ns_lock);
941 session->ns_data.dd_env[session->ns_data.dd_env_len].name = namebuf;
942 session->ns_data.dd_env[session->ns_data.dd_env_len].value = valbuf;
943 session->ns_data.dd_env_len++;
944 (void) mutex_unlock(&session->ns_lock);
945
946 return (0);
947 }
|