xref: /illumos-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_mark.c (revision 2654012f)
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
count_bits_cb(int bmd,u_longlong_t bn,void * arg)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
count_set_bits(char * path,int bmd)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
traverse(ndmpd_session_t * session,ndmp_lbr_params_t * nlp,fs_traverse_t * ftp)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
mark_cb(void * arg,fst_node_t * pnp,fst_node_t * enp)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
mark_inodes_v2(ndmpd_session_t * session,ndmp_lbr_params_t * nlp,char * path)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 = &mp;
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
create_bitmap(char * path,int value)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
create_allset_bitmap(ndmp_lbr_params_t * nlp)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
mark_common_v2(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)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
mark_tar_inodes_v2(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)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
mark_dump_inodes_v2(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)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
ndmpd_mark_inodes_v2(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)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
ndmpd_abort_marking_v2(ndmpd_session_t * session)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
mark_tokv3(ndmpd_session_t * session,ndmp_lbr_params_t * nlp,char * path)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 = &mp;
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
marklbrv3_cb(void * arg,fst_node_t * pnp,fst_node_t * enp)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
mark_lbrv3(ndmpd_session_t * session,ndmp_lbr_params_t * nlp,char * path)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 = &mp;
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
mark_levelv3(ndmpd_session_t * session,ndmp_lbr_params_t * nlp,char * path)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 = &mp;
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
mark_commonv3(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)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
mark_tar_inodesv3(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)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
ndmpd_mark_inodes_v3(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)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