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