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 = ∓
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 = ∓
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 = ∓
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 = ∓
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