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 <stdlib.h> 40 #include <ctype.h> 41 #include <stdio.h> 42 #include <limits.h> 43 #include <string.h> 44 #include <time.h> 45 #include <sys/types.h> 46 #include <sys/acl.h> 47 #include <utime.h> 48 #include <unistd.h> 49 #include <pthread.h> 50 #include <archives.h> 51 #include <priv.h> 52 #include <tlm.h> 53 #include <libzfs.h> 54 #include <ndmpd_prop.h> 55 #include "tlm_proto.h" 56 57 58 #define PM_EXACT_OR_CHILD(m) ((m) == PM_EXACT || (m) == PM_CHILD) 59 60 typedef boolean_t name_match_fp_t(char *s, char *t); 61 62 static void set_acl(char *name, 63 tlm_acls_t *acls); 64 static long restore_file(int *fp, 65 char *real_name, 66 long size, 67 longlong_t huge_size, 68 tlm_acls_t *, 69 boolean_t want_this_file, 70 tlm_cmd_t *, 71 tlm_job_stats_t *); 72 static long restore_xattr_hdr(int *fp, 73 char *name, 74 char *fname, 75 long size, 76 tlm_acls_t *acls, 77 tlm_cmd_t *local_commands, 78 tlm_job_stats_t *job_stats); 79 static int get_long_name(int lib, 80 int drv, 81 long recsize, 82 char *name, 83 long *buf_spot, 84 tlm_cmd_t *local_commands); 85 static int get_humongus_file_header(int lib, 86 int drv, 87 long recsize, 88 longlong_t *size, 89 char *name, 90 tlm_cmd_t *); 91 static int create_directory(char *dir, 92 tlm_job_stats_t *); 93 static int create_hard_link(char *name, 94 char *link, 95 tlm_acls_t *, 96 tlm_job_stats_t *); 97 static int create_sym_link(char *dst, 98 char *target, 99 tlm_acls_t *, 100 tlm_job_stats_t *); 101 static int create_fifo(char *name, 102 tlm_acls_t *); 103 static long load_acl_info(int lib, 104 int drv, 105 long size, 106 tlm_acls_t *, 107 long *acl_spot, 108 tlm_cmd_t *); 109 static char *get_read_buffer(int want, 110 int *error, 111 int *actual_size, 112 tlm_cmd_t *); 113 static boolean_t wildcard_enabled(void); 114 static boolean_t is_file_wanted(char *name, 115 char **sels, 116 char **exls, 117 int flags, 118 int *mchtype, 119 int *pos); 120 static char *catnames(struct rs_name_maker *rnp, 121 char *buf, 122 int pos, 123 char *path); 124 125 static char *rs_new_name(struct rs_name_maker *rnp, 126 char *real_name, 127 int pos, 128 char *path); 129 130 typedef struct stack_ent { 131 char *se_name; 132 tlm_acls_t se_acls; 133 } stack_ent_t; 134 135 136 /* 137 * dtree_push 138 */ 139 int 140 dtree_push(cstack_t *stp, char *nmp, tlm_acls_t *acls) 141 { 142 int len; 143 stack_ent_t *sp; 144 145 sp = ndmp_malloc(sizeof (stack_ent_t)); 146 if (!sp || !nmp || !acls) { 147 free(sp); 148 return (-1); 149 } 150 151 len = strlen(nmp) + 1; 152 sp->se_name = ndmp_malloc(len); 153 if (!sp->se_name) { 154 free(sp); 155 return (-1); 156 } 157 158 (void) strlcpy(sp->se_name, nmp, len); 159 (void) memcpy(&sp->se_acls, acls, sizeof (*acls)); 160 161 return (cstack_push(stp, (void *)sp, sizeof (*sp))); 162 } 163 164 /* 165 * dtree_pop 166 */ 167 int 168 dtree_pop(cstack_t *stp) 169 { 170 int err; 171 stack_ent_t *sp; 172 173 err = cstack_pop(stp, (void **)&sp, (void *)NULL); 174 if (err) 175 return (-1); 176 177 set_acl(sp->se_name, &sp->se_acls); 178 179 free(sp->se_name); 180 free(sp); 181 return (err); 182 } 183 184 185 /* 186 * dtree_peek 187 */ 188 char * 189 dtree_peek(cstack_t *stp) 190 { 191 int err; 192 stack_ent_t *sp; 193 194 err = cstack_top(stp, (void **)&sp, (void *)NULL); 195 if (err) 196 return (NULL); 197 198 return (sp->se_name); 199 } 200 201 /* 202 * NBU and EBS may not send us the correct file list containing hardlinks 203 * during a DAR restore, e.g. they appear always send the first name 204 * associated with an inode, even if other link names were 205 * selected for the restore. As a workaround, we use the file name entry 206 * in sels[] (ignore the name in the tar header) as restore target. 207 */ 208 static char * 209 rs_darhl_new_name(struct rs_name_maker *rnp, char *name, char **sels, int *pos, 210 char *longname) 211 { 212 int x; 213 214 for (x = 0; sels[x] != NULL; x++) { 215 if (strcmp(sels[x], " ")) { 216 *pos = x; 217 (void) strlcpy(longname, sels[x], TLM_MAX_PATH_NAME); 218 NDMP_LOG(LOG_DEBUG, 219 "to replace hardlink name [%s], pos [%d]", 220 longname, *pos); 221 222 return (rs_new_name(rnp, name, *pos, longname)); 223 } 224 } 225 226 return (NULL); 227 } 228 229 230 /* 231 * Main dir restore funciton for tar 232 */ 233 int 234 tar_getdir(tlm_commands_t *commands, 235 tlm_cmd_t *local_commands, 236 tlm_job_stats_t *job_stats, 237 struct rs_name_maker *rnp, 238 int lib, 239 int drv, 240 char **sels, /* what to get off the tape */ 241 char **exls, /* what to leave behind */ 242 int flags, 243 int DAR, struct hardlink_q *hardlink_q) 244 { 245 int fp = 0; /* file being restored ... */ 246 /* ...need to preserve across volume changes */ 247 tlm_acls_t *acls; /* file access info */ 248 char *longname; 249 boolean_t is_long_name = FALSE; 250 char *longlink; 251 char *hugename; 252 longlong_t huge_size = 0; /* size of a HUGE file */ 253 long acl_spot; /* any ACL info on the next volume */ 254 long file_size; /* size of file to restore */ 255 long size_left = 0; /* need this after volume change */ 256 int last_action = 0; /* what we are doing at EOT */ 257 boolean_t multi_volume = FALSE; /* is this a multi-volume switch ? */ 258 int chk_rv; /* scratch area */ 259 260 int mchtype, pos; 261 /* 262 * if an exact match is found for 263 * restore and its position in the 264 * selections list 265 */ 266 int nzerohdr; /* the number of empty tar headers */ 267 boolean_t break_flg; /* exit the while loop */ 268 int rv; 269 long nm_end, lnk_end; 270 char *name, *nmp; 271 cstack_t *stp; 272 char *bkpath; 273 char *parentlnk; 274 /* 275 * The directory where temporary files may be created during a partial 276 * non-DAR restore of hardlinks. It is intended to be initialized by 277 * an environment variable that can be set by user. 278 * 279 * It is not initialized for now. We keep it here for future use. 280 */ 281 char *tmplink_dir = NULL; 282 283 /* 284 * startup 285 */ 286 287 longname = ndmp_malloc(TLM_MAX_PATH_NAME); 288 longlink = ndmp_malloc(TLM_MAX_PATH_NAME); 289 hugename = ndmp_malloc(TLM_MAX_PATH_NAME); 290 parentlnk = ndmp_malloc(TLM_MAX_PATH_NAME); 291 name = ndmp_malloc(TLM_MAX_PATH_NAME); 292 acls = ndmp_malloc(sizeof (tlm_acls_t)); 293 stp = cstack_new(); 294 if (longname == NULL || longlink == NULL || hugename == NULL || 295 name == NULL || acls == NULL || stp == NULL || parentlnk == NULL) { 296 cstack_delete(stp); 297 free(longname); 298 free(longlink); 299 free(hugename); 300 free(parentlnk); 301 free(name); 302 free(acls); 303 return (-TLM_NO_SCRATCH_SPACE); 304 } 305 306 acl_spot = 0; 307 *hugename = '\0'; 308 *parentlnk = '\0'; 309 nm_end = 0; 310 *longname = '\0'; 311 lnk_end = 0; 312 *longlink = '\0'; 313 (void) memset(acls, 0, sizeof (tlm_acls_t)); 314 if (IS_SET(flags, RSFLG_OVR_ALWAYS)) { 315 acls->acl_overwrite = TRUE; 316 NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_ALWAYS"); 317 } else if (IS_SET(flags, RSFLG_OVR_UPDATE)) { 318 acls->acl_update = TRUE; 319 NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_UPDATE"); 320 } 321 322 /* 323 * work 324 */ 325 rv = 0; 326 nzerohdr = 0; 327 break_flg = FALSE; 328 while (commands->tcs_writer != TLM_ABORT && 329 local_commands->tc_writer != TLM_STOP) { 330 tlm_tar_hdr_t fake_tar_hdr; 331 char *file_name; 332 char *link_name; 333 int erc; 334 int actual_size; 335 boolean_t want_this_file; 336 int want = sizeof (tlm_tar_hdr_t); 337 tlm_tar_hdr_t *tar_hdr; 338 339 /* The inode of an LF_LINK type. */ 340 unsigned long hardlink_inode = 0; 341 342 /* 343 * Indicate whether a file with the same inode has been 344 * restored. 345 */ 346 int hardlink_done = 0; 347 348 /* The path of the restored hardlink file */ 349 char *hardlink_target = NULL; 350 int is_hardlink = 0; 351 352 /* 353 * Whether a temporary file should be created for restoring 354 * hardlink. 355 */ 356 int hardlink_tmp_file = 0; 357 char *hardlink_tmp_name = ".tmphlrsnondar"; 358 359 /* used to make up hardlink_tmp_name */ 360 static int hardlink_tmp_idx = 0; 361 362 if (break_flg) { 363 NDMP_LOG(LOG_DEBUG, 364 "Exiting writer thread drive %d", drv); 365 break; 366 } 367 368 if (multi_volume) { 369 NDMP_LOG(LOG_DEBUG, "multi_volume %c %d", 370 last_action, size_left); 371 372 /* 373 * the previous volume is out of data 374 * and is back in the rack, a new tape 375 * is loaded and ready to read. 376 * 377 * We need to pick up where we left off. 378 */ 379 (void) memset(&fake_tar_hdr, 0, sizeof (fake_tar_hdr)); 380 file_size = size_left; 381 tar_hdr = &fake_tar_hdr; 382 tar_hdr->th_linkflag = last_action; 383 384 multi_volume = FALSE; 385 last_action = 0; 386 } else { 387 tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(want, 388 &erc, &actual_size, local_commands); 389 /* 390 * we can ignore read errors here because 391 * 1) they are logged by Restore Reader 392 * 2) we are not doing anything important here 393 * just looking for the next work record. 394 */ 395 if (actual_size < want) { 396 /* 397 * EOF hits here 398 * 399 * wait for another buffer to come along 400 * or until the Reader thread tells us 401 * that no more tapes will be loaded ... 402 * time to stop. 403 */ 404 continue; 405 } 406 407 /* 408 * check for "we are lost" 409 */ 410 chk_rv = tlm_vfy_tar_checksum(tar_hdr); 411 if (chk_rv == 0) { 412 /* one of the end of tar file marks */ 413 if (++nzerohdr >= 2) { 414 NDMP_LOG(LOG_DEBUG, 415 "nzerohdr %d, breaking", 416 nzerohdr); 417 /* end of tar file */ 418 break; 419 } 420 NDMP_LOG(LOG_DEBUG, "nzerohdr %d, continuing", 421 nzerohdr); 422 continue; 423 } else if (chk_rv < 0) { 424 nzerohdr = 0; 425 /* skip this record */ 426 continue; 427 } 428 nzerohdr = 0; 429 430 /* 431 * When files are spanned to the next tape, the 432 * information of the acls must not be over-written 433 * by the information of the LF_MULTIVOL and LF_VOLHDR 434 * header, whose information is irrelevant to the file. 435 * The information of the original header must be 436 * kept in the 'acl'. 437 */ 438 if (tar_hdr->th_linkflag != LF_MULTIVOL && 439 tar_hdr->th_linkflag != LF_VOLHDR) { 440 acls->acl_attr.st_mode = 441 oct_atoi(tar_hdr->th_mode); 442 acls->acl_attr.st_size = 443 oct_atoi(tar_hdr->th_size); 444 acls->acl_attr.st_uid = 445 oct_atoi(tar_hdr->th_uid); 446 acls->acl_attr.st_gid = 447 oct_atoi(tar_hdr->th_gid); 448 acls->acl_attr.st_mtime = 449 oct_atoi(tar_hdr->th_mtime); 450 file_size = oct_atoi(tar_hdr->th_size); 451 acl_spot = 0; 452 last_action = tar_hdr->th_linkflag; 453 } 454 } 455 456 NDMP_LOG(LOG_DEBUG, "n [%s] f [%c] s %lld m %o u %d g %d t %d", 457 tar_hdr->th_name, tar_hdr->th_linkflag, 458 acls->acl_attr.st_size, acls->acl_attr.st_mode, 459 acls->acl_attr.st_uid, acls->acl_attr.st_gid, 460 acls->acl_attr.st_mtime); 461 462 switch (tar_hdr->th_linkflag) { 463 case LF_MULTIVOL: 464 multi_volume = TRUE; 465 break; 466 case LF_LINK: 467 is_hardlink = 1; 468 hardlink_inode = 469 oct_atoi(tar_hdr->th_shared.th_hlink_ino); 470 471 /* 472 * Check if we have restored a link with the same inode 473 * If the inode is 0, we have to restore it as a 474 * regular file. 475 */ 476 if (hardlink_inode) { 477 hardlink_done = !hardlink_q_get(hardlink_q, 478 hardlink_inode, 0, &hardlink_target); 479 } 480 481 if (hardlink_done) { 482 NDMP_LOG(LOG_DEBUG, 483 "found hardlink, inode = %u, target = [%s]", 484 hardlink_inode, 485 hardlink_target? hardlink_target : "--"); 486 487 /* create a hardlink to hardlink_target */ 488 file_name = (*longname == 0) ? 489 tar_hdr->th_name : longname; 490 if (!is_file_wanted(file_name, sels, exls, 491 flags, &mchtype, &pos)) { 492 nmp = NULL; 493 /* 494 * This means that DMA did not send us 495 * the correct fh_info for the file 496 * in restore list. We use the file 497 * name entry in sels[] (ignore the 498 * name in the tar header) as restore 499 * target. 500 */ 501 if (DAR) { 502 nmp = rs_darhl_new_name(rnp, 503 name, sels, &pos, 504 file_name); 505 } 506 } else { 507 nmp = rs_new_name(rnp, name, pos, 508 file_name); 509 if (!nmp) { 510 NDMP_LOG(LOG_DEBUG, 511 "can't make name for %s", 512 longname); 513 } 514 } 515 516 if (nmp) { 517 if (hardlink_target) { 518 erc = create_hard_link( 519 hardlink_target, nmp, 520 acls, job_stats); 521 if (erc == 0) { 522 (void) 523 tlm_entry_restored( 524 job_stats, 525 file_name, pos); 526 NDMP_LOG(LOG_DEBUG, 527 "restored %s -> %s", 528 nmp, 529 hardlink_target); 530 } 531 } else { 532 NDMP_LOG(LOG_DEBUG, 533 "no target for hardlink %s", 534 nmp); 535 } 536 537 name[0] = 0; 538 is_long_name = FALSE; 539 } 540 541 nm_end = 0; 542 longname[0] = 0; 543 lnk_end = 0; 544 longlink[0] = 0; 545 546 break; 547 } 548 /* otherwise fall through, restore like a normal file */ 549 /*FALLTHROUGH*/ 550 case LF_OLDNORMAL: 551 /* 552 * check for TAR's end-of-tape method 553 * of zero filled records. 554 */ 555 if (tar_hdr->th_name[0] == 0) { 556 break; 557 } 558 /* 559 * otherwise fall through, 560 * this is an old style normal file header 561 */ 562 /*FALLTHROUGH*/ 563 case LF_NORMAL: 564 case LF_CONTIG: 565 job_stats->js_files_so_far++; 566 if (*hugename != 0) { 567 (void) strlcpy(longname, hugename, 568 TLM_MAX_PATH_NAME); 569 } else if (*longname == 0) { 570 if (tar_hdr->th_name[0] != '/') { 571 /* 572 * check for old tar format, it 573 * does not have a leading "/" 574 */ 575 longname[0] = '/'; 576 longname[1] = 0; 577 (void) strlcat(longname, 578 tar_hdr->th_name, 579 TLM_MAX_PATH_NAME); 580 } else { 581 (void) strlcpy(longname, 582 tar_hdr->th_name, 583 TLM_MAX_PATH_NAME); 584 } 585 } 586 587 want_this_file = is_file_wanted(longname, sels, exls, 588 flags, &mchtype, &pos); 589 if (!want_this_file) { 590 nmp = NULL; 591 /* 592 * This means that DMA did not send us valid 593 * fh_info for the file in restore list. We 594 * use the file name entry in sels[] (ignore 595 * the name in the tar header) as restore 596 * target. 597 */ 598 if (DAR && (tar_hdr->th_linkflag == LF_LINK)) { 599 nmp = rs_darhl_new_name(rnp, name, 600 sels, &pos, longname); 601 602 if (nmp) { 603 want_this_file = TRUE; 604 mchtype = PM_EXACT; 605 } else { 606 break_flg = TRUE; 607 break; 608 } 609 } 610 } else { 611 nmp = rs_new_name(rnp, name, pos, longname); 612 if (!nmp) 613 want_this_file = FALSE; 614 } 615 616 if (nmp) 617 (void) strlcpy(parentlnk, nmp, strlen(nmp) + 1); 618 619 /* 620 * For a hardlink, even if it's not asked to be 621 * restored, we restore it to a temporary location, 622 * in case other links to the same file need to be 623 * restored later. 624 * 625 * The temp files are created in tmplink_dir, with 626 * names like ".tmphlrsnondar*". They are cleaned up 627 * at the completion of a restore. However, if a 628 * restore were interrupted, e.g. by a system reboot, 629 * they would have to be cleaned up manually in order 630 * for the disk space to be freed. 631 * 632 * If tmplink_dir is NULL, no temperorary files are 633 * created during a restore. This may result in some 634 * hardlinks not being restored during a partial 635 * restore. 636 */ 637 if (is_hardlink && !DAR && !want_this_file && !nmp) { 638 if (tmplink_dir) { 639 (void) snprintf(name, TLM_MAX_PATH_NAME, 640 "%s/%s_%d", tmplink_dir, 641 hardlink_tmp_name, 642 hardlink_tmp_idx); 643 nmp = name; 644 645 hardlink_tmp_idx++; 646 hardlink_tmp_file = 1; 647 want_this_file = TRUE; 648 NDMP_LOG(LOG_DEBUG, 649 "To restore temp hardlink file %s.", 650 nmp); 651 } else { 652 NDMP_LOG(LOG_DEBUG, 653 "No tmplink_dir specified."); 654 } 655 } 656 657 size_left = restore_file(&fp, nmp, file_size, 658 huge_size, acls, want_this_file, local_commands, 659 job_stats); 660 661 /* 662 * In the case of non-DAR, we have to record the first 663 * link for an inode that has multiple links. That's 664 * the only link with data records actually backed up. 665 * In this way, when we run into the other links, they 666 * will be treated as links, and we won't go to look 667 * for the data records to restore. This is not a 668 * problem for DAR, where DMA tells the tape where 669 * to locate the data records. 670 */ 671 if (is_hardlink && !DAR) { 672 if (hardlink_q_add(hardlink_q, hardlink_inode, 673 0, nmp, hardlink_tmp_file)) 674 NDMP_LOG(LOG_DEBUG, 675 "failed to add (%u, %s) to HL q", 676 hardlink_inode, nmp); 677 } 678 679 /* remove / reverse the temporary stuff */ 680 if (hardlink_tmp_file) { 681 nmp = NULL; 682 want_this_file = FALSE; 683 hardlink_tmp_file = 0; 684 } 685 686 /* 687 * Check if it is time to set the attribute 688 * of the restored directory 689 */ 690 while (nmp && ((bkpath = dtree_peek(stp)) != NULL)) { 691 if (strstr(nmp, bkpath)) 692 break; 693 694 (void) dtree_pop(stp); 695 } 696 697 NDMP_LOG(LOG_DEBUG, "sizeleft %s %d, %lld", longname, 698 size_left, huge_size); 699 700 if (size_left == -TLM_STOP) { 701 break_flg = TRUE; 702 rv = -1; 703 commands->tcs_reader = TLM_ABORT; 704 NDMP_LOG(LOG_DEBUG, "restoring [%s] failed", 705 longname); 706 break; 707 } 708 709 if (want_this_file) { 710 job_stats->js_bytes_total += file_size; 711 job_stats->js_files_total++; 712 } 713 714 huge_size -= file_size; 715 if (huge_size < 0) { 716 huge_size = 0; 717 } 718 if (size_left == 0 && huge_size == 0) { 719 if (PM_EXACT_OR_CHILD(mchtype)) { 720 (void) tlm_entry_restored(job_stats, 721 longname, pos); 722 723 /* 724 * Add an entry to hardlink_q to record 725 * this hardlink. 726 */ 727 if (is_hardlink) { 728 NDMP_LOG(LOG_DEBUG, 729 "Restored hardlink file %s", 730 nmp); 731 732 if (DAR) { 733 (void) hardlink_q_add( 734 hardlink_q, 735 hardlink_inode, 0, 736 nmp, 0); 737 } 738 } 739 } 740 741 nm_end = 0; 742 longname[0] = 0; 743 lnk_end = 0; 744 longlink[0] = 0; 745 hugename[0] = 0; 746 name[0] = 0; 747 is_long_name = FALSE; 748 } 749 break; 750 case LF_XATTR: 751 file_name = (*longname == 0) ? tar_hdr->th_name : 752 longname; 753 754 size_left = restore_xattr_hdr(&fp, parentlnk, 755 file_name, file_size, acls, local_commands, 756 job_stats); 757 758 break; 759 case LF_SYMLINK: 760 file_name = (*longname == 0) ? tar_hdr->th_name : 761 longname; 762 link_name = (*longlink == 0) ? 763 tar_hdr->th_linkname : longlink; 764 NDMP_LOG(LOG_DEBUG, "file_name[%s]", file_name); 765 NDMP_LOG(LOG_DEBUG, "link_name[%s]", link_name); 766 if (is_file_wanted(file_name, sels, exls, flags, 767 &mchtype, &pos)) { 768 nmp = rs_new_name(rnp, name, pos, file_name); 769 if (nmp) { 770 erc = create_sym_link(nmp, link_name, 771 acls, job_stats); 772 if (erc == 0 && 773 PM_EXACT_OR_CHILD(mchtype)) 774 (void) tlm_entry_restored( 775 job_stats, file_name, pos); 776 name[0] = 0; 777 } 778 } 779 nm_end = 0; 780 longname[0] = 0; 781 lnk_end = 0; 782 longlink[0] = 0; 783 break; 784 case LF_DIR: 785 file_name = *longname == 0 ? tar_hdr->th_name : 786 longname; 787 if (is_file_wanted(file_name, sels, exls, flags, 788 &mchtype, &pos)) { 789 nmp = rs_new_name(rnp, name, pos, file_name); 790 if (nmp && mchtype != PM_PARENT) { 791 (void) strlcpy(parentlnk, nmp, 792 strlen(nmp)); 793 erc = create_directory(nmp, job_stats); 794 if (erc == 0 && 795 PM_EXACT_OR_CHILD(mchtype)) 796 (void) tlm_entry_restored( 797 job_stats, file_name, pos); 798 /* 799 * Check if it is time to set 800 * the attribute of the restored 801 * directory 802 */ 803 while ((bkpath = dtree_peek(stp)) 804 != NULL) { 805 if (strstr(nmp, bkpath)) 806 break; 807 (void) dtree_pop(stp); 808 } 809 810 (void) dtree_push(stp, nmp, acls); 811 name[0] = 0; 812 } 813 } 814 nm_end = 0; 815 longname[0] = 0; 816 lnk_end = 0; 817 longlink[0] = 0; 818 break; 819 case LF_FIFO: 820 file_name = *longname == 0 ? tar_hdr->th_name : 821 longname; 822 if (is_file_wanted(file_name, sels, exls, flags, 823 &mchtype, &pos)) { 824 nmp = rs_new_name(rnp, name, pos, file_name); 825 if (nmp) { 826 erc = create_fifo(nmp, acls); 827 if (erc == 0 && 828 PM_EXACT_OR_CHILD(mchtype)) 829 (void) tlm_entry_restored( 830 job_stats, file_name, pos); 831 name[0] = 0; 832 } 833 } 834 nm_end = 0; 835 longname[0] = 0; 836 lnk_end = 0; 837 longlink[0] = 0; 838 break; 839 case LF_LONGLINK: 840 file_size = min(file_size, TLM_MAX_PATH_NAME - lnk_end); 841 file_size = max(0, file_size); 842 size_left = get_long_name(lib, drv, file_size, longlink, 843 &lnk_end, local_commands); 844 845 if (size_left != 0) 846 NDMP_LOG(LOG_DEBUG, 847 "fsize %d sleft %d lnkend %d", 848 file_size, size_left, lnk_end); 849 break; 850 case LF_LONGNAME: 851 file_size = min(file_size, TLM_MAX_PATH_NAME - nm_end); 852 file_size = max(0, file_size); 853 size_left = get_long_name(lib, drv, file_size, longname, 854 &nm_end, local_commands); 855 856 if (size_left != 0) 857 NDMP_LOG(LOG_DEBUG, 858 "fsize %d sleft %d nmend %d", 859 file_size, size_left, nm_end); 860 is_long_name = TRUE; 861 break; 862 case LF_ACL: 863 size_left = load_acl_info(lib, drv, file_size, acls, 864 &acl_spot, local_commands); 865 break; 866 case LF_VOLHDR: 867 break; 868 case LF_HUMONGUS: 869 (void) memset(hugename, 0, TLM_MAX_PATH_NAME); 870 (void) get_humongus_file_header(lib, drv, file_size, 871 &huge_size, hugename, local_commands); 872 break; 873 default: 874 break; 875 876 } 877 878 /* 879 * If the restore is running using DAR we should check for 880 * long file names and HUGE file sizes. 881 */ 882 if (DAR && tar_hdr->th_linkflag != LF_ACL && 883 !huge_size && !is_long_name) 884 break; 885 } 886 887 /* 888 * tear down 889 */ 890 if (fp != 0) { 891 (void) close(fp); 892 } 893 while (dtree_pop(stp) != -1) 894 ; 895 cstack_delete(stp); 896 free(acls); 897 free(longname); 898 free(parentlnk); 899 free(longlink); 900 free(hugename); 901 free(name); 902 return (rv); 903 } 904 905 /* 906 * Main file restore function for tar (should run as a thread) 907 */ 908 int 909 tar_getfile(tlm_backup_restore_arg_t *argp) 910 { 911 tlm_job_stats_t *job_stats; 912 char **sels; /* list of files desired */ 913 char **exls; /* list of files not wanted */ 914 char *dir; /* where to restore the files */ 915 char job[TLM_MAX_BACKUP_JOB_NAME+1]; 916 /* the restore job name */ 917 int erc; /* error return codes */ 918 int flags; 919 struct rs_name_maker rn; 920 tlm_commands_t *commands; 921 tlm_cmd_t *local_commands; 922 char *list = NULL; 923 924 commands = argp->ba_commands; 925 local_commands = argp->ba_cmd; 926 927 flags = 0; 928 929 dir = ndmp_malloc(TLM_MAX_PATH_NAME); 930 if (dir == NULL) { 931 local_commands->tc_reader = TLM_STOP; 932 (void) pthread_barrier_wait(&argp->ba_barrier); 933 return (-1); 934 } 935 936 (void) strlcpy(job, argp->ba_job, TLM_MAX_BACKUP_JOB_NAME+1); 937 (void) strlcpy(dir, argp->ba_dir, TLM_MAX_PATH_NAME); 938 939 flags |= RSFLG_OVR_ALWAYS; 940 flags |= RSFLG_IGNORE_CASE; 941 942 /* 943 * do not test for "dir" having no string, since that 944 * is a legal condition. Restore to origional location 945 * will not have a restore directory. 946 */ 947 if (*job == '\0') { 948 NDMP_LOG(LOG_DEBUG, "No job defined"); 949 local_commands->tc_reader = TLM_STOP; 950 free(dir); 951 (void) pthread_barrier_wait(&argp->ba_barrier); 952 return (-1); 953 } 954 955 sels = argp->ba_sels; 956 if (sels == NULL) { 957 local_commands->tc_reader = TLM_STOP; 958 free(dir); 959 (void) pthread_barrier_wait(&argp->ba_barrier); 960 return (-1); 961 } 962 exls = &list; 963 964 tlm_log_list("selections", sels); 965 tlm_log_list("exclusions", exls); 966 967 if (wildcard_enabled()) 968 flags |= RSFLG_MATCH_WCARD; 969 970 local_commands->tc_ref++; 971 commands->tcs_writer_count++; 972 973 /* 974 * let the launcher continue 975 */ 976 (void) pthread_barrier_wait(&argp->ba_barrier); 977 978 job_stats = tlm_ref_job_stats(job); 979 980 rn.rn_fp = catnames; 981 rn.rn_nlp = dir; 982 983 /* 984 * work 985 */ 986 NDMP_LOG(LOG_DEBUG, "start restore job %s", job); 987 erc = tar_getdir(commands, local_commands, job_stats, &rn, 1, 1, 988 sels, exls, flags, 0, NULL); 989 990 /* 991 * teardown 992 */ 993 NDMP_LOG(LOG_DEBUG, "end restore job %s", job); 994 tlm_un_ref_job_stats(job); 995 tlm_release_list(sels); 996 tlm_release_list(exls); 997 998 commands->tcs_writer_count--; 999 local_commands->tc_reader = TLM_STOP; 1000 tlm_release_reader_writer_ipc(local_commands); 1001 free(dir); 1002 return (erc); 1003 } 1004 1005 /* 1006 * Creates the directories all the way down to the 1007 * end if they dont exist 1008 */ 1009 int 1010 make_dirs(char *dir) 1011 { 1012 char c; 1013 char *cp, *end; 1014 struct stat64 st; 1015 1016 cp = dir; 1017 cp += strspn(cp, "/"); 1018 end = dir + strlen(dir); 1019 do { 1020 if (*cp == '\0' || *cp == '/') { 1021 c = *cp; 1022 *cp = '\0'; 1023 if (lstat64(dir, &st) < 0) 1024 if (mkdir(dir, 0777) < 0) { 1025 NDMP_LOG(LOG_DEBUG, "Error %d" 1026 " creating directory %s", 1027 errno, dir); 1028 *cp = c; 1029 return (-1); 1030 } 1031 1032 *cp = c; 1033 } 1034 } while (++cp <= end); 1035 1036 return (0); 1037 } 1038 1039 /* 1040 * Creates the directories leading to the given path 1041 */ 1042 int 1043 mkbasedir(char *path) 1044 { 1045 int rv; 1046 char *cp; 1047 struct stat64 st; 1048 1049 if (!path || !*path) { 1050 NDMP_LOG(LOG_DEBUG, "Invalid argument"); 1051 return (-1); 1052 } 1053 1054 cp = strrchr(path, '/'); 1055 if (cp) 1056 *cp = '\0'; 1057 rv = lstat64(path, &st); 1058 if (rv < 0) /* need new directories */ 1059 rv = make_dirs(path); 1060 if (cp) 1061 *cp = '/'; 1062 1063 return (rv); 1064 } 1065 1066 1067 /* 1068 * read the file off the tape back onto disk 1069 */ 1070 static long 1071 restore_file(int *fp, 1072 char *real_name, 1073 long size, 1074 longlong_t huge_size, 1075 tlm_acls_t *acls, 1076 boolean_t want_this_file, 1077 tlm_cmd_t *local_commands, 1078 tlm_job_stats_t *job_stats) 1079 { 1080 struct stat64 attr; 1081 1082 if (!real_name) { 1083 if (want_this_file) { 1084 NDMP_LOG(LOG_DEBUG, "No file name but wanted!"); 1085 want_this_file = FALSE; 1086 } 1087 } else 1088 NDMP_LOG(LOG_DEBUG, "new file[%s]", real_name); 1089 1090 /* 1091 * OK, some FM is creeping in here ... 1092 * int *fp is used to keep the 1093 * backup file channel open through 1094 * the interruption of EOT and 1095 * processing the headers of the 1096 * next tape. So, if *fp is zero 1097 * then no file is open yet and all 1098 * is normal. If *fp has a number 1099 * then we are returning after an 1100 * EOT break. 1101 * 1102 * *fp is now also open for HUGE files 1103 * that are put back in sections. 1104 */ 1105 1106 if (*fp == 0 && want_this_file) { 1107 int erc_stat; 1108 1109 if (mkbasedir(real_name) < 0) 1110 job_stats->js_errors++; 1111 1112 erc_stat = stat64(real_name, (struct stat64 *)&attr); 1113 if (erc_stat < 0) { 1114 /*EMPTY*/ 1115 /* new file */ 1116 } else if (acls->acl_overwrite) { 1117 /*EMPTY*/ 1118 /* take this file no matter what */ 1119 } else if (acls->acl_update) { 1120 if (attr.st_mtime < acls->acl_attr.st_mtime) { 1121 /*EMPTY*/ 1122 /* tape is newer */ 1123 } else { 1124 /* disk file is newer */ 1125 want_this_file = FALSE; 1126 } 1127 } else { 1128 /* 1129 * no overwrite, no update, 1130 * do not ever replace old files. 1131 */ 1132 want_this_file = TRUE; 1133 } 1134 if (want_this_file) { 1135 1136 *fp = open(real_name, O_CREAT | O_WRONLY, 1137 S_IRUSR | S_IWUSR); 1138 if (*fp == -1) { 1139 NDMP_LOG(LOG_ERR, 1140 "Could not open %s for restore.", 1141 real_name); 1142 NDMP_LOG(LOG_DEBUG, 1143 "fp=%d err=%d ", *fp, errno); 1144 job_stats->js_errors++; 1145 want_this_file = FALSE; 1146 /* 1147 * we cannot return here, 1148 * the file is still on 1149 * the tape and must be 1150 * skipped over. 1151 */ 1152 } 1153 } 1154 (void) strlcpy(local_commands->tc_file_name, real_name, 1155 TLM_MAX_PATH_NAME); 1156 } 1157 1158 /* 1159 * this is the size left in the next segment 1160 */ 1161 huge_size -= size; 1162 1163 /* 1164 * work 1165 */ 1166 while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) { 1167 int actual_size; 1168 int error; 1169 char *rec; 1170 int write_size; 1171 1172 /* 1173 * Use bytes_in_file field to tell reader the amount 1174 * of data still need to be read for this file. 1175 */ 1176 job_stats->js_bytes_in_file = size; 1177 1178 error = 0; 1179 rec = get_read_buffer(size, &error, &actual_size, 1180 local_commands); 1181 if (actual_size <= 0) { 1182 NDMP_LOG(LOG_DEBUG, 1183 "RESTORE WRITER> error %d, actual_size %d", 1184 error, actual_size); 1185 1186 /* no more data for this file for now */ 1187 job_stats->js_bytes_in_file = 0; 1188 1189 return (size); 1190 } else if (error) { 1191 NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]", 1192 error, local_commands->tc_file_name); 1193 break; 1194 } else { 1195 write_size = min(size, actual_size); 1196 if (want_this_file) { 1197 write_size = write(*fp, rec, write_size); 1198 } 1199 NS_ADD(wdisk, write_size); 1200 NS_INC(wfile); 1201 size -= write_size; 1202 } 1203 } 1204 1205 /* no more data for this file for now */ 1206 job_stats->js_bytes_in_file = 0; 1207 1208 /* 1209 * teardown 1210 */ 1211 if (*fp != 0 && huge_size <= 0) { 1212 (void) close(*fp); 1213 *fp = 0; 1214 set_acl(real_name, acls); 1215 } 1216 return (0); 1217 } 1218 1219 /* 1220 * Set the extended attributes file attribute 1221 */ 1222 static void 1223 set_xattr(int fd, struct stat64 st) 1224 { 1225 struct timeval times[2]; 1226 1227 times[0].tv_sec = st.st_atime; 1228 times[1].tv_sec = st.st_mtime; 1229 1230 (void) fchmod(fd, st.st_mode); 1231 (void) fchown(fd, st.st_uid, st.st_gid); 1232 (void) futimesat(fd, ".", times); 1233 } 1234 1235 /* 1236 * read the extended attribute header and write 1237 * it to the file 1238 */ 1239 static long 1240 restore_xattr_hdr(int *fp, 1241 char *name, 1242 char *fname, 1243 long size, 1244 tlm_acls_t *acls, 1245 tlm_cmd_t *local_commands, 1246 tlm_job_stats_t *job_stats) 1247 { 1248 tlm_tar_hdr_t *tar_hdr; 1249 struct xattr_hdr *xhdr; 1250 struct xattr_buf *xbuf; 1251 int namelen; 1252 char *xattrname; 1253 int actual_size; 1254 int error; 1255 1256 if (!fname) { 1257 NDMP_LOG(LOG_DEBUG, "No file name but wanted!"); 1258 } else { 1259 NDMP_LOG(LOG_DEBUG, "new xattr[%s]", fname); 1260 } 1261 1262 error = 0; 1263 xhdr = (struct xattr_hdr *)get_read_buffer(size, &error, 1264 &actual_size, local_commands); 1265 if (error) { 1266 NDMP_LOG(LOG_DEBUG, 1267 "Could not read xattr [%s:%s] for restore. ", 1268 name, fname); 1269 job_stats->js_errors++; 1270 return (0); 1271 } 1272 1273 /* Check extended attribute header */ 1274 if (strcmp(xhdr->h_version, XATTR_ARCH_VERS) != 0) { 1275 NDMP_LOG(LOG_DEBUG, 1276 "Unrecognized header format [%s]", xhdr->h_version); 1277 return (0); 1278 } 1279 xbuf = (struct xattr_buf *)(((char *)xhdr) + sizeof (struct xattr_hdr)); 1280 1281 (void) sscanf(xbuf->h_namesz, "%7d", &namelen); 1282 xattrname = xbuf->h_names + strlen(xbuf->h_names) + 1; 1283 1284 if (*fp == 0) { 1285 int fd; 1286 1287 fd = attropen(name, xattrname, O_CREAT | O_RDWR, 0755); 1288 if (fd == -1) { 1289 NDMP_LOG(LOG_DEBUG, 1290 "Could not open xattr [%s:%s] for restore.", 1291 name, xattrname); 1292 NDMP_LOG(LOG_DEBUG, "err=%d ", errno); 1293 job_stats->js_errors++; 1294 } 1295 (void) strlcpy(local_commands->tc_file_name, xattrname, 1296 TLM_MAX_PATH_NAME); 1297 *fp = fd; 1298 } 1299 1300 /* Get the actual extended attribute file */ 1301 tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(sizeof (*tar_hdr), 1302 &error, &actual_size, local_commands); 1303 if (error) { 1304 NDMP_LOG(LOG_DEBUG, 1305 "Could not read xattr data [%s:%s] for restore. ", 1306 fname, xattrname); 1307 job_stats->js_errors++; 1308 return (0); 1309 } 1310 acls->acl_attr.st_mode = oct_atoi(tar_hdr->th_mode); 1311 acls->acl_attr.st_size = oct_atoi(tar_hdr->th_size); 1312 acls->acl_attr.st_uid = oct_atoi(tar_hdr->th_uid); 1313 acls->acl_attr.st_gid = oct_atoi(tar_hdr->th_gid); 1314 acls->acl_attr.st_mtime = oct_atoi(tar_hdr->th_mtime); 1315 1316 size = acls->acl_attr.st_size; 1317 while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) { 1318 char *rec; 1319 int write_size; 1320 1321 error = 0; 1322 rec = get_read_buffer(size, &error, &actual_size, 1323 local_commands); 1324 if (actual_size <= 0) { 1325 NDMP_LOG(LOG_DEBUG, 1326 "RESTORE WRITER> error %d, actual_size %d", 1327 error, actual_size); 1328 1329 return (size); 1330 } else if (error) { 1331 NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]", 1332 error, local_commands->tc_file_name); 1333 break; 1334 } else { 1335 write_size = min(size, actual_size); 1336 write_size = write(*fp, rec, write_size); 1337 NS_ADD(wdisk, write_size); 1338 NS_INC(wfile); 1339 size -= write_size; 1340 } 1341 } 1342 1343 if (*fp != 0) { 1344 set_xattr(*fp, acls->acl_attr); 1345 (void) close(*fp); 1346 *fp = 0; 1347 } 1348 return (0); 1349 } 1350 1351 /* 1352 * Match the name with the list 1353 */ 1354 static int 1355 exact_find(char *name, char **list) 1356 { 1357 boolean_t found; 1358 int i; 1359 char *cp; 1360 1361 found = FALSE; 1362 for (i = 0; *list != NULL; list++, i++) { 1363 cp = *list + strspn(*list, "/"); 1364 if (match(cp, name)) { 1365 found = TRUE; 1366 NDMP_LOG(LOG_DEBUG, "exact_find> found[%s]", cp); 1367 break; 1368 } 1369 } 1370 1371 return (found); 1372 } 1373 1374 /* 1375 * On error, return FALSE and prevent restoring(probably) unwanted data. 1376 */ 1377 static int 1378 is_parent(char *parent, char *child, int flags) 1379 { 1380 char tmp[TLM_MAX_PATH_NAME]; 1381 boolean_t rv; 1382 1383 if (IS_SET(flags, RSFLG_MATCH_WCARD)) { 1384 if (!tlm_cat_path(tmp, parent, "*")) { 1385 NDMP_LOG(LOG_DEBUG, 1386 "is_parent> path too long [%s]", parent); 1387 rv = FALSE; 1388 } else 1389 rv = (match(tmp, child) != 0) ? TRUE : FALSE; 1390 } else { 1391 if (!tlm_cat_path(tmp, parent, "/")) { 1392 NDMP_LOG(LOG_DEBUG, 1393 "is_parent> path too long [%s]", parent); 1394 rv = FALSE; 1395 } else 1396 rv = (strncmp(tmp, child, strlen(tmp)) == 0) ? 1397 TRUE : FALSE; 1398 } 1399 1400 return (rv); 1401 } 1402 1403 /* 1404 * Used to match the filename inside the list 1405 */ 1406 static boolean_t 1407 strexactcmp(char *s, char *t) 1408 { 1409 return ((strcmp(s, t) == 0) ? TRUE : FALSE); 1410 } 1411 1412 /* 1413 * Check if the file is needed to be restored 1414 */ 1415 static boolean_t 1416 is_file_wanted(char *name, 1417 char **sels, 1418 char **exls, 1419 int flags, 1420 int *mchtype, 1421 int *pos) 1422 { 1423 char *p_sel; 1424 char *uc_name, *retry, *namep; 1425 boolean_t found; 1426 int i; 1427 name_match_fp_t *cmp_fp; 1428 1429 if (name == NULL || sels == NULL || exls == NULL) 1430 return (FALSE); 1431 1432 found = FALSE; 1433 if (mchtype != NULL) 1434 *mchtype = PM_NONE; 1435 if (pos != NULL) 1436 *pos = 0; 1437 1438 /* 1439 * For empty selection, restore everything 1440 */ 1441 if (*sels == NULL || **sels == '\0') { 1442 NDMP_LOG(LOG_DEBUG, "is_file_wanted: Restore all"); 1443 return (TRUE); 1444 } 1445 1446 uc_name = ndmp_malloc(TLM_MAX_PATH_NAME); 1447 retry = ndmp_malloc(TLM_MAX_PATH_NAME); 1448 if (uc_name == NULL || retry == NULL) { 1449 free(uc_name); 1450 free(retry); 1451 return (FALSE); 1452 } 1453 1454 if (IS_SET(flags, RSFLG_MATCH_WCARD)) 1455 cmp_fp = match; 1456 else 1457 cmp_fp = strexactcmp; 1458 1459 namep = name + strspn(name, "/"); 1460 if (IS_SET(flags, RSFLG_IGNORE_CASE)) { 1461 (void) strlcpy(uc_name, namep, TLM_MAX_PATH_NAME); 1462 (void) strupr(uc_name); 1463 namep = uc_name; 1464 } 1465 NDMP_LOG(LOG_DEBUG, "is_file_wanted> flg: 0x%x name: [%s]", 1466 flags, name); 1467 1468 for (i = 0; *sels != NULL; sels++, i++) { 1469 p_sel = *sels + strspn(*sels, "/"); 1470 1471 /* 1472 * Try exact match. 1473 */ 1474 if ((*cmp_fp)(p_sel, namep)) { 1475 NDMP_LOG(LOG_DEBUG, "match1> pos: %d [%s][%s]", 1476 i, p_sel, name); 1477 found = TRUE; 1478 if (mchtype != NULL) 1479 *mchtype = PM_EXACT; 1480 break; 1481 } 1482 /* 1483 * Try "entry/" and the current selection. The 1484 * current selection may be something like "<something>/". 1485 */ 1486 (void) tlm_cat_path(retry, namep, "/"); 1487 if ((*cmp_fp)(p_sel, retry)) { 1488 NDMP_LOG(LOG_DEBUG, "match2> pos %d [%s][%s]", 1489 i, p_sel, name); 1490 found = TRUE; 1491 if (mchtype != NULL) 1492 *mchtype = PM_EXACT; 1493 break; 1494 } 1495 /* 1496 * If the following check returns true it means that the 1497 * 'name' is an entry below the 'p_sel' hierarchy. 1498 */ 1499 if (is_parent(p_sel, namep, flags)) { 1500 NDMP_LOG(LOG_DEBUG, "parent1> pos %d [%s][%s]", 1501 i, p_sel, name); 1502 found = TRUE; 1503 if (mchtype != NULL) 1504 *mchtype = PM_CHILD; 1505 break; 1506 } 1507 1508 /* 1509 * There is a special case for parent directories of a 1510 * selection. If 'p_sel' is something like "*d1", the 1511 * middle directories of the final entry can't be determined 1512 * until the final entry matches with 'p_sel'. At that 1513 * time the middle directories of the entry have been passed 1514 * and they can't be restored. 1515 */ 1516 if (is_parent(namep, p_sel, flags)) { 1517 NDMP_LOG(LOG_DEBUG, "parent2> pos %d [%s][%s]", 1518 i, p_sel, name); 1519 found = TRUE; 1520 if (mchtype != NULL) 1521 *mchtype = PM_PARENT; 1522 break; 1523 } 1524 } 1525 1526 /* Check for exclusions. */ 1527 if (found && exact_find(namep, exls)) { 1528 if (mchtype != NULL) 1529 *mchtype = PM_NONE; 1530 found = FALSE; 1531 } 1532 if (found && pos != NULL) 1533 *pos = i; 1534 1535 free(uc_name); 1536 free(retry); 1537 return (found); 1538 } 1539 1540 /* 1541 * Read the specified amount data into the buffer. Detects EOT or EOF 1542 * during read. 1543 * 1544 * Returns the number of bytes actually read. On error returns -1. 1545 */ 1546 static int 1547 input_mem(int l, 1548 int d, 1549 tlm_cmd_t *lcmds, 1550 char *mem, 1551 int len) 1552 { 1553 int err; 1554 int toread, actual_size, rec_size; 1555 char *rec; 1556 1557 if (l <= 0 || d <= 0 || !lcmds || !mem) { 1558 NDMP_LOG(LOG_DEBUG, "Invalid argument"); 1559 return (-1); 1560 } 1561 1562 toread = len; 1563 while (toread > 0) { 1564 rec = get_read_buffer(toread, &err, &actual_size, lcmds); 1565 if (actual_size <= 0) { 1566 NDMP_LOG(LOG_DEBUG, "err %d act_size %d detected", 1567 err, actual_size); 1568 break; 1569 } else if (err) { 1570 NDMP_LOG(LOG_DEBUG, "error %d reading data", err); 1571 return (-1); 1572 } 1573 rec_size = min(actual_size, toread); 1574 (void) memcpy(mem, rec, rec_size); 1575 mem += rec_size; 1576 toread -= rec_size; 1577 } 1578 1579 return (len - toread); 1580 } 1581 1582 /* 1583 * pick up the name and size of a HUGE file 1584 */ 1585 static int 1586 get_humongus_file_header(int lib, 1587 int drv, 1588 long recsize, 1589 longlong_t *size, 1590 char *name, 1591 tlm_cmd_t *local_commands) 1592 { 1593 char *p_record, *value; 1594 int rv; 1595 1596 NDMP_LOG(LOG_DEBUG, "HUGE Record found: %d", recsize); 1597 1598 rv = 0; 1599 if (recsize == 0) { 1600 /* 1601 * The humongus_file_header was written in a 1602 * RECORDSIZE block and the header.size field of this 1603 * record was 0 before this fix. For backward compatiblity 1604 * read only one RECORDSIZE-size block if the header.size 1605 * field is 0. Otherwise the header.size field should show 1606 * the length of the data of this header. 1607 */ 1608 NDMP_LOG(LOG_DEBUG, "Old HUGE record found"); 1609 recsize = RECORDSIZE; 1610 } 1611 1612 if (input_mem(lib, drv, local_commands, name, recsize) != recsize) { 1613 rv = -1; 1614 *size = 0; 1615 *name = '\0'; 1616 NDMP_LOG(LOG_DEBUG, "Error reading a HUGE file name"); 1617 } else { 1618 NDMP_LOG(LOG_DEBUG, "HUGE [%s]", name); 1619 1620 p_record = name; 1621 value = parse(&p_record, " "); 1622 *size = atoll(value); 1623 /* 1624 * Note: Since the backed up names are not longer than 1625 * NAME_MAX and the buffer passed to us is 1626 * TLM_MAX_PATH_NAME, it should be safe to use strlcpy 1627 * without check on the buffer size. 1628 */ 1629 (void) strlcpy(name, p_record, TLM_MAX_PATH_NAME); 1630 } 1631 1632 NDMP_LOG(LOG_DEBUG, "HUGE Record %lld [%s]", *size, name); 1633 1634 return (rv); 1635 } 1636 1637 /* 1638 * pick up the long name from the special tape file 1639 */ 1640 static int 1641 get_long_name(int lib, 1642 int drv, 1643 long recsize, 1644 char *name, 1645 long *buf_spot, 1646 tlm_cmd_t *local_commands) 1647 { 1648 int nread; 1649 1650 NDMP_LOG(LOG_DEBUG, "LONGNAME Record found rs %d bs %d", recsize, 1651 *buf_spot); 1652 1653 if (*buf_spot < 0) 1654 *buf_spot = 0; 1655 1656 nread = input_mem(lib, drv, local_commands, name + *buf_spot, 1657 recsize); 1658 if (nread < 0) { 1659 nread = recsize; /* return 0 as size left */ 1660 name[*buf_spot] = '\0'; 1661 NDMP_LOG(LOG_ERR, "Error %d reading a long file name %s.", 1662 nread, name); 1663 } else { 1664 *buf_spot += nread; 1665 name[*buf_spot] = '\0'; 1666 NDMP_LOG(LOG_DEBUG, "LONGNAME [%s]", name); 1667 } 1668 1669 return (recsize - nread); 1670 } 1671 1672 /* 1673 * create a new directory 1674 */ 1675 static int 1676 create_directory(char *dir, tlm_job_stats_t *job_stats) 1677 { 1678 struct stat64 attr; 1679 char *p; 1680 char temp; 1681 int erc; 1682 1683 /* 1684 * Make sure all directories in this path exist, create them if 1685 * needed. 1686 */ 1687 NDMP_LOG(LOG_DEBUG, "new dir[%s]", dir); 1688 1689 erc = 0; 1690 p = &dir[1]; 1691 do { 1692 temp = *p; 1693 if (temp == '/' || temp == 0) { 1694 *p = 0; 1695 if (stat64(dir, &attr) < 0) { 1696 erc = mkdir(dir, 0777); 1697 if (erc < 0) { 1698 job_stats->js_errors++; 1699 NDMP_LOG(LOG_DEBUG, 1700 "Could not create directory %s", 1701 dir); 1702 break; 1703 } 1704 } 1705 *p = temp; 1706 } 1707 p++; 1708 } while (temp != 0); 1709 1710 return (erc); 1711 } 1712 1713 /* 1714 * create a new hardlink 1715 */ 1716 static int 1717 create_hard_link(char *name_old, char *name_new, 1718 tlm_acls_t *acls, tlm_job_stats_t *job_stats) 1719 { 1720 int erc; 1721 1722 if (mkbasedir(name_new)) { 1723 NDMP_LOG(LOG_DEBUG, "faile to make base dir for [%s]", 1724 name_new); 1725 1726 return (-1); 1727 } 1728 1729 erc = link(name_old, name_new); 1730 if (erc) { 1731 job_stats->js_errors++; 1732 NDMP_LOG(LOG_DEBUG, "error %d (errno %d) hardlink [%s] to [%s]", 1733 erc, errno, name_new, name_old); 1734 } else { 1735 set_acl(name_new, acls); 1736 } 1737 return (erc); 1738 } 1739 1740 /* 1741 * create a new symlink 1742 */ 1743 /*ARGSUSED*/ 1744 static int 1745 create_sym_link(char *dst, char *target, tlm_acls_t *acls, 1746 tlm_job_stats_t *job_satats) 1747 { 1748 int erc; 1749 1750 if (mkbasedir(dst) < 0) 1751 return (-1); 1752 1753 erc = symlink(target, dst); 1754 if (erc) { 1755 job_satats->js_errors++; 1756 NDMP_LOG(LOG_DEBUG, "error %d (errno %d) softlink [%s] to [%s]", 1757 erc, errno, dst, target); 1758 } 1759 1760 return (erc); 1761 } 1762 1763 /* 1764 * create a new FIFO 1765 */ 1766 static int 1767 create_fifo(char *name, tlm_acls_t *acls) 1768 { 1769 (void) mknod(name, 0777 + S_IFIFO, 0); 1770 set_acl(name, acls); 1771 return (0); 1772 } 1773 1774 /* 1775 * read in the ACLs for the next file 1776 */ 1777 static long 1778 load_acl_info(int lib, 1779 int drv, 1780 long file_size, 1781 tlm_acls_t *acls, 1782 long *acl_spot, 1783 tlm_cmd_t *local_commands) 1784 { 1785 char *bp; 1786 int nread; 1787 1788 /* 1789 * If the ACL is spanned on tapes, then the acl_spot should NOT be 1790 * 0 on next calls to this function to read the rest of the ACL 1791 * on next tapes. 1792 */ 1793 if (*acl_spot == 0) { 1794 (void) memset(acls, 0, sizeof (tlm_acls_t)); 1795 } 1796 1797 bp = ((char *)&acls->acl_info) + *acl_spot; 1798 nread = input_mem(lib, drv, local_commands, (void *)bp, file_size); 1799 if (nread < 0) { 1800 *acl_spot = 0; 1801 (void) memset(acls, 0, sizeof (tlm_acls_t)); 1802 NDMP_LOG(LOG_DEBUG, "Error reading ACL data"); 1803 return (0); 1804 } 1805 *acl_spot += nread; 1806 acls->acl_non_trivial = TRUE; 1807 1808 return (file_size - nread); 1809 } 1810 1811 static int 1812 ndmp_set_eprivs_least(void) 1813 { 1814 priv_set_t *priv_set; 1815 1816 if ((priv_set = priv_allocset()) == NULL) { 1817 NDMP_LOG(LOG_ERR, "Out of memory."); 1818 return (-1); 1819 } 1820 priv_emptyset(priv_set); 1821 (void) priv_addset(priv_set, "basic"); 1822 (void) priv_addset(priv_set, "proc_audit"); 1823 (void) priv_addset(priv_set, "proc_setid"); 1824 (void) priv_addset(priv_set, "proc_owner"); 1825 (void) priv_addset(priv_set, "file_chown"); 1826 (void) priv_addset(priv_set, "file_chown_self"); 1827 (void) priv_addset(priv_set, "file_dac_read"); 1828 (void) priv_addset(priv_set, "file_dac_search"); 1829 (void) priv_addset(priv_set, "file_dac_write"); 1830 (void) priv_addset(priv_set, "file_owner"); 1831 (void) priv_addset(priv_set, "file_setid"); 1832 (void) priv_addset(priv_set, "sys_linkdir"); 1833 (void) priv_addset(priv_set, "sys_devices"); 1834 (void) priv_addset(priv_set, "sys_mount"); 1835 (void) priv_addset(priv_set, "sys_config"); 1836 1837 if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) == -1) { 1838 NDMP_LOG(LOG_ERR, "Additional privileges required."); 1839 priv_freeset(priv_set); 1840 return (-1); 1841 } 1842 priv_freeset(priv_set); 1843 return (0); 1844 } 1845 1846 static int 1847 ndmp_set_eprivs_all(void) 1848 { 1849 priv_set_t *priv_set; 1850 1851 if ((priv_set = priv_str_to_set("all", ",", NULL)) == NULL) { 1852 NDMP_LOG(LOG_ERR, "Could not set privileges to 'all'."); 1853 return (-1); 1854 } 1855 if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) != 0) { 1856 NDMP_LOG(LOG_ERR, "Additional privileges required."); 1857 return (-1); 1858 } 1859 priv_freeset(priv_set); 1860 return (0); 1861 } 1862 1863 /* 1864 * Set the standard attributes of the file 1865 */ 1866 static void 1867 set_attr(char *name, struct stat64 *st) 1868 { 1869 struct utimbuf tbuf; 1870 boolean_t priv_all = FALSE; 1871 1872 if (!name || !st) 1873 return; 1874 1875 NDMP_LOG(LOG_DEBUG, "set_attr: %s uid %d gid %d mode %o", name, 1876 st->st_uid, st->st_gid, st->st_mode); 1877 1878 if (chown(name, st->st_uid, st->st_gid)) 1879 NDMP_LOG(LOG_ERR, 1880 "Could not set uid or/and gid for file %s.", name); 1881 1882 if ((st->st_mode & (S_ISUID | S_ISGID)) != 0) { 1883 /* 1884 * Change effective privileges to 'all' which is required to 1885 * change setuid bit for 'root' owned files. If fails, just 1886 * send error to log file and proceed. 1887 */ 1888 if (ndmp_set_eprivs_all()) { 1889 NDMP_LOG(LOG_ERR, 1890 "Could not set effective privileges to 'all'."); 1891 } else { 1892 priv_all = TRUE; 1893 } 1894 } 1895 1896 if (chmod(name, st->st_mode)) 1897 NDMP_LOG(LOG_ERR, 1898 "Could not set correct file permission for file %s.", name); 1899 1900 if (priv_all == TRUE) { 1901 /* 1902 * Give up the 'all' privileges for effective sets and go back 1903 * to least required privileges. If fails, just send error to 1904 * log file and proceed. 1905 */ 1906 if (ndmp_set_eprivs_least()) 1907 NDMP_LOG(LOG_ERR, 1908 "Could not set least required privileges."); 1909 } 1910 1911 tbuf.modtime = st->st_mtime; 1912 tbuf.actime = st->st_atime; 1913 (void) utime(name, &tbuf); 1914 } 1915 1916 /* 1917 * Set the ACL info for the file 1918 */ 1919 static void 1920 set_acl(char *name, tlm_acls_t *acls) 1921 { 1922 int erc; 1923 acl_t *aclp = NULL; 1924 1925 if (name) 1926 NDMP_LOG(LOG_DEBUG, "set_acl: %s", name); 1927 if (acls != 0) { 1928 /* Need a place to save real modification time */ 1929 1930 set_attr(name, &acls->acl_attr); 1931 1932 if (!acls->acl_non_trivial) { 1933 (void) memset(acls, 0, sizeof (tlm_acls_t)); 1934 NDMP_LOG(LOG_DEBUG, "set_acl: skipping trivial"); 1935 return; 1936 } 1937 1938 erc = acl_fromtext(acls->acl_info.attr_info, &aclp); 1939 if (erc != 0) { 1940 NDMP_LOG(LOG_DEBUG, 1941 "TAPE RESTORE> acl_fromtext errno %d", erc); 1942 } 1943 if (aclp) { 1944 erc = acl_set(name, aclp); 1945 if (erc < 0) { 1946 NDMP_LOG(LOG_DEBUG, 1947 "TAPE RESTORE> acl_set errno %d", errno); 1948 } 1949 acl_free(aclp); 1950 } 1951 (void) memset(acls, 0, sizeof (tlm_acls_t)); 1952 } 1953 } 1954 1955 /* 1956 * a wrapper to tlm_get_read_buffer so that 1957 * we can cleanly detect ABORT commands 1958 * without involving the TLM library with 1959 * our problems. 1960 */ 1961 static char * 1962 get_read_buffer(int want, 1963 int *error, 1964 int *actual_size, 1965 tlm_cmd_t *local_commands) 1966 { 1967 while (local_commands->tc_writer == TLM_RESTORE_RUN) { 1968 char *rec; 1969 rec = tlm_get_read_buffer(want, error, 1970 local_commands->tc_buffers, actual_size); 1971 if (rec != 0) { 1972 return (rec); 1973 } 1974 } 1975 1976 /* 1977 * the job is ending, give Writer a buffer that will never be read ... 1978 * it does not matter anyhow, we are aborting. 1979 */ 1980 *actual_size = RECORDSIZE; 1981 return (NULL); 1982 } 1983 1984 /* 1985 * Enable wildcard for restore options 1986 */ 1987 static boolean_t 1988 wildcard_enabled(void) 1989 { 1990 char *cp; 1991 1992 cp = ndmpd_get_prop_default(NDMP_RESTORE_WILDCARD_ENABLE, "n"); 1993 return ((toupper(*cp) == 'Y') ? TRUE : FALSE); 1994 } 1995 1996 1997 /* 1998 * Concatenate two names 1999 */ 2000 /*ARGSUSED*/ 2001 static char * 2002 catnames(struct rs_name_maker *rnp, char *buf, int pos, char *path) 2003 { 2004 char *rv; 2005 2006 rv = NULL; 2007 if (!buf) { 2008 NDMP_LOG(LOG_DEBUG, "buf is NULL"); 2009 } else if (!path) { 2010 NDMP_LOG(LOG_DEBUG, "path is NULL"); 2011 } else if (!rnp->rn_nlp) { 2012 NDMP_LOG(LOG_DEBUG, "rn_nlp is NULL [%s]", path); 2013 } else if (!tlm_cat_path(buf, rnp->rn_nlp, path)) { 2014 NDMP_LOG(LOG_DEBUG, "Path too long [%s][%s]", 2015 rnp->rn_nlp, path); 2016 } else 2017 rv = buf; 2018 2019 return (rv); 2020 } 2021 2022 2023 /* 2024 * Create a new name path for restore 2025 */ 2026 static char * 2027 rs_new_name(struct rs_name_maker *rnp, char *buf, int pos, char *path) 2028 { 2029 if (!rnp || !rnp->rn_fp) 2030 return (NULL); 2031 2032 return (*rnp->rn_fp)(rnp, buf, pos, path); 2033 } 2034 2035 /* 2036 * Iterate over ZFS metadata stored in the backup stream and use the callback 2037 * to restore it. 2038 */ 2039 int 2040 ndmp_iter_zfs(ndmp_context_t *nctx, int (*np_restore_property)(nvlist_t *, 2041 void *), void *ptr) 2042 { 2043 tlm_commands_t *cmds; 2044 ndmp_metadata_header_t *mhp; 2045 ndmp_metadata_property_t *mpp; 2046 tlm_cmd_t *lcmd; 2047 int actual_size; 2048 nvlist_t *nvl; 2049 nvlist_t *nvl_head; 2050 nvlist_t *valp; 2051 nvpair_t *nvp = NULL; 2052 nvpair_t *nvph = NULL; 2053 char plname[100]; 2054 char *mhbuf, *pp, *tp; 2055 int rv, i; 2056 int size, lsize, sz; 2057 int align = RECORDSIZE - 1; 2058 2059 if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL) 2060 return (-1); 2061 2062 nctx->nc_plname = plname; 2063 if ((lcmd = cmds->tcs_command) == NULL || 2064 lcmd->tc_buffers == NULL) 2065 return (-1); 2066 2067 size = sizeof (ndmp_metadata_header_t) + 2068 ZFS_MAX_PROPS * sizeof (ndmp_metadata_property_t); 2069 size += align; 2070 size &= ~align; 2071 2072 /* For nvlist cleanup */ 2073 if (nvlist_alloc(&nvl_head, NV_UNIQUE_NAME, 0) != 0) 2074 return (-1); 2075 2076 if ((mhbuf = malloc(size)) == NULL) 2077 return (-1); 2078 2079 /* LINTED improper alignment */ 2080 while ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv, 2081 &actual_size, lcmd)) != NULL) { 2082 pp = mhbuf; 2083 2084 if (strncmp(mhp->nh_magic, ZFS_META_MAGIC, 2085 sizeof (mhp->nh_magic)) != 0) { 2086 /* No more metadata */ 2087 tlm_unget_read_buffer(lcmd->tc_buffers, actual_size); 2088 nvlist_free(nvl_head); 2089 return (0); 2090 } 2091 2092 (void) memcpy(pp, (char *)mhp, (actual_size < size) ? 2093 actual_size : size); 2094 pp += (actual_size < size) ? actual_size : size; 2095 2096 sz = actual_size; 2097 while (sz < size && 2098 ((tp = get_read_buffer(size - sz, &rv, &lsize, 2099 lcmd))) != NULL) { 2100 (void) memcpy(pp, tp, size - sz); 2101 sz += lsize; 2102 pp += lsize; 2103 } 2104 if (sz > size) { 2105 tlm_unget_read_buffer(lcmd->tc_buffers, sz - size); 2106 } 2107 /* LINTED improper alignment */ 2108 mhp = (ndmp_metadata_header_t *)mhbuf; 2109 2110 nctx->nc_plversion = mhp->nh_plversion; 2111 (void) strlcpy(plname, mhp->nh_plname, sizeof (plname)); 2112 2113 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 2114 goto nvlist_err; 2115 2116 mpp = &mhp->nh_property[0]; 2117 for (i = 0; i < mhp->nh_count && mpp; i++) { 2118 if (nvlist_alloc(&valp, NV_UNIQUE_NAME, 0) != 0 || 2119 nvlist_add_string(valp, "value", 2120 mpp->mp_value) != 0 || 2121 nvlist_add_string(valp, "source", 2122 mpp->mp_source) != 0 || 2123 nvlist_add_nvlist(nvl, mpp->mp_name, valp) != 0) 2124 goto nvlist_err; 2125 mpp++; 2126 } 2127 2128 if (np_restore_property(nvl, ptr) != 0) 2129 goto nvlist_err; 2130 2131 (void) nvlist_add_nvlist(nvl_head, "_", nvl); 2132 } 2133 free(mhbuf); 2134 2135 nvlist_free(nvl_head); 2136 return (0); 2137 2138 nvlist_err: 2139 free(mhbuf); 2140 while ((nvph = nvlist_next_nvpair(nvl_head, nvph)) != NULL && 2141 nvpair_value_nvlist(nvph, &nvl) == 0) { 2142 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL && 2143 nvpair_value_nvlist(nvp, &valp) == 0) { 2144 nvlist_free(valp); 2145 } 2146 nvlist_free(nvl); 2147 } 2148 nvlist_free(nvl_head); 2149 return (-1); 2150 } 2151 2152 /* 2153 * Returns the version number of the plugin which created the metadata 2154 */ 2155 uint_t 2156 ndmp_context_get_version(ndmp_context_t *nctx) 2157 { 2158 tlm_commands_t *cmds; 2159 ndmp_metadata_header_t *mhp; 2160 tlm_cmd_t *lcmd; 2161 int actual_size; 2162 int rv; 2163 int size; 2164 int align = RECORDSIZE - 1; 2165 2166 if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL) 2167 return (0); 2168 2169 if ((lcmd = cmds->tcs_command) == NULL || 2170 lcmd->tc_buffers == NULL) 2171 return (0); 2172 2173 size = sizeof (ndmp_metadata_header_t); 2174 size += align; 2175 size &= ~align; 2176 2177 /* LINTED improper alignment */ 2178 if ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv, 2179 &actual_size, lcmd)) != NULL) { 2180 if (strncmp(mhp->nh_magic, ZFS_META_MAGIC, 2181 sizeof (mhp->nh_magic)) != 0) { 2182 /* No more metadata */ 2183 tlm_unget_read_buffer(lcmd->tc_buffers, actual_size); 2184 return (0); 2185 } 2186 2187 nctx->nc_plversion = mhp->nh_plversion; 2188 tlm_unget_read_buffer(lcmd->tc_buffers, actual_size); 2189 } 2190 2191 return (nctx->nc_plversion); 2192 } 2193