5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * Copyright 2013 Nexenta Systems, Inc. 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.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define PM_EXACT_OR_CHILD(m) ((m) == PM_EXACT || (m) == PM_CHILD)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl#define ERROR_IS_FATAL(err) ((err) == ENOSPC || (err) == EDQUOT)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef boolean_t name_match_fp_t(char *s, char *t);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdarstatic int create_special(char,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *rs_new_name(struct rs_name_maker *rnp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dtree_push
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardtree_push(cstack_t *stp, char *nmp, tlm_acls_t *acls)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(&sp->se_acls, acls, sizeof (*acls));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cstack_push(stp, (void *)sp, sizeof (*sp)));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = cstack_pop(stp, (void **)&sp, (void *)NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dtree_peek
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = cstack_top(stp, (void **)&sp, (void *)NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NBU and EBS may not send us the correct file list containing hardlinks
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * during a DAR restore, e.g. they appear always send the first name
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * associated with an inode, even if other link names were
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * selected for the restore. As a workaround, we use the file name entry
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in sels[] (ignore the name in the tar header) as restore target.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarrs_darhl_new_name(struct rs_name_maker *rnp, char *name, char **sels, int *pos,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(longname, sels[x], TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "to replace hardlink name [%s], pos [%d]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rs_new_name(rnp, name, *pos, longname));
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar * Main dir restore function for tar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * If this function returns non-zero return value it means that fatal error
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * was encountered.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* ...need to preserve across volume changes */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t huge_size = 0; /* size of a HUGE file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long acl_spot; /* any ACL info on the next volume */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size_left = 0; /* need this after volume change */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int last_action = 0; /* what we are doing at EOT */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t multi_volume = FALSE; /* is this a multi-volume switch ? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * if an exact match is found for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restore and its position in the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * selections list
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int nzerohdr; /* the number of empty tar headers */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The directory where temporary files may be created during a partial
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * non-DAR restore of hardlinks. It is intended to be initialized by
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * an environment variable that can be set by user.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * It is not initialized for now. We keep it here for future use.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (longname == NULL || longlink == NULL || hugename == NULL ||
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar name == NULL || acls == NULL || stp == NULL || parentlnk == NULL ||
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl local_commands->tc_writer != TLM_STOP && rv == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* The inode of an LF_LINK type. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Indicate whether a file with the same inode has been
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* The path of the restored hardlink file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Whether a temporary file should be created for restoring
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* used to make up hardlink_tmp_name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the previous volume is out of data
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and is back in the rack, a new tape
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is loaded and ready to read.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * We need to pick up where we left off.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(&fake_tar_hdr, 0, sizeof (fake_tar_hdr));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(want,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we can ignore read errors here because
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 1) they are logged by Restore Reader
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 2) we are not doing anything important here
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * just looking for the next work record.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * EOF hits here
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * wait for another buffer to come along
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * or until the Reader thread tells us
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * that no more tapes will be loaded ...
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * time to stop.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for "we are lost"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* one of the end of tar file marks */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "nzerohdr %d, breaking",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* end of tar file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (chk_rv < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* skip this record */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * When files are spanned to the next tape, the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * information of the acls must not be over-written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * by the information of the LF_MULTIVOL and LF_VOLHDR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * header, whose information is irrelevant to the file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The information of the original header must be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * kept in the 'acl'.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "n [%s] f [%c] s %lld m %o u %d g %d t %d",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * If the restore is running using DAR we should check for
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar * extended attribute entries
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar rs_create_new_bkpath(bk_path, tar_hdr->th_name, thname_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if we have restored a link with the same inode
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the inode is 0, we have to restore it as a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * regular file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "found hardlink, inode = %u, target = [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* create a hardlink to hardlink_target */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This means that DMA did not send us
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the correct fh_info for the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in restore list. We use the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * name entry in sels[] (ignore the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * name in the tar header) as restore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "can't make name for %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "restored %s -> %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "no target for hardlink %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* otherwise fall through, restore like a normal file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*FALLTHROUGH*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for TAR's end-of-tape method
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of zero filled records.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * otherwise fall through,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this is an old style normal file header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*FALLTHROUGH*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (*longname == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for old tar format, it
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * does not have a leading "/"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = is_file_wanted(longname, sels, exls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This means that DMA did not send us valid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * fh_info for the file in restore list. We
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * use the file name entry in sels[] (ignore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the name in the tar header) as restore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(parentlnk, nmp, strlen(nmp) + 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For a hardlink, even if it's not asked to be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restored, we restore it to a temporary location,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in case other links to the same file need to be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restored later.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The temp files are created in tmplink_dir, with
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * names like ".tmphlrsnondar*". They are cleaned up
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * at the completion of a restore. However, if a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restore were interrupted, e.g. by a system reboot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * they would have to be cleaned up manually in order
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * for the disk space to be freed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If tmplink_dir is NULL, no temperorary files are
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * created during a restore. This may result in some
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * hardlinks not being restored during a partial
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_hardlink && !DAR && !want_this_file && !nmp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "To restore temp hardlink file %s.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "No tmplink_dir specified.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar huge_size, acls, want_this_file, local_commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In the case of non-DAR, we have to record the first
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * link for an inode that has multiple links. That's
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the only link with data records actually backed up.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In this way, when we run into the other links, they
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will be treated as links, and we won't go to look
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * for the data records to restore. This is not a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * problem for DAR, where DMA tells the tape where
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to locate the data records.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "failed to add (%u, %s) to HL q",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* remove / reverse the temporary stuff */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if it is time to set the attribute
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of the restored directory
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (nmp && ((bkpath = dtree_peek(stp)) != NULL)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "sizeleft %s %d, %lld", longname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Add an entry to hardlink_q to record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this hardlink.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Restored hardlink file %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "file_name[%s]", file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "link_name[%s]", link_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_file_wanted(file_name, sels, exls, flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_file_wanted(file_name, sels, exls, flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if it is time to set
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the attribute of the restored
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_file_wanted(file_name, sels, exls, flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left = get_long_name(lib, drv, file_size, longlink,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "fsize %d sleft %d lnkend %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left = get_long_name(lib, drv, file_size, longname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "fsize %d sleft %d nmend %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left = load_acl_info(lib, drv, file_size, acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) get_humongus_file_header(lib, drv, file_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the restore is running using DAR we should check for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * long file names and HUGE file sizes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Main file restore function for tar (should run as a thread)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* the restore job name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(job, argp->ba_job, TLM_MAX_BACKUP_JOB_NAME+1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(dir, argp->ba_dir, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * do not test for "dir" having no string, since that
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is a legal condition. Restore to origional location
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will not have a restore directory.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * let the launcher continue
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "start restore job %s", job);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar erc = tar_getdir(commands, local_commands, job_stats, &rn, 1, 1,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Creates the directories all the way down to the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * end if they dont exist
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar " creating directory %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Creates the directories leading to the given path
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read the file off the tape back onto disk
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * If the function returns a non-zero return code, it means that fatal error
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * was encountered and restore should terminate immediately.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * OK, some FM is creeping in here ...
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * int *fp is used to keep the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * backup file channel open through
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the interruption of EOT and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * processing the headers of the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * next tape. So, if *fp is zero
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * then no file is open yet and all
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is normal. If *fp has a number
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * then we are returning after an
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * EOT break.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * *fp is now also open for HUGE files
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * that are put back in sections.
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ret != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* new file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* take this file no matter what */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* tape is newer */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* disk file is newer */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * no overwrite, no update,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * do not ever replace old files.
c211fc479225fa54805cf480633bf6689ca9a2dbReza Sabdar *fp = open(real_name, O_CREAT | O_TRUNC | O_WRONLY,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "Could not open %s for restore: %d",
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * In case of non-fatal error we cannot return
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * here, because the file is still on the tape
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * and must be skipped over.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(local_commands->tc_file_name, real_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this is the size left in the next segment
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use bytes_in_file field to tell reader the amount
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of data still need to be read for this file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = get_read_buffer(size, &error, &actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "RESTORE WRITER> error %d, actual_size %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* no more data for this file for now */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (error) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "Partial write for file [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* no more data for this file for now */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (rv == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set the extended attributes file attribute
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_read_one_buf(char *rec, int actual_size, int size, int *error,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar p = get_read_buffer(size - actual_size, error, &read_size, lc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read the extended attribute header and write
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * it to the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xhdr = (struct xattr_hdr *)get_read_buffer(size, &error,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not read xattr [%s:%s] for restore. ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Check extended attribute header */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strcmp(xhdr->h_version, XATTR_ARCH_VERS) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Unrecognized header format [%s]", xhdr->h_version);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xbuf = (struct xattr_buf *)(((char *)xhdr) + sizeof (struct xattr_hdr));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xattrname = xbuf->h_names + strlen(xbuf->h_names) + 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*fp == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fd = attropen(name, xattrname, O_CREAT | O_RDWR, 0755);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "Could not open xattr [%s:%s] for restore err=%d.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(local_commands->tc_file_name, xattrname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Get the actual extended attribute file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(sizeof (*tar_hdr),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not read xattr data [%s:%s] for restore. ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_mode = oct_atoi(tar_hdr->th_mode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_size = oct_atoi(tar_hdr->th_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_uid = oct_atoi(tar_hdr->th_uid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_gid = oct_atoi(tar_hdr->th_gid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_mtime = oct_atoi(tar_hdr->th_mtime);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "xattr_hdr: %s size %d mode %06o uid %d gid %d",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar xattrname, acls->acl_attr.st_size, acls->acl_attr.st_mode,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = get_read_buffer(size, &error, &actual_size,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((actual_size < size) && sysattr_rw(xattrname)) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar rec = get_read_one_buf(rec, actual_size, size, &error,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "RESTORE WRITER> error %d, actual_size %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (error) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((write_size = write(*fp, rec, write_size)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*fp != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Match the name with the list
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "exact_find> found[%s]", cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * On error, return FALSE and prevent restoring(probably) unwanted data.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Used to match the filename inside the list
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if the file is needed to be restored
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (name == NULL || sels == NULL || exls == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For empty selection, restore everything
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "is_file_wanted: Restore all");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(uc_name, namep, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "is_file_wanted> flg: 0x%x name: [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Try exact match.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Try "entry/" and the current selection. The
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * current selection may be something like "<something>/".
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the following check returns true it means that the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 'name' is an entry below the 'p_sel' hierarchy.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * There is a special case for parent directories of a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * selection. If 'p_sel' is something like "*d1", the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * middle directories of the final entry can't be determined
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * until the final entry matches with 'p_sel'. At that
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * time the middle directories of the entry have been passed
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and they can't be restored.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Check for exclusions. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Read the specified amount data into the buffer. Detects EOT or EOF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * during read.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the number of bytes actually read. On error returns -1.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (toread > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = get_read_buffer(toread, &err, &actual_size, lcmds);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "err %d act_size %d detected",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (err) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "error %d reading data", err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * pick up the name and size of a HUGE file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "HUGE Record found: %d", recsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The humongus_file_header was written in a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * RECORDSIZE block and the header.size field of this
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * record was 0 before this fix. For backward compatiblity
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read only one RECORDSIZE-size block if the header.size
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * field is 0. Otherwise the header.size field should show
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the length of the data of this header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (input_mem(lib, drv, local_commands, name, recsize) != recsize) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error reading a HUGE file name");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Note: Since the backed up names are not longer than
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NAME_MAX and the buffer passed to us is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TLM_MAX_PATH_NAME, it should be safe to use strlcpy
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * without check on the buffer size.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(name, p_record, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "HUGE Record %lld [%s]", *size, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * pick up the long name from the special tape file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "LONGNAME Record found rs %d bs %d", recsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nread = input_mem(lib, drv, local_commands, name + *buf_spot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Error %d reading a long file name %s.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * create a new directory
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcreate_directory(char *dir, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Make sure all directories in this path exist, create them if
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "Could not create directory %s: %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (temp != 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * create a new hardlink
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl /* Nothing to do if the destination already exists */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "error %d (errno %d) hardlink [%s] to [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * create a new symlink
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcreate_sym_link(char *dst, char *target, tlm_acls_t *acls,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NDMP_LOG(LOG_DEBUG, "error %d softlink [%s] to [%s]",
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar * create a new FIFO, char/block device special files
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdarcreate_special(char flag, char *name, tlm_acls_t *acls, int major, int minor,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar return (-1);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar /* Remove the old entry first */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read in the ACLs for the next file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the ACL is spanned on tapes, then the acl_spot should NOT be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on next calls to this function to read the rest of the ACL
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * on next tapes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nread = input_mem(lib, drv, local_commands, (void *)bp, file_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_PROC_AUDIT);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_PROC_SETID);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_PROC_OWNER);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_CHOWN);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_CHOWN_SELF);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_DAC_READ);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_DAC_SEARCH);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_DAC_WRITE);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_OWNER);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_SETID);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_LINKDIR);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_DEVICES);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_MOUNT);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_CONFIG);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Additional privileges required.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Additional privileges required.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set the standard attributes of the file
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "set_attr: %s uid %d gid %d uname %s gname %s "
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "mode %o", name, st->st_uid, st->st_gid, acls->uname, acls->gname,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "set_attr: new uid %d old %d",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "set_attr: new gid %d old %d",
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not set uid or/and gid for file %s.", name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Change effective privileges to 'all' which is required to
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * change setuid bit for 'root' owned files. If fails, just
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * send error to log file and proceed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not set effective privileges to 'all'.");
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Give up the 'all' privileges for effective sets and go back
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to least required privileges. If fails, just send error to
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * log file and proceed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not set least required privileges.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set the ACL info for the file
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl /* Need a place to save real modification time */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = acl_fromtext(acls->acl_info.attr_info, &aclp);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a wrapper to tlm_get_read_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_writer == TLM_RESTORE_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the job is ending, give Writer a buffer that will never be read ...
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * it does not matter anyhow, we are aborting.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Enable wildcard for restore options
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = ndmpd_get_prop_default(NDMP_RESTORE_WILDCARD_ENABLE, "n");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Concatenate two names
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcatnames(struct rs_name_maker *rnp, char *buf, int pos, char *path)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!path) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "rn_nlp is NULL [%s]", path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!tlm_cat_path(buf, rnp->rn_nlp, path)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Create a new name path for restore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarrs_new_name(struct rs_name_maker *rnp, char *buf, int pos, char *path)
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar * Clear the extra "/" in the tar header if exists
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdarrs_create_new_bkpath(char *bk_path, char *path, char *pbuf)
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar (void) snprintf(pbuf, TLM_MAX_PATH_NAME, "%s%s", bk_path, p);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar (void) snprintf(pbuf, TLM_MAX_PATH_NAME, "%s/%s", bk_path, p);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar NDMP_LOG(LOG_DEBUG, "old path [%s] new path [%s]", path, pbuf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Iterate over ZFS metadata stored in the backup stream and use the callback
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to restore it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_iter_zfs(ndmp_context_t *nctx, int (*np_restore_property)(nvlist_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar void *), void *ptr)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* Default minimum bytes needed */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ZFS_MAX_PROPS * sizeof (ndmp_metadata_property_t);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* No more metadata */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(pp, (char *)mhp, (actual_size < size) ?
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp += (actual_size < size) ? actual_size : size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_read_buffer(lcmd->tc_buffers, sz - size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* New metadata format */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* LINTED improper alignment */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* Major header mismatch */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* Minor header mismatch */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar "metadata header mismatch m%d != m%d",
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar for (i = 0; i < mhpx->nh_count && mppx; i++, mppx++) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar for (i = 0; i < mhp->nh_count && mpp; i++, mpp++) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL &&
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the version number of the plugin which created the metadata
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* No more metadata */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);