2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens * Copyright (c) 2015 by Delphix. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * are met:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <limits.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <time.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/stat.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <unistd.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <dirent.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <pthread.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <archives.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <tlm.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/fs/zfs.h>
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar#include <sys/mkdev.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <libzfs.h>
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar#include <libcmdutils.h>
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar#include <pwd.h>
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar#include <grp.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "tlm_proto.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *get_write_buffer(long size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long *actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t zero,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int output_acl_header(sec_attr_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int output_file_header(char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *link,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int section,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int output_xattr_header(char *fname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *aname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int fd,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int section,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarextern libzfs_handle_t *zlibh;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarextern mutex_t zlib_mtx;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar#define S_ISPECIAL(a) (S_ISLNK(a) || S_ISFIFO(a) || S_ISBLK(a) || \
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar S_ISCHR(a))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_mem
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Gets a IO write buffer and copies memory to the that.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaroutput_mem(tlm_cmd_t *local_commands, char *mem,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size, rec_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rec;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (len > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = get_write_buffer(len, &actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar FALSE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec_size = min(actual_size, len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(rec, mem, rec_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mem += rec_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar len -= rec_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_output_dir
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put the directory information into the output buffers.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_output_dir(char *name, tlm_acls_t *tlm_acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_longlong_t pos;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Send the node or path history of the directory itself.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pos = tlm_get_data_offset(local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "pos: %10lld [%s]", pos, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_log_fhnode(job_stats, name, "", &tlm_acls->acl_attr, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_log_fhpath_name(job_stats, name, &tlm_acls->acl_attr, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* fhdir_cb is handled in ndmpd_tar3.c */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_acl_header(&tlm_acls->acl_info,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_file_header(name, "", tlm_acls, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tar_putdir
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Main dir backup function for tar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartar_putdir(char *name, tlm_acls_t *tlm_acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = tlm_output_dir(name, tlm_acls, local_commands, job_stats);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv < 0 ? rv : 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_acl_header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output the ACL header record and data
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaroutput_acl_header(sec_attr_t *acl_info,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_tar_hdr_t *tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long acl_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((acl_info == NULL) || (*acl_info->attr_info == '\0'))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tar_hdr)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = LF_ACL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acl_info->attr_type = UFSD_ACL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(acl_info->attr_len, sizeof (acl_info->attr_len),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%06o", strlen(acl_info->attr_info));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acl_size = sizeof (*acl_info);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_name, "UFSACL", TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acl_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar 0444);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid), "%06o ", 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid), "%06o ", 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%011o ", 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_magic, TLM_MAGIC,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_magic));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_build_header_checksum(tar_hdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_mem(local_commands, (void *)acl_info, acl_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_humongus_header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output a special header record for HUGE files
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output is: 1) a TAR "HUGE" header redord
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 2) a "file" of size, name
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaroutput_humongus_header(char *fullname, longlong_t file_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_tar_hdr_t *tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * buf will contain: "%llu %s":
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - 20 is the maximum length of 'ulong_tlong' decimal notation.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The first '1' is for the ' ' between the "%llu" and the fullname.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The last '1' is for the null-terminator of fullname.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar len = 20 + 1 + strlen(fullname) + 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((buf = ndmp_malloc(sizeof (char) * len)) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tar_hdr) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = LF_HUMONGUS;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_build_header_checksum(tar_hdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(buf, len, "%lld %s", file_size, fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_mem(local_commands, buf, len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_xattr_header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output the TAR header record for extended attributes
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaroutput_xattr_header(char *fname, char *aname, int fd,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *tlm_acls, int section, tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct stat64 *attr = &tlm_acls->acl_attr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct xattr_hdr *xhdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct xattr_buf *xbuf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_tar_hdr_t *tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *section_name = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int hsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int comlen;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int namesz;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (section_name == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-TLM_NO_SCRATCH_SPACE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fstat64(fd, attr) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "output_file_header stat failed.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-TLM_OPEN_ERR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * if the file has to go out in sections,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we must mung the name.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (section == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(section_name, TLM_MAX_PATH_NAME,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "/dev/null/%s.hdr", aname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(section_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_MAX_PATH_NAME, "%s.%03d", aname, section);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar namesz = strlen(section_name) + strlen(fname) + 2; /* 2 nulls */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hsize = namesz + sizeof (struct xattr_hdr) + sizeof (struct xattr_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar comlen = namesz + sizeof (struct xattr_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tar_hdr) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_name, section_name, TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = LF_XATTR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar attr->st_mode & 07777);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar attr->st_uid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar attr->st_gid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar attr->st_mtime);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_magic, TLM_MAGIC,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_magic));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "xattr_hdr: %s size %d mode %06o uid %d gid %d",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar aname, hsize, attr->st_mode & 07777, attr->st_uid, attr->st_gid);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_build_header_checksum(tar_hdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xhdr = (struct xattr_hdr *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!xhdr) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xhdr->h_version, sizeof (xhdr->h_version), "%s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar XATTR_ARCH_VERS);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xhdr->h_size, sizeof (xhdr->h_size), "%0*d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (xhdr->h_size) - 1, hsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xhdr->h_component_len, sizeof (xhdr->h_component_len),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%0*d", sizeof (xhdr->h_component_len) - 1, comlen);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xhdr->h_link_component_len,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (xhdr->h_link_component_len), "%0*d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (xhdr->h_link_component_len) - 1, 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xbuf = (struct xattr_buf *)(((caddr_t)xhdr) +
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (struct xattr_hdr));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xbuf->h_namesz, sizeof (xbuf->h_namesz), "%0*d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (xbuf->h_namesz) - 1, namesz);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* No support for links in extended attributes */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xbuf->h_typeflag = LF_NORMAL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(xbuf->h_names, fname, TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(&xbuf->h_names[strlen(fname) + 1], aname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_file_header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output the TAR header record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaroutput_file_header(char *name, char *link,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *tlm_acls, int section, tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar static longlong_t file_count = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct stat64 *attr = &tlm_acls->acl_attr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_tar_hdr_t *tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t long_name = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t long_link = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *section_name = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int nmlen, lnklen;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uid_t uid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gid_t gid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar char *uname = "";
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar char *gname = "";
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar struct passwd *pwd;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar struct group *grp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (section_name == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-TLM_NO_SCRATCH_SPACE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * if the file has to go out in sections,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we must mung the name.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (section == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(section_name, name, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(section_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_MAX_PATH_NAME, "%s.%03d", name, section);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((pwd = getpwuid(attr->st_uid)) != NULL)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uname = pwd->pw_name;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((grp = getgrgid(attr->st_gid)) != NULL)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gname = grp->gr_name;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((ulong_t)(uid = attr->st_uid) > (ulong_t)OCTAL7CHAR)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uid = UID_NOBODY;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((ulong_t)(gid = attr->st_gid) > (ulong_t)OCTAL7CHAR)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gid = GID_NOBODY;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmlen = strlen(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nmlen >= NAMSIZ) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * file name is too big, it must go out
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in its own data file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tar_hdr) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_name),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%s%08qd.fil",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar LONGNAME_PREFIX,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_count++);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = LF_LONGNAME;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%011o ", nmlen);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%06o ", attr->st_mode & 07777);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%06o ", uid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%06o ", gid);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_uname, sizeof (tar_hdr->th_uname),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%.31s", uname);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_gname, sizeof (tar_hdr->th_gname),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%.31s", gname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%011o ", attr->st_mtime);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_magic, TLM_MAGIC,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_magic));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_build_header_checksum(tar_hdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_mem(local_commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void *)section_name, nmlen);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long_name = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnklen = strlen(link);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (lnklen >= NAMSIZ) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * link name is too big, it must go out
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in its own data file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tar_hdr) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_linkname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_name),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%s%08qd.slk",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar LONGNAME_PREFIX,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_count++);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = LF_LONGLINK;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%011o ", lnklen);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%06o ", attr->st_mode & 07777);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%06o ", uid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%06o ", gid);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_uname, sizeof (tar_hdr->th_uname),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%.31s", uname);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_gname, sizeof (tar_hdr->th_gname),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "%.31s", gname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%011o ", attr->st_mtime);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_magic, TLM_MAGIC,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_magic));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_build_header_checksum(tar_hdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_mem(local_commands, (void *)link,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnklen);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long_link = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tar_hdr) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (long_name) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_name),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%s%08qd.fil",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar LONGNAME_PREFIX,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_count++);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_name, section_name, TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "long_link: %s [%s]", long_link ? "TRUE" : "FALSE",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar link);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (long_link) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_linkname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_name),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%s%08qd.slk",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar LONGNAME_PREFIX,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_count++);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_linkname, link, TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar switch (attr->st_mode & S_IFMT) {
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case S_IFDIR:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = LF_DIR;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar break;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case S_IFIFO:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = LF_FIFO;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar break;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case S_IFBLK:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case S_IFCHR:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar if (S_ISBLK(attr->st_mode))
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tar_hdr->th_linkflag = LF_BLK;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar else
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tar_hdr->th_linkflag = LF_CHR;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar (void) snprintf(tar_hdr->th_shared.th_dev.th_devmajor,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar sizeof (tar_hdr->th_shared.th_dev.th_devmajor), "%06o ",
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar major(attr->st_rdev));
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar (void) snprintf(tar_hdr->th_shared.th_dev.th_devminor,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar sizeof (tar_hdr->th_shared.th_dev.th_devminor), "%06o ",
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar minor(attr->st_rdev));
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar break;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar default:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar if (attr->st_nlink > 1) {
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar /* mark file with hardlink LF_LINK */
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tar_hdr->th_linkflag = LF_LINK;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar (void) snprintf(tar_hdr->th_shared.th_hlink_ino,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar sizeof (tar_hdr->th_shared.th_hlink_ino),
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar "%011llo ", attr->st_ino);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar } else {
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tar_hdr->th_linkflag = *link == 0 ? LF_NORMAL :
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar LF_SYMLINK;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar NDMP_LOG(LOG_DEBUG, "linkflag: '%c'",
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tar_hdr->th_linkflag);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (long)attr->st_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar attr->st_mode & 07777);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid), "%06o ",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid), "%06o ",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gid);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_uname, sizeof (tar_hdr->th_uname), "%.31s",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uname);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_gname, sizeof (tar_hdr->th_gname), "%.31s",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar attr->st_mtime);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_magic, TLM_MAGIC,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (tar_hdr->th_magic));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_build_header_checksum(tar_hdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (long_name || long_link) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (file_count > 99999990) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_count = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(section_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_readlink
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Read where the softlink points to. Read the link in the checkpointed
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * path if the backup is being done on a checkpointed file system.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_readlink(char *nm, char *snap, char *buf, int bufsize)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((len = readlink(snap, buf, bufsize)) >= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * realink(2) doesn't null terminate the link name. We must
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * do it here.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buf[len] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error %d reading softlink of [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar errno, nm);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buf[0] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Backup the link if the destination missing */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (errno == ENOENT)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar/*
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * Read the system attribute file in a single buffer to write
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * it as a single write. A partial write to system attribute would
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * cause an EINVAL on write.
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar */
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdarstatic char *
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdarget_write_one_buf(char *buf, char *rec, int buf_size, int rec_size,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar tlm_cmd_t *lc)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar{
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar int len;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar long write_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (rec_size > buf_size)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (rec);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar len = rec_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) memcpy(rec, buf, len);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar buf += len;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar while (rec_size < buf_size) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar rec = get_write_buffer(buf_size - rec_size,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar &write_size, FALSE, lc);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (!rec)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (0);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar len = min(buf_size - rec_size, write_size);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) memcpy(rec, buf, len);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar rec_size += len;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar buf += len;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (rec);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar}
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_output_xattr
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put this file into the output buffers.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarlonglong_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_output_xattr(char *dir, char *name, char *chkdir,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *tlm_acls, tlm_commands_t *commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *fullname; /* directory + name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *snapname; /* snapshot name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int section; /* section of a huge file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int fd;
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar int afd = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t seek_spot = 0; /* location in the file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* for Multi Volume record */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_longlong_t pos;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar DIR *dp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct dirent *dtp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *attrname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *fnamep;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar if (S_ISPECIAL(tlm_acls->acl_attr.st_mode)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (TLM_NO_SOURCE_FILE);
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fullname = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fullname == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-TLM_NO_SCRATCH_SPACE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tlm_cat_path(fullname, dir, name)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Path too long.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-TLM_NO_SCRATCH_SPACE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (pathconf(fullname, _PC_XATTR_EXISTS) != 1 &&
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar sysattr_support(fullname, _PC_SATTR_EXISTS) != 1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar attrname = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar snapname = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (attrname == NULL || snapname == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -TLM_NO_SCRATCH_SPACE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tlm_cat_path(snapname, chkdir, name)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Path too long.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -TLM_NO_SCRATCH_SPACE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fnamep = (tlm_acls->acl_checkpointed) ? snapname : fullname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Open the file for reading.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar fd = attropen(fnamep, ".", O_RDONLY);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fd == -1) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "BACKUP> Can't open file [%s][%s]",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar fullname, fnamep);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = TLM_NO_SOURCE_FILE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pos = tlm_get_data_offset(local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "pos: %10lld [%s]", pos, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dp = (DIR *)fdopendir(fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (dp == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "BACKUP> Can't open file [%s]", fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = TLM_NO_SOURCE_FILE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((dtp = readdir(dp)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int section_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*dtp->d_name == '.')
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (sysattr_rdonly(dtp->d_name))
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar continue;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar afd = attropen(fnamep, dtp->d_name, O_RDONLY);
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar if (afd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "problem(%d) opening xattr file [%s][%s]", errno,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar fullname, fnamep);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar (void) output_xattr_header(fullname, dtp->d_name, afd,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls, section, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(attrname, TLM_MAX_PATH_NAME, "/dev/null/%s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dtp->d_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_file_header(attrname, "", tlm_acls, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section_size = (long)llmin(tlm_acls->acl_attr.st_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (longlong_t)TLM_MAX_TAR_IMAGE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* We only can read upto one section extended attribute */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (section_size > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int read_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar int sysattr_read = 0;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar char *rec;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar int size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (commands->tcs_reader != TLM_BACKUP_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_writer = TLM_ABORT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer[
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tb_file_size = section_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer[
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tb_seek_spot = seek_spot;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buf = get_write_buffer(section_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, FALSE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!buf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((actual_size < section_size) &&
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar sysattr_rw(dtp->d_name)) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar rec = buf;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar buf = ndmp_malloc(section_size);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (!buf)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar goto tear_down;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar size = actual_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar actual_size = section_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar sysattr_read = 1;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (commands->tcs_reader != TLM_BACKUP_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_writer = TLM_ABORT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar read_size = min(section_size, actual_size);
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar if ((actual_size = read(afd, buf, read_size)) < 0)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar break;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (sysattr_read) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (get_write_one_buf(buf, rec, read_size,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar size, local_commands) == 0) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar free(buf);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar goto tear_down;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar free(buf);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_ADD(rdisk, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_INC(rfile);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (actual_size == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "problem(%d) reading file [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar errno, fullname, snapname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar seek_spot += actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section_size -= actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar (void) close(afd);
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar afd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartear_down:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer[
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].tb_seek_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar if (afd > 0)
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar (void) close(afd);
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar /* closedir closes fd too */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) closedir(dp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarerr_out:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(attrname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(snapname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_output_file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put this file into the output buffers.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarlonglong_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_output_file(char *dir, char *name, char *chkdir,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *tlm_acls, tlm_commands_t *commands, tlm_cmd_t *local_commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *job_stats, struct hardlink_q *hardlink_q)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *fullname; /* directory + name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *snapname; /* snapshot name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *linkname; /* where this file points */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int section = 0; /* section of a huge file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int fd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t real_size; /* the origional file size */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t file_size; /* real size of this file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t seek_spot = 0; /* location in the file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* for Multi Volume record */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_longlong_t pos;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *fnamep;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Indicate whether a file with the same inode has been backed up. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int hardlink_done = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If a file with the same inode has been backed up, hardlink_pos holds
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the tape offset of the data record.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar u_longlong_t hardlink_pos = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tlm_is_too_long(tlm_acls->acl_checkpointed, dir, name)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Path too long [%s][%s]", dir, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-TLM_NO_SCRATCH_SPACE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fullname = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar linkname = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar snapname = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fullname == NULL || linkname == NULL || snapname == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar real_size = -TLM_NO_SCRATCH_SPACE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tlm_cat_path(fullname, dir, name) ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar !tlm_cat_path(snapname, chkdir, name)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Path too long.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar real_size = -TLM_NO_SCRATCH_SPACE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pos = tlm_get_data_offset(local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "pos: %10lld [%s]", pos, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar if (S_ISPECIAL(tlm_acls->acl_attr.st_mode)) {
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar if (S_ISLNK(tlm_acls->acl_attr.st_mode)) {
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar file_size = tlm_readlink(fullname, snapname, linkname,
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar TLM_MAX_PATH_NAME-1);
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar if (file_size < 0) {
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar real_size = -ENOENT;
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar goto err_out;
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Since soft links can not be read(2), we should only
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * backup the file header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_file_header(fullname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar linkname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_log_fhnode(job_stats, dir, name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &tlm_acls->acl_attr, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_log_fhpath_name(job_stats, fullname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &tlm_acls->acl_attr, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(linkname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(snapname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fnamep = (tlm_acls->acl_checkpointed) ? snapname : fullname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For hardlink, only read the data if no other link
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * belonging to the same inode has been backed up.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tlm_acls->acl_attr.st_nlink > 1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_done = !hardlink_q_get(hardlink_q,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls->acl_attr.st_ino, &hardlink_pos, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!hardlink_done) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Open the file for reading.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fd = open(fnamep, O_RDONLY);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "BACKUP> Can't open file [%s][%s] err(%d)",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar fullname, fnamep, errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar real_size = -TLM_NO_SOURCE_FILE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar NDMP_LOG(LOG_DEBUG, "found hardlink, inode = %llu, pos = %llu ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls->acl_attr.st_ino, hardlink_pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fd = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar linkname[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar real_size = tlm_acls->acl_attr.st_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_acl_header(&tlm_acls->acl_info,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * section = 0: file is small enough for TAR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * section > 0: file goes out in TLM_MAX_TAR_IMAGE sized chunks
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and the file name gets munged
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size = real_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (file_size > TLM_MAX_TAR_IMAGE) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (output_humongus_header(fullname, file_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar real_size = -TLM_NO_SCRATCH_SPACE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto err_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For hardlink, if other link belonging to the same inode
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * has been backed up, only backup an empty record.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (hardlink_done)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * work
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (file_size == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_file_header(fullname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar linkname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this can fall right through since zero size files
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will be skipped by the WHILE loop anyway
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (file_size > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int section_size = llmin(file_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (longlong_t)TLM_MAX_TAR_IMAGE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls->acl_attr.st_size = (longlong_t)section_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_file_header(fullname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar linkname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (section_size > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int read_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (commands->tcs_reader != TLM_BACKUP_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_writer = TLM_ABORT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer[
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tb_file_size = section_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer[
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tb_seek_spot = seek_spot;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buf = get_write_buffer(section_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, FALSE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!buf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (commands->tcs_reader != TLM_BACKUP_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_writer = TLM_ABORT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar read_size = min(section_size, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar actual_size = read(fd, buf, read_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_ADD(rdisk, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_INC(rfile);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (actual_size == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (actual_size == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "problem(%d) reading file [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar errno, fullname, snapname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto tear_down;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar seek_spot += actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size -= actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section_size -= actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If data belonging to this hardlink has been backed up, add the link
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to hardlink queue.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tlm_acls->acl_attr.st_nlink > 1 && !hardlink_done) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) hardlink_q_add(hardlink_q, tlm_acls->acl_attr.st_ino,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pos, NULL, 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar "backed up hardlink file %s, inode = %llu, pos = %llu ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fullname, tlm_acls->acl_attr.st_ino, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For hardlink, if other link belonging to the same inode has been
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar * backed up, no add_node entry should be sent for this link.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (hardlink_done) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar "backed up hardlink link %s, inode = %llu, pos = %llu ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fullname, tlm_acls->acl_attr.st_ino, hardlink_pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_log_fhnode(job_stats, dir, name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &tlm_acls->acl_attr, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_log_fhpath_name(job_stats, fullname, &tlm_acls->acl_attr,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartear_down:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer[
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].tb_seek_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(fd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarerr_out:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(linkname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(snapname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (real_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tar_putfile
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Main file backup function for tar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartar_putfile(char *dir, char *name, char *chkdir,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *tlm_acls, tlm_commands_t *commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct hardlink_q *hardlink_q)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = tlm_output_file(dir, name, chkdir, tlm_acls, commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands, job_stats, hardlink_q);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = tlm_output_xattr(dir, name, chkdir, tlm_acls, commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands, job_stats);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv < 0 ? rv : 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * get_write_buffer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a wrapper to tlm_get_write_buffer so that
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we can cleanly detect ABORT commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * without involving the TLM library with
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * our problems.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarget_write_buffer(long size, long *actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t zero, tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (local_commands->tc_reader == TLM_BACKUP_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rec = tlm_get_write_buffer(size, actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers, zero);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rec != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rec);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define NDMP_MORE_RECORDS 2
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * write_tar_eof
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This function is initially written for NDMP support. It appends
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * two tar headers to the tar file, and also N more empty buffers
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to make sure that the two tar headers will be read as a part of
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a mover record and don't get locked because of EOM on the mover
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * side.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarwrite_tar_eof(tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffers_t *bufs;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output 2 zero filled records,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TAR wants this.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) get_write_buffer(sizeof (tlm_tar_hdr_t),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) get_write_buffer(sizeof (tlm_tar_hdr_t),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP: Clear the rest of the buffer and write two more buffers
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to the tape.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs = local_commands->tc_buffers;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) get_write_buffer(bufs->tbs_data_transfer_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < NDMP_MORE_RECORDS &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_reader == TLM_BACKUP_RUN; i++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * We don't need the return value of get_write_buffer(),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * since it's already zeroed out if the buffer is returned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) get_write_buffer(bufs->tbs_data_transfer_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, TRUE, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_buffer[bufs->tbs_buffer_in].tb_full = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffer_release_in_buf(bufs);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Callback to backup each ZFS property
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarzfs_put_prop_cb(int prop, void *pp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_handle_t *mhd;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_header_ext_t *mhp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_property_ext_t *mpp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar char vbuf[ZFS_MAXPROPLEN];
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar char sbuf[ZFS_MAXPROPLEN];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zprop_source_t stype;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar char *sourcestr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (pp == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (ZPROP_INVAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhd = (ndmp_metadata_handle_t *)pp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp = mhd->ml_xhdr;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mpp = &mhp->nh_property[mhp->nh_count];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (mhp->nh_count * sizeof (ndmp_metadata_property_ext_t) +
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (ndmp_metadata_header_ext_t) > mhp->nh_total_bytes)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (ZPROP_INVAL);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (zfs_prop_get(mhd->ml_handle, prop, vbuf, sizeof (vbuf),
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar &stype, sbuf, sizeof (sbuf), B_TRUE) != 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp->nh_count++;
674cb4b09c0706bc1cb658e79f39997d43bad8a0Reza Sabdar return (ZPROP_CONT);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
674cb4b09c0706bc1cb658e79f39997d43bad8a0Reza Sabdar
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) strlcpy(mpp->mp_name, zfs_prop_to_name(prop),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens ZFS_MAX_DATASET_NAME_LEN);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_value, vbuf, ZFS_MAXPROPLEN);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar switch (stype) {
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar case ZPROP_SRC_NONE:
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar sourcestr = "none";
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar break;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar case ZPROP_SRC_RECEIVED:
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sourcestr = "received";
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar break;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar case ZPROP_SRC_LOCAL:
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar sourcestr = mhp->nh_dataset;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar break;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar case ZPROP_SRC_TEMPORARY:
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar sourcestr = "temporary";
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar break;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar case ZPROP_SRC_DEFAULT:
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar sourcestr = "default";
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar break;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar default:
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar sourcestr = sbuf;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar break;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_source, sourcestr, ZFS_MAXPROPLEN);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp->nh_count++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (ZPROP_CONT);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar/*
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar * Callback to backup each ZFS user/group quota
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarstatic int
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarzfs_put_quota_cb(void *pp, const char *domain, uid_t rid, uint64_t space)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar{
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_handle_t *mhd;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_header_ext_t *mhp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_property_ext_t *mpp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar char *typestr;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (pp == NULL)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (ZPROP_INVAL);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhd = (ndmp_metadata_handle_t *)pp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp = mhd->ml_xhdr;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mpp = &mhp->nh_property[mhp->nh_count];
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (mhp->nh_count * sizeof (ndmp_metadata_property_ext_t) +
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (ndmp_metadata_header_ext_t) > mhp->nh_total_bytes)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (ZPROP_INVAL);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (mhd->ml_quota_prop == ZFS_PROP_USERQUOTA)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar typestr = "userquota";
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar else
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar typestr = "groupquota";
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens if (domain == NULL || *domain == '\0') {
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(mpp->mp_name, ZFS_MAX_DATASET_NAME_LEN,
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens "%s@%llu", typestr, (longlong_t)rid);
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens } else {
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(mpp->mp_name, ZFS_MAX_DATASET_NAME_LEN,
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens "%s@%s-%llu", typestr, domain, (longlong_t)rid);
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) snprintf(mpp->mp_value, ZFS_MAXPROPLEN, "%llu", space);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_source, mhp->nh_dataset, ZFS_MAXPROPLEN);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp->nh_count++;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (0);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar}
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar/*
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar * Callback to count each ZFS property
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar/*ARGSUSED*/
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarstatic int
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarzfs_count_prop_cb(int prop, void *pp)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar{
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (*(int *)pp)++;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (ZPROP_CONT);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar}
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar/*
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar * Callback to count each ZFS user/group quota
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar/*ARGSUSED*/
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarstatic int
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarzfs_count_quota_cb(void *pp, const char *domain, uid_t rid, uint64_t space)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar{
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (*(int *)pp)++;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (0);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar}
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar/*
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar * Count the number of ZFS properties and user/group quotas
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarint
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarzfs_get_prop_counts(zfs_handle_t *zhp)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar{
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar int count = 0;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_t *uprops;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvpair_t *elp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (zhp == NULL)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (0);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zprop_iter(zfs_count_prop_cb, &count, TRUE, TRUE,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ZFS_TYPE_VOLUME | ZFS_TYPE_DATASET);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(zhp, ZFS_PROP_USERQUOTA, zfs_count_quota_cb,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar &count);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(zhp, ZFS_PROP_GROUPQUOTA, zfs_count_quota_cb,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar &count);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar uprops = zfs_get_user_props(zhp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar elp = nvlist_next_nvpair(uprops, NULL);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar for (; elp != NULL; elp = nvlist_next_nvpair(uprops, elp))
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar count++;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (count);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Notifies ndmpd that the metadata associated with the given ZFS dataset
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * should be backed up.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_include_zfs(ndmp_context_t *nctx, const char *dataset)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_commands_t *cmds;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_handle_t mhd;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_header_ext_t *mhp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_property_ext_t *mpp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar zfs_handle_t *zhp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *lcmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_t *uprops, *ulist;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar const char *pname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvpair_t *elp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *sval, *ssrc;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *wbuf, *pp, *tp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size, lsize, sz;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int align = RECORDSIZE - 1;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar int pcount;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((lcmd = cmds->tcs_command) == NULL ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lcmd->tc_buffers == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) mutex_lock(&zlib_mtx);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if ((zhp = zfs_open(zlibh, dataset, ZFS_TYPE_DATASET)) == NULL) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) mutex_unlock(&zlib_mtx);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar pcount = zfs_get_prop_counts(zhp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar size = sizeof (ndmp_metadata_header_ext_t) +
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar pcount * sizeof (ndmp_metadata_property_ext_t);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size += align;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size &= ~align;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if ((mhp = malloc(size)) == NULL) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar zfs_close(zhp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(mhp, 0, size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhd.ml_handle = zhp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhd.ml_xhdr = mhp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp->nh_total_bytes = size;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp->nh_major = META_HDR_MAJOR_VERSION;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp->nh_minor = META_HDR_MINOR_VERSION;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mhp->nh_plversion = nctx->nc_plversion;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(mhp->nh_plname, nctx->nc_plname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (mhp->nh_plname));
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mhp->nh_magic, ZFS_META_MAGIC_EXT,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (mhp->nh_magic));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(mhp->nh_dataset, dataset, sizeof (mhp->nh_dataset));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Get all the ZFS properties */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zprop_iter(zfs_put_prop_cb, &mhd, TRUE, TRUE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ZFS_TYPE_VOLUME | ZFS_TYPE_DATASET);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Get user properties */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar uprops = zfs_get_user_props(mhd.ml_handle);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar elp = nvlist_next_nvpair(uprops, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (elp != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mpp = &mhp->nh_property[mhp->nh_count];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nvpair_value_nvlist(elp, &ulist) != 0 ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_lookup_string(ulist, ZPROP_VALUE, &sval) != 0 ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_lookup_string(ulist, ZPROP_SOURCE, &ssrc) != 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar zfs_close(mhd.ml_handle);
89f9eb8701145fa396cfc2ac0b468bd5c8466494Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(mhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens if ((pname = nvpair_name(elp)) != NULL) {
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) strlcpy(mpp->mp_name, pname,
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens ZFS_MAX_DATASET_NAME_LEN);
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_value, sval, ZFS_MAXPROPLEN);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_source, ssrc, ZFS_MAXPROPLEN);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mhp->nh_count++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar elp = nvlist_next_nvpair(uprops, elp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhd.ml_quota_prop = ZFS_PROP_USERQUOTA;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(mhd.ml_handle, ZFS_PROP_USERQUOTA,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar zfs_put_quota_cb, &mhd);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhd.ml_quota_prop = ZFS_PROP_GROUPQUOTA;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(mhd.ml_handle, ZFS_PROP_GROUPQUOTA,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar zfs_put_quota_cb, &mhd);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhp->nh_count = pcount;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar zfs_close(mhd.ml_handle);
89f9eb8701145fa396cfc2ac0b468bd5c8466494Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((wbuf = get_write_buffer(size, &actual_size, TRUE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lcmd)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp = (char *)mhp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(wbuf, pp, (actual_size < size) ?
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar actual_size : size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp += (actual_size < size) ? actual_size : size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sz = actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (sz < size &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((tp = get_write_buffer(size - sz, &lsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TRUE, lcmd))) != NULL) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) memcpy(tp, pp, lsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sz += lsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp += lsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (sz > size) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_write_buffer(lcmd->tc_buffers, sz - size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(mhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}