Print this page
NEX-9532 NDMP: readdir errors when file/directory has special characters
Reviewed by: Peer Dampmann <peer.dampmann@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@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-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-355 NDMP backup, EOF position remains on BOT side of filemark
NEX-249 NS ndmp can't write to a brand new tape with IO error (fix cstyle)
SUP-484 NDMP backup jobs error out when reaching the end of media (EOM)
NEX-249 NS ndmp can't write to a brand new tape with IO error
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/ndmpd/ndmp/ndmpd_tape.c
+++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_tape.c
1 1 /*
2 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 3 * Use is subject to license terms.
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/param.h>
43 +#include <syslog.h>
43 44 #include <fcntl.h>
44 45 #include <sys/mtio.h>
45 46 #include <errno.h>
46 47 #include <stdio.h>
47 48 #include <string.h>
48 49 #include <unistd.h>
49 50 #include "ndmpd_common.h"
50 51 #include "ndmpd.h"
51 52
52 53 static void tape_open_send_reply(ndmp_connection_t *connection, int err);
53 54 static void unbuffered_read(ndmpd_session_t *session, char *buf, long wanted,
54 55 ndmp_tape_read_reply *reply);
55 56 static boolean_t validmode(int mode);
56 57 static void common_tape_open(ndmp_connection_t *connection, char *devname,
57 58 int ndmpmode);
58 59 static void common_tape_close(ndmp_connection_t *connection);
59 60
60 61 /*
61 62 * Configurable delay & time when the tape is
62 63 * busy during opening the tape.
63 64 */
64 65 int ndmp_tape_open_retries = 5;
65 66 int ndmp_tape_open_delay = 1000;
66 67
67 68 /*
68 69 * A few words about EOT (end-of-tape) and EOM handling on tapes with SVR4
69 70 * semantic:
70 71 *
71 72 * We adhere to terminology as used in st driver. EOT means end of recorded
72 73 * data on a tape. This is different from EOM (somewhere referred to as LEOT)
73 74 * which is the end of tape medium. EOT is meaningful only for reads while EOM
74 75 * is meaningful only for writes. It's not possible to read after EOT (fails
75 76 * with EIO), but it's possible to write data after EOM. EOM returned by st
76 77 * driver on modern tape drives is just indication that the physical end of
77 78 * tape medium is nearing and that writer should write just the necessary
78 79 * minimum and stop writing. When physical end of tape is reached all writes
79 80 * return EIO. If EOM is crossed during read operation then st driver doesn't
80 81 * bother to report it to client and that's alright because reads don't care
81 82 * where medium physically ends but they care about meaningful data recorded on
82 83 * the tape and as long as there are such data reads should continue to work.
83 84 *
84 85 * When reading EOT is signalled by st driver by two empty consecutive reads
85 86 * (with FSF done between them). When writing EOM is signalled by empty write
86 87 * (a write which writes zero bytes). Following writes succeed until physical
87 88 * end of tape is reached in which case EIO is returned.
88 89 */
89 90
90 91 /*
91 92 * ************************************************************************
92 93 * NDMP V2 HANDLERS
93 94 * ************************************************************************
94 95 */
95 96
96 97 /*
97 98 * ndmpd_tape_open_v2
98 99 *
99 100 * This handler opens the specified tape device.
100 101 *
101 102 * Parameters:
102 103 * connection (input) - connection handle.
103 104 * body (input) - request message body.
104 105 *
105 106 * Returns:
106 107 * void
107 108 */
|
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
108 109 void
109 110 ndmpd_tape_open_v2(ndmp_connection_t *connection, void *body)
110 111 {
111 112 ndmp_tape_open_request_v2 *request = (ndmp_tape_open_request_v2 *) body;
112 113 ndmpd_session_t *session = ndmp_get_client_data(connection);
113 114 char adptnm[SCSI_MAX_NAME];
114 115 int mode;
115 116 int sid, lun;
116 117 int err;
117 118 scsi_adapter_t *sa;
118 - int devid;
119 + int devid = -1;
119 120
120 121 err = NDMP_NO_ERR;
121 122
122 123 if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
123 - NDMP_LOG(LOG_INFO,
124 + syslog(LOG_INFO,
124 125 "Connection already has a tape or scsi device open");
125 126 err = NDMP_DEVICE_OPENED_ERR;
126 127 } else if (request->mode != NDMP_TAPE_READ_MODE &&
127 128 request->mode != NDMP_TAPE_WRITE_MODE &&
128 129 request->mode != NDMP_TAPE_RAW1_MODE) {
129 130 err = NDMP_ILLEGAL_ARGS_ERR;
130 131 }
131 132
132 133 if ((sa = scsi_get_adapter(0)) != NULL) {
133 - NDMP_LOG(LOG_DEBUG,
134 - "Adapter device opened: %s", request->device.name);
135 134 (void) strlcpy(adptnm, request->device.name, SCSI_MAX_NAME-2);
136 135 adptnm[SCSI_MAX_NAME-1] = '\0';
137 136 sid = lun = -1;
138 137 }
139 138 /* try to get the scsi id etc.... */
140 139 if (sa) {
141 140 scsi_find_sid_lun(sa, request->device.name, &sid, &lun);
142 141 if (ndmp_open_list_find(request->device.name, sid, lun) == 0 &&
143 142 (devid = tape_open(request->device.name,
144 143 O_RDWR | O_NDELAY)) < 0) {
145 - NDMP_LOG(LOG_ERR, "Failed to open device %s: %m.",
144 + syslog(LOG_ERR, "Failed to open device %s: %m.",
146 145 request->device.name);
147 146 err = NDMP_NO_DEVICE_ERR;
148 147 }
149 148 else
150 149 (void) close(devid);
151 150 } else {
152 - NDMP_LOG(LOG_ERR, "%s: No such tape device.",
151 + syslog(LOG_ERR, "%s: No such tape device.",
153 152 request->device.name);
154 153 err = NDMP_NO_DEVICE_ERR;
155 154 }
156 155 if (err != NDMP_NO_ERR) {
157 156 tape_open_send_reply(connection, err);
158 157 return;
159 158 }
160 159
161 160 switch (ndmp_open_list_add(connection, adptnm, sid, lun, devid)) {
162 161 case 0:
163 162 err = NDMP_NO_ERR;
164 163 break;
165 164 case EBUSY:
166 165 err = NDMP_DEVICE_BUSY_ERR;
167 166 break;
168 167 case ENOMEM:
169 168 err = NDMP_NO_MEM_ERR;
170 169 break;
171 170 default:
172 171 err = NDMP_IO_ERR;
173 172 }
174 173 if (err != NDMP_NO_ERR) {
175 174 tape_open_send_reply(connection, err);
176 175 return;
177 176 }
178 177
179 178 /*
180 179 * According to Connectathon 2001, the 0x7fffffff is a secret
181 180 * code between "Workstartion Solutions" and * net_app.
182 181 * If mode is set to this value, tape_open() won't fail if
183 182 * the tape device is not ready.
184 183 */
|
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
185 184 if (request->mode != NDMP_TAPE_RAW1_MODE &&
186 185 !is_tape_unit_ready(adptnm, 0)) {
187 186 (void) ndmp_open_list_del(adptnm, sid, lun);
188 187 tape_open_send_reply(connection, NDMP_NO_TAPE_LOADED_ERR);
189 188 return;
190 189 }
191 190
192 191 mode = (request->mode == NDMP_TAPE_READ_MODE) ? O_RDONLY : O_RDWR;
193 192 mode |= O_NDELAY;
194 193 if ((session->ns_tape.td_fd = open(request->device.name, mode)) < 0) {
195 - NDMP_LOG(LOG_ERR, "Failed to open tape device %s: %m.",
194 + syslog(LOG_ERR, "Failed to open tape device %s: %m.",
196 195 request->device.name);
197 196 switch (errno) {
198 197 case EACCES:
199 198 err = NDMP_WRITE_PROTECT_ERR;
200 199 break;
201 200 case ENXIO:
202 201 case ENOENT:
203 202 err = NDMP_NO_DEVICE_ERR;
204 203 break;
205 204 case EBUSY:
206 205 err = NDMP_DEVICE_BUSY_ERR;
207 206 break;
208 207 default:
209 208 err = NDMP_IO_ERR;
210 209 }
211 210
212 211 (void) ndmp_open_list_del(adptnm, sid, lun);
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
213 212 tape_open_send_reply(connection, err);
214 213 return;
215 214 }
216 215
217 216 session->ns_tape.td_mode = request->mode;
218 217 session->ns_tape.td_sid = sid;
219 218 session->ns_tape.td_lun = lun;
220 219 (void) strlcpy(session->ns_tape.td_adapter_name, adptnm, SCSI_MAX_NAME);
221 220 session->ns_tape.td_record_count = 0;
222 221
223 - NDMP_LOG(LOG_DEBUG, "Tape is opened fd: %d", session->ns_tape.td_fd);
224 -
225 222 tape_open_send_reply(connection, NDMP_NO_ERR);
226 223 }
227 224
228 225
229 226 /*
230 227 * ndmpd_tape_close_v2
231 228 *
232 229 * This handler closes the currently open tape device.
233 230 *
234 231 * Parameters:
235 232 * connection (input) - connection handle.
236 233 * body (input) - request message body.
237 234 *
238 235 * Returns:
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
239 236 * void
240 237 */
241 238 /*ARGSUSED*/
242 239 void
243 240 ndmpd_tape_close_v2(ndmp_connection_t *connection, void *body)
244 241 {
245 242 ndmp_tape_close_reply reply;
246 243 ndmpd_session_t *session = ndmp_get_client_data(connection);
247 244
248 245 if (session->ns_tape.td_fd == -1) {
249 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
246 + syslog(LOG_ERR, "Tape device is not open.");
250 247 reply.error = NDMP_DEV_NOT_OPEN_ERR;
251 248 ndmp_send_reply(connection, (void *) &reply,
252 249 "sending tape_close reply");
253 250 return;
254 251 }
255 252 common_tape_close(connection);
256 253
257 254 }
258 255
259 256 /*
260 257 * ndmpd_tape_get_state_v2
261 258 *
262 259 * This handler handles the tape_get_state request.
263 260 * Status information for the currently open tape device is returned.
264 261 *
265 262 * Parameters:
266 263 * connection (input) - connection handle.
267 264 * body (input) - request message body.
268 265 *
269 266 * Returns:
270 267 * void
271 268 */
272 269 /*ARGSUSED*/
273 270 void
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
274 271 ndmpd_tape_get_state_v2(ndmp_connection_t *connection, void *body)
275 272
276 273 {
277 274 ndmp_tape_get_state_reply_v2 reply;
278 275 ndmpd_session_t *session = ndmp_get_client_data(connection);
279 276 struct mtget mtstatus;
280 277 struct mtdrivetype_request dtpr;
281 278 struct mtdrivetype dtp;
282 279
283 280 if (session->ns_tape.td_fd == -1) {
284 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
281 + syslog(LOG_ERR, "Tape device is not open.");
285 282 reply.error = NDMP_DEV_NOT_OPEN_ERR;
286 283 ndmp_send_reply(connection, (void *) &reply,
287 284 "sending tape_get_state reply");
288 285 return;
289 286 }
290 287
291 288 if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) < 0) {
292 - NDMP_LOG(LOG_ERR, "Failed to get status from tape: %m.");
293 - NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGET) error: %m.");
289 + syslog(LOG_ERR, "Failed to get status from tape: %m.");
294 290 reply.error = NDMP_IO_ERR;
295 291 ndmp_send_reply(connection, (void *)&reply,
296 292 "sending tape_get_state reply");
297 293 return;
298 294 }
299 295
300 296 dtpr.size = sizeof (struct mtdrivetype);
301 297 dtpr.mtdtp = &dtp;
302 298 if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
303 - NDMP_LOG(LOG_ERR,
299 + syslog(LOG_ERR,
304 300 "Failed to get drive type information from tape: %m.");
305 - NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
306 301 reply.error = NDMP_IO_ERR;
307 302 ndmp_send_reply(connection, (void *)&reply,
308 303 "sending tape_get_state reply");
309 304 return;
310 305 }
311 306
312 307 reply.flags = 0;
313 308
314 309 reply.file_num = mtstatus.mt_fileno;
315 310 reply.soft_errors = 0;
316 311 reply.block_size = dtp.bsize;
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
317 312 if (dtp.bsize == 0)
318 313 reply.blockno = mtstatus.mt_blkno;
319 314 else
320 315 reply.blockno = mtstatus.mt_blkno *
321 316 (session->ns_mover.md_record_size / dtp.bsize);
322 317
323 318 reply.soft_errors = 0;
324 319 reply.total_space = long_long_to_quad(0); /* not supported */
325 320 reply.space_remain = long_long_to_quad(0); /* not supported */
326 321
327 - NDMP_LOG(LOG_DEBUG,
328 - "flags: 0x%x, file_num: %d, block_size: %d, blockno: %d",
329 - reply.flags, reply.file_num, reply.block_size, reply.blockno);
330 -
331 322 reply.error = NDMP_NO_ERR;
332 323 ndmp_send_reply(connection, (void *) &reply,
333 324 "sending tape_get_state reply");
334 325 }
335 326
336 327
337 328 /*
338 329 * ndmpd_tape_mtio_v2
339 330 *
340 331 * This handler handles tape_mtio requests.
341 332 *
342 333 * Parameters:
343 334 * connection (input) - connection handle.
344 335 * body (input) - request message body.
345 336 *
346 337 * Returns:
347 338 * void
348 339 */
349 340 void
350 341 ndmpd_tape_mtio_v2(ndmp_connection_t *connection, void *body)
351 342 {
352 343 ndmp_tape_mtio_request *request = (ndmp_tape_mtio_request *) body;
353 344 ndmp_tape_mtio_reply reply;
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
354 345 ndmpd_session_t *session = ndmp_get_client_data(connection);
355 346
356 347 struct mtop tapeop;
357 348 struct mtget mtstatus;
358 349 int retry = 0;
359 350 int rc;
360 351
361 352 reply.resid_count = 0;
362 353
363 354 if (session->ns_tape.td_fd == -1) {
364 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
355 + syslog(LOG_ERR, "Tape device is not open.");
365 356 reply.error = NDMP_DEV_NOT_OPEN_ERR;
366 357 ndmp_send_reply(connection, (void *) &reply,
367 358 "sending tape_mtio reply");
368 359 return;
369 360 }
370 361
371 362 reply.error = NDMP_NO_ERR;
372 363 switch (request->tape_op) {
373 364 case NDMP_MTIO_FSF:
374 365 tapeop.mt_op = MTFSF;
375 366 break;
376 367 case NDMP_MTIO_BSF:
377 368 tapeop.mt_op = MTBSF;
378 369 break;
379 370 case NDMP_MTIO_FSR:
380 371 tapeop.mt_op = MTFSR;
381 372 break;
382 373 case NDMP_MTIO_BSR:
383 374 tapeop.mt_op = MTBSR;
384 375 break;
385 376 case NDMP_MTIO_REW:
386 377 tapeop.mt_op = MTREW;
387 378 break;
388 379 case NDMP_MTIO_EOF:
389 380 if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE)
390 381 reply.error = NDMP_PERMISSION_ERR;
391 382 tapeop.mt_op = MTWEOF;
392 383 break;
393 384 case NDMP_MTIO_OFF:
394 385 tapeop.mt_op = MTOFFL;
395 386 break;
396 387
397 388 case NDMP_MTIO_TUR: /* test unit ready */
398 389
399 390 if (is_tape_unit_ready(session->ns_tape.td_adapter_name,
400 391 session->ns_tape.td_fd) == 0)
401 392 /* tape not ready ? */
402 393 reply.error = NDMP_NO_TAPE_LOADED_ERR;
403 394 break;
404 395
405 396 default:
406 397 reply.error = NDMP_ILLEGAL_ARGS_ERR;
|
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
407 398 }
408 399
409 400 if (reply.error == NDMP_NO_ERR && request->tape_op != NDMP_MTIO_TUR) {
410 401 tapeop.mt_count = request->count;
411 402
412 403 do {
413 404 NS_UPD(twait, trun);
414 405 errno = 0;
415 406 rc = ioctl(session->ns_tape.td_fd, MTIOCTOP, &tapeop);
416 407 NS_UPD(trun, twait);
417 - NDMP_LOG(LOG_DEBUG,
418 - "ioctl MTIO rc:%d, cmd:%d, retry:%d, error: %d",
419 - rc, tapeop.mt_op, retry, errno);
420 408 } while (rc < 0 && errno == EIO &&
421 409 retry++ < 5);
422 410
423 411 /*
424 412 * Ignore I/O errors since these usually are the result of
425 413 * attempting to position past the beginning or end of the tape.
426 414 * The residual count will be returned and can be used to
427 415 * determine that the call was not completely successful.
428 416 */
429 417 if (rc < 0) {
430 - NDMP_LOG(LOG_ERR,
418 + syslog(LOG_ERR,
431 419 "Failed to send command to tape: %m.");
432 - NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCTOP) error: %m.");
433 420
434 421 /* MTWEOF doesnt have residual count */
435 422 if (tapeop.mt_op == MTWEOF)
436 423 reply.error = NDMP_IO_ERR;
437 424 else
438 425 reply.error = NDMP_NO_ERR;
439 426 reply.resid_count = tapeop.mt_count;
440 427 ndmp_send_reply(connection, (void *)&reply,
441 428 "sending tape_mtio reply");
442 429 return;
443 430 }
444 431
445 432 if (request->tape_op != NDMP_MTIO_REW &&
446 433 request->tape_op != NDMP_MTIO_OFF) {
447 434 if (ioctl(session->ns_tape.td_fd, MTIOCGET,
448 435 &mtstatus) < 0) {
449 - NDMP_LOG(LOG_ERR,
436 + syslog(LOG_ERR,
450 437 "Failed to send command to tape: %m.");
451 - NDMP_LOG(LOG_DEBUG,
452 - "ioctl(MTIOCGET) error: %m.");
453 438 reply.error = NDMP_IO_ERR;
454 439 ndmp_send_reply(connection, (void *)&reply,
455 440 "sending tape_mtio reply");
456 441
457 442 return;
458 443 }
459 444
460 445 reply.resid_count = labs(mtstatus.mt_resid);
461 446 }
462 447 }
463 448
464 - NDMP_LOG(LOG_DEBUG, "resid_count: %d",
465 - reply.resid_count);
466 449 ndmp_send_reply(connection, (void *) &reply, "sending tape_mtio reply");
467 450 }
468 451
469 452
470 453 /*
471 454 * ndmpd_tape_read_v2
472 455 *
473 456 * This handler handles tape_read requests.
474 457 * This interface is a non-buffered interface. Each read request
475 458 * maps directly to a read to the tape device. It is the responsibility
476 459 * of the NDMP client to issue read requests with a length that is at
477 460 * least as large as the record size used write the tape. The tape driver
478 461 * always reads a full record. Data is discarded if the read request is
479 462 * smaller than the record size.
480 463 * It is the responsibility of the NDMP client to ensure that the
481 464 * length is a multiple of the tape block size if the tape device
482 465 * is in fixed block mode.
483 466 *
484 467 * Parameters:
485 468 * connection (input) - connection handle.
486 469 * body (input) - request message body.
487 470 *
488 471 * Returns:
489 472 * void
490 473 */
491 474 void
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
492 475 ndmpd_tape_read_v2(ndmp_connection_t *connection, void *body)
493 476 {
494 477 ndmp_tape_read_request *request = (ndmp_tape_read_request *) body;
495 478 ndmp_tape_read_reply reply;
496 479 ndmpd_session_t *session = ndmp_get_client_data(connection);
497 480 char *buf;
498 481
499 482 reply.data_in.data_in_len = 0;
500 483
501 484 if (session->ns_tape.td_fd == -1) {
502 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
485 + syslog(LOG_ERR, "Tape device is not open.");
503 486 reply.error = NDMP_DEV_NOT_OPEN_ERR;
504 487 ndmp_send_reply(connection, (void *)&reply,
505 488 "sending tape_read reply");
506 489 return;
507 490 }
508 491 if (request->count == 0) {
509 492 reply.error = NDMP_NO_ERR;
510 493 ndmp_send_reply(connection, (void *)&reply,
511 494 "sending tape_read reply");
512 495 return;
513 496 }
514 497 if ((buf = ndmp_malloc(request->count)) == 0) {
515 498 reply.error = NDMP_NO_MEM_ERR;
516 499 ndmp_send_reply(connection, (void *)&reply,
517 500 "sending tape_read reply");
518 501 return;
519 502 }
520 503
521 504 unbuffered_read(session, buf, request->count, &reply);
522 505
523 506 ndmp_send_reply(connection, (void *) &reply, "sending tape_read reply");
524 507 (void) free(buf);
525 508 }
526 509
527 510
528 511 /*
529 512 * ndmpd_tape_execute_cdb_v2
530 513 *
531 514 * This handler handles tape_execute_cdb requests.
532 515 *
533 516 * Parameters:
534 517 * connection (input) - connection handle.
535 518 * body (input) - request message body.
536 519 *
537 520 * Returns:
538 521 * void
539 522 */
540 523 void
541 524 ndmpd_tape_execute_cdb_v2(ndmp_connection_t *connection, void *body)
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
542 525 {
543 526 ndmp_tape_execute_cdb_request *request;
544 527 ndmp_tape_execute_cdb_reply reply;
545 528 ndmpd_session_t *session = ndmp_get_client_data(connection);
546 529
547 530 request = (ndmp_tape_execute_cdb_request *) body;
548 531
549 532 if (session->ns_tape.td_fd == -1) {
550 533 (void) memset((void *) &reply, 0, sizeof (reply));
551 534
552 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
535 + syslog(LOG_ERR, "Tape device is not open.");
553 536 reply.error = NDMP_DEV_NOT_OPEN_ERR;
554 537 ndmp_send_reply(connection, (void *) &reply,
555 538 "sending tape_execute_cdb reply");
556 539 } else {
557 540 ndmp_execute_cdb(session, session->ns_tape.td_adapter_name,
558 541 session->ns_tape.td_sid, session->ns_tape.td_lun,
559 542 (ndmp_execute_cdb_request *)request);
560 543 }
561 544 }
562 545
563 546
564 547 /*
565 548 * ************************************************************************
566 549 * NDMP V3 HANDLERS
567 550 * ************************************************************************
568 551 */
569 552
570 553 /*
571 554 * ndmpd_tape_open_v3
572 555 *
573 556 * This handler opens the specified tape device.
574 557 *
575 558 * Parameters:
576 559 * connection (input) - connection handle.
577 560 * body (input) - request message body.
578 561 *
579 562 * Returns:
580 563 * void
581 564 */
582 565 void
583 566 ndmpd_tape_open_v3(ndmp_connection_t *connection, void *body)
584 567 {
585 568 ndmp_tape_open_request_v3 *request = (ndmp_tape_open_request_v3 *)body;
586 569
587 570 common_tape_open(connection, request->device, request->mode);
588 571 }
589 572
590 573
591 574 /*
592 575 * ndmpd_tape_get_state_v3
593 576 *
594 577 * This handler handles the ndmp_tape_get_state_request.
595 578 * Status information for the currently open tape device is returned.
596 579 *
597 580 * Parameters:
598 581 * connection (input) - connection handle.
599 582 * body (input) - request message body.
600 583 *
601 584 * Returns:
602 585 * void
603 586 */
604 587 /*ARGSUSED*/
|
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
605 588 void
606 589 ndmpd_tape_get_state_v3(ndmp_connection_t *connection, void *body)
607 590 {
608 591 ndmp_tape_get_state_reply_v3 reply;
609 592 ndmpd_session_t *session = ndmp_get_client_data(connection);
610 593 struct mtdrivetype_request dtpr;
611 594 struct mtdrivetype dtp;
612 595 struct mtget mtstatus;
613 596
614 597 if (session->ns_tape.td_fd == -1) {
615 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
598 + syslog(LOG_ERR, "Tape device is not open.");
616 599 reply.error = NDMP_DEV_NOT_OPEN_ERR;
617 600 ndmp_send_reply(connection, (void *) &reply,
618 601 "sending tape_get_state reply");
619 602 return;
620 603 }
621 604
622 605 if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == -1) {
623 - NDMP_LOG(LOG_ERR, "Failed to get status from tape: %m.");
624 - NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGET) error: %m.");
606 + syslog(LOG_ERR, "Failed to get status from tape: %m.");
625 607
626 608 reply.error = NDMP_IO_ERR;
627 609 ndmp_send_reply(connection, (void *)&reply,
628 610 "sending tape_get_state reply");
629 611 return;
630 612 }
631 613
632 614 dtpr.size = sizeof (struct mtdrivetype);
633 615 dtpr.mtdtp = &dtp;
634 616 if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
635 - NDMP_LOG(LOG_ERR,
617 + syslog(LOG_ERR,
636 618 "Failed to get drive type information from tape: %m.");
637 - NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
638 619
639 620 reply.error = NDMP_IO_ERR;
640 621 ndmp_send_reply(connection, (void *)&reply,
641 622 "sending tape_get_state reply");
642 623 return;
643 624 }
644 625
645 626 reply.flags = 0;
646 627
647 628 reply.file_num = mtstatus.mt_fileno;
648 629 reply.soft_errors = 0;
649 630 reply.block_size = dtp.bsize;
650 631 if (dtp.bsize == 0)
651 632 reply.blockno = mtstatus.mt_blkno;
652 633 else
653 634 reply.blockno = mtstatus.mt_blkno *
654 635 (session->ns_mover.md_record_size / dtp.bsize);
655 636 reply.total_space = long_long_to_quad(0); /* not supported */
656 637 reply.space_remain = long_long_to_quad(0); /* not supported */
657 638 reply.partition = 0; /* not supported */
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
658 639
659 640 reply.soft_errors = 0;
660 641 reply.total_space = long_long_to_quad(0LL);
661 642 reply.space_remain = long_long_to_quad(0LL);
662 643
663 644 reply.invalid = NDMP_TAPE_STATE_SOFT_ERRORS_INVALID |
664 645 NDMP_TAPE_STATE_TOTAL_SPACE_INVALID |
665 646 NDMP_TAPE_STATE_SPACE_REMAIN_INVALID |
666 647 NDMP_TAPE_STATE_PARTITION_INVALID;
667 648
668 -
669 - NDMP_LOG(LOG_DEBUG, "f 0x%x, fnum %d, bsize %d, bno: %d",
670 - reply.flags, reply.file_num, reply.block_size, reply.blockno);
671 -
672 649 reply.error = NDMP_NO_ERR;
673 650 ndmp_send_reply(connection, (void *) &reply,
674 651 "sending tape_get_state reply");
675 652 }
676 653
677 654 /*
678 655 * tape_is_at_bot
679 656 *
680 657 * Returns 1 if tape is at BOT, 0 on error or not at BOT.
681 658 *
682 659 */
683 660 int
684 661 tape_is_at_bot(ndmpd_session_t *session)
685 662 {
686 663 struct mtget mtstatus;
687 664
688 665 if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == 0 &&
689 666 mtstatus.mt_fileno == 0 && mtstatus.mt_blkno == 0)
690 667 return (1);
691 668
692 669 return (0);
693 670 }
694 671
695 672 /*
696 673 * If we are at the beginning of a file (block # is zero) and read returns
697 674 * zero bytes then this has to be end of recorded data on the tape. Repeated
698 675 * reads at EOT return EIO. In both cases (zero read and EIO read) this
699 676 * function should be used to test if we are at EOT.
700 677 *
701 678 * Returns 1 if tape is at BOF, 0 on error or not at BOF.
702 679 */
703 680 int
704 681 tape_is_at_bof(ndmpd_session_t *session)
705 682 {
706 683 struct mtget mtstatus;
707 684
708 685 if ((ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == 0) &&
709 686 (mtstatus.mt_fileno > 0) && (mtstatus.mt_blkno == 0))
710 687 return (1);
711 688
712 689 return (0);
713 690 }
714 691
715 692 /*
716 693 * Skips forward over a file mark and then back before the file mark. Why is
717 694 * this needed? There are two reasons for it:
718 695 *
719 696 * 1) Because NDMPv4 spec requires that when EOF is encountered, the tape
720 697 * position should remain on BOT side of the file mark. When st driver reaches
721 698 * end of file get-position mtioctl reports position before file mark, however
722 699 * the file mark has already been read and the real position is thus after the
723 700 * file mark (real position as reported for example by uscsi commands). Thus we
724 701 * need to do FSF, which does nothing but only updates file & block counter in
725 702 * st driver and then BSF, which sets the position before the file mark. Thus
726 703 * current position as reported by scsi and mtioctl will be in sync.
727 704 *
728 705 * 2) st driver returns EIO for repeated reads at EOF while according to NDMP
729 706 * spec we should continue to return zero bytes until FSF is done. By skipping
730 707 * forward and backward, st driver will return zero bytes for the next read
731 708 * again and we don't need to specifically handle this case.
732 709 */
733 710 void
734 711 fm_dance(ndmpd_session_t *session)
735 712 {
736 713 (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
737 714 (void) ndmp_mtioctl(session->ns_tape.td_fd, MTBSF, 1);
738 715 }
739 716
740 717 /*
741 718 * ndmpd_tape_write_v3
742 719 *
743 720 * This handler handles tape_write requests. This interface is a non-buffered
744 721 * interface. Each write request maps directly to a write to the tape device.
745 722 * It is the responsibility of the NDMP client to pad the data to the desired
746 723 * record size. It is the responsibility of the NDMP client to ensure that the
747 724 * length is a multiple of the tape block size if the tape device is in fixed
748 725 * block mode.
749 726 *
750 727 * A logical end of tape will return number of bytes written less than
751 728 * requested, and one more request to write will give 0 and NDMP_EOM_ERR,
752 729 * followed by NDMP_NO_ERR until NDMP_IO_ERR when physical end of tape is
753 730 * reached.
754 731 *
755 732 * Parameters:
756 733 * connection (input) - connection handle.
|
↓ open down ↓ |
75 lines elided |
↑ open up ↑ |
757 734 * body (input) - request message body.
758 735 */
759 736 void ndmpd_tape_write_v3(ndmp_connection_t *connection, void *body) {
760 737 ndmp_tape_write_request *request = (ndmp_tape_write_request *)body;
761 738 ndmp_tape_write_reply reply; ndmpd_session_t *session =
762 739 ndmp_get_client_data(connection); ssize_t n;
763 740
764 741 reply.count = 0;
765 742
766 743 if (session->ns_tape.td_fd == -1) {
767 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
744 + syslog(LOG_ERR, "Tape device is not open.");
768 745 reply.error = NDMP_DEV_NOT_OPEN_ERR;
769 746 ndmp_send_reply(connection, (void *) &reply,
770 747 "sending tape_write reply");
771 748 return;
772 749 }
773 750 if (session->ns_tape.td_mode == NDMP_TAPE_READ_MODE) {
774 - NDMP_LOG(LOG_INFO, "Tape device opened in read-only mode");
751 + syslog(LOG_INFO, "Tape device opened in read-only mode");
775 752 reply.error = NDMP_PERMISSION_ERR;
776 753 ndmp_send_reply(connection, (void *) &reply,
777 754 "sending tape_write reply");
778 755 return;
779 756 }
780 757 if (request->data_out.data_out_len == 0) {
781 758 reply.error = NDMP_NO_ERR;
782 759 ndmp_send_reply(connection, (void *) &reply,
783 760 "sending tape_write reply");
784 761 return;
785 762 }
786 763
787 764 /*
788 765 * V4 suggests that this should not be accepted
789 766 * when mover is in listen or active state
790 767 */
791 768 if (session->ns_protocol_version == NDMPV4 &&
792 769 (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
793 770 session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE)) {
794 771
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
795 772 reply.error = NDMP_DEVICE_BUSY_ERR;
796 773 ndmp_send_reply(connection, (void *) &reply,
797 774 "sending tape_write reply");
798 775 return;
799 776 }
800 777
801 778 n = write(session->ns_tape.td_fd, request->data_out.data_out_val,
802 779 request->data_out.data_out_len);
803 780
804 781 if (n < 0) {
805 - NDMP_LOG(LOG_ERR, "Tape write error: %m.");
782 + syslog(LOG_ERR, "Tape write error: %m.");
806 783 reply.error = NDMP_IO_ERR;
807 784 } else if (n == 0) {
808 - NDMP_LOG(LOG_INFO, "EOM detected");
785 + syslog(LOG_INFO, "EOM detected");
809 786 reply.error = NDMP_EOM_ERR;
810 787 } else {
811 788 NS_ADD(wtape, n);
812 789 reply.count = n;
813 790 reply.error = NDMP_NO_ERR;
814 791
815 792 if (n < request->data_out.data_out_len)
816 - NDMP_LOG(LOG_DEBUG,
793 + syslog(LOG_DEBUG,
817 794 "EOM is coming (partial write of %d bytes)", n);
818 795 }
819 796
820 797 ndmp_send_reply(connection, (void *) &reply,
821 798 "sending tape_write reply");
822 799 }
823 800
824 801 /*
825 802 * ndmpd_tape_read_v3
826 803 *
827 804 * This handler handles tape_read requests. This interface is a non-buffered
828 805 * interface. Each read request maps directly to a read to the tape device. It
829 806 * is the responsibility of the NDMP client to issue read requests with a
830 807 * length that is at least as large as the record size used write the tape. The
831 808 * tape driver always reads a full record. Data is discarded if the read
832 809 * request is smaller than the record size. It is the responsibility of the
833 810 * NDMP client to ensure that the length is a multiple of the tape block size
834 811 * if the tape device is in fixed block mode.
835 812 *
836 813 * A logical end of tape will return less bytes than requested, and one more
837 814 * request to read will give 0 and NDMP_EOM_ERR. All subsequent reads will
838 815 * return NDMP_EOM_ERR until the tape is repositioned.
839 816 *
840 817 * Parameters:
841 818 * connection (input) - connection handle.
842 819 * body (input) - request message body.
843 820 */
844 821 void
845 822 ndmpd_tape_read_v3(ndmp_connection_t *connection, void *body)
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
846 823 {
847 824 ndmp_tape_read_request *request = (ndmp_tape_read_request *) body;
848 825 ndmp_tape_read_reply reply;
849 826 ndmpd_session_t *session = ndmp_get_client_data(connection);
850 827 char *buf;
851 828 int n;
852 829
853 830 reply.data_in.data_in_len = 0;
854 831
855 832 if (session->ns_tape.td_fd == -1) {
856 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
833 + syslog(LOG_ERR, "Tape device is not open.");
857 834 reply.error = NDMP_DEV_NOT_OPEN_ERR;
858 835 ndmp_send_reply(connection, (void *) &reply,
859 836 "sending tape_read reply");
860 837 return;
861 838 }
862 839 if (request->count == 0) {
863 840 reply.error = NDMP_NO_ERR;
864 841 ndmp_send_reply(connection, (void *) &reply,
865 842 "sending tape_read reply");
866 843 return;
867 844 }
868 845
869 846 /*
870 847 * V4 suggests that this should not be accepted
871 848 * when mover is in listen or active state
872 849 */
873 850 if (session->ns_protocol_version == NDMPV4 &&
874 851 (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
875 852 session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE)) {
876 853
877 854 reply.error = NDMP_DEVICE_BUSY_ERR;
878 855 ndmp_send_reply(connection, (void *) &reply,
879 856 "sending tape_read reply");
880 857 return;
881 858 }
882 859
883 860 if ((buf = ndmp_malloc(request->count)) == NULL) {
884 861 reply.error = NDMP_NO_MEM_ERR;
885 862 ndmp_send_reply(connection, (void *) &reply,
886 863 "sending tape_read reply");
887 864 return;
888 865 }
889 866
890 867 n = read(session->ns_tape.td_fd, buf, request->count);
891 868 if (n < 0) {
892 869 /*
893 870 * This fix is for Symantec during importing
|
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
894 871 * of spanned data between the tapes.
895 872 */
896 873 if (errno == ENOSPC) {
897 874 reply.error = NDMP_EOF_ERR;
898 875 }
899 876 /*
900 877 * If at beginning of file and read fails with EIO, then it's
901 878 * repeated attempt to read at EOT.
902 879 */
903 880 else if (errno == EIO && tape_is_at_bof(session)) {
904 - NDMP_LOG(LOG_DEBUG, "Repeated read at EOT");
881 + syslog(LOG_DEBUG, "Repeated read at EOT");
905 882 reply.error = NDMP_EOM_ERR;
906 883 }
907 884 /*
908 885 * According to NDMPv4 spec preferred error code when
909 886 * trying to read from blank tape is NDMP_EOM_ERR.
910 887 */
911 888 else if (errno == EIO && tape_is_at_bot(session)) {
912 - NDMP_LOG(LOG_ERR, "Blank tape detected, returning EOM");
889 + syslog(LOG_ERR, "Blank tape detected, returning EOM");
913 890 reply.error = NDMP_EOM_ERR;
914 891 } else {
915 - NDMP_LOG(LOG_ERR, "Tape read error: %m.");
892 + syslog(LOG_ERR, "Tape read error: %m.");
916 893 reply.error = NDMP_IO_ERR;
917 894 }
918 895 } else if (n == 0) {
919 896 if (tape_is_at_bof(session)) {
920 - NDMP_LOG(LOG_DEBUG, "EOT detected");
897 + syslog(LOG_DEBUG, "EOT detected");
921 898 reply.error = NDMP_EOM_ERR;
922 899 } else {
923 900 /* reposition the tape to BOT side of FM */
924 901 fm_dance(session);
925 - NDMP_LOG(LOG_DEBUG, "EOF detected");
902 + syslog(LOG_DEBUG, "EOF detected");
926 903 reply.error = NDMP_EOF_ERR;
927 904 }
928 905 } else {
929 906 session->ns_tape.td_pos += n;
930 907 reply.data_in.data_in_len = n;
931 908 reply.data_in.data_in_val = buf;
932 909 reply.error = NDMP_NO_ERR;
933 910 NS_ADD(rtape, n);
934 911 }
935 912
936 913 ndmp_send_reply(connection, (void *) &reply, "sending tape_read reply");
937 914 free(buf);
938 915 }
939 916
940 917
941 918 /*
942 919 * ************************************************************************
943 920 * NDMP V4 HANDLERS
944 921 * ************************************************************************
945 922 */
946 923
947 924 /*
948 925 * ndmpd_tape_get_state_v4
949 926 *
950 927 * This handler handles the ndmp_tape_get_state_request.
951 928 * Status information for the currently open tape device is returned.
952 929 *
953 930 * Parameters:
954 931 * connection (input) - connection handle.
955 932 * body (input) - request message body.
956 933 *
957 934 * Returns:
958 935 * void
959 936 */
960 937 /*ARGSUSED*/
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
961 938 void
962 939 ndmpd_tape_get_state_v4(ndmp_connection_t *connection, void *body)
963 940 {
964 941 ndmp_tape_get_state_reply_v4 reply;
965 942 ndmpd_session_t *session = ndmp_get_client_data(connection);
966 943 struct mtget mtstatus;
967 944 struct mtdrivetype_request dtpr;
968 945 struct mtdrivetype dtp;
969 946
970 947 if (session->ns_tape.td_fd == -1) {
971 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
948 + syslog(LOG_ERR, "Tape device is not open.");
972 949 reply.error = NDMP_DEV_NOT_OPEN_ERR;
973 950 ndmp_send_reply(connection, (void *) &reply,
974 951 "sending tape_get_state reply");
975 952 return;
976 953 }
977 954
978 955 /*
979 956 * Need code to detect NDMP_TAPE_STATE_NOREWIND
980 957 */
981 958
982 959 if (ioctl(session->ns_tape.td_fd, MTIOCGET, &mtstatus) == -1) {
983 - NDMP_LOG(LOG_ERR,
960 + syslog(LOG_ERR,
984 961 "Failed to get status information from tape: %m.");
985 - NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGET) error: %m.");
986 962
987 963 reply.error = NDMP_IO_ERR;
988 964 ndmp_send_reply(connection, (void *)&reply,
989 965 "sending tape_get_state reply");
990 966 return;
991 967 }
992 968
993 969 dtpr.size = sizeof (struct mtdrivetype);
994 970 dtpr.mtdtp = &dtp;
995 971 if (ioctl(session->ns_tape.td_fd, MTIOCGETDRIVETYPE, &dtpr) == -1) {
996 - NDMP_LOG(LOG_ERR,
972 + syslog(LOG_ERR,
997 973 "Failed to get drive type information from tape: %m.");
998 - NDMP_LOG(LOG_DEBUG, "ioctl(MTIOCGETDRIVETYPE) error: %m.");
999 974
1000 975 reply.error = NDMP_IO_ERR;
1001 976 ndmp_send_reply(connection, (void *)&reply,
1002 977 "sending tape_get_state reply");
1003 978 return;
1004 979 }
1005 980
1006 981 reply.flags = NDMP_TAPE_NOREWIND;
1007 982
1008 983 reply.file_num = mtstatus.mt_fileno;
1009 984 reply.soft_errors = 0;
1010 985 reply.block_size = dtp.bsize;
1011 986
1012 987 if (dtp.bsize == 0)
1013 988 reply.blockno = mtstatus.mt_blkno;
1014 989 else
1015 990 reply.blockno = mtstatus.mt_blkno /
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
1016 991 (session->ns_mover.md_record_size / dtp.bsize);
1017 992
1018 993 reply.total_space = long_long_to_quad(0LL); /* not supported */
1019 994 reply.space_remain = long_long_to_quad(0LL); /* not supported */
1020 995 reply.soft_errors = 0;
1021 996 reply.unsupported = NDMP_TAPE_STATE_SOFT_ERRORS_INVALID |
1022 997 NDMP_TAPE_STATE_TOTAL_SPACE_INVALID |
1023 998 NDMP_TAPE_STATE_SPACE_REMAIN_INVALID |
1024 999 NDMP_TAPE_STATE_PARTITION_INVALID;
1025 1000
1026 - NDMP_LOG(LOG_DEBUG, "f 0x%x, fnum %d, bsize %d, bno: %d",
1027 - reply.flags, reply.file_num, reply.block_size, reply.blockno);
1028 -
1029 1001 reply.error = NDMP_NO_ERR;
1030 1002 ndmp_send_reply(connection, (void *) &reply,
1031 1003 "sending tape_get_state reply");
1032 1004 }
1033 1005 /*
1034 1006 * ndmpd_tape_close_v4
1035 1007 *
1036 1008 * This handler (v4) closes the currently open tape device.
1037 1009 *
1038 1010 * Parameters:
1039 1011 * connection (input) - connection handle.
1040 1012 * body (input) - request message body.
1041 1013 *
1042 1014 * Returns:
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1043 1015 * void
1044 1016 */
1045 1017 /*ARGSUSED*/
1046 1018 void
1047 1019 ndmpd_tape_close_v4(ndmp_connection_t *connection, void *body)
1048 1020 {
1049 1021 ndmp_tape_close_reply reply;
1050 1022 ndmpd_session_t *session = ndmp_get_client_data(connection);
1051 1023
1052 1024 if (session->ns_tape.td_fd == -1) {
1053 - NDMP_LOG(LOG_ERR, "Tape device is not open.");
1025 + syslog(LOG_ERR, "Tape device is not open.");
1054 1026 reply.error = NDMP_DEV_NOT_OPEN_ERR;
1055 1027 ndmp_send_reply(connection, (void *) &reply,
1056 1028 "sending tape_close reply");
1057 1029 return;
1058 1030 }
1059 1031
1060 1032 /*
1061 1033 * V4 suggests that this should not be accepted
1062 1034 * when mover is in listen or active state
1063 1035 */
1064 1036 if (session->ns_mover.md_state == NDMP_MOVER_STATE_LISTEN ||
1065 1037 session->ns_mover.md_state == NDMP_MOVER_STATE_ACTIVE) {
1066 1038
1067 1039 reply.error = NDMP_DEVICE_BUSY_ERR;
1068 1040 ndmp_send_reply(connection, (void *) &reply,
1069 1041 "sending tape_close reply");
1070 1042 return;
1071 1043 }
1072 1044
1073 1045 common_tape_close(connection);
1074 1046 }
1075 1047
1076 1048
1077 1049 /*
1078 1050 * ************************************************************************
1079 1051 * LOCALS
1080 1052 * ************************************************************************
1081 1053 */
1082 1054 /*
1083 1055 * tape_open_send_reply
1084 1056 *
1085 1057 * Send a reply to the tape open message
1086 1058 *
1087 1059 * Parameters:
1088 1060 * connection (input) - connection handle.
1089 1061 * err (input) - NDMP error
1090 1062 *
1091 1063 * Returns:
1092 1064 * void
1093 1065 */
1094 1066 static void
1095 1067 tape_open_send_reply(ndmp_connection_t *connection, int err)
1096 1068 {
1097 1069 ndmp_tape_open_reply reply;
1098 1070
1099 1071 reply.error = err;
1100 1072 ndmp_send_reply(connection, (void *) &reply, "sending tape_open reply");
1101 1073 }
1102 1074
1103 1075 /*
1104 1076 * unbuffered_read
1105 1077 *
1106 1078 * Perform tape read without read-ahead
1107 1079 *
1108 1080 * Parameters:
1109 1081 * session (input) - session handle
1110 1082 * bp (output) - read buffer
1111 1083 * wanted (input) - number of bytes wanted
1112 1084 * reply (output) - tape read reply message
1113 1085 *
1114 1086 * Returns:
1115 1087 * void
1116 1088 */
1117 1089 static void
1118 1090 unbuffered_read(ndmpd_session_t *session, char *buf, long wanted,
1119 1091 ndmp_tape_read_reply *reply)
1120 1092 {
1121 1093 int n, len;
|
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
1122 1094
1123 1095 n = read(session->ns_tape.td_fd, buf, wanted);
1124 1096 if (n < 0) {
1125 1097 /*
1126 1098 * This fix is for Symantec during importing
1127 1099 * of spanned data between the tapes.
1128 1100 */
1129 1101 if (errno == ENOSPC) {
1130 1102 reply->error = NDMP_EOF_ERR;
1131 1103 } else {
1132 - NDMP_LOG(LOG_ERR, "Tape read error: %m.");
1104 + syslog(LOG_ERR, "Tape read error: %m.");
1133 1105 reply->error = NDMP_IO_ERR;
1134 1106 }
1135 1107 } else if (n == 0) {
1136 - NDMP_LOG(LOG_DEBUG, "NDMP_EOF_ERR");
1137 -
1138 1108 reply->error = NDMP_EOF_ERR;
1139 1109
1140 1110 (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
1141 1111
1142 1112 len = strlen(NDMP_EOM_MAGIC);
1143 1113 (void) memset(buf, 0, len);
1144 1114 n = read(session->ns_tape.td_fd, buf, len);
1145 1115 buf[len] = '\0';
1146 1116
1147 - NDMP_LOG(LOG_DEBUG, "Checking EOM: nread %d [%s]", n, buf);
1148 -
1149 1117 (void) ndmp_mtioctl(session->ns_tape.td_fd, MTBSF, 1);
1150 1118
1151 1119 if (strncmp(buf, NDMP_EOM_MAGIC, len) != 0)
1152 1120 (void) ndmp_mtioctl(session->ns_tape.td_fd, MTFSF, 1);
1153 1121 } else {
1154 1122 session->ns_tape.td_pos += n;
1155 1123 reply->data_in.data_in_len = n;
1156 1124 reply->data_in.data_in_val = buf;
1157 1125 reply->error = NDMP_NO_ERR;
1158 1126 NS_ADD(rtape, n);
1159 1127 }
1160 1128 }
1161 1129
1162 1130
1163 1131 /*
1164 1132 * validmode
1165 1133 *
1166 1134 * Check the tape read mode is valid
1167 1135 */
1168 1136 static boolean_t
1169 1137 validmode(int mode)
1170 1138 {
1171 1139 boolean_t rv;
1172 1140
1173 1141 switch (mode) {
1174 1142 case NDMP_TAPE_READ_MODE:
1175 1143 case NDMP_TAPE_WRITE_MODE:
1176 1144 case NDMP_TAPE_RAW1_MODE:
1177 1145 case NDMP_TAPE_RAW2_MODE:
1178 1146 rv = TRUE;
1179 1147 break;
1180 1148 default:
1181 1149 rv = FALSE;
1182 1150 }
1183 1151
1184 1152 return (rv);
1185 1153 }
1186 1154
1187 1155
1188 1156 /*
1189 1157 * common_tape_open
1190 1158 *
1191 1159 * Generic function for opening the tape for all versions
1192 1160 *
1193 1161 * Parameters:
1194 1162 * connection (input) - connection handle.
1195 1163 * devname (input) - tape device name to open.
1196 1164 * ndmpmode (input) - mode of opening (read, write, raw)
1197 1165 *
1198 1166 * Returns:
1199 1167 * void
|
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
1200 1168 */
1201 1169 static void
1202 1170 common_tape_open(ndmp_connection_t *connection, char *devname, int ndmpmode)
1203 1171 {
1204 1172 ndmpd_session_t *session = ndmp_get_client_data(connection);
1205 1173 char adptnm[SCSI_MAX_NAME];
1206 1174 int err;
1207 1175 int mode;
1208 1176 int sid, lun;
1209 1177 scsi_adapter_t *sa;
1210 - int devid;
1178 + int devid = -1;
1211 1179
1212 1180 err = NDMP_NO_ERR;
1213 1181
1214 1182 if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
1215 - NDMP_LOG(LOG_INFO,
1183 + syslog(LOG_INFO,
1216 1184 "Connection already has a tape or scsi device open");
1217 1185 err = NDMP_DEVICE_OPENED_ERR;
1218 1186 } else if (!validmode(ndmpmode))
1219 1187 err = NDMP_ILLEGAL_ARGS_ERR;
1220 1188 if ((sa = scsi_get_adapter(0)) != NULL) {
1221 - NDMP_LOG(LOG_DEBUG, "Adapter device opened: %s", devname);
1222 1189 (void) strlcpy(adptnm, devname, SCSI_MAX_NAME-2);
1223 1190 adptnm[SCSI_MAX_NAME-1] = '\0';
1224 1191 sid = lun = -1;
1225 1192 }
1226 1193 if (sa) {
1227 1194 scsi_find_sid_lun(sa, devname, &sid, &lun);
1228 1195 if (ndmp_open_list_find(devname, sid, lun) == 0 &&
1229 1196 (devid = open(devname, O_RDWR | O_NDELAY)) < 0) {
1230 - NDMP_LOG(LOG_ERR,
1197 + syslog(LOG_ERR,
1231 1198 "Failed to open device %s: %m.", devname);
1232 1199 err = NDMP_NO_DEVICE_ERR;
1233 1200 } else {
1234 1201 (void) close(devid);
1235 1202 }
1236 1203 } else {
1237 - NDMP_LOG(LOG_ERR, "%s: No such tape device.", devname);
1204 + syslog(LOG_ERR, "%s: No such tape device.", devname);
1238 1205 err = NDMP_NO_DEVICE_ERR;
1239 1206 }
1240 1207
1241 1208 if (err != NDMP_NO_ERR) {
1242 1209 tape_open_send_reply(connection, err);
1243 1210 return;
1244 1211 }
1245 1212
1246 1213 /*
1247 1214 * If tape is not opened in raw mode and tape is not loaded
1248 1215 * return error.
1249 1216 */
1250 1217 if (ndmpmode != NDMP_TAPE_RAW1_MODE &&
1251 1218 ndmpmode != NDMP_TAPE_RAW2_MODE &&
1252 1219 !is_tape_unit_ready(adptnm, 0)) {
1253 1220 tape_open_send_reply(connection, NDMP_NO_TAPE_LOADED_ERR);
1254 1221 return;
1255 1222 }
1256 1223
1257 1224 mode = (ndmpmode == NDMP_TAPE_READ_MODE) ? O_RDONLY : O_RDWR;
1258 1225 mode |= O_NDELAY;
1259 1226 session->ns_tape.td_fd = open(devname, mode);
1260 1227 if (session->ns_protocol_version == NDMPV4 &&
1261 1228 session->ns_tape.td_fd < 0 &&
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
1262 1229 ndmpmode == NDMP_TAPE_RAW_MODE && errno == EACCES) {
1263 1230 /*
1264 1231 * V4 suggests that if the tape is open in raw mode
1265 1232 * and could not be opened with write access, it should
1266 1233 * be opened read only instead.
1267 1234 */
1268 1235 ndmpmode = NDMP_TAPE_READ_MODE;
1269 1236 session->ns_tape.td_fd = open(devname, O_RDONLY);
1270 1237 }
1271 1238 if (session->ns_tape.td_fd < 0) {
1272 - NDMP_LOG(LOG_ERR, "Failed to open tape device %s: %m.",
1239 + syslog(LOG_ERR, "Failed to open tape device %s: %m.",
1273 1240 devname);
1274 1241 switch (errno) {
1275 1242 case EACCES:
1276 1243 err = NDMP_WRITE_PROTECT_ERR;
1277 1244 break;
1278 1245 case ENOENT:
1279 1246 err = NDMP_NO_DEVICE_ERR;
1280 1247 break;
1281 1248 case EBUSY:
1282 1249 err = NDMP_DEVICE_BUSY_ERR;
1283 1250 break;
1284 1251 case EPERM:
1285 1252 err = NDMP_PERMISSION_ERR;
1286 1253 break;
1287 1254 default:
1288 1255 err = NDMP_IO_ERR;
1289 1256 }
1290 1257
1291 1258 tape_open_send_reply(connection, err);
1292 1259 return;
1293 1260 }
1294 1261
1295 1262 switch (ndmp_open_list_add(connection,
1296 1263 adptnm, sid, lun, session->ns_tape.td_fd)) {
1297 1264 case 0:
1298 1265 err = NDMP_NO_ERR;
1299 1266 break;
1300 1267 case EBUSY:
1301 1268 err = NDMP_DEVICE_BUSY_ERR;
1302 1269 break;
1303 1270 case ENOMEM:
1304 1271 err = NDMP_NO_MEM_ERR;
1305 1272 break;
1306 1273 default:
1307 1274 err = NDMP_IO_ERR;
1308 1275 }
1309 1276 if (err != NDMP_NO_ERR) {
|
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
1310 1277 tape_open_send_reply(connection, err);
1311 1278 return;
1312 1279 }
1313 1280
1314 1281 session->ns_tape.td_mode = ndmpmode;
1315 1282 session->ns_tape.td_sid = sid;
1316 1283 session->ns_tape.td_lun = lun;
1317 1284 (void) strlcpy(session->ns_tape.td_adapter_name, adptnm, SCSI_MAX_NAME);
1318 1285 session->ns_tape.td_record_count = 0;
1319 1286
1320 - NDMP_LOG(LOG_DEBUG, "Tape is opened fd: %d", session->ns_tape.td_fd);
1321 -
1322 1287 tape_open_send_reply(connection, NDMP_NO_ERR);
1323 1288 }
1324 1289
1325 1290
1326 1291 /*
1327 1292 * common_tape_close
1328 1293 *
1329 1294 * Generic function for closing the tape
1330 1295 *
1331 1296 * Parameters:
1332 1297 * connection (input) - connection handle.
1333 1298 *
1334 1299 * Returns:
1335 1300 * void
1336 1301 */
1337 1302 static void
1338 1303 common_tape_close(ndmp_connection_t *connection)
1339 1304 {
1340 1305 ndmpd_session_t *session = ndmp_get_client_data(connection);
1341 1306 ndmp_tape_close_reply reply;
1342 1307
1343 1308 (void) ndmp_open_list_del(session->ns_tape.td_adapter_name,
1344 1309 session->ns_tape.td_sid, session->ns_tape.td_lun);
1345 1310 (void) close(session->ns_tape.td_fd);
1346 1311 session->ns_tape.td_fd = -1;
1347 1312 session->ns_tape.td_sid = 0;
1348 1313 session->ns_tape.td_lun = 0;
1349 1314 (void) memset(session->ns_tape.td_adapter_name, 0,
1350 1315 sizeof (session->ns_tape.td_adapter_name));
1351 1316 session->ns_tape.td_record_count = 0;
1352 1317
1353 1318 reply.error = NDMP_NO_ERR;
1354 1319 ndmp_send_reply(connection, (void *) &reply,
1355 1320 "sending tape_close reply");
1356 1321 }
1357 1322
1358 1323 /*
1359 1324 * tape_open
1360 1325 *
1361 1326 * Will try to open the tape with the given flags and
1362 1327 * path using the given retries and delay intervals
1363 1328 */
1364 1329 int
1365 1330 tape_open(char *path, int flags)
1366 1331 {
1367 1332 int fd;
1368 1333 int i = 0;
1369 1334
1370 1335 while ((fd = open(path, flags)) == -1 &&
1371 1336 i++ < ndmp_tape_open_retries) {
1372 1337 if (errno != EBUSY)
1373 1338 break;
1374 1339 (void) usleep(ndmp_tape_open_delay);
1375 1340 }
1376 1341 return (fd);
1377 1342 }
|
↓ open down ↓ |
46 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX