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