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