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