1*2654012fSReza Sabdar /* 2*2654012fSReza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3*2654012fSReza Sabdar * Use is subject to license terms. 4*2654012fSReza Sabdar */ 5*2654012fSReza Sabdar 6*2654012fSReza Sabdar /* 7*2654012fSReza Sabdar * BSD 3 Clause License 8*2654012fSReza Sabdar * 9*2654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 10*2654012fSReza Sabdar * 11*2654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 12*2654012fSReza Sabdar * modification, are permitted provided that the following conditions 13*2654012fSReza Sabdar * are met: 14*2654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 15*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 16*2654012fSReza Sabdar * 17*2654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 18*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 19*2654012fSReza Sabdar * the documentation and/or other materials provided with the 20*2654012fSReza Sabdar * distribution. 21*2654012fSReza Sabdar * 22*2654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 23*2654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 24*2654012fSReza Sabdar * products derived from this software without specific prior written 25*2654012fSReza Sabdar * permission. 26*2654012fSReza Sabdar * 27*2654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28*2654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29*2654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30*2654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31*2654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32*2654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33*2654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34*2654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35*2654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36*2654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37*2654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 38*2654012fSReza Sabdar */ 39*2654012fSReza Sabdar #include <sys/stat.h> 40*2654012fSReza Sabdar #include <sys/types.h> 41*2654012fSReza Sabdar #include <cstack.h> 42*2654012fSReza Sabdar #include <ctype.h> 43*2654012fSReza Sabdar #include <dirent.h> 44*2654012fSReza Sabdar #include <errno.h> 45*2654012fSReza Sabdar #include "ndmpd.h" 46*2654012fSReza Sabdar #include <bitmap.h> 47*2654012fSReza Sabdar #include <traverse.h> 48*2654012fSReza Sabdar #include <limits.h> 49*2654012fSReza Sabdar #include <stdio.h> 50*2654012fSReza Sabdar #include <stdlib.h> 51*2654012fSReza Sabdar #include <string.h> 52*2654012fSReza Sabdar #include <time.h> 53*2654012fSReza Sabdar #include "tlm_buffers.h" 54*2654012fSReza Sabdar 55*2654012fSReza Sabdar 56*2654012fSReza Sabdar /* 57*2654012fSReza Sabdar * Parameter passed to traverse for marking inodes 58*2654012fSReza Sabdar * when traversing backup hierarchy in V2. It 59*2654012fSReza Sabdar * includes: 60*2654012fSReza Sabdar * mp_bmd: the bitmap describptor. 61*2654012fSReza Sabdar * mp_ddate: backup date. 62*2654012fSReza Sabdar * mp_session: pointer to the session structure. 63*2654012fSReza Sabdar * mp_nlp: pointer to the nlp. 64*2654012fSReza Sabdar * mp_tacl: pointer to the acl. 65*2654012fSReza Sabdar */ 66*2654012fSReza Sabdar typedef struct mark_param { 67*2654012fSReza Sabdar int mp_bmd; 68*2654012fSReza Sabdar time_t mp_ddate; 69*2654012fSReza Sabdar ndmpd_session_t *mp_session; 70*2654012fSReza Sabdar ndmp_lbr_params_t *mp_nlp; 71*2654012fSReza Sabdar tlm_acls_t *mp_tacl; 72*2654012fSReza Sabdar } mark_param_t; 73*2654012fSReza Sabdar 74*2654012fSReza Sabdar 75*2654012fSReza Sabdar /* 76*2654012fSReza Sabdar * Set this variable to non-zero to print the inodes 77*2654012fSReza Sabdar * marked after traversing file system. 78*2654012fSReza Sabdar */ 79*2654012fSReza Sabdar static int ndmpd_print_inodes = 0; 80*2654012fSReza Sabdar 81*2654012fSReza Sabdar 82*2654012fSReza Sabdar /* 83*2654012fSReza Sabdar * Flag passed to traverse_post. 84*2654012fSReza Sabdar */ 85*2654012fSReza Sabdar static int ndmpd_mark_flags = 0; 86*2654012fSReza Sabdar 87*2654012fSReza Sabdar 88*2654012fSReza Sabdar /* 89*2654012fSReza Sabdar * Verbose traversing prints the file/dir path names 90*2654012fSReza Sabdar * if they are being marked. 91*2654012fSReza Sabdar */ 92*2654012fSReza Sabdar static int ndmpd_verbose_traverse = 0; 93*2654012fSReza Sabdar 94*2654012fSReza Sabdar 95*2654012fSReza Sabdar /* 96*2654012fSReza Sabdar * Set this flag to count the number of inodes marked 97*2654012fSReza Sabdar * after traversing backup hierarchy. 98*2654012fSReza Sabdar */ 99*2654012fSReza Sabdar static int ndmpd_mark_count_flag = 0; 100*2654012fSReza Sabdar 101*2654012fSReza Sabdar 102*2654012fSReza Sabdar /* 103*2654012fSReza Sabdar * Set this variable to non-zero value to force traversing 104*2654012fSReza Sabdar * backup hierarchy for tar format. 105*2654012fSReza Sabdar */ 106*2654012fSReza Sabdar static int ndmp_tar_force_traverse = 0; 107*2654012fSReza Sabdar 108*2654012fSReza Sabdar 109*2654012fSReza Sabdar /* 110*2654012fSReza Sabdar * Set this variable to non-zero value to skip processing 111*2654012fSReza Sabdar * directories both for tar and dump. 112*2654012fSReza Sabdar */ 113*2654012fSReza Sabdar static int ndmp_skip_traverse = 0; 114*2654012fSReza Sabdar 115*2654012fSReza Sabdar 116*2654012fSReza Sabdar /* 117*2654012fSReza Sabdar * count_bits_cb 118*2654012fSReza Sabdar * 119*2654012fSReza Sabdar * Call back for counting the set bits in the dbitmap. 120*2654012fSReza Sabdar * 121*2654012fSReza Sabdar * Parameters: 122*2654012fSReza Sabdar * bmd (input) - bitmap descriptor 123*2654012fSReza Sabdar * bn (input) - the bit number 124*2654012fSReza Sabdar * arg (input) - pointer to the argument 125*2654012fSReza Sabdar * 126*2654012fSReza Sabdar * Returns: 127*2654012fSReza Sabdar * 0: always 128*2654012fSReza Sabdar */ 129*2654012fSReza Sabdar static int 130*2654012fSReza Sabdar count_bits_cb(int bmd, u_longlong_t bn, void *arg) 131*2654012fSReza Sabdar { 132*2654012fSReza Sabdar if (dbm_getone(bmd, bn)) { 133*2654012fSReza Sabdar (*(u_longlong_t *)arg)++; 134*2654012fSReza Sabdar if (ndmpd_print_inodes) 135*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%llu", bn); 136*2654012fSReza Sabdar } 137*2654012fSReza Sabdar 138*2654012fSReza Sabdar return (0); 139*2654012fSReza Sabdar } 140*2654012fSReza Sabdar 141*2654012fSReza Sabdar 142*2654012fSReza Sabdar /* 143*2654012fSReza Sabdar * count_set_bits 144*2654012fSReza Sabdar * 145*2654012fSReza Sabdar * Count bits set in the bitmap. 146*2654012fSReza Sabdar * 147*2654012fSReza Sabdar * Parameters: 148*2654012fSReza Sabdar * path (input) - the backup path 149*2654012fSReza Sabdar * bmd (input) - bitmap descriptor 150*2654012fSReza Sabdar * 151*2654012fSReza Sabdar * Returns: 152*2654012fSReza Sabdar * void 153*2654012fSReza Sabdar */ 154*2654012fSReza Sabdar void 155*2654012fSReza Sabdar count_set_bits(char *path, int bmd) 156*2654012fSReza Sabdar { 157*2654012fSReza Sabdar u_longlong_t cnt; 158*2654012fSReza Sabdar 159*2654012fSReza Sabdar if (!ndmpd_mark_count_flag) 160*2654012fSReza Sabdar return; 161*2654012fSReza Sabdar 162*2654012fSReza Sabdar cnt = 0; 163*2654012fSReza Sabdar (void) dbm_apply_ifset(bmd, count_bits_cb, &cnt); 164*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s %llu inodes marked", path, cnt); 165*2654012fSReza Sabdar } 166*2654012fSReza Sabdar 167*2654012fSReza Sabdar 168*2654012fSReza Sabdar /* 169*2654012fSReza Sabdar * traverse 170*2654012fSReza Sabdar * 171*2654012fSReza Sabdar * Starts the post-traverse the backup hierarchy. Checks 172*2654012fSReza Sabdar * for exceptional cases, like aborting operation and if 173*2654012fSReza Sabdar * asked, report detailed information after traversing. 174*2654012fSReza Sabdar * 175*2654012fSReza Sabdar * Parameters: 176*2654012fSReza Sabdar * session (input) - pointer to the session 177*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 178*2654012fSReza Sabdar * ftp (input) - pointer to the traverse parameters 179*2654012fSReza Sabdar * 180*2654012fSReza Sabdar * Returns: 181*2654012fSReza Sabdar * 0: on success 182*2654012fSReza Sabdar * != 0: otherwise 183*2654012fSReza Sabdar */ 184*2654012fSReza Sabdar int 185*2654012fSReza Sabdar traverse(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, 186*2654012fSReza Sabdar fs_traverse_t *ftp) 187*2654012fSReza Sabdar { 188*2654012fSReza Sabdar int rv; 189*2654012fSReza Sabdar time_t s, e; 190*2654012fSReza Sabdar 191*2654012fSReza Sabdar if (!session || !nlp || !ftp) { 192*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 193*2654012fSReza Sabdar return (-1); 194*2654012fSReza Sabdar } 195*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Processing directories of \"%s\"", 196*2654012fSReza Sabdar nlp->nlp_backup_path); 197*2654012fSReza Sabdar 198*2654012fSReza Sabdar (void) time(&s); 199*2654012fSReza Sabdar if (traverse_post(ftp) != 0) { 200*2654012fSReza Sabdar rv = -1; 201*2654012fSReza Sabdar if (!session->ns_data.dd_abort && !NLP_ISSET(nlp, 202*2654012fSReza Sabdar NLPF_ABORTED)) { 203*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 204*2654012fSReza Sabdar "Traversing backup path hierarchy \"%s\"", 205*2654012fSReza Sabdar nlp->nlp_backup_path); 206*2654012fSReza Sabdar } 207*2654012fSReza Sabdar } else { 208*2654012fSReza Sabdar (void) dbm_setone(nlp->nlp_bkmap, (u_longlong_t)ROOT_INODE); 209*2654012fSReza Sabdar rv = 0; 210*2654012fSReza Sabdar (void) time(&e); 211*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 212*2654012fSReza Sabdar "\"%s\" traversed in %u sec", nlp->nlp_backup_path, 213*2654012fSReza Sabdar (uint_t)(e-s)); 214*2654012fSReza Sabdar 215*2654012fSReza Sabdar count_set_bits(nlp->nlp_backup_path, nlp->nlp_bkmap); 216*2654012fSReza Sabdar } 217*2654012fSReza Sabdar 218*2654012fSReza Sabdar return (rv); 219*2654012fSReza Sabdar } 220*2654012fSReza Sabdar 221*2654012fSReza Sabdar 222*2654012fSReza Sabdar /* 223*2654012fSReza Sabdar * mark_cb 224*2654012fSReza Sabdar * 225*2654012fSReza Sabdar * The callback function, called by traverse_post to mark bits 226*2654012fSReza Sabdar * in the bitmap. 227*2654012fSReza Sabdar * 228*2654012fSReza Sabdar * Set the bit of the entry if it's been modified (obviously 229*2654012fSReza Sabdar * should be backed up) plus its parent directory. 230*2654012fSReza Sabdar * 231*2654012fSReza Sabdar * If the entry is a directory and is not modified itself, 232*2654012fSReza Sabdar * but it's marked, then there is something below it that 233*2654012fSReza Sabdar * is being backed up. It shows the the path, leads to 234*2654012fSReza Sabdar * an object that will be backed up. So the path should 235*2654012fSReza Sabdar * be marked too. 236*2654012fSReza Sabdar * 237*2654012fSReza Sabdar * The backup path itself is always marked. 238*2654012fSReza Sabdar * 239*2654012fSReza Sabdar * Parameters: 240*2654012fSReza Sabdar * arg (input) - pointer to the mark parameter 241*2654012fSReza Sabdar * pnp (input) - pointer to the path node 242*2654012fSReza Sabdar * enp (input) - pointer to the entry node 243*2654012fSReza Sabdar * 244*2654012fSReza Sabdar * Returns: 245*2654012fSReza Sabdar * 0: as long as traversing should continue 246*2654012fSReza Sabdar * != 0: if traversing should stop 247*2654012fSReza Sabdar */ 248*2654012fSReza Sabdar int 249*2654012fSReza Sabdar mark_cb(void *arg, fst_node_t *pnp, fst_node_t *enp) 250*2654012fSReza Sabdar { 251*2654012fSReza Sabdar int bmd; 252*2654012fSReza Sabdar int rv; 253*2654012fSReza Sabdar u_longlong_t bl; 254*2654012fSReza Sabdar time_t ddate; 255*2654012fSReza Sabdar fs_fhandle_t *pfhp, *efhp; 256*2654012fSReza Sabdar struct stat64 *pstp, *estp; 257*2654012fSReza Sabdar mark_param_t *mpp; 258*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 259*2654012fSReza Sabdar tlm_acls_t *tacl; 260*2654012fSReza Sabdar 261*2654012fSReza Sabdar rv = 0; 262*2654012fSReza Sabdar mpp = (mark_param_t *)arg; 263*2654012fSReza Sabdar tacl = mpp->mp_tacl; 264*2654012fSReza Sabdar nlp = ndmp_get_nlp(mpp->mp_session); 265*2654012fSReza Sabdar if (!mpp) { 266*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "NULL argument passed"); 267*2654012fSReza Sabdar rv = -1; 268*2654012fSReza Sabdar } else if (mpp->mp_session->ns_eof) { 269*2654012fSReza Sabdar NDMP_LOG(LOG_INFO, "Connection to the client is closed"); 270*2654012fSReza Sabdar rv = -1; 271*2654012fSReza Sabdar } else if (mpp->mp_session->ns_data.dd_abort || 272*2654012fSReza Sabdar (nlp && NLP_ISSET(nlp, NLPF_ABORTED))) { 273*2654012fSReza Sabdar NDMP_LOG(LOG_INFO, "Processing directories aborted."); 274*2654012fSReza Sabdar rv = -1; 275*2654012fSReza Sabdar } 276*2654012fSReza Sabdar 277*2654012fSReza Sabdar if (rv != 0) 278*2654012fSReza Sabdar return (rv); 279*2654012fSReza Sabdar 280*2654012fSReza Sabdar ddate = mpp->mp_ddate; 281*2654012fSReza Sabdar bmd = mpp->mp_bmd; 282*2654012fSReza Sabdar bl = dbm_getlen(bmd); 283*2654012fSReza Sabdar 284*2654012fSReza Sabdar pfhp = pnp->tn_fh; 285*2654012fSReza Sabdar pstp = pnp->tn_st; 286*2654012fSReza Sabdar 287*2654012fSReza Sabdar /* sanity check on fh and stat of the path passed */ 288*2654012fSReza Sabdar if (pstp->st_ino > bl) { 289*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid path inode #%u", 290*2654012fSReza Sabdar (uint_t)pstp->st_ino); 291*2654012fSReza Sabdar return (-1); 292*2654012fSReza Sabdar } 293*2654012fSReza Sabdar if (pstp->st_ino != pfhp->fh_fid) { 294*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Path ino mismatch %u %u", 295*2654012fSReza Sabdar (uint_t)pstp->st_ino, (uint_t)pfhp->fh_fid); 296*2654012fSReza Sabdar return (-1); 297*2654012fSReza Sabdar } 298*2654012fSReza Sabdar 299*2654012fSReza Sabdar /* 300*2654012fSReza Sabdar * Always mark the backup path inode number. 301*2654012fSReza Sabdar */ 302*2654012fSReza Sabdar if (!enp->tn_path) { 303*2654012fSReza Sabdar (void) dbm_setone(bmd, pstp->st_ino); 304*2654012fSReza Sabdar return (0); 305*2654012fSReza Sabdar } 306*2654012fSReza Sabdar 307*2654012fSReza Sabdar efhp = enp->tn_fh; 308*2654012fSReza Sabdar estp = enp->tn_st; 309*2654012fSReza Sabdar 310*2654012fSReza Sabdar /* sanity check on fh and stat of the entry passed */ 311*2654012fSReza Sabdar if (estp->st_ino > bl) { 312*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid entry inode #%u", 313*2654012fSReza Sabdar (uint_t)estp->st_ino); 314*2654012fSReza Sabdar return (-1); 315*2654012fSReza Sabdar } 316*2654012fSReza Sabdar if (estp->st_ino != efhp->fh_fid) { 317*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Entry ino mismatch %u %u", estp->st_ino, 318*2654012fSReza Sabdar (uint_t)pfhp->fh_fid); 319*2654012fSReza Sabdar return (-1); 320*2654012fSReza Sabdar } 321*2654012fSReza Sabdar 322*2654012fSReza Sabdar /* check the dates and mark the bitmap inode */ 323*2654012fSReza Sabdar if (ddate == 0) { 324*2654012fSReza Sabdar /* base backup */ 325*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); 326*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); 327*2654012fSReza Sabdar if (ndmpd_verbose_traverse) { 328*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Base Backup"); 329*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", 330*2654012fSReza Sabdar pnp->tn_path, enp->tn_path); 331*2654012fSReza Sabdar } 332*2654012fSReza Sabdar 333*2654012fSReza Sabdar } else if (estp->st_mtime > ddate) { 334*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); 335*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); 336*2654012fSReza Sabdar if (ndmpd_verbose_traverse) { 337*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 338*2654012fSReza Sabdar "m(%u,%u,%u,%u)", (uint_t)pstp->st_ino, 339*2654012fSReza Sabdar (uint_t)estp->st_ino, (uint_t)estp->st_mtime, 340*2654012fSReza Sabdar (uint_t)ddate); 341*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", 342*2654012fSReza Sabdar pnp->tn_path, enp->tn_path); 343*2654012fSReza Sabdar } 344*2654012fSReza Sabdar } else if (iscreated(nlp, NULL, tacl, ddate)) { 345*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); 346*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); 347*2654012fSReza Sabdar if (ndmpd_verbose_traverse) { 348*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 349*2654012fSReza Sabdar "cr(%u,%u,%u,%u)", (uint_t)pstp->st_ino, 350*2654012fSReza Sabdar (uint_t)estp->st_ino, (uint_t)estp->st_mtime, 351*2654012fSReza Sabdar (uint_t)ddate); 352*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", 353*2654012fSReza Sabdar pnp->tn_path, enp->tn_path); 354*2654012fSReza Sabdar } 355*2654012fSReza Sabdar } else if (estp->st_ctime > ddate) { 356*2654012fSReza Sabdar if (!NLP_IGNCTIME(nlp)) { 357*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); 358*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); 359*2654012fSReza Sabdar } 360*2654012fSReza Sabdar if (ndmpd_verbose_traverse) { 361*2654012fSReza Sabdar if (NLP_IGNCTIME(nlp)) { 362*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 363*2654012fSReza Sabdar "ign c(%u,%u,%u,%u)", (uint_t)pstp->st_ino, 364*2654012fSReza Sabdar (uint_t)estp->st_ino, 365*2654012fSReza Sabdar (uint_t)estp->st_ctime, (uint_t)ddate); 366*2654012fSReza Sabdar } else { 367*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 368*2654012fSReza Sabdar "c(%u,%u,%u,%u)", (uint_t)pstp->st_ino, 369*2654012fSReza Sabdar (uint_t)estp->st_ino, 370*2654012fSReza Sabdar (uint_t)estp->st_ctime, (uint_t)ddate); 371*2654012fSReza Sabdar } 372*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", 373*2654012fSReza Sabdar pnp->tn_path, enp->tn_path); 374*2654012fSReza Sabdar } 375*2654012fSReza Sabdar } else if (S_ISDIR(estp->st_mode) && 376*2654012fSReza Sabdar dbm_getone(bmd, (u_longlong_t)estp->st_ino)) { 377*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); 378*2654012fSReza Sabdar if (ndmpd_verbose_traverse) { 379*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "d(%u,%u)", 380*2654012fSReza Sabdar (uint_t)pstp->st_ino, (uint_t)estp->st_ino); 381*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s, %s\"", 382*2654012fSReza Sabdar pnp->tn_path, enp->tn_path); 383*2654012fSReza Sabdar } 384*2654012fSReza Sabdar } 385*2654012fSReza Sabdar 386*2654012fSReza Sabdar return (0); 387*2654012fSReza Sabdar } 388*2654012fSReza Sabdar 389*2654012fSReza Sabdar 390*2654012fSReza Sabdar /* 391*2654012fSReza Sabdar * mark_inodes_v2 392*2654012fSReza Sabdar * 393*2654012fSReza Sabdar * Traverse the file system in post-order and mark 394*2654012fSReza Sabdar * all the modified objects and also directories leading 395*2654012fSReza Sabdar * to them. 396*2654012fSReza Sabdar * 397*2654012fSReza Sabdar * Parameters: 398*2654012fSReza Sabdar * session (input) - pointer to the session 399*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 400*2654012fSReza Sabdar * path (input) - the physical path to traverse 401*2654012fSReza Sabdar * 402*2654012fSReza Sabdar * Returns: 403*2654012fSReza Sabdar * 0: on success. 404*2654012fSReza Sabdar * != 0: on error. 405*2654012fSReza Sabdar */ 406*2654012fSReza Sabdar int 407*2654012fSReza Sabdar mark_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) 408*2654012fSReza Sabdar { 409*2654012fSReza Sabdar fs_traverse_t ft; 410*2654012fSReza Sabdar mark_param_t mp; 411*2654012fSReza Sabdar 412*2654012fSReza Sabdar if (!session || !nlp || !path || !*path) { 413*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 414*2654012fSReza Sabdar return (-1); 415*2654012fSReza Sabdar } 416*2654012fSReza Sabdar 417*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "path \"%s\"", path); 418*2654012fSReza Sabdar 419*2654012fSReza Sabdar mp.mp_bmd = nlp->nlp_bkmap; 420*2654012fSReza Sabdar mp.mp_ddate = nlp->nlp_ldate; 421*2654012fSReza Sabdar mp.mp_session = session; 422*2654012fSReza Sabdar mp.mp_nlp = nlp; 423*2654012fSReza Sabdar 424*2654012fSReza Sabdar ft.ft_path = path; 425*2654012fSReza Sabdar ft.ft_lpath = nlp->nlp_backup_path; 426*2654012fSReza Sabdar ft.ft_callbk = mark_cb; 427*2654012fSReza Sabdar ft.ft_arg = ∓ 428*2654012fSReza Sabdar ft.ft_logfp = (ft_log_t)ndmp_log; 429*2654012fSReza Sabdar ft.ft_flags = ndmpd_mark_flags; 430*2654012fSReza Sabdar 431*2654012fSReza Sabdar return (traverse(session, nlp, &ft)); 432*2654012fSReza Sabdar } 433*2654012fSReza Sabdar 434*2654012fSReza Sabdar 435*2654012fSReza Sabdar /* 436*2654012fSReza Sabdar * create_bitmap 437*2654012fSReza Sabdar * 438*2654012fSReza Sabdar * Create a dbitmap and return its descriptor. 439*2654012fSReza Sabdar * 440*2654012fSReza Sabdar * Parameters: 441*2654012fSReza Sabdar * path (input) - path for which the bitmap should be created 442*2654012fSReza Sabdar * value (input) - the initial value for the bitmap 443*2654012fSReza Sabdar * 444*2654012fSReza Sabdar * Returns: 445*2654012fSReza Sabdar * the dbitmap descriptor 446*2654012fSReza Sabdar */ 447*2654012fSReza Sabdar static int 448*2654012fSReza Sabdar create_bitmap(char *path, int value) 449*2654012fSReza Sabdar { 450*2654012fSReza Sabdar char bm_fname[PATH_MAX]; 451*2654012fSReza Sabdar char buf[TLM_MAX_PATH_NAME]; 452*2654012fSReza Sabdar char *livepath; 453*2654012fSReza Sabdar ulong_t ninode; 454*2654012fSReza Sabdar 455*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "path \"%s\"", path); 456*2654012fSReza Sabdar 457*2654012fSReza Sabdar if (fs_is_chkpntvol(path)) 458*2654012fSReza Sabdar livepath = (char *)tlm_remove_checkpoint(path, buf); 459*2654012fSReza Sabdar else 460*2654012fSReza Sabdar livepath = path; 461*2654012fSReza Sabdar ninode = 1024 * 1024 * 1024; 462*2654012fSReza Sabdar if (ninode == 0) 463*2654012fSReza Sabdar return (-1); 464*2654012fSReza Sabdar (void) ndmpd_mk_temp(bm_fname); 465*2654012fSReza Sabdar 466*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "path \"%s\"ninode %u bm_fname \"%s\"", 467*2654012fSReza Sabdar livepath, ninode, bm_fname); 468*2654012fSReza Sabdar 469*2654012fSReza Sabdar return (dbm_alloc(bm_fname, (u_longlong_t)ninode, value)); 470*2654012fSReza Sabdar } 471*2654012fSReza Sabdar 472*2654012fSReza Sabdar 473*2654012fSReza Sabdar /* 474*2654012fSReza Sabdar * create_allset_bitmap 475*2654012fSReza Sabdar * 476*2654012fSReza Sabdar * A helper function to create a bitmap with all the 477*2654012fSReza Sabdar * values set to 1. 478*2654012fSReza Sabdar * 479*2654012fSReza Sabdar * Parameters: 480*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 481*2654012fSReza Sabdar * 482*2654012fSReza Sabdar * Returns: 483*2654012fSReza Sabdar * the dbitmap descriptor 484*2654012fSReza Sabdar */ 485*2654012fSReza Sabdar static int 486*2654012fSReza Sabdar create_allset_bitmap(ndmp_lbr_params_t *nlp) 487*2654012fSReza Sabdar { 488*2654012fSReza Sabdar int rv; 489*2654012fSReza Sabdar 490*2654012fSReza Sabdar nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 1); 491*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); 492*2654012fSReza Sabdar 493*2654012fSReza Sabdar if (nlp->nlp_bkmap < 0) { 494*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); 495*2654012fSReza Sabdar rv = -1; 496*2654012fSReza Sabdar } else 497*2654012fSReza Sabdar rv = 0; 498*2654012fSReza Sabdar 499*2654012fSReza Sabdar return (rv); 500*2654012fSReza Sabdar } 501*2654012fSReza Sabdar 502*2654012fSReza Sabdar 503*2654012fSReza Sabdar /* 504*2654012fSReza Sabdar * mark_common_v2 505*2654012fSReza Sabdar * 506*2654012fSReza Sabdar * Create the inode bitmap. If last date of the the 507*2654012fSReza Sabdar * backup is epoch, then all the objects should be backed 508*2654012fSReza Sabdar * up; there is no need to traverse the backup hierarchy 509*2654012fSReza Sabdar * and mark the inodes. All the bits should be marked. 510*2654012fSReza Sabdar * 511*2654012fSReza Sabdar * Otherwise, the backup hierarchy should be traversed and 512*2654012fSReza Sabdar * the objects should be marked. 513*2654012fSReza Sabdar * 514*2654012fSReza Sabdar * Parameters: 515*2654012fSReza Sabdar * session (input) - pointer to the session 516*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 517*2654012fSReza Sabdar * 518*2654012fSReza Sabdar * Returns: 519*2654012fSReza Sabdar * 0: on success. 520*2654012fSReza Sabdar * != 0: on error. 521*2654012fSReza Sabdar */ 522*2654012fSReza Sabdar static int 523*2654012fSReza Sabdar mark_common_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) 524*2654012fSReza Sabdar { 525*2654012fSReza Sabdar char buf[TLM_MAX_PATH_NAME], *chkpath; 526*2654012fSReza Sabdar int rv; 527*2654012fSReza Sabdar 528*2654012fSReza Sabdar /* 529*2654012fSReza Sabdar * Everything is needed for full backup. 530*2654012fSReza Sabdar */ 531*2654012fSReza Sabdar if (nlp->nlp_ldate == (time_t)0) 532*2654012fSReza Sabdar return (create_allset_bitmap(nlp)); 533*2654012fSReza Sabdar 534*2654012fSReza Sabdar rv = 0; 535*2654012fSReza Sabdar nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); 536*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); 537*2654012fSReza Sabdar 538*2654012fSReza Sabdar if (nlp->nlp_bkmap < 0) { 539*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); 540*2654012fSReza Sabdar rv = -1; 541*2654012fSReza Sabdar } else { 542*2654012fSReza Sabdar if (fs_is_chkpntvol(nlp->nlp_backup_path)) 543*2654012fSReza Sabdar chkpath = nlp->nlp_backup_path; 544*2654012fSReza Sabdar else 545*2654012fSReza Sabdar chkpath = tlm_build_snapshot_name( 546*2654012fSReza Sabdar nlp->nlp_backup_path, buf, 547*2654012fSReza Sabdar nlp->nlp_jstat->js_job_name); 548*2654012fSReza Sabdar rv = mark_inodes_v2(session, nlp, chkpath); 549*2654012fSReza Sabdar (void) dbm_setone(nlp->nlp_bkmap, (u_longlong_t)ROOT_INODE); 550*2654012fSReza Sabdar } 551*2654012fSReza Sabdar 552*2654012fSReza Sabdar return (rv); 553*2654012fSReza Sabdar } 554*2654012fSReza Sabdar 555*2654012fSReza Sabdar 556*2654012fSReza Sabdar /* 557*2654012fSReza Sabdar * mark_tar_inodes_v2 558*2654012fSReza Sabdar * 559*2654012fSReza Sabdar * Create the bitmap for tar backup format. 560*2654012fSReza Sabdar * 561*2654012fSReza Sabdar * Parameters: 562*2654012fSReza Sabdar * session (input) - pointer to the session 563*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 564*2654012fSReza Sabdar * 565*2654012fSReza Sabdar * Returns: 566*2654012fSReza Sabdar * 0: on success. 567*2654012fSReza Sabdar * != 0: on error. 568*2654012fSReza Sabdar */ 569*2654012fSReza Sabdar static int 570*2654012fSReza Sabdar mark_tar_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) 571*2654012fSReza Sabdar { 572*2654012fSReza Sabdar int rv; 573*2654012fSReza Sabdar 574*2654012fSReza Sabdar if (ndmp_tar_force_traverse) 575*2654012fSReza Sabdar rv = mark_common_v2(session, nlp); 576*2654012fSReza Sabdar else 577*2654012fSReza Sabdar rv = create_allset_bitmap(nlp); 578*2654012fSReza Sabdar 579*2654012fSReza Sabdar return (rv); 580*2654012fSReza Sabdar } 581*2654012fSReza Sabdar 582*2654012fSReza Sabdar 583*2654012fSReza Sabdar /* 584*2654012fSReza Sabdar * mark_dump_inodes_v2 585*2654012fSReza Sabdar * 586*2654012fSReza Sabdar * Create the bitmap for dump backup format. 587*2654012fSReza Sabdar * 588*2654012fSReza Sabdar * Parameters: 589*2654012fSReza Sabdar * session (input) - pointer to the session 590*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 591*2654012fSReza Sabdar * 592*2654012fSReza Sabdar * Returns: 593*2654012fSReza Sabdar * 0: on success. 594*2654012fSReza Sabdar * != 0: on error. 595*2654012fSReza Sabdar */ 596*2654012fSReza Sabdar static int 597*2654012fSReza Sabdar mark_dump_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) 598*2654012fSReza Sabdar { 599*2654012fSReza Sabdar return (mark_common_v2(session, nlp)); 600*2654012fSReza Sabdar } 601*2654012fSReza Sabdar 602*2654012fSReza Sabdar 603*2654012fSReza Sabdar /* 604*2654012fSReza Sabdar * ndmpd_mark_inodes_v2 605*2654012fSReza Sabdar * 606*2654012fSReza Sabdar * Mark the inodes of the backup hierarchy if necessary. 607*2654012fSReza Sabdar * 608*2654012fSReza Sabdar * Parameters: 609*2654012fSReza Sabdar * session (input) - pointer to the session 610*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 611*2654012fSReza Sabdar * 612*2654012fSReza Sabdar * Returns: 613*2654012fSReza Sabdar * 0: on success. 614*2654012fSReza Sabdar * != 0: on error. 615*2654012fSReza Sabdar */ 616*2654012fSReza Sabdar int 617*2654012fSReza Sabdar ndmpd_mark_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) 618*2654012fSReza Sabdar { 619*2654012fSReza Sabdar int rv; 620*2654012fSReza Sabdar 621*2654012fSReza Sabdar if (ndmp_skip_traverse) { 622*2654012fSReza Sabdar NDMP_LOG(LOG_INFO, "Skip processing directories \"%s\"", 623*2654012fSReza Sabdar nlp->nlp_backup_path); 624*2654012fSReza Sabdar rv = create_allset_bitmap(nlp); 625*2654012fSReza Sabdar } else { 626*2654012fSReza Sabdar if (NLP_ISTAR(nlp)) 627*2654012fSReza Sabdar rv = mark_tar_inodes_v2(session, nlp); 628*2654012fSReza Sabdar else if (NLP_ISDUMP(nlp)) 629*2654012fSReza Sabdar rv = mark_dump_inodes_v2(session, nlp); 630*2654012fSReza Sabdar else { 631*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"", 632*2654012fSReza Sabdar nlp->nlp_backup_path); 633*2654012fSReza Sabdar rv = -1; 634*2654012fSReza Sabdar } 635*2654012fSReza Sabdar } 636*2654012fSReza Sabdar 637*2654012fSReza Sabdar return (rv); 638*2654012fSReza Sabdar } 639*2654012fSReza Sabdar 640*2654012fSReza Sabdar 641*2654012fSReza Sabdar /* 642*2654012fSReza Sabdar * ndmpd_abort_making_v2 643*2654012fSReza Sabdar * 644*2654012fSReza Sabdar * Abort the process of marking inodes. 645*2654012fSReza Sabdar * 646*2654012fSReza Sabdar * Parameters: 647*2654012fSReza Sabdar * session (input) - pointer to the session 648*2654012fSReza Sabdar * 649*2654012fSReza Sabdar * Returns: 650*2654012fSReza Sabdar * void 651*2654012fSReza Sabdar */ 652*2654012fSReza Sabdar void 653*2654012fSReza Sabdar ndmpd_abort_marking_v2(ndmpd_session_t *session) 654*2654012fSReza Sabdar { 655*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 656*2654012fSReza Sabdar 657*2654012fSReza Sabdar nlp = ndmp_get_nlp(session); 658*2654012fSReza Sabdar if (nlp) 659*2654012fSReza Sabdar NLP_SET(nlp, NLPF_ABORTED); 660*2654012fSReza Sabdar } 661*2654012fSReza Sabdar 662*2654012fSReza Sabdar 663*2654012fSReza Sabdar /* 664*2654012fSReza Sabdar * mark_tokv3 665*2654012fSReza Sabdar * 666*2654012fSReza Sabdar * Traverse the backup hierarchy and mark the bits for the 667*2654012fSReza Sabdar * modified objects of directories leading to a modified 668*2654012fSReza Sabdar * object for the token-based backup. 669*2654012fSReza Sabdar * 670*2654012fSReza Sabdar * Parameters: 671*2654012fSReza Sabdar * session (input) - pointer to the session 672*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 673*2654012fSReza Sabdar * path (input) - the physical path to traverse 674*2654012fSReza Sabdar * 675*2654012fSReza Sabdar * Returns: 676*2654012fSReza Sabdar * 0: on success 677*2654012fSReza Sabdar * != 0: otherwise 678*2654012fSReza Sabdar */ 679*2654012fSReza Sabdar int 680*2654012fSReza Sabdar mark_tokv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) 681*2654012fSReza Sabdar { 682*2654012fSReza Sabdar fs_traverse_t ft; 683*2654012fSReza Sabdar mark_param_t mp; 684*2654012fSReza Sabdar 685*2654012fSReza Sabdar if (!session || !nlp || !path || !*path) { 686*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 687*2654012fSReza Sabdar return (-1); 688*2654012fSReza Sabdar } 689*2654012fSReza Sabdar if (nlp->nlp_tokdate == (time_t)0) 690*2654012fSReza Sabdar return (create_allset_bitmap(nlp)); 691*2654012fSReza Sabdar 692*2654012fSReza Sabdar nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); 693*2654012fSReza Sabdar if (nlp->nlp_bkmap < 0) { 694*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); 695*2654012fSReza Sabdar return (-1); 696*2654012fSReza Sabdar } 697*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); 698*2654012fSReza Sabdar 699*2654012fSReza Sabdar mp.mp_bmd = nlp->nlp_bkmap; 700*2654012fSReza Sabdar mp.mp_ddate = nlp->nlp_tokdate; 701*2654012fSReza Sabdar mp.mp_session = session; 702*2654012fSReza Sabdar mp.mp_nlp = nlp; 703*2654012fSReza Sabdar 704*2654012fSReza Sabdar ft.ft_path = path; 705*2654012fSReza Sabdar ft.ft_lpath = nlp->nlp_backup_path; 706*2654012fSReza Sabdar ft.ft_callbk = mark_cb; 707*2654012fSReza Sabdar ft.ft_arg = ∓ 708*2654012fSReza Sabdar ft.ft_logfp = (ft_log_t)ndmp_log; 709*2654012fSReza Sabdar ft.ft_flags = ndmpd_mark_flags; 710*2654012fSReza Sabdar 711*2654012fSReza Sabdar return (traverse(session, nlp, &ft)); 712*2654012fSReza Sabdar } 713*2654012fSReza Sabdar 714*2654012fSReza Sabdar 715*2654012fSReza Sabdar /* 716*2654012fSReza Sabdar * marklbrv3_cb 717*2654012fSReza Sabdar * 718*2654012fSReza Sabdar * The callback function, called by traverse_post to mark 719*2654012fSReza Sabdar * bits in the bitmap. 720*2654012fSReza Sabdar * 721*2654012fSReza Sabdar * It's so much like mark_cb for time-based (token-based 722*2654012fSReza Sabdar * and level-type) backup types, except that it looks at 723*2654012fSReza Sabdar * the archive bit of the objects instead of their timestamp. 724*2654012fSReza Sabdar * 725*2654012fSReza Sabdar * Parameters: 726*2654012fSReza Sabdar * arg (input) - pointer to the mark parameter 727*2654012fSReza Sabdar * pnp (input) - pointer to the path node 728*2654012fSReza Sabdar * enp (input) - pointer to the entry node 729*2654012fSReza Sabdar * 730*2654012fSReza Sabdar * Returns: 731*2654012fSReza Sabdar * 0: as long as traversing should continue 732*2654012fSReza Sabdar * != 0: if traversing should stop 733*2654012fSReza Sabdar */ 734*2654012fSReza Sabdar int 735*2654012fSReza Sabdar marklbrv3_cb(void *arg, fst_node_t *pnp, fst_node_t *enp) 736*2654012fSReza Sabdar { 737*2654012fSReza Sabdar int bmd; 738*2654012fSReza Sabdar u_longlong_t bl; 739*2654012fSReza Sabdar fs_fhandle_t *pfhp, *efhp; 740*2654012fSReza Sabdar struct stat64 *pstp, *estp; 741*2654012fSReza Sabdar mark_param_t *mpp; 742*2654012fSReza Sabdar ndmp_lbr_params_t *nlp; 743*2654012fSReza Sabdar 744*2654012fSReza Sabdar mpp = (mark_param_t *)arg; 745*2654012fSReza Sabdar if (!mpp) { 746*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "NULL argument passed"); 747*2654012fSReza Sabdar return (-1); 748*2654012fSReza Sabdar } 749*2654012fSReza Sabdar nlp = ndmp_get_nlp(mpp->mp_session); 750*2654012fSReza Sabdar if (mpp->mp_session->ns_data.dd_abort || 751*2654012fSReza Sabdar (nlp && NLP_ISSET(nlp, NLPF_ABORTED))) { 752*2654012fSReza Sabdar NDMP_LOG(LOG_INFO, "Processing directories aborted."); 753*2654012fSReza Sabdar return (-1); 754*2654012fSReza Sabdar } 755*2654012fSReza Sabdar 756*2654012fSReza Sabdar bmd = mpp->mp_bmd; 757*2654012fSReza Sabdar bl = dbm_getlen(bmd); 758*2654012fSReza Sabdar 759*2654012fSReza Sabdar pfhp = pnp->tn_fh; 760*2654012fSReza Sabdar pstp = pnp->tn_st; 761*2654012fSReza Sabdar 762*2654012fSReza Sabdar /* sanity check on fh and stat of the path passed */ 763*2654012fSReza Sabdar if (pstp->st_ino > bl) { 764*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid path inode #%u", 765*2654012fSReza Sabdar (uint_t)pstp->st_ino); 766*2654012fSReza Sabdar return (-1); 767*2654012fSReza Sabdar } 768*2654012fSReza Sabdar if (pstp->st_ino != pfhp->fh_fid) { 769*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Path ino mismatch %u %u", 770*2654012fSReza Sabdar (uint_t)pstp->st_ino, (uint_t)pfhp->fh_fid); 771*2654012fSReza Sabdar return (-1); 772*2654012fSReza Sabdar } 773*2654012fSReza Sabdar 774*2654012fSReza Sabdar /* 775*2654012fSReza Sabdar * Always mark the backup path inode number. 776*2654012fSReza Sabdar */ 777*2654012fSReza Sabdar if (!enp->tn_path) { 778*2654012fSReza Sabdar (void) dbm_setone(bmd, pstp->st_ino); 779*2654012fSReza Sabdar if (ndmpd_verbose_traverse) { 780*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "d(%u)", (uint_t)pstp->st_ino); 781*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s\"", pnp->tn_path); 782*2654012fSReza Sabdar } 783*2654012fSReza Sabdar return (0); 784*2654012fSReza Sabdar } 785*2654012fSReza Sabdar 786*2654012fSReza Sabdar efhp = enp->tn_fh; 787*2654012fSReza Sabdar estp = enp->tn_st; 788*2654012fSReza Sabdar 789*2654012fSReza Sabdar /* sanity check on fh and stat of the entry passed */ 790*2654012fSReza Sabdar if (estp->st_ino > bl) { 791*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid entry inode #%u", 792*2654012fSReza Sabdar (uint_t)estp->st_ino); 793*2654012fSReza Sabdar return (-1); 794*2654012fSReza Sabdar } 795*2654012fSReza Sabdar if (estp->st_ino != efhp->fh_fid) { 796*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Entry ino mismatch %u %u", estp->st_ino, 797*2654012fSReza Sabdar (uint_t)pfhp->fh_fid); 798*2654012fSReza Sabdar return (-1); 799*2654012fSReza Sabdar } 800*2654012fSReza Sabdar 801*2654012fSReza Sabdar if (S_ISDIR(estp->st_mode) && 802*2654012fSReza Sabdar dbm_getone(bmd, (u_longlong_t)estp->st_ino)) { 803*2654012fSReza Sabdar (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); 804*2654012fSReza Sabdar if (ndmpd_verbose_traverse) { 805*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "d(%u,%u)", 806*2654012fSReza Sabdar (uint_t)pstp->st_ino, (uint_t)estp->st_ino); 807*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s, %s\"", 808*2654012fSReza Sabdar pnp->tn_path, enp->tn_path); 809*2654012fSReza Sabdar } 810*2654012fSReza Sabdar } 811*2654012fSReza Sabdar 812*2654012fSReza Sabdar return (0); 813*2654012fSReza Sabdar } 814*2654012fSReza Sabdar 815*2654012fSReza Sabdar 816*2654012fSReza Sabdar /* 817*2654012fSReza Sabdar * mark_lbrv3 818*2654012fSReza Sabdar * 819*2654012fSReza Sabdar * Traverse the backup hierarchy and mark the bits for the 820*2654012fSReza Sabdar * modified objects of directories leading to a modified 821*2654012fSReza Sabdar * object for the LBR-type backup. 822*2654012fSReza Sabdar * 823*2654012fSReza Sabdar * Parameters: 824*2654012fSReza Sabdar * session (input) - pointer to the session 825*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 826*2654012fSReza Sabdar * path (input) - the physical path to traverse 827*2654012fSReza Sabdar * 828*2654012fSReza Sabdar * Returns: 829*2654012fSReza Sabdar * 0: on success 830*2654012fSReza Sabdar * != 0: otherwise 831*2654012fSReza Sabdar */ 832*2654012fSReza Sabdar int 833*2654012fSReza Sabdar mark_lbrv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) 834*2654012fSReza Sabdar { 835*2654012fSReza Sabdar char c; 836*2654012fSReza Sabdar fs_traverse_t ft; 837*2654012fSReza Sabdar mark_param_t mp; 838*2654012fSReza Sabdar 839*2654012fSReza Sabdar if (!session || !nlp || !path || !*path) { 840*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 841*2654012fSReza Sabdar return (-1); 842*2654012fSReza Sabdar } 843*2654012fSReza Sabdar /* full and archive backups backup everything */ 844*2654012fSReza Sabdar c = toupper(nlp->nlp_clevel); 845*2654012fSReza Sabdar if (c == 'F' || c == 'A') 846*2654012fSReza Sabdar return (create_allset_bitmap(nlp)); 847*2654012fSReza Sabdar 848*2654012fSReza Sabdar nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); 849*2654012fSReza Sabdar if (nlp->nlp_bkmap < 0) { 850*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); 851*2654012fSReza Sabdar return (-1); 852*2654012fSReza Sabdar } 853*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); 854*2654012fSReza Sabdar 855*2654012fSReza Sabdar mp.mp_bmd = nlp->nlp_bkmap; 856*2654012fSReza Sabdar mp.mp_ddate = 0; 857*2654012fSReza Sabdar mp.mp_session = session; 858*2654012fSReza Sabdar mp.mp_nlp = nlp; 859*2654012fSReza Sabdar 860*2654012fSReza Sabdar ft.ft_path = path; 861*2654012fSReza Sabdar ft.ft_lpath = nlp->nlp_backup_path; 862*2654012fSReza Sabdar ft.ft_callbk = marklbrv3_cb; 863*2654012fSReza Sabdar ft.ft_arg = ∓ 864*2654012fSReza Sabdar ft.ft_logfp = (ft_log_t)ndmp_log; 865*2654012fSReza Sabdar ft.ft_flags = ndmpd_mark_flags; 866*2654012fSReza Sabdar 867*2654012fSReza Sabdar return (traverse(session, nlp, &ft)); 868*2654012fSReza Sabdar } 869*2654012fSReza Sabdar 870*2654012fSReza Sabdar 871*2654012fSReza Sabdar /* 872*2654012fSReza Sabdar * mark_levelv3 873*2654012fSReza Sabdar * 874*2654012fSReza Sabdar * Traverse the backup hierarchy and mark the bits for the 875*2654012fSReza Sabdar * modified objects of directories leading to a modified 876*2654012fSReza Sabdar * object for the level-type backup. 877*2654012fSReza Sabdar * 878*2654012fSReza Sabdar * Parameters: 879*2654012fSReza Sabdar * session (input) - pointer to the session 880*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 881*2654012fSReza Sabdar * path (input) - the physical path to traverse 882*2654012fSReza Sabdar * 883*2654012fSReza Sabdar * Returns: 884*2654012fSReza Sabdar * 0: on success 885*2654012fSReza Sabdar * != 0: otherwise 886*2654012fSReza Sabdar */ 887*2654012fSReza Sabdar int 888*2654012fSReza Sabdar mark_levelv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path) 889*2654012fSReza Sabdar { 890*2654012fSReza Sabdar fs_traverse_t ft; 891*2654012fSReza Sabdar mark_param_t mp; 892*2654012fSReza Sabdar tlm_acls_t traverse_acl; 893*2654012fSReza Sabdar 894*2654012fSReza Sabdar if (!session || !nlp || !path || !*path) { 895*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument"); 896*2654012fSReza Sabdar return (-1); 897*2654012fSReza Sabdar } 898*2654012fSReza Sabdar if (nlp->nlp_ldate == (time_t)0) 899*2654012fSReza Sabdar return (create_allset_bitmap(nlp)); 900*2654012fSReza Sabdar 901*2654012fSReza Sabdar nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); 902*2654012fSReza Sabdar if (nlp->nlp_bkmap < 0) { 903*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap."); 904*2654012fSReza Sabdar return (-1); 905*2654012fSReza Sabdar } 906*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); 907*2654012fSReza Sabdar 908*2654012fSReza Sabdar /* 909*2654012fSReza Sabdar * We do not want to allocate memory for acl every time we 910*2654012fSReza Sabdar * process a file. 911*2654012fSReza Sabdar */ 912*2654012fSReza Sabdar (void) memset(&traverse_acl, 0, sizeof (traverse_acl)); 913*2654012fSReza Sabdar mp.mp_tacl = &traverse_acl; 914*2654012fSReza Sabdar 915*2654012fSReza Sabdar mp.mp_bmd = nlp->nlp_bkmap; 916*2654012fSReza Sabdar mp.mp_ddate = nlp->nlp_ldate; 917*2654012fSReza Sabdar mp.mp_session = session; 918*2654012fSReza Sabdar mp.mp_nlp = nlp; 919*2654012fSReza Sabdar 920*2654012fSReza Sabdar ft.ft_path = path; 921*2654012fSReza Sabdar ft.ft_lpath = nlp->nlp_backup_path; 922*2654012fSReza Sabdar ft.ft_callbk = mark_cb; 923*2654012fSReza Sabdar ft.ft_arg = ∓ 924*2654012fSReza Sabdar ft.ft_logfp = (ft_log_t)ndmp_log; 925*2654012fSReza Sabdar ft.ft_flags = ndmpd_mark_flags; 926*2654012fSReza Sabdar 927*2654012fSReza Sabdar return (traverse(session, nlp, &ft)); 928*2654012fSReza Sabdar } 929*2654012fSReza Sabdar 930*2654012fSReza Sabdar 931*2654012fSReza Sabdar /* 932*2654012fSReza Sabdar * mark_commonv3 933*2654012fSReza Sabdar * 934*2654012fSReza Sabdar * Create the inode bitmap. If last date of the the 935*2654012fSReza Sabdar * backup is epoch, then all the objects should be backed 936*2654012fSReza Sabdar * up; there is no need to traverse the backup hierarchy 937*2654012fSReza Sabdar * and mark the inodes. All the bits should be marked. 938*2654012fSReza Sabdar * 939*2654012fSReza Sabdar * Otherwise, the backup hierarchy should be traversed and 940*2654012fSReza Sabdar * the objects should be marked. 941*2654012fSReza Sabdar * 942*2654012fSReza Sabdar * Parameters: 943*2654012fSReza Sabdar * session (input) - pointer to the session 944*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 945*2654012fSReza Sabdar * 946*2654012fSReza Sabdar * Returns: 947*2654012fSReza Sabdar * 0: on success. 948*2654012fSReza Sabdar * != 0: on error. 949*2654012fSReza Sabdar */ 950*2654012fSReza Sabdar int 951*2654012fSReza Sabdar mark_commonv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) 952*2654012fSReza Sabdar { 953*2654012fSReza Sabdar char buf[TLM_MAX_PATH_NAME], *chkpath; 954*2654012fSReza Sabdar int rv; 955*2654012fSReza Sabdar 956*2654012fSReza Sabdar if (NLP_ISCHKPNTED(nlp)) 957*2654012fSReza Sabdar chkpath = nlp->nlp_backup_path; 958*2654012fSReza Sabdar else 959*2654012fSReza Sabdar chkpath = tlm_build_snapshot_name(nlp->nlp_backup_path, buf, 960*2654012fSReza Sabdar nlp->nlp_jstat->js_job_name); 961*2654012fSReza Sabdar 962*2654012fSReza Sabdar if (NLP_ISSET(nlp, NLPF_TOKENBK)) 963*2654012fSReza Sabdar rv = mark_tokv3(session, nlp, chkpath); 964*2654012fSReza Sabdar else if (NLP_ISSET(nlp, NLPF_LBRBK)) 965*2654012fSReza Sabdar rv = mark_lbrv3(session, nlp, chkpath); 966*2654012fSReza Sabdar else if (NLP_ISSET(nlp, NLPF_LEVELBK)) { 967*2654012fSReza Sabdar rv = mark_levelv3(session, nlp, chkpath); 968*2654012fSReza Sabdar } else { 969*2654012fSReza Sabdar rv = -1; 970*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"", 971*2654012fSReza Sabdar nlp->nlp_backup_path); 972*2654012fSReza Sabdar } 973*2654012fSReza Sabdar 974*2654012fSReza Sabdar return (rv); 975*2654012fSReza Sabdar } 976*2654012fSReza Sabdar 977*2654012fSReza Sabdar 978*2654012fSReza Sabdar /* 979*2654012fSReza Sabdar * mark_tar_inodesv3 980*2654012fSReza Sabdar * 981*2654012fSReza Sabdar * Mark bits for tar backup format of V3. Normally, the 982*2654012fSReza Sabdar * backup hierarchy is not traversed for tar format 983*2654012fSReza Sabdar * unless it's forced by setting the ndmp_tar_force_traverse 984*2654012fSReza Sabdar * to a non-zero value. 985*2654012fSReza Sabdar * 986*2654012fSReza Sabdar * Parameters: 987*2654012fSReza Sabdar * session (input) - pointer to the session 988*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 989*2654012fSReza Sabdar * 990*2654012fSReza Sabdar * Returns: 991*2654012fSReza Sabdar * 0: on success 992*2654012fSReza Sabdar * != 0: otherwise 993*2654012fSReza Sabdar */ 994*2654012fSReza Sabdar int 995*2654012fSReza Sabdar mark_tar_inodesv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) 996*2654012fSReza Sabdar { 997*2654012fSReza Sabdar int rv; 998*2654012fSReza Sabdar 999*2654012fSReza Sabdar if (ndmp_tar_force_traverse) 1000*2654012fSReza Sabdar rv = mark_commonv3(session, nlp); 1001*2654012fSReza Sabdar else 1002*2654012fSReza Sabdar rv = create_allset_bitmap(nlp); 1003*2654012fSReza Sabdar 1004*2654012fSReza Sabdar return (rv); 1005*2654012fSReza Sabdar } 1006*2654012fSReza Sabdar 1007*2654012fSReza Sabdar 1008*2654012fSReza Sabdar /* 1009*2654012fSReza Sabdar * ndmpd_mark_inodes_v3 1010*2654012fSReza Sabdar * 1011*2654012fSReza Sabdar * Mark the inodes of the backup hierarchy if necessary. 1012*2654012fSReza Sabdar * 1013*2654012fSReza Sabdar * Parameters: 1014*2654012fSReza Sabdar * session (input) - pointer to the session 1015*2654012fSReza Sabdar * nlp (input) - pointer to the nlp structure 1016*2654012fSReza Sabdar * 1017*2654012fSReza Sabdar * Returns: 1018*2654012fSReza Sabdar * 0: on success. 1019*2654012fSReza Sabdar * != 0: on error. 1020*2654012fSReza Sabdar */ 1021*2654012fSReza Sabdar int 1022*2654012fSReza Sabdar ndmpd_mark_inodes_v3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) 1023*2654012fSReza Sabdar { 1024*2654012fSReza Sabdar int rv; 1025*2654012fSReza Sabdar 1026*2654012fSReza Sabdar if (ndmp_skip_traverse) { 1027*2654012fSReza Sabdar NDMP_LOG(LOG_INFO, "Skip processing directories \"%s\"", 1028*2654012fSReza Sabdar nlp->nlp_backup_path); 1029*2654012fSReza Sabdar rv = create_allset_bitmap(nlp); 1030*2654012fSReza Sabdar } else { 1031*2654012fSReza Sabdar if (NLP_ISTAR(nlp)) 1032*2654012fSReza Sabdar rv = mark_tar_inodesv3(session, nlp); 1033*2654012fSReza Sabdar else if (NLP_ISDUMP(nlp)) { 1034*2654012fSReza Sabdar rv = mark_commonv3(session, nlp); 1035*2654012fSReza Sabdar } else { 1036*2654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"", 1037*2654012fSReza Sabdar nlp->nlp_backup_path); 1038*2654012fSReza Sabdar rv = -1; 1039*2654012fSReza Sabdar } 1040*2654012fSReza Sabdar } 1041*2654012fSReza Sabdar 1042*2654012fSReza Sabdar return (rv); 1043*2654012fSReza Sabdar } 1044