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
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/ndmpd/tlm/tlm_lib.c
+++ new/usr/src/cmd/ndmpd/tlm/tlm_lib.c
1 1 /*
2 2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3 3 * Copyright (c) 2015 by Delphix. All rights reserved.
4 4 */
5 5
6 6 /*
7 7 * BSD 3 Clause License
8 8 *
9 9 * Copyright (c) 2007, The Storage Networking Industry Association.
10 10 *
11 11 * Redistribution and use in source and binary forms, with or without
12 12 * modification, are permitted provided that the following conditions
13 13 * are met:
14 14 * - Redistributions of source code must retain the above copyright
15 15 * notice, this list of conditions and the following disclaimer.
16 16 *
17 17 * - Redistributions in binary form must reproduce the above copyright
18 18 * notice, this list of conditions and the following disclaimer in
19 19 * the documentation and/or other materials provided with the
20 20 * distribution.
21 21 *
22 22 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 23 * nor the names of its contributors may be used to endorse or promote
24 24 * products derived from this software without specific prior written
25 25 * permission.
26 26 *
27 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
29 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 37 * POSSIBILITY OF SUCH DAMAGE.
38 38 */
39 +/* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
40 +
39 41 #include <sys/errno.h>
42 +#include <syslog.h>
40 43 #include <ctype.h>
41 44 #include <stdlib.h>
42 45 #include <time.h>
43 46 #include <sys/types.h>
44 47 #include <unistd.h>
45 48 #include <libzfs.h>
46 49 #include <pthread.h>
47 50 #include "tlm.h"
48 51 #include "tlm_proto.h"
49 52 #include <ndmpd_prop.h>
50 53 #include <sys/mtio.h>
51 54 #include <sys/mnttab.h>
52 55 #include <sys/mntent.h>
53 56 #include <sys/statvfs.h>
54 57 #include <sys/scsi/impl/uscsi.h>
55 58 #include <sys/scsi/scsi.h>
56 59 #include <sys/mtio.h>
57 60 #include <thread.h>
58 61 #include <synch.h>
59 62 #include <sys/mutex.h>
60 63 #include <sys/sysmacros.h>
61 64 #include <sys/mkdev.h>
62 65
63 66 /*
64 67 * Tar archiving ops vector
65 68 */
66 69 tm_ops_t tm_tar_ops = {
67 70 "tar",
68 71 tar_putfile,
69 72 tar_putdir,
70 73 NULL,
71 74 tar_getfile,
72 75 tar_getdir,
73 76 NULL
74 77 };
75 78
76 79 extern libzfs_handle_t *zlibh;
77 80 extern mutex_t zlib_mtx;
78 81
79 82 /*
80 83 * get the next tape buffer from the drive's pool of buffers
81 84 */
82 85 /*ARGSUSED*/
83 86 char *
84 87 tlm_get_write_buffer(long want, long *actual_size,
85 88 tlm_buffers_t *buffers, int zero)
86 89 {
87 90 int buf = buffers->tbs_buffer_in;
88 91 tlm_buffer_t *buffer = &buffers->tbs_buffer[buf];
89 92 int align_size = RECORDSIZE - 1;
90 93 char *rec;
91 94
92 95 /*
93 96 * make sure the allocation is in chunks of 512 bytes
94 97 */
95 98 want += align_size;
96 99 want &= ~align_size;
97 100
98 101 *actual_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
99 102 if (*actual_size <= 0) {
100 103 /*
101 104 * no room, send this one
102 105 * and wait for a free one
103 106 */
104 107 if (!buffer->tb_full) {
105 108 /*
106 109 * we are now ready to send a full buffer
107 110 * instead of trying to get a new buffer
108 111 *
109 112 * do not send if we failed to get a buffer
110 113 * on the previous call
111 114 */
112 115 buffer->tb_full = TRUE;
113 116
114 117 /*
115 118 * tell the writer that a buffer is available
116 119 */
117 120 tlm_buffer_release_in_buf(buffers);
118 121
119 122 buffer = tlm_buffer_advance_in_idx(buffers);
120 123 }
121 124
122 125 buffer = tlm_buffer_in_buf(buffers, NULL);
123 126
124 127 if (buffer->tb_full) {
125 128 /*
126 129 * wait for the writer to free up a buffer
127 130 */
128 131 tlm_buffer_out_buf_timed_wait(buffers, 500);
129 132 }
130 133
131 134 buffer = tlm_buffer_in_buf(buffers, NULL);
132 135 if (buffer->tb_full) {
133 136 /*
134 137 * the next buffer is still full
135 138 * of data from previous activity
136 139 *
137 140 * nothing has changed.
138 141 */
139 142 return (0);
140 143 }
141 144
142 145 buffer->tb_buffer_spot = 0;
143 146 *actual_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
144 147 }
145 148
146 149 *actual_size = min(want, *actual_size);
147 150 rec = &buffer->tb_buffer_data[buffer->tb_buffer_spot];
148 151 buffer->tb_buffer_spot += *actual_size;
149 152 buffers->tbs_offset += *actual_size;
150 153 if (zero) {
151 154 (void) memset(rec, 0, *actual_size);
152 155 }
153 156 return (rec);
154 157 }
155 158
156 159 /*
157 160 * get a read record from the tape buffer,
158 161 * and read a tape block if necessary
159 162 */
160 163 /*ARGSUSED*/
161 164 char *
162 165 tlm_get_read_buffer(int want, int *error,
163 166 tlm_buffers_t *buffers, int *actual_size)
164 167 {
165 168 tlm_buffer_t *buffer;
166 169 int align_size = RECORDSIZE - 1;
167 170 int buf;
168 171 int current_size;
169 172 char *rec;
170 173
171 174 buf = buffers->tbs_buffer_out;
172 175 buffer = &buffers->tbs_buffer[buf];
173 176
174 177 /*
175 178 * make sure the allocation is in chunks of 512 bytes
176 179 */
177 180 want += align_size;
178 181 want &= ~align_size;
179 182
180 183 current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
181 184 if (buffer->tb_full && current_size <= 0) {
182 185 /*
183 186 * no more data, release this
184 187 * one and go get another
185 188 */
186 189
187 190 /*
188 191 * tell the reader that a buffer is available
189 192 */
190 193 buffer->tb_full = FALSE;
191 194 tlm_buffer_release_out_buf(buffers);
192 195
193 196 buffer = tlm_buffer_advance_out_idx(buffers);
194 197 current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
195 198 }
196 199
197 200 if (!buffer->tb_full) {
198 201 /*
199 202 * next buffer is not full yet.
200 203 * wait for the reader.
201 204 */
202 205 tlm_buffer_in_buf_timed_wait(buffers, 500);
203 206
204 207 buffer = tlm_buffer_out_buf(buffers, NULL);
205 208 if (!buffer->tb_full) {
206 209 /*
207 210 * we do not have anything from the tape yet
208 211 */
209 212 return (0);
210 213 }
211 214
212 215 current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot;
213 216 }
214 217
215 218 /* Make sure we got something */
216 219 if (current_size <= 0)
217 220 return (NULL);
218 221
219 222 current_size = min(want, current_size);
220 223 rec = &buffer->tb_buffer_data[buffer->tb_buffer_spot];
221 224 buffer->tb_buffer_spot += current_size;
222 225 *actual_size = current_size;
223 226
224 227 /*
225 228 * the error flag is only sent back one time,
226 229 * since the flag refers to a previous read
227 230 * attempt, not the data in this buffer.
228 231 */
229 232 *error = buffer->tb_errno;
230 233
231 234 return (rec);
232 235 }
233 236
234 237
235 238 /*
236 239 * unread a previously read buffer back to the tape buffer
237 240 */
238 241 void
239 242 tlm_unget_read_buffer(tlm_buffers_t *buffers, int size)
240 243 {
241 244 tlm_buffer_t *buffer;
242 245 int align_size = RECORDSIZE - 1;
243 246 int buf;
244 247 int current_size;
245 248
246 249 buf = buffers->tbs_buffer_out;
247 250 buffer = &buffers->tbs_buffer[buf];
248 251
249 252 /*
250 253 * make sure the allocation is in chunks of 512 bytes
251 254 */
252 255 size += align_size;
253 256 size &= ~align_size;
254 257
255 258 current_size = min(size, buffer->tb_buffer_spot);
256 259 buffer->tb_buffer_spot -= current_size;
257 260 }
258 261
259 262
260 263 /*
261 264 * unwrite a previously written buffer
262 265 */
263 266 void
264 267 tlm_unget_write_buffer(tlm_buffers_t *buffers, int size)
265 268 {
266 269 tlm_buffer_t *buffer;
267 270 int align_size = RECORDSIZE - 1;
268 271 int buf;
269 272 int current_size;
270 273
271 274 buf = buffers->tbs_buffer_in;
272 275 buffer = &buffers->tbs_buffer[buf];
273 276
274 277 /*
275 278 * make sure the allocation is in chunks of 512 bytes
276 279 */
277 280 size += align_size;
278 281 size &= ~align_size;
279 282
280 283 current_size = min(size, buffer->tb_buffer_spot);
281 284 buffer->tb_buffer_spot -= current_size;
282 285 }
283 286
284 287
285 288 /*
286 289 * build a checksum for a TAR header record
287 290 */
288 291 void
289 292 tlm_build_header_checksum(tlm_tar_hdr_t *r)
290 293 {
291 294 int i;
292 295 int sum = 0;
293 296 char *c = (char *)r;
294 297
295 298 (void) memcpy(r->th_chksum, CHKBLANKS, strlen(CHKBLANKS));
296 299 for (i = 0; i < RECORDSIZE; i++) {
297 300 sum += c[i] & 0xFF;
298 301 }
299 302 (void) snprintf(r->th_chksum, sizeof (r->th_chksum), "%6o", sum);
300 303 }
301 304
302 305 /*
303 306 * verify the tar header checksum
304 307 */
305 308 int
306 309 tlm_vfy_tar_checksum(tlm_tar_hdr_t *tar_hdr)
307 310 {
308 311 int chksum = oct_atoi(tar_hdr->th_chksum);
309 312 uchar_t *p = (uchar_t *)tar_hdr;
310 313 int sum = 0; /* initial value of checksum */
|
↓ open down ↓ |
261 lines elided |
↑ open up ↑ |
311 314 int i; /* loop counter */
312 315
313 316 /*
314 317 * compute the checksum
315 318 */
316 319 for (i = 0; i < RECORDSIZE; i++) {
317 320 sum += p[i] & 0xFF;
318 321 }
319 322
320 323 if (sum == 0) {
321 - NDMP_LOG(LOG_DEBUG,
324 + syslog(LOG_DEBUG,
322 325 "should be %d, is 0", chksum);
323 326 /* a zero record ==> end of tar file */
324 327 return (0);
325 328 }
326 329
327 330 /*
328 331 * subtract out the label's checksum values
329 332 * this lets us undo the old checksum "in-
330 333 * place", no need to swap blanks in and out
331 334 */
332 335 for (i = 0; i < 8; i++) {
333 336 sum -= 0xFF & tar_hdr->th_chksum[i];
334 337 }
335 338
336 339 /*
337 340 * replace the old checksum field with blanks
338 341 */
339 342 sum += ' ' * 8;
340 343
341 - if (sum != chksum)
342 - NDMP_LOG(LOG_DEBUG,
344 + if (sum != chksum) {
345 + syslog(LOG_DEBUG,
343 346 "should be %d, is %d", chksum, sum);
347 + }
344 348
345 349 return ((sum == chksum) ? 1 : -1);
346 350 }
347 351
348 352 /*
349 353 * get internal scsi_sasd entry for this tape drive
350 354 */
351 355 int
352 356 tlm_get_scsi_sasd_entry(int lib, int drv)
353 357 {
354 358 int entry;
355 359 int i, n;
356 360 scsi_link_t *sl;
357 361 tlm_drive_t *dp;
358 362
359 363 entry = -1;
360 364 dp = tlm_drive(lib, drv);
361 365 if (!dp) {
362 - NDMP_LOG(LOG_DEBUG, "NULL dp for (%d.%d)", lib, drv);
366 + syslog(LOG_DEBUG, "NULL dp for (%d.%d)", lib, drv);
363 367 } else if (!dp->td_slink) {
364 - NDMP_LOG(LOG_DEBUG, "NULL dp->td_slink for (%d.%d)", lib, drv);
368 + syslog(LOG_DEBUG, "NULL dp->td_slink for (%d.%d)", lib, drv);
365 369 } else if (!dp->td_slink->sl_sa) {
366 - NDMP_LOG(LOG_DEBUG, "NULL dp->td_slink->sl_sa for (%d.%d)",
370 + syslog(LOG_DEBUG, "NULL dp->td_slink->sl_sa for (%d.%d)",
367 371 lib, drv);
368 372 } else {
369 373 /* search through the SASD table */
370 374 n = sasd_dev_count();
371 375 for (i = 0; i < n; i++) {
372 376 sl = sasd_dev_slink(i);
373 377 if (!sl)
374 378 continue;
375 379
376 380 if (dp->td_slink->sl_sa == sl->sl_sa &&
377 381 dp->td_scsi_id == sl->sl_sid &&
378 382 dp->td_lun == sl->sl_lun) {
379 383 /* all 3 variables match */
380 384 entry = i;
381 385 break;
382 386 }
383 387 }
384 388 }
385 389
386 390 return (entry);
387 391 }
388 392
389 393 /*
390 394 * get the OS device name for this tape
391 395 */
392 396 char *
393 397 tlm_get_tape_name(int lib, int drv)
394 398 {
395 399 int entry;
396 400
397 401 entry = tlm_get_scsi_sasd_entry(lib, drv);
398 402 if (entry >= 0) {
399 403 sasd_drive_t *sd;
400 404
401 405 if ((sd = sasd_drive(entry)) != 0)
402 406 return (sd->sd_name);
403 407 }
404 408
405 409 return ("");
406 410 }
407 411
408 412 /*
409 413 * create the IPC area between the reader and writer
410 414 */
411 415 tlm_cmd_t *
412 416 tlm_create_reader_writer_ipc(boolean_t write, long data_transfer_size)
413 417 {
414 418 tlm_cmd_t *cmd;
415 419
416 420 cmd = ndmp_malloc(sizeof (tlm_cmd_t));
417 421 if (cmd == NULL)
418 422 return (NULL);
419 423
420 424 cmd->tc_reader = TLM_BACKUP_RUN;
421 425 cmd->tc_writer = TLM_BACKUP_RUN;
422 426 cmd->tc_ref = 1;
423 427
424 428 cmd->tc_buffers = tlm_allocate_buffers(write, data_transfer_size);
425 429 if (cmd->tc_buffers == NULL) {
426 430 free(cmd);
427 431 return (NULL);
428 432 }
429 433
430 434 (void) mutex_init(&cmd->tc_mtx, 0, NULL);
431 435 (void) cond_init(&cmd->tc_cv, 0, NULL);
432 436
433 437 return (cmd);
434 438 }
435 439
436 440 /*
437 441 * release(destroy) the IPC between the reader and writer
438 442 */
439 443 void
440 444 tlm_release_reader_writer_ipc(tlm_cmd_t *cmd)
441 445 {
442 446 if (--cmd->tc_ref <= 0) {
443 447 (void) mutex_lock(&cmd->tc_mtx);
444 448 tlm_release_buffers(cmd->tc_buffers);
445 449 (void) cond_destroy(&cmd->tc_cv);
446 450 (void) mutex_unlock(&cmd->tc_mtx);
447 451 (void) mutex_destroy(&cmd->tc_mtx);
448 452 free(cmd);
449 453 }
450 454 }
451 455
452 456
453 457 /*
454 458 * NDMP support begins here.
455 459 */
456 460
457 461 /*
458 462 * Initialize the file history callback functions
459 463 */
460 464 lbr_fhlog_call_backs_t *
461 465 lbrlog_callbacks_init(void *cookie, path_hist_func_t log_pname_func,
462 466 dir_hist_func_t log_dir_func, node_hist_func_t log_node_func)
463 467 {
464 468 lbr_fhlog_call_backs_t *p;
465 469
466 470 p = ndmp_malloc(sizeof (lbr_fhlog_call_backs_t));
467 471 if (p == NULL)
468 472 return (NULL);
469 473
470 474 p->fh_cookie = cookie;
471 475 p->fh_logpname = (func_t)log_pname_func;
472 476 p->fh_log_dir = (func_t)log_dir_func;
473 477 p->fh_log_node = (func_t)log_node_func;
474 478 return (p);
475 479 }
476 480
477 481 /*
478 482 * Cleanup the callbacks
479 483 */
480 484 void
481 485 lbrlog_callbacks_done(lbr_fhlog_call_backs_t *p)
482 486 {
483 487 if (p != NULL)
484 488 (void) free((char *)p);
485 489 }
486 490
487 491 /*
488 492 * Call back for file history directory info
|
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
489 493 */
490 494 int
491 495 tlm_log_fhdir(tlm_job_stats_t *job_stats, char *dir, struct stat64 *stp,
492 496 fs_fhandle_t *fhp)
493 497 {
494 498 int rv;
495 499 lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
496 500
497 501 rv = 0;
498 502 if (job_stats == NULL) {
499 - NDMP_LOG(LOG_DEBUG, "log_fhdir: jstat is NULL");
503 + syslog(LOG_DEBUG, "log_fhdir: jstat is NULL");
500 504 } else if (dir == NULL) {
501 - NDMP_LOG(LOG_DEBUG, "log_fhdir: dir is NULL");
505 + syslog(LOG_DEBUG, "log_fhdir: dir is NULL");
502 506 } else if (stp == NULL) {
503 - NDMP_LOG(LOG_DEBUG, "log_fhdir: stp is NULL");
507 + syslog(LOG_DEBUG, "log_fhdir: stp is NULL");
504 508 } else if ((cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks)
505 509 == NULL) {
506 - NDMP_LOG(LOG_DEBUG, "log_fhdir: cbp is NULL");
510 + syslog(LOG_DEBUG, "log_fhdir: cbp is NULL");
507 511 } else if (cbp->fh_log_dir == NULL) {
508 - NDMP_LOG(LOG_DEBUG, "log_fhdir: callback is NULL");
512 + syslog(LOG_DEBUG, "log_fhdir: callback is NULL");
509 513 } else
510 514 rv = (*cbp->fh_log_dir)(cbp, dir, stp, fhp);
511 515
512 516 return (rv);
513 517 }
514 518
515 519 /*
516 520 * Call back for file history node info
517 521 */
518 522 int
519 523 tlm_log_fhnode(tlm_job_stats_t *job_stats, char *dir, char *file,
520 524 struct stat64 *stp, u_longlong_t off)
521 525 {
522 526 int rv;
523 527 lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
524 528
525 529 rv = 0;
526 530 if (job_stats == NULL) {
527 - NDMP_LOG(LOG_DEBUG, "log_fhnode: jstat is NULL");
531 + syslog(LOG_DEBUG, "log_fhnode: jstat is NULL");
528 532 } else if (dir == NULL) {
529 - NDMP_LOG(LOG_DEBUG, "log_fhnode: dir is NULL");
533 + syslog(LOG_DEBUG, "log_fhnode: dir is NULL");
530 534 } else if (file == NULL) {
531 - NDMP_LOG(LOG_DEBUG, "log_fhnode: file is NULL");
535 + syslog(LOG_DEBUG, "log_fhnode: file is NULL");
532 536 } else if (stp == NULL) {
533 - NDMP_LOG(LOG_DEBUG, "log_fhnode: stp is NULL");
537 + syslog(LOG_DEBUG, "log_fhnode: stp is NULL");
534 538 } else if ((cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks)
535 539 == NULL) {
536 - NDMP_LOG(LOG_DEBUG, "log_fhnode: cbp is NULL");
540 + syslog(LOG_DEBUG, "log_fhnode: cbp is NULL");
537 541 } else if (cbp->fh_log_node == NULL) {
538 - NDMP_LOG(LOG_DEBUG, "log_fhnode: callback is NULL");
542 + syslog(LOG_DEBUG, "log_fhnode: callback is NULL");
539 543 } else
540 544 rv = (*cbp->fh_log_node)(cbp, dir, file, stp, off);
541 545
542 546 return (rv);
543 547 }
544 548
545 549 /*
546 550 * Call back for file history path info
547 551 */
548 552 int
549 553 tlm_log_fhpath_name(tlm_job_stats_t *job_stats, char *pathname,
550 554 struct stat64 *stp, u_longlong_t off)
551 555 {
552 556 int rv;
553 557 lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
554 558
555 559 rv = 0;
556 560 if (!job_stats) {
557 - NDMP_LOG(LOG_DEBUG, "log_fhpath_name: jstat is NULL");
561 + syslog(LOG_DEBUG, "log_fhpath_name: jstat is NULL");
558 562 } else if (!pathname) {
559 - NDMP_LOG(LOG_DEBUG, "log_fhpath_name: pathname is NULL");
563 + syslog(LOG_DEBUG, "log_fhpath_name: pathname is NULL");
560 564 } else if (!stp) {
561 - NDMP_LOG(LOG_DEBUG, "log_fhpath_name: stp is NULL");
565 + syslog(LOG_DEBUG, "log_fhpath_name: stp is NULL");
562 566 } else if ((cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks)
563 567 == 0) {
564 - NDMP_LOG(LOG_DEBUG, "log_fhpath_name: cbp is NULL");
568 + syslog(LOG_DEBUG, "log_fhpath_name: cbp is NULL");
565 569 } else if (!cbp->fh_logpname) {
566 - NDMP_LOG(LOG_DEBUG, "log_fhpath_name: callback is NULL");
570 + syslog(LOG_DEBUG, "log_fhpath_name: callback is NULL");
567 571 } else
568 572 rv = (*cbp->fh_logpname)(cbp, pathname, stp, off);
569 573
570 574 return (rv);
571 575 }
572 576
573 577
574 578 /*
575 579 * Log call back to report the entry recovery
576 580 */
577 581 int
578 582 tlm_entry_restored(tlm_job_stats_t *job_stats, char *name, int pos)
579 583 {
580 584 lbr_fhlog_call_backs_t *cbp; /* callbacks pointer */
581 585
582 - NDMP_LOG(LOG_DEBUG, "name: \"%s\", pos: %d", name, pos);
583 -
584 586 if (job_stats == NULL) {
585 - NDMP_LOG(LOG_DEBUG, "entry_restored: jstat is NULL");
587 + syslog(LOG_DEBUG, "entry_restored: jstat is NULL");
586 588 return (0);
587 589 }
588 590 cbp = (lbr_fhlog_call_backs_t *)job_stats->js_callbacks;
589 591 if (cbp == NULL) {
590 - NDMP_LOG(LOG_DEBUG, "entry_restored is NULL");
592 + syslog(LOG_DEBUG, "entry_restored is NULL");
591 593 return (0);
592 594 }
593 595 return (*cbp->fh_logpname)(cbp, name, 0, (longlong_t)pos);
594 596 }
595 597 /*
596 598 * NDMP support ends here.
597 599 */
598 600
599 601 /*
600 602 * Function: tlm_cat_path
601 603 * Concatenates two path names
602 604 * or directory name and file name
603 605 * into a buffer passed by the caller. A slash
604 606 * is inserted if required. Buffer is assumed
605 607 * to hold PATH_MAX characters.
606 608 *
607 609 * Parameters:
608 610 * char *buf - buffer to write new dir/name string
609 611 * char *dir - directory name
610 612 * char *name - file name
611 613 *
612 614 * Returns:
613 615 * TRUE - No errors. buf contains the dir/name string
614 616 * FALSE - Error. buf is not modified.
615 617 */
616 618 boolean_t
617 619 tlm_cat_path(char *buf, char *dir, char *name)
618 620 {
619 621 char *fmt;
620 622 int dirlen = strlen(dir);
621 623 int filelen = strlen(name);
622 624
623 625 if ((dirlen + filelen + 1) >= PATH_MAX) {
624 626 return (FALSE);
625 627 }
626 628
627 629 if (*dir == '\0' || *name == '\0' || dir[dirlen - 1] == '/' ||
628 630 *name == '/') {
629 631 fmt = "%s%s";
630 632 } else {
631 633 fmt = "%s/%s";
632 634 }
633 635
634 636 /* check for ".../" and "/...." */
635 637 if ((dirlen > 0) && (dir[dirlen - 1] == '/') && (*name == '/'))
636 638 name += strspn(name, "/");
637 639
638 640 /* LINTED variable format */
|
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
639 641 (void) snprintf(buf, TLM_MAX_PATH_NAME, fmt, dir, name);
640 642
641 643 return (TRUE);
642 644 }
643 645
644 646 /*
645 647 * Get the checkpoint (snapshot) creation time.
646 648 * This is necessary to check for checkpoints not being stale.
647 649 */
648 650 int
649 -tlm_get_chkpnt_time(char *path, int auto_checkpoint, time_t *tp, char *jname)
651 +tlm_get_chkpnt_time(char *path, time_t *tp)
650 652 {
651 - char volname[TLM_VOLNAME_MAX_LENGTH];
652 - char chk_name[PATH_MAX];
653 - char *cp_nm;
653 + zfs_handle_t *zhp;
654 654
655 - NDMP_LOG(LOG_DEBUG, "path [%s] auto_checkpoint: %d",
656 - path, auto_checkpoint);
657 -
658 - if (path == NULL || *path == '\0' || tp == NULL)
655 + if (path == NULL || *path == '\0' || tp == NULL) {
656 + syslog(LOG_ERR, "tlm_get_chkpnt_time: bad params");
659 657 return (-1);
658 + }
660 659
661 - if (get_zfsvolname(volname, TLM_VOLNAME_MAX_LENGTH,
662 - path) == -1)
660 + (void) mutex_lock(&zlib_mtx);
661 + if ((zhp = zfs_open(zlibh, path, ZFS_TYPE_DATASET)) == NULL) {
662 + syslog(LOG_DEBUG, "tlm_get_chkpnt_time: open %s failed",
663 + path);
664 + (void) mutex_unlock(&zlib_mtx);
663 665 return (-1);
664 -
665 - if (auto_checkpoint) {
666 - NDMP_LOG(LOG_DEBUG, "volname [%s]", volname);
667 - (void) snprintf(chk_name, PATH_MAX, "%s", jname);
668 - return (chkpnt_creationtime_bypattern(volname, chk_name, tp));
669 666 }
670 - cp_nm = strchr(volname, '@');
671 - NDMP_LOG(LOG_DEBUG, "volname [%s] cp_nm [%s]", volname, cp_nm);
672 667
673 - return (chkpnt_creationtime_bypattern(volname, cp_nm, tp));
668 + *tp = zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
669 +
670 + zfs_close(zhp);
671 + (void) mutex_unlock(&zlib_mtx);
672 +
673 + return (0);
674 674 }
675 675
676 676 /*
677 677 * Release an array of pointers and the pointers themselves.
678 678 */
679 679 void
680 680 tlm_release_list(char **lpp)
681 681 {
682 682 char **save;
683 683
684 684 if ((save = lpp) == 0)
685 685 return;
686 686
687 687 while (*lpp)
688 688 free(*lpp++);
689 689
690 690 free(save);
691 691 }
692 692
693 693 /*
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
694 694 * Print the list of array of strings in the backup log
695 695 */
696 696 void
697 697 tlm_log_list(char *title, char **lpp)
698 698 {
699 699 int i;
700 700
701 701 if (!lpp)
702 702 return;
703 703
704 - NDMP_LOG(LOG_DEBUG, "%s:", title);
704 + syslog(LOG_DEBUG, "%s:", title);
705 705
706 706 for (i = 0; *lpp; lpp++, i++)
707 - NDMP_LOG(LOG_DEBUG, "%d: [%s]", i, *lpp);
707 + syslog(LOG_DEBUG, "%d: [%s]", i, *lpp);
708 708 }
709 709
710 710 /*
711 711 * Insert the backup snapshot name into the path.
712 712 *
713 713 * Input:
714 714 * name: Original path name.
715 715 *
716 716 * Output:
717 717 * name: Original name modified to include a snapshot.
718 718 *
719 719 * Returns:
720 720 * Original name modified to include a snapshot.
721 721 */
722 722 char *
723 723 tlm_build_snapshot_name(char *name, char *sname, char *jname)
724 724 {
725 725 zfs_handle_t *zhp;
726 - char *rest;
727 - char volname[ZFS_MAX_DATASET_NAME_LEN];
728 - char mountpoint[PATH_MAX];
726 + char volname[ZFS_MAX_DATASET_NAME_LEN] = {'\0'};
727 + char mountpoint[PATH_MAX] = {'\0'};
728 + char zpoolname[ZFS_MAX_DATASET_NAME_LEN] = {'\0'};
729 + char *slash, *rest;
729 730
730 731 if (get_zfsvolname(volname, ZFS_MAX_DATASET_NAME_LEN, name) == -1)
731 732 goto notzfs;
732 733
733 734 (void) mutex_lock(&zlib_mtx);
734 735 if ((zlibh == NULL) ||
735 736 (zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == NULL) {
736 737 (void) mutex_unlock(&zlib_mtx);
737 738 goto notzfs;
738 739 }
739 740
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
740 741 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint, PATH_MAX, NULL,
741 742 NULL, 0, B_FALSE) != 0) {
742 743 zfs_close(zhp);
743 744 (void) mutex_unlock(&zlib_mtx);
744 745 goto notzfs;
745 746 }
746 747
747 748 zfs_close(zhp);
748 749 (void) mutex_unlock(&zlib_mtx);
749 750
751 + (void) strlcpy(zpoolname, volname, ZFS_MAX_DATASET_NAME_LEN);
752 + slash = strchr(zpoolname, '/');
753 + if (slash != 0) {
754 + *slash = '\0';
755 + }
756 +
750 757 rest = name + strlen(mountpoint);
751 - (void) snprintf(sname, TLM_MAX_PATH_NAME, "%s/%s/%s%s", mountpoint,
752 - TLM_SNAPSHOT_DIR, jname, rest);
758 + (void) snprintf(sname,
759 + TLM_MAX_PATH_NAME, "/%s/%s%s", zpoolname, jname, rest);
753 760
754 761 return (sname);
755 762
756 763 notzfs:
757 764 (void) strlcpy(sname, name, TLM_MAX_PATH_NAME);
758 765 return (sname);
759 766 }
760 767
761 768 /*
762 769 * Remove the checkpoint from a path name.
763 770 *
764 771 * Input:
765 772 * name: Full pathname with checkpoint embeded.
766 773 *
767 774 * Output:
768 775 * unchkp_name: real pathname with no checkpoint.
769 776 *
770 777 * Returns:
771 778 * Pointer to the un-checkpointed path.
772 779 */
773 780 char *
774 781 tlm_remove_checkpoint(char *name, char *unchkp_name)
775 782 {
776 783 char *cp;
777 784 int i;
778 785 int plen;
779 786
780 787 unchkp_name[0] = name[0];
781 788 plen = strlen(TLM_SNAPSHOT_PREFIX);
782 789 for (i = 1; i <= TLM_VOLNAME_MAX_LENGTH + 1; i++) {
783 790 switch (name[i]) {
784 791 case '.':
785 792 if (strncmp(&name[i], TLM_SNAPSHOT_PREFIX,
786 793 plen) == 0) {
787 794 unchkp_name[i] = '\0';
788 795 i += plen;
789 796 if (name[i] == '\0') {
790 797 /*
791 798 * name == "/v1.chkpnt"
792 799 */
793 800 return (unchkp_name);
794 801 }
795 802 if ((cp = strchr(&name[++i], '/')) != NULL) {
796 803 (void) strlcat(unchkp_name, cp,
797 804 TLM_VOLNAME_MAX_LENGTH + 1);
798 805 }
799 806 return (unchkp_name);
800 807 } else {
801 808 unchkp_name[i] = name[i];
802 809 }
803 810 break;
804 811 case '/':
805 812 return (name);
806 813 case 0:
807 814 return (name);
808 815 default:
809 816 unchkp_name[i] = name[i];
810 817 break;
811 818 }
812 819 }
813 820 return (name);
814 821 }
815 822
816 823 /*
817 824 * see if we should exclude this file.
818 825 */
|
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
819 826 boolean_t
820 827 tlm_is_excluded(char *dir, char *name, char **excl_files)
821 828 {
822 829 int i;
823 830 char full_name[TLM_MAX_PATH_NAME];
824 831
825 832 if (!dir || !name || !excl_files)
826 833 return (FALSE);
827 834
828 835 if (!tlm_cat_path(full_name, dir, name)) {
829 - NDMP_LOG(LOG_DEBUG, "Path too long [%s][%s]",
836 + syslog(LOG_DEBUG, "Path too long [%s][%s]",
830 837 dir, name);
831 838 return (FALSE);
832 839 }
833 840 for (i = 0; excl_files[i] != 0; i++) {
834 841 if (match(excl_files[i], full_name)) {
835 842 return (TRUE);
836 843 }
837 844 }
838 845 return (FALSE);
839 846 }
840 847
841 848 /*
842 849 * Check if the path is too long
843 850 */
844 851 boolean_t
845 852 tlm_is_too_long(int checkpointed, char *dir, char *nm)
846 853 {
847 854 int nlen, tot;
848 855
849 856 tot = 0;
850 857 if (dir)
851 858 tot += strlen(dir);
852 859 if (checkpointed)
853 860 tot += strlen(TLM_SNAPSHOT_DIR) + 1;
854 861 if (nm) {
855 862 if ((nlen = strlen(nm)) > 0)
856 863 tot += nlen + 1;
857 864 }
858 865 return ((tot >= PATH_MAX) ? TRUE : FALSE);
859 866 }
860 867
861 868 /*
862 869 * Get the data offset of inside the buffer
863 870 */
864 871 longlong_t
865 872 tlm_get_data_offset(tlm_cmd_t *lcmds)
866 873 {
867 874 if (!lcmds)
868 875 return (0LL);
869 876
870 877 return (lcmds->tc_buffers->tbs_offset);
871 878 }
872 879
|
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
873 880 /*
874 881 * Enable the barcode capability on the library
875 882 */
876 883 void
877 884 tlm_enable_barcode(int l)
878 885 {
879 886 tlm_library_t *lp;
880 887
881 888 if ((lp = tlm_library(l))) {
882 889 lp->tl_capability_barcodes = TRUE;
883 - NDMP_LOG(LOG_DEBUG,
890 + syslog(LOG_DEBUG,
884 891 "Barcode capability on library %d enabled.", l);
885 892 }
886 893 }
887 894
888 895 /*
889 896 * SASD SCSI support
890 897 */
891 898 static scsi_adapter_t my_sa;
892 899 static int sasd_drive_count = 0;
893 900 static scsi_sasd_drive_t *scsi_sasd_drives[128];
894 901
895 902 /*
896 903 * Count of SCSI devices
897 904 */
898 905 int
899 906 sasd_dev_count(void)
900 907 {
901 908 return (sasd_drive_count);
902 909 }
903 910
904 911 /*
905 912 * Return the SCSI device name
906 913 */
907 914 char *
908 915 sasd_slink_name(scsi_link_t *slink)
909 916 {
910 917 int i;
911 918
912 919 for (i = 0; i < sasd_drive_count; i++) {
913 920 if (&scsi_sasd_drives[i]->ss_slink == slink)
914 921 return (scsi_sasd_drives[i]->ss_sd.sd_name);
915 922 }
916 923 return (NULL);
917 924 }
918 925
919 926 /*
920 927 * Return the SCSI drive structure
921 928 */
922 929 sasd_drive_t *
923 930 sasd_slink_drive(scsi_link_t *slink)
924 931 {
925 932 int i;
926 933
927 934 for (i = 0; i < sasd_drive_count; i++) {
928 935 if (&scsi_sasd_drives[i]->ss_slink == slink)
929 936 return (&scsi_sasd_drives[i]->ss_sd);
930 937 }
931 938 return (NULL);
932 939 }
933 940
934 941 /*
935 942 * Return the SCSI link pointer for the given index
936 943 */
937 944 scsi_link_t *
938 945 sasd_dev_slink(int entry)
939 946 {
940 947 scsi_link_t *rv;
941 948
942 949 if (entry >= 0 && entry < sasd_drive_count)
943 950 rv = &scsi_sasd_drives[entry]->ss_slink;
944 951 else
945 952 rv = NULL;
946 953
947 954 return (rv);
948 955 }
949 956
950 957 /*
951 958 * Return the SCSI drive for the given index
952 959 */
953 960 sasd_drive_t *
954 961 sasd_drive(int entry)
955 962 {
956 963 sasd_drive_t *rv;
957 964
958 965 if (entry >= 0 && entry < sasd_drive_count)
959 966 rv = &scsi_sasd_drives[entry]->ss_sd;
960 967 else
961 968 rv = NULL;
962 969
963 970 return (rv);
964 971 }
965 972
966 973 /*
967 974 * Attach the SCSI device by updating the structures
968 975 */
969 976 void
970 977 scsi_sasd_attach(scsi_adapter_t *sa, int sid, int lun, char *name,
971 978 int type)
972 979 {
973 980 scsi_link_t *sl, *next;
974 981 scsi_sasd_drive_t *ssd;
975 982
976 983 ssd = ndmp_malloc(sizeof (scsi_sasd_drive_t));
977 984 if (ssd == NULL)
978 985 return;
979 986
980 987 scsi_sasd_drives[sasd_drive_count++] = ssd;
981 988
982 989 switch (type) {
983 990 case DTYPE_CHANGER:
984 991 (void) snprintf(ssd->ss_sd.sd_name,
985 992 sizeof (ssd->ss_sd.sd_name), "%s/%s", SCSI_CHANGER_DIR,
986 993 name);
987 994 break;
988 995 case DTYPE_SEQUENTIAL:
989 996 (void) snprintf(ssd->ss_sd.sd_name,
990 997 sizeof (ssd->ss_sd.sd_name), "%s/%s", SCSI_TAPE_DIR, name);
991 998 break;
992 999 }
993 1000
994 1001 sl = &ssd->ss_slink;
995 1002 sl->sl_type = type;
996 1003 sl->sl_sa = sa;
997 1004 sl->sl_lun = lun;
998 1005 sl->sl_sid = sid;
999 1006 sl->sl_requested_max_active = 1;
1000 1007
1001 1008 /* Insert slink */
1002 1009 next = sa->sa_link_head.sl_next;
1003 1010 sa->sa_link_head.sl_next = sl;
1004 1011 sl->sl_next = next;
1005 1012 }
1006 1013
1007 1014 /*
1008 1015 * Go through the attached devices and detect the tape
1009 1016 * and robot by checking the /dev entries
1010 1017 */
1011 1018 int
1012 1019 probe_scsi(void)
1013 1020 {
1014 1021 DIR *dirp;
1015 1022 struct dirent *dp;
1016 1023 scsi_adapter_t *sa = &my_sa;
1017 1024 char *p;
|
↓ open down ↓ |
124 lines elided |
↑ open up ↑ |
1018 1025 int lun = 0;
1019 1026 int sid = 0;
1020 1027 char *drive_type;
1021 1028
1022 1029 /* Initialize the scsi adapter link */
1023 1030 sa->sa_link_head.sl_next = &sa->sa_link_head;
1024 1031
1025 1032 /* Scan for the changer */
1026 1033 dirp = opendir(SCSI_CHANGER_DIR);
1027 1034 if (dirp == NULL) {
1028 - NDMP_LOG(LOG_DEBUG,
1035 + syslog(LOG_DEBUG,
1029 1036 "Changer directory read error %s", SCSI_CHANGER_DIR);
1030 1037 } else {
1031 1038 while ((dp = readdir(dirp)) != NULL) {
1032 1039 if ((strcmp(dp->d_name, ".") == 0) ||
1033 1040 (strcmp(dp->d_name, "..") == 0))
1034 1041 continue;
1035 1042
1036 1043 if ((p = strchr(dp->d_name, 'd')) != NULL) {
1037 1044 lun = atoi(++p);
1038 1045 p = strchr(dp->d_name, 't');
1039 1046 sid = atoi(++p);
1040 1047 }
1041 1048 else
1042 1049 sid = atoi(dp->d_name);
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1043 1050
1044 1051 scsi_sasd_attach(sa, 0, lun, dp->d_name,
1045 1052 DTYPE_CHANGER);
1046 1053 }
1047 1054 (void) closedir(dirp);
1048 1055 }
1049 1056
1050 1057 /* Scan for tape drives */
1051 1058 dirp = opendir(SCSI_TAPE_DIR);
1052 1059 if (dirp == NULL) {
1053 - NDMP_LOG(LOG_DEBUG,
1060 + syslog(LOG_DEBUG,
1054 1061 "Tape directory read error %s", SCSI_TAPE_DIR);
1055 1062 } else {
1056 1063 drive_type = ndmpd_get_prop(NDMP_DRIVE_TYPE);
1057 1064
1058 1065 if ((strcasecmp(drive_type, "sysv") != 0) &&
1059 1066 (strcasecmp(drive_type, "bsd") != 0)) {
1060 - NDMP_LOG(LOG_ERR, "Invalid ndmpd/drive-type value. "
1067 + syslog(LOG_ERR, "Invalid ndmpd/drive-type value. "
1061 1068 "Valid values are 'sysv' and 'bsd'.");
1062 1069 return (-1);
1063 1070 }
1064 1071
1065 1072 while ((dp = readdir(dirp)) != NULL) {
1066 1073 if ((strcmp(dp->d_name, ".") == 0) ||
1067 1074 (strcmp(dp->d_name, "..") == 0))
1068 1075 continue;
1069 1076
1070 1077 /* Skip special modes */
1071 1078 if (strpbrk(dp->d_name, "chlmu") != NULL)
1072 1079 continue;
1073 1080
1074 1081 /* Pick the non-rewind device */
1075 1082 if (strchr(dp->d_name, 'n') == NULL)
1076 1083 continue;
1077 1084
1078 1085 if (strcasecmp(drive_type, "sysv") == 0) {
1079 1086 if (strchr(dp->d_name, 'b') != NULL)
1080 1087 continue;
1081 1088 } else if (strcasecmp(drive_type, "bsd") == 0) {
1082 1089 if (strchr(dp->d_name, 'b') == NULL)
1083 1090 continue;
1084 1091 }
1085 1092
1086 1093 sid = atoi(dp->d_name);
1087 1094
1088 1095 /*
1089 1096 * SCSI ID should match with the ID of the device
1090 1097 * (will be checked by SCSI get elements page later)
1091 1098 */
1092 1099 scsi_sasd_attach(sa, sid, 0, dp->d_name,
1093 1100 DTYPE_SEQUENTIAL);
1094 1101 }
1095 1102 (void) closedir(dirp);
1096 1103 }
1097 1104
1098 1105 return (0);
1099 1106 }
1100 1107
1101 1108 /*
1102 1109 * Get the SCSI device type (tape, robot)
1103 1110 */
1104 1111 /*ARGSUSED*/
1105 1112 int
1106 1113 scsi_get_devtype(char *adapter, int sid, int lun)
1107 1114 {
1108 1115 int rv;
1109 1116 scsi_adapter_t *sa = &my_sa;
1110 1117 scsi_link_t *sl, *sh;
1111 1118
1112 1119 rv = -1;
1113 1120 sh = &sa->sa_link_head;
1114 1121 for (sl = sh->sl_next; sl != sh; sl = sl->sl_next)
1115 1122 if (sl->sl_sid == sid && sl->sl_lun == lun)
1116 1123 rv = sl->sl_type;
1117 1124
1118 1125 return (rv);
1119 1126 }
1120 1127
1121 1128
1122 1129 /*
1123 1130 * Check if the SCSI device exists
1124 1131 */
1125 1132 /*ARGSUSED*/
1126 1133 int
1127 1134 scsi_dev_exists(char *adapter, int sid, int lun)
1128 1135 {
1129 1136 scsi_adapter_t *sa = &my_sa;
1130 1137 scsi_link_t *sl, *sh;
1131 1138
1132 1139 sh = &sa->sa_link_head;
1133 1140 for (sl = sh->sl_next; sl != sh; sl = sl->sl_next)
1134 1141 if (sl->sl_sid == sid && sl->sl_lun == lun)
1135 1142 return (1);
1136 1143 return (0);
1137 1144 }
1138 1145
1139 1146
1140 1147 /*
1141 1148 * Count of SCSI adapters
1142 1149 */
1143 1150 int
1144 1151 scsi_get_adapter_count(void)
1145 1152 {
1146 1153 /* Currently support one adapter only */
1147 1154 return (1);
1148 1155 }
1149 1156
1150 1157 /*
1151 1158 * Return the SCSI adapter structure
1152 1159 */
1153 1160 /*ARGSUSED*/
1154 1161 scsi_adapter_t *
1155 1162 scsi_get_adapter(int adapter)
1156 1163 {
1157 1164 return (&my_sa);
|
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
1158 1165 }
1159 1166
1160 1167 /*
1161 1168 * IOCTL wrapper with retries
1162 1169 */
1163 1170 int
1164 1171 tlm_ioctl(int fd, int cmd, void *data)
1165 1172 {
1166 1173 int retries = 0;
1167 1174
1168 - NDMP_LOG(LOG_DEBUG, "tlm_ioctl fd %d cmd %d", fd, cmd);
1175 + syslog(LOG_DEBUG, "tlm_ioctl fd %d cmd %d", fd, cmd);
1169 1176 if (fd == 0 || data == NULL)
1170 1177 return (EINVAL);
1171 1178
1172 1179 do {
1173 1180 if (ioctl(fd, cmd, data) == 0)
1174 1181 break;
1175 1182
1176 1183 if (errno != EIO && errno != 0) {
1177 - NDMP_LOG(LOG_ERR,
1184 + syslog(LOG_ERR,
1178 1185 "Failed to send command to device: %m.");
1179 - NDMP_LOG(LOG_DEBUG, "IOCTL error %d", errno);
1186 + syslog(LOG_DEBUG, "IOCTL error %d", errno);
1180 1187 return (errno);
1181 1188 }
1182 1189 (void) sleep(1);
1183 1190 } while (retries++ < MAXIORETRY);
1184 1191
1185 1192 return (0);
1186 1193 }
1187 1194
1188 1195 /*
1189 1196 * Checkpoint or snapshot calls
1190 1197 */
1191 1198
1192 1199 /*
1193 1200 * Get the snapshot creation time
1194 1201 */
1195 1202 int
1196 1203 chkpnt_creationtime_bypattern(char *volname, char *pattern, time_t *tp)
1197 1204 {
1198 1205 char chk_name[PATH_MAX];
1199 1206 zfs_handle_t *zhp;
1200 1207 char *p;
1201 1208
1202 1209 if (!volname || !*volname)
1203 1210 return (-1);
1204 1211
1205 1212 /* Should also return -1 if checkpoint not enabled */
1206 1213
1207 1214 /* Remove the leading slash */
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
1208 1215 p = volname;
1209 1216 while (*p == '/')
1210 1217 p++;
1211 1218
1212 1219 (void) strlcpy(chk_name, p, PATH_MAX);
1213 1220 (void) strlcat(chk_name, "@", PATH_MAX);
1214 1221 (void) strlcat(chk_name, pattern, PATH_MAX);
1215 1222
1216 1223 (void) mutex_lock(&zlib_mtx);
1217 1224 if ((zhp = zfs_open(zlibh, chk_name, ZFS_TYPE_DATASET)) == NULL) {
1218 - NDMP_LOG(LOG_DEBUG, "chkpnt_creationtime: open %s failed",
1225 + syslog(LOG_DEBUG, "chkpnt_creationtime: open %s failed",
1219 1226 chk_name);
1220 1227 (void) mutex_unlock(&zlib_mtx);
1221 1228 return (-1);
1222 1229 }
1223 1230
1224 1231 *tp = zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
1225 1232 zfs_close(zhp);
1226 1233 (void) mutex_unlock(&zlib_mtx);
1227 1234
1228 1235 return (0);
1229 1236 }
1230 1237
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
1231 1238
1232 1239 /*
1233 1240 * Get the ZFS volume name out of the given path
1234 1241 */
1235 1242 int
1236 1243 get_zfsvolname(char *volname, int len, char *path)
1237 1244 {
1238 1245 struct stat64 stbuf;
1239 1246 struct extmnttab ent;
1240 1247 FILE *mntfp;
1241 - int rv;
1248 + int rv = 0;
1242 1249
1243 1250 *volname = '\0';
1244 1251 if (stat64(path, &stbuf) != 0) {
1252 + syslog(LOG_DEBUG, "stat64 failed open %s - %s",
1253 + volname, path);
1245 1254 return (-1);
1246 1255 }
1247 1256
1248 1257 if ((mntfp = fopen(MNTTAB, "r")) == NULL) {
1258 + syslog(LOG_DEBUG, "failed open mnttab");
1249 1259 return (-1);
1250 1260 }
1251 1261 while ((rv = getextmntent(mntfp, &ent, 0)) == 0) {
1252 1262 if (makedevice(ent.mnt_major, ent.mnt_minor) ==
1253 1263 stbuf.st_dev)
1254 1264 break;
1255 1265 }
1256 1266
1257 1267 if (rv == 0 &&
1258 - strcmp(ent.mnt_fstype, MNTTYPE_ZFS) == 0)
1268 + strcmp(ent.mnt_fstype, MNTTYPE_ZFS) == 0) {
1259 1269 (void) strlcpy(volname, ent.mnt_special, len);
1260 - else
1270 + } else {
1261 1271 rv = -1;
1262 -
1272 + }
1263 1273 (void) fclose(mntfp);
1264 1274 return (rv);
1265 1275 }
1266 1276
1267 1277
1268 1278 /*
1269 1279 * Check if the volume type is snapshot volume
1270 1280 */
1271 1281 boolean_t
1272 1282 fs_is_chkpntvol(char *path)
1273 1283 {
1274 1284 zfs_handle_t *zhp;
1275 1285 char vol[ZFS_MAX_DATASET_NAME_LEN];
1276 1286
1277 1287 if (!path || !*path)
1278 1288 return (FALSE);
1279 1289
1280 1290 if (get_zfsvolname(vol, sizeof (vol), path) == -1)
1281 1291 return (FALSE);
1282 1292
1283 1293 (void) mutex_lock(&zlib_mtx);
1284 1294 if ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) == NULL) {
1285 1295 (void) mutex_unlock(&zlib_mtx);
1286 1296 return (FALSE);
1287 1297 }
1288 1298
1289 1299 if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) {
1290 1300 zfs_close(zhp);
1291 1301 (void) mutex_unlock(&zlib_mtx);
1292 1302 return (FALSE);
1293 1303 }
1294 1304 zfs_close(zhp);
1295 1305 (void) mutex_unlock(&zlib_mtx);
1296 1306
1297 1307 return (TRUE);
1298 1308 }
1299 1309
1300 1310 /*
1301 1311 * Check if the volume is capable of checkpoints
1302 1312 */
1303 1313 boolean_t
1304 1314 fs_is_chkpnt_enabled(char *path)
1305 1315 {
1306 1316 zfs_handle_t *zhp;
1307 1317 char vol[ZFS_MAX_DATASET_NAME_LEN];
1308 1318
1309 1319 if (!path || !*path)
1310 1320 return (FALSE);
1311 1321
1312 1322 (void) mutex_lock(&zlib_mtx);
1313 1323 if (get_zfsvolname(vol, sizeof (vol), path) == -1) {
1314 1324 (void) mutex_unlock(&zlib_mtx);
1315 1325 return (FALSE);
1316 1326 }
1317 1327
1318 1328 if ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) == NULL) {
1319 1329 (void) mutex_unlock(&zlib_mtx);
1320 1330 return (FALSE);
1321 1331 }
1322 1332 zfs_close(zhp);
1323 1333 (void) mutex_unlock(&zlib_mtx);
1324 1334
1325 1335 return (TRUE);
1326 1336 }
1327 1337
1328 1338 /*
1329 1339 * Check if the volume is read-only
1330 1340 */
1331 1341 boolean_t
1332 1342 fs_is_rdonly(char *path)
1333 1343 {
1334 1344 return (fs_is_chkpntvol(path));
1335 1345 }
1336 1346
1337 1347 /*
1338 1348 * Min/max functions
1339 1349 */
1340 1350 unsigned
1341 1351 min(unsigned a, unsigned b)
1342 1352 {
1343 1353 return (a < b ? a : b);
1344 1354 }
1345 1355
1346 1356 unsigned
1347 1357 max(unsigned a, unsigned b)
1348 1358 {
1349 1359 return (a > b ? a : b);
1350 1360 }
1351 1361
1352 1362 longlong_t
1353 1363 llmin(longlong_t a, longlong_t b)
1354 1364 {
1355 1365 return (a < b ? a : b);
1356 1366 }
|
↓ open down ↓ |
84 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX