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 * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
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 * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
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 * - 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 * 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.
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar#define S_ISPECIAL(a) (S_ISLNK(a) || S_ISFIFO(a) || S_ISBLK(a) || \
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_mem
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Gets a IO write buffer and copies memory to the that.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (len > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_output_dir
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put the directory information into the output buffers.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Send the node or path history of the directory itself.
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 (void) output_file_header(name, "", tlm_acls, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tar_putdir
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Main dir backup function for tar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = tlm_output_dir(name, tlm_acls, local_commands, job_stats);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_acl_header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output the ACL header record and data
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((acl_info == NULL) || (*acl_info->attr_info == '\0'))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(acl_info->attr_len, sizeof (acl_info->attr_len),
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 (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode), "%06o ",
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) output_mem(local_commands, (void *)acl_info, acl_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_humongus_header
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 Sabdaroutput_humongus_header(char *fullname, longlong_t file_size,
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 if ((buf = ndmp_malloc(sizeof (char) * len)) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(buf, len, "%lld %s", file_size, fullname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_xattr_header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output the TAR header record for extended attributes
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 char *section_name = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "output_file_header stat failed.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * if the file has to go out in sections,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we must mung the name.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(section_name, TLM_MAX_PATH_NAME,
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 tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_name, section_name, TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime), "%011o ",
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);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xhdr = (struct xattr_hdr *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xhdr->h_version, sizeof (xhdr->h_version), "%s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xhdr->h_size, sizeof (xhdr->h_size), "%0*d",
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 sizeof (struct xattr_hdr));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(xbuf->h_namesz, sizeof (xbuf->h_namesz), "%0*d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* No support for links in extended attributes */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(xbuf->h_names, fname, TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(&xbuf->h_names[strlen(fname) + 1], aname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output_file_header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * output the TAR header record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *tlm_acls, int section, tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *section_name = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * if the file has to go out in sections,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we must mung the name.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(section_name, name, TLM_MAX_PATH_NAME);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((ulong_t)(uid = attr->st_uid) > (ulong_t)OCTAL7CHAR)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((ulong_t)(gid = attr->st_gid) > (ulong_t)OCTAL7CHAR)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * file name is too big, it must go out
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in its own data file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%s%08qd.fil",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_uname, sizeof (tar_hdr->th_uname),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_gname, sizeof (tar_hdr->th_gname),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * link name is too big, it must go out
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in its own data file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_uname, sizeof (tar_hdr->th_uname),
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_gname, sizeof (tar_hdr->th_gname),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_write_buffer(RECORDSIZE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%s%08qd.fil",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_name, section_name, TLM_NAME_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "long_link: %s [%s]", long_link ? "TRUE" : "FALSE",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tar_hdr->th_linkname, link, TLM_NAME_SIZE);
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 (void) snprintf(tar_hdr->th_shared.th_dev.th_devminor,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar sizeof (tar_hdr->th_shared.th_dev.th_devminor), "%06o ",
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar /* mark file with hardlink LF_LINK */
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar (void) snprintf(tar_hdr->th_shared.th_hlink_ino,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_size, sizeof (tar_hdr->th_size), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mode, sizeof (tar_hdr->th_mode), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_uid, sizeof (tar_hdr->th_uid), "%06o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_gid, sizeof (tar_hdr->th_gid), "%06o ",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_uname, sizeof (tar_hdr->th_uname), "%.31s",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) snprintf(tar_hdr->th_gname, sizeof (tar_hdr->th_gname), "%.31s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(tar_hdr->th_mtime, sizeof (tar_hdr->th_mtime), "%011o ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_readlink
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 Sabdartlm_readlink(char *nm, char *snap, char *buf, int bufsize)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((len = readlink(snap, buf, bufsize)) >= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * realink(2) doesn't null terminate the link name. We must
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * do it here.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error %d reading softlink of [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Backup the link if the destination missing */
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 Sabdarstatic char *
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdarget_write_one_buf(char *buf, char *rec, int buf_size, int rec_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_output_xattr
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put this file into the output buffers.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_output_xattr(char *dir, char *name, char *chkdir,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t seek_spot = 0; /* location in the file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* for Multi Volume record */
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (pathconf(fullname, _PC_XATTR_EXISTS) != 1 &&
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar sysattr_support(fullname, _PC_SATTR_EXISTS) != 1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fnamep = (tlm_acls->acl_checkpointed) ? snapname : fullname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Open the file for reading.
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "BACKUP> Can't open file [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "pos: %10lld [%s]", pos, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "BACKUP> Can't open file [%s]", fullname);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "problem(%d) opening xattr file [%s][%s]", errno,
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar (void) output_xattr_header(fullname, dtp->d_name, afd,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(attrname, TLM_MAX_PATH_NAME, "/dev/null/%s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) output_file_header(attrname, "", tlm_acls, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar section_size = (long)llmin(tlm_acls->acl_attr.st_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* We only can read upto one section extended attribute */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar if ((actual_size = read(afd, buf, read_size)) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "problem(%d) reading file [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].tb_seek_spot = 0;
0fd800607f9e1d26f56908606b5ab776694af8d7Reza Sabdar /* closedir closes fd too */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_output_file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put this file into the output buffers.
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 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 /* Indicate whether a file with the same inode has been backed up. */
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 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 if (fullname == NULL || linkname == NULL || snapname == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "pos: %10lld [%s]", pos, name);
295e611f647a9229cb7b346b6febc77618b605c4Reza Sabdar file_size = tlm_readlink(fullname, snapname, linkname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Since soft links can not be read(2), we should only
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * backup the file header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fnamep = (tlm_acls->acl_checkpointed) ? snapname : fullname;
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 tlm_acls->acl_attr.st_ino, &hardlink_pos, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Open the file for reading.
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "BACKUP> Can't open file [%s][%s] err(%d)",
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar NDMP_LOG(LOG_DEBUG, "found hardlink, inode = %llu, pos = %llu ",
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 * For hardlink, if other link belonging to the same inode
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * has been backed up, only backup an empty record.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this can fall right through since zero size files
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will be skipped by the WHILE loop anyway
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (file_size > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls->acl_attr.st_size = (longlong_t)section_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for Abort commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "problem(%d) reading file [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If data belonging to this hardlink has been backed up, add the link
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to hardlink queue.
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,
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar "backed up hardlink file %s, inode = %llu, pos = %llu ",
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.
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar "backed up hardlink link %s, inode = %llu, pos = %llu ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fullname, tlm_acls->acl_attr.st_ino, hardlink_pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_log_fhpath_name(job_stats, fullname, &tlm_acls->acl_attr,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers->tbs_buffer_in].tb_seek_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tar_putfile
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Main file backup function for tar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = tlm_output_file(dir, name, chkdir, tlm_acls, commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = tlm_output_xattr(dir, name, chkdir, tlm_acls, commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * get_write_buffer
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 Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (local_commands->tc_reader == TLM_BACKUP_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rec = tlm_get_write_buffer(size, actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * write_tar_eof
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 * output 2 zero filled records,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TAR wants this.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP: Clear the rest of the buffer and write two more buffers
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to the tape.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) get_write_buffer(bufs->tbs_data_transfer_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < NDMP_MORE_RECORDS &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_reader == TLM_BACKUP_RUN; i++) {
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 (void) get_write_buffer(bufs->tbs_data_transfer_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_buffer[bufs->tbs_buffer_in].tb_full = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Callback to backup each ZFS property
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 if (zfs_prop_get(mhd->ml_handle, prop, vbuf, sizeof (vbuf),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) strlcpy(mpp->mp_name, zfs_prop_to_name(prop),
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_value, vbuf, ZFS_MAXPROPLEN);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_source, sourcestr, ZFS_MAXPROPLEN);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar * Callback to backup each ZFS user/group quota
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarzfs_put_quota_cb(void *pp, const char *domain, uid_t rid, uint64_t space)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (mhp->nh_count * sizeof (ndmp_metadata_property_ext_t) +
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (ndmp_metadata_header_ext_t) > mhp->nh_total_bytes)
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(mpp->mp_name, ZFS_MAX_DATASET_NAME_LEN,
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(mpp->mp_name, ZFS_MAX_DATASET_NAME_LEN,
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens "%s@%s-%llu", typestr, domain, (longlong_t)rid);
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 * Callback to count each ZFS property
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (*(int *)pp)++;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar * Callback to count each ZFS user/group quota
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdarzfs_count_quota_cb(void *pp, const char *domain, uid_t rid, uint64_t space)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (*(int *)pp)++;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar * Count the number of ZFS properties and user/group quotas
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zprop_iter(zfs_count_prop_cb, &count, TRUE, TRUE,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(zhp, ZFS_PROP_USERQUOTA, zfs_count_quota_cb,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(zhp, ZFS_PROP_GROUPQUOTA, zfs_count_quota_cb,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar for (; elp != NULL; elp = nvlist_next_nvpair(uprops, elp))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Notifies ndmpd that the metadata associated with the given ZFS dataset
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * should be backed up.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_include_zfs(ndmp_context_t *nctx, const char *dataset)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if ((zhp = zfs_open(zlibh, dataset, ZFS_TYPE_DATASET)) == NULL) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mhp->nh_magic, ZFS_META_MAGIC_EXT,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(mhp->nh_dataset, dataset, sizeof (mhp->nh_dataset));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Get all the ZFS properties */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zprop_iter(zfs_put_prop_cb, &mhd, TRUE, TRUE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Get user properties */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_lookup_string(ulist, ZPROP_VALUE, &sval) != 0 ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_lookup_string(ulist, ZPROP_SOURCE, &ssrc) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_value, sval, ZFS_MAXPROPLEN);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(mpp->mp_source, ssrc, ZFS_MAXPROPLEN);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(mhd.ml_handle, ZFS_PROP_USERQUOTA,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) zfs_userspace(mhd.ml_handle, ZFS_PROP_GROUPQUOTA,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((wbuf = get_write_buffer(size, &actual_size, TRUE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp += (actual_size < size) ? actual_size : size;