/* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * BSD 3 Clause License * * Copyright (c) 2007, The Storage Networking Industry Association. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * - Neither the name of The Storage Networking Industry Association (SNIA) * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include "ndmpd.h" #include #include #include #include #include #include #include #include "tlm_buffers.h" /* * Parameter passed to traverse for marking inodes * when traversing backup hierarchy in V2. It * includes: * mp_bmd: the bitmap describptor. * mp_ddate: backup date. * mp_session: pointer to the session structure. * mp_nlp: pointer to the nlp. * mp_tacl: pointer to the acl. */ typedef struct mark_param { int mp_bmd; time_t mp_ddate; ndmpd_session_t *mp_session; ndmp_lbr_params_t *mp_nlp; tlm_acls_t *mp_tacl; } mark_param_t; /* * Set this variable to non-zero to print the inodes * marked after traversing file system. */ static int ndmpd_print_inodes = 0; /* * Flag passed to traverse_post. */ static int ndmpd_mark_flags = 0; /* * Verbose traversing prints the file/dir path names * if they are being marked. */ static int ndmpd_verbose_traverse = 0; /* * Set this flag to count the number of inodes marked * after traversing backup hierarchy. */ static int ndmpd_mark_count_flag = 0; /* * Set this variable to non-zero value to force traversing * backup hierarchy for tar format. */ static int ndmp_tar_force_traverse = 0; /* * Set this variable to non-zero value to skip processing * directories both for tar and dump. */ static int ndmp_skip_traverse = 0; /* * count_bits_cb * * Call back for counting the set bits in the dbitmap. * * Parameters: * bmd (input) - bitmap descriptor * bn (input) - the bit number * arg (input) - pointer to the argument * * Returns: * 0: always */ static int count_bits_cb(int bmd, u_longlong_t bn, void *arg) { if (dbm_getone(bmd, bn)) { (*(u_longlong_t *)arg)++; if (ndmpd_print_inodes) NDMP_LOG(LOG_DEBUG, "%llu", bn); } return (0); } /* * count_set_bits * * Count bits set in the bitmap. * * Parameters: * path (input) - the backup path * bmd (input) - bitmap descriptor * * Returns: * void */ void count_set_bits(char *path, int bmd) { u_longlong_t cnt; if (!ndmpd_mark_count_flag) return; cnt = 0; (void) dbm_apply_ifset(bmd, count_bits_cb, &cnt); NDMP_LOG(LOG_DEBUG, "%s %llu inodes marked", path, cnt); } /* * traverse * * Starts the post-traverse the backup hierarchy. Checks * for exceptional cases, like aborting operation and if * asked, report detailed information after traversing. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * ftp (input) - pointer to the traverse parameters * * Returns: * 0: on success * != 0: otherwise */ int traverse(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, fs_traverse_t *ftp) { int rv; time_t s, e; if (!session || !nlp || !ftp) { NDMP_LOG(LOG_DEBUG, "Invalid argument"); return (-1); } NDMP_LOG(LOG_DEBUG, "Processing directories of \"%s\"", nlp->nlp_backup_path); (void) time(&s); if (traverse_post(ftp) != 0) { rv = -1; if (!session->ns_data.dd_abort && !NLP_ISSET(nlp, NLPF_ABORTED)) { NDMP_LOG(LOG_DEBUG, "Traversing backup path hierarchy \"%s\"", nlp->nlp_backup_path); } } else { (void) dbm_setone(nlp->nlp_bkmap, (u_longlong_t)ROOT_INODE); rv = 0; (void) time(&e); NDMP_LOG(LOG_DEBUG, "\"%s\" traversed in %u sec", nlp->nlp_backup_path, (uint_t)(e-s)); count_set_bits(nlp->nlp_backup_path, nlp->nlp_bkmap); } return (rv); } /* * mark_cb * * The callback function, called by traverse_post to mark bits * in the bitmap. * * Set the bit of the entry if it's been modified (obviously * should be backed up) plus its parent directory. * * If the entry is a directory and is not modified itself, * but it's marked, then there is something below it that * is being backed up. It shows the the path, leads to * an object that will be backed up. So the path should * be marked too. * * The backup path itself is always marked. * * Parameters: * arg (input) - pointer to the mark parameter * pnp (input) - pointer to the path node * enp (input) - pointer to the entry node * * Returns: * 0: as long as traversing should continue * != 0: if traversing should stop */ int mark_cb(void *arg, fst_node_t *pnp, fst_node_t *enp) { int bmd; int rv; u_longlong_t bl; time_t ddate; fs_fhandle_t *pfhp, *efhp; struct stat64 *pstp, *estp; mark_param_t *mpp; ndmp_lbr_params_t *nlp; tlm_acls_t *tacl; rv = 0; mpp = (mark_param_t *)arg; tacl = mpp->mp_tacl; nlp = ndmp_get_nlp(mpp->mp_session); if (!mpp) { NDMP_LOG(LOG_DEBUG, "NULL argument passed"); rv = -1; } else if (mpp->mp_session->ns_eof) { NDMP_LOG(LOG_INFO, "Connection to the client is closed"); rv = -1; } else if (mpp->mp_session->ns_data.dd_abort || (nlp && NLP_ISSET(nlp, NLPF_ABORTED))) { NDMP_LOG(LOG_INFO, "Processing directories aborted."); rv = -1; } if (rv != 0) return (rv); ddate = mpp->mp_ddate; bmd = mpp->mp_bmd; bl = dbm_getlen(bmd); pfhp = pnp->tn_fh; pstp = pnp->tn_st; /* sanity check on fh and stat of the path passed */ if (pstp->st_ino > bl) { NDMP_LOG(LOG_DEBUG, "Invalid path inode #%u", (uint_t)pstp->st_ino); return (-1); } if (pstp->st_ino != pfhp->fh_fid) { NDMP_LOG(LOG_DEBUG, "Path ino mismatch %u %u", (uint_t)pstp->st_ino, (uint_t)pfhp->fh_fid); return (-1); } /* * Always mark the backup path inode number. */ if (!enp->tn_path) { (void) dbm_setone(bmd, pstp->st_ino); return (0); } efhp = enp->tn_fh; estp = enp->tn_st; /* sanity check on fh and stat of the entry passed */ if (estp->st_ino > bl) { NDMP_LOG(LOG_DEBUG, "Invalid entry inode #%u", (uint_t)estp->st_ino); return (-1); } if (estp->st_ino != efhp->fh_fid) { NDMP_LOG(LOG_DEBUG, "Entry ino mismatch %u %u", estp->st_ino, (uint_t)pfhp->fh_fid); return (-1); } /* check the dates and mark the bitmap inode */ if (ddate == 0) { /* base backup */ (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); if (ndmpd_verbose_traverse) { NDMP_LOG(LOG_DEBUG, "Base Backup"); NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", pnp->tn_path, enp->tn_path); } } else if (estp->st_mtime > ddate) { (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); if (ndmpd_verbose_traverse) { NDMP_LOG(LOG_DEBUG, "m(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_mtime, (uint_t)ddate); NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", pnp->tn_path, enp->tn_path); } } else if (iscreated(nlp, NULL, tacl, ddate)) { (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); if (ndmpd_verbose_traverse) { NDMP_LOG(LOG_DEBUG, "cr(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_mtime, (uint_t)ddate); NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", pnp->tn_path, enp->tn_path); } } else if (estp->st_ctime > ddate) { if (!NLP_IGNCTIME(nlp)) { (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); } if (ndmpd_verbose_traverse) { if (NLP_IGNCTIME(nlp)) { NDMP_LOG(LOG_DEBUG, "ign c(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_ctime, (uint_t)ddate); } else { NDMP_LOG(LOG_DEBUG, "c(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_ctime, (uint_t)ddate); } NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", pnp->tn_path, enp->tn_path); } } else if (S_ISDIR(estp->st_mode) && dbm_getone(bmd, (u_longlong_t)estp->st_ino)) { (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); if (ndmpd_verbose_traverse) { NDMP_LOG(LOG_DEBUG, "d(%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino); NDMP_LOG(LOG_DEBUG, "\"%s, %s\"", pnp->tn_path, enp->tn_path); } } return (0); } /* * mark_inodes_v2 * * Traverse the file system in post-order and mark * all the modified objects and also directories leading * to them. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * path (input) - the physical path to traverse * * Returns: * 0: on success. * != 0: on error. */ int mark_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) { fs_traverse_t ft; mark_param_t mp; if (!session || !nlp || !path || !*path) { NDMP_LOG(LOG_DEBUG, "Invalid argument"); return (-1); } NDMP_LOG(LOG_DEBUG, "path \"%s\"", path); mp.mp_bmd = nlp->nlp_bkmap; mp.mp_ddate = nlp->nlp_ldate; mp.mp_session = session; mp.mp_nlp = nlp; ft.ft_path = path; ft.ft_lpath = nlp->nlp_backup_path; ft.ft_callbk = mark_cb; ft.ft_arg = ∓ ft.ft_logfp = (ft_log_t)ndmp_log; ft.ft_flags = ndmpd_mark_flags; return (traverse(session, nlp, &ft)); } /* * create_bitmap * * Create a dbitmap and return its descriptor. * * Parameters: * path (input) - path for which the bitmap should be created * value (input) - the initial value for the bitmap * * Returns: * the dbitmap descriptor */ static int create_bitmap(char *path, int value) { char bm_fname[PATH_MAX]; char buf[TLM_MAX_PATH_NAME]; char *livepath; ulong_t ninode; NDMP_LOG(LOG_DEBUG, "path \"%s\"", path); if (fs_is_chkpntvol(path)) livepath = (char *)tlm_remove_checkpoint(path, buf); else livepath = path; ninode = 1024 * 1024 * 1024; if (ninode == 0) return (-1); (void) ndmpd_mk_temp(bm_fname); NDMP_LOG(LOG_DEBUG, "path \"%s\"ninode %u bm_fname \"%s\"", livepath, ninode, bm_fname); return (dbm_alloc(bm_fname, (u_longlong_t)ninode, value)); } /* * create_allset_bitmap * * A helper function to create a bitmap with all the * values set to 1. * * Parameters: * nlp (input) - pointer to the nlp structure * * Returns: * the dbitmap descriptor */ static int create_allset_bitmap(ndmp_lbr_params_t *nlp) { int rv; nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 1); NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); if (nlp->nlp_bkmap < 0) { NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); rv = -1; } else rv = 0; return (rv); } /* * mark_common_v2 * * Create the inode bitmap. If last date of the the * backup is epoch, then all the objects should be backed * up; there is no need to traverse the backup hierarchy * and mark the inodes. All the bits should be marked. * * Otherwise, the backup hierarchy should be traversed and * the objects should be marked. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success. * != 0: on error. */ static int mark_common_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { char buf[TLM_MAX_PATH_NAME], *chkpath; int rv; /* * Everything is needed for full backup. */ if (nlp->nlp_ldate == (time_t)0) return (create_allset_bitmap(nlp)); rv = 0; nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); if (nlp->nlp_bkmap < 0) { NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); rv = -1; } else { if (fs_is_chkpntvol(nlp->nlp_backup_path)) chkpath = nlp->nlp_backup_path; else chkpath = tlm_build_snapshot_name( nlp->nlp_backup_path, buf, nlp->nlp_jstat->js_job_name); rv = mark_inodes_v2(session, nlp, chkpath); (void) dbm_setone(nlp->nlp_bkmap, (u_longlong_t)ROOT_INODE); } return (rv); } /* * mark_tar_inodes_v2 * * Create the bitmap for tar backup format. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success. * != 0: on error. */ static int mark_tar_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { int rv; if (ndmp_tar_force_traverse) rv = mark_common_v2(session, nlp); else rv = create_allset_bitmap(nlp); return (rv); } /* * mark_dump_inodes_v2 * * Create the bitmap for dump backup format. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success. * != 0: on error. */ static int mark_dump_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { return (mark_common_v2(session, nlp)); } /* * ndmpd_mark_inodes_v2 * * Mark the inodes of the backup hierarchy if necessary. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success. * != 0: on error. */ int ndmpd_mark_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { int rv; if (ndmp_skip_traverse) { NDMP_LOG(LOG_INFO, "Skip processing directories \"%s\"", nlp->nlp_backup_path); rv = create_allset_bitmap(nlp); } else { if (NLP_ISTAR(nlp)) rv = mark_tar_inodes_v2(session, nlp); else if (NLP_ISDUMP(nlp)) rv = mark_dump_inodes_v2(session, nlp); else { NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"", nlp->nlp_backup_path); rv = -1; } } return (rv); } /* * ndmpd_abort_making_v2 * * Abort the process of marking inodes. * * Parameters: * session (input) - pointer to the session * * Returns: * void */ void ndmpd_abort_marking_v2(ndmpd_session_t *session) { ndmp_lbr_params_t *nlp; nlp = ndmp_get_nlp(session); if (nlp) NLP_SET(nlp, NLPF_ABORTED); } /* * mark_tokv3 * * Traverse the backup hierarchy and mark the bits for the * modified objects of directories leading to a modified * object for the token-based backup. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * path (input) - the physical path to traverse * * Returns: * 0: on success * != 0: otherwise */ int mark_tokv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) { fs_traverse_t ft; mark_param_t mp; if (!session || !nlp || !path || !*path) { NDMP_LOG(LOG_DEBUG, "Invalid argument"); return (-1); } if (nlp->nlp_tokdate == (time_t)0) return (create_allset_bitmap(nlp)); nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); if (nlp->nlp_bkmap < 0) { NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); return (-1); } NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); mp.mp_bmd = nlp->nlp_bkmap; mp.mp_ddate = nlp->nlp_tokdate; mp.mp_session = session; mp.mp_nlp = nlp; ft.ft_path = path; ft.ft_lpath = nlp->nlp_backup_path; ft.ft_callbk = mark_cb; ft.ft_arg = ∓ ft.ft_logfp = (ft_log_t)ndmp_log; ft.ft_flags = ndmpd_mark_flags; return (traverse(session, nlp, &ft)); } /* * marklbrv3_cb * * The callback function, called by traverse_post to mark * bits in the bitmap. * * It's so much like mark_cb for time-based (token-based * and level-type) backup types, except that it looks at * the archive bit of the objects instead of their timestamp. * * Parameters: * arg (input) - pointer to the mark parameter * pnp (input) - pointer to the path node * enp (input) - pointer to the entry node * * Returns: * 0: as long as traversing should continue * != 0: if traversing should stop */ int marklbrv3_cb(void *arg, fst_node_t *pnp, fst_node_t *enp) { int bmd; u_longlong_t bl; fs_fhandle_t *pfhp, *efhp; struct stat64 *pstp, *estp; mark_param_t *mpp; ndmp_lbr_params_t *nlp; mpp = (mark_param_t *)arg; if (!mpp) { NDMP_LOG(LOG_DEBUG, "NULL argument passed"); return (-1); } nlp = ndmp_get_nlp(mpp->mp_session); if (mpp->mp_session->ns_data.dd_abort || (nlp && NLP_ISSET(nlp, NLPF_ABORTED))) { NDMP_LOG(LOG_INFO, "Processing directories aborted."); return (-1); } bmd = mpp->mp_bmd; bl = dbm_getlen(bmd); pfhp = pnp->tn_fh; pstp = pnp->tn_st; /* sanity check on fh and stat of the path passed */ if (pstp->st_ino > bl) { NDMP_LOG(LOG_DEBUG, "Invalid path inode #%u", (uint_t)pstp->st_ino); return (-1); } if (pstp->st_ino != pfhp->fh_fid) { NDMP_LOG(LOG_DEBUG, "Path ino mismatch %u %u", (uint_t)pstp->st_ino, (uint_t)pfhp->fh_fid); return (-1); } /* * Always mark the backup path inode number. */ if (!enp->tn_path) { (void) dbm_setone(bmd, pstp->st_ino); if (ndmpd_verbose_traverse) { NDMP_LOG(LOG_DEBUG, "d(%u)", (uint_t)pstp->st_ino); NDMP_LOG(LOG_DEBUG, "\"%s\"", pnp->tn_path); } return (0); } efhp = enp->tn_fh; estp = enp->tn_st; /* sanity check on fh and stat of the entry passed */ if (estp->st_ino > bl) { NDMP_LOG(LOG_DEBUG, "Invalid entry inode #%u", (uint_t)estp->st_ino); return (-1); } if (estp->st_ino != efhp->fh_fid) { NDMP_LOG(LOG_DEBUG, "Entry ino mismatch %u %u", estp->st_ino, (uint_t)pfhp->fh_fid); return (-1); } if (S_ISDIR(estp->st_mode) && dbm_getone(bmd, (u_longlong_t)estp->st_ino)) { (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); if (ndmpd_verbose_traverse) { NDMP_LOG(LOG_DEBUG, "d(%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino); NDMP_LOG(LOG_DEBUG, "\"%s, %s\"", pnp->tn_path, enp->tn_path); } } return (0); } /* * mark_lbrv3 * * Traverse the backup hierarchy and mark the bits for the * modified objects of directories leading to a modified * object for the LBR-type backup. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * path (input) - the physical path to traverse * * Returns: * 0: on success * != 0: otherwise */ int mark_lbrv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) { char c; fs_traverse_t ft; mark_param_t mp; if (!session || !nlp || !path || !*path) { NDMP_LOG(LOG_DEBUG, "Invalid argument"); return (-1); } /* full and archive backups backup everything */ c = toupper(nlp->nlp_clevel); if (c == 'F' || c == 'A') return (create_allset_bitmap(nlp)); nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); if (nlp->nlp_bkmap < 0) { NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); return (-1); } NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); mp.mp_bmd = nlp->nlp_bkmap; mp.mp_ddate = 0; mp.mp_session = session; mp.mp_nlp = nlp; ft.ft_path = path; ft.ft_lpath = nlp->nlp_backup_path; ft.ft_callbk = marklbrv3_cb; ft.ft_arg = ∓ ft.ft_logfp = (ft_log_t)ndmp_log; ft.ft_flags = ndmpd_mark_flags; return (traverse(session, nlp, &ft)); } /* * mark_levelv3 * * Traverse the backup hierarchy and mark the bits for the * modified objects of directories leading to a modified * object for the level-type backup. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * path (input) - the physical path to traverse * * Returns: * 0: on success * != 0: otherwise */ int mark_levelv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) { fs_traverse_t ft; mark_param_t mp; tlm_acls_t traverse_acl; if (!session || !nlp || !path || !*path) { NDMP_LOG(LOG_DEBUG, "Invalid argument"); return (-1); } if (nlp->nlp_ldate == (time_t)0) return (create_allset_bitmap(nlp)); nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); if (nlp->nlp_bkmap < 0) { NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); return (-1); } NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); /* * We do not want to allocate memory for acl every time we * process a file. */ (void) memset(&traverse_acl, 0, sizeof (traverse_acl)); mp.mp_tacl = &traverse_acl; mp.mp_bmd = nlp->nlp_bkmap; mp.mp_ddate = nlp->nlp_ldate; mp.mp_session = session; mp.mp_nlp = nlp; ft.ft_path = path; ft.ft_lpath = nlp->nlp_backup_path; ft.ft_callbk = mark_cb; ft.ft_arg = ∓ ft.ft_logfp = (ft_log_t)ndmp_log; ft.ft_flags = ndmpd_mark_flags; return (traverse(session, nlp, &ft)); } /* * mark_commonv3 * * Create the inode bitmap. If last date of the the * backup is epoch, then all the objects should be backed * up; there is no need to traverse the backup hierarchy * and mark the inodes. All the bits should be marked. * * Otherwise, the backup hierarchy should be traversed and * the objects should be marked. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success. * != 0: on error. */ int mark_commonv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { char buf[TLM_MAX_PATH_NAME], *chkpath; int rv; if (NLP_ISCHKPNTED(nlp)) chkpath = nlp->nlp_backup_path; else chkpath = tlm_build_snapshot_name(nlp->nlp_backup_path, buf, nlp->nlp_jstat->js_job_name); if (NLP_ISSET(nlp, NLPF_TOKENBK)) rv = mark_tokv3(session, nlp, chkpath); else if (NLP_ISSET(nlp, NLPF_LBRBK)) rv = mark_lbrv3(session, nlp, chkpath); else if (NLP_ISSET(nlp, NLPF_LEVELBK)) { rv = mark_levelv3(session, nlp, chkpath); } else { rv = -1; NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"", nlp->nlp_backup_path); } return (rv); } /* * mark_tar_inodesv3 * * Mark bits for tar backup format of V3. Normally, the * backup hierarchy is not traversed for tar format * unless it's forced by setting the ndmp_tar_force_traverse * to a non-zero value. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success * != 0: otherwise */ int mark_tar_inodesv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { int rv; if (ndmp_tar_force_traverse) rv = mark_commonv3(session, nlp); else rv = create_allset_bitmap(nlp); return (rv); } /* * ndmpd_mark_inodes_v3 * * Mark the inodes of the backup hierarchy if necessary. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success. * != 0: on error. */ int ndmpd_mark_inodes_v3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { int rv; if (ndmp_skip_traverse) { NDMP_LOG(LOG_INFO, "Skip processing directories \"%s\"", nlp->nlp_backup_path); rv = create_allset_bitmap(nlp); } else { if (NLP_ISTAR(nlp)) rv = mark_tar_inodesv3(session, nlp); else if (NLP_ISDUMP(nlp)) { rv = mark_commonv3(session, nlp); } else { NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"", nlp->nlp_backup_path); rv = -1; } } return (rv); }