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