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