8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / ndmpd / ndmp / ndmpd_mark.c
blob5b10c01e1622637203643925c042b0645ff9f671
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 /*
7 * BSD 3 Clause License
9 * Copyright (c) 2007, The Storage Networking Industry Association.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * - Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
22 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 * nor the names of its contributors may be used to endorse or promote
24 * products derived from this software without specific prior written
25 * permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <cstack.h>
42 #include <ctype.h>
43 #include <dirent.h>
44 #include <errno.h>
45 #include "ndmpd.h"
46 #include <bitmap.h>
47 #include <traverse.h>
48 #include <limits.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <time.h>
53 #include "tlm_buffers.h"
57 * Parameter passed to traverse for marking inodes
58 * when traversing backup hierarchy in V2. It
59 * includes:
60 * mp_bmd: the bitmap describptor.
61 * mp_ddate: backup date.
62 * mp_session: pointer to the session structure.
63 * mp_nlp: pointer to the nlp.
64 * mp_tacl: pointer to the acl.
66 typedef struct mark_param {
67 int mp_bmd;
68 time_t mp_ddate;
69 ndmpd_session_t *mp_session;
70 ndmp_lbr_params_t *mp_nlp;
71 tlm_acls_t *mp_tacl;
72 } mark_param_t;
76 * Set this variable to non-zero to print the inodes
77 * marked after traversing file system.
79 static int ndmpd_print_inodes = 0;
83 * Flag passed to traverse_post.
85 static int ndmpd_mark_flags = 0;
89 * Verbose traversing prints the file/dir path names
90 * if they are being marked.
92 static int ndmpd_verbose_traverse = 0;
96 * Set this flag to count the number of inodes marked
97 * after traversing backup hierarchy.
99 static int ndmpd_mark_count_flag = 0;
103 * Set this variable to non-zero value to force traversing
104 * backup hierarchy for tar format.
106 static int ndmp_tar_force_traverse = 0;
110 * Set this variable to non-zero value to skip processing
111 * directories both for tar and dump.
113 static int ndmp_skip_traverse = 0;
117 * count_bits_cb
119 * Call back for counting the set bits in the dbitmap.
121 * Parameters:
122 * bmd (input) - bitmap descriptor
123 * bn (input) - the bit number
124 * arg (input) - pointer to the argument
126 * Returns:
127 * 0: always
129 static int
130 count_bits_cb(int bmd, u_longlong_t bn, void *arg)
132 if (dbm_getone(bmd, bn)) {
133 (*(u_longlong_t *)arg)++;
134 if (ndmpd_print_inodes)
135 NDMP_LOG(LOG_DEBUG, "%llu", bn);
138 return (0);
143 * count_set_bits
145 * Count bits set in the bitmap.
147 * Parameters:
148 * path (input) - the backup path
149 * bmd (input) - bitmap descriptor
151 * Returns:
152 * void
154 void
155 count_set_bits(char *path, int bmd)
157 u_longlong_t cnt;
159 if (!ndmpd_mark_count_flag)
160 return;
162 cnt = 0;
163 (void) dbm_apply_ifset(bmd, count_bits_cb, &cnt);
164 NDMP_LOG(LOG_DEBUG, "%s %llu inodes marked", path, cnt);
169 * traverse
171 * Starts the post-traverse the backup hierarchy. Checks
172 * for exceptional cases, like aborting operation and if
173 * asked, report detailed information after traversing.
175 * Parameters:
176 * session (input) - pointer to the session
177 * nlp (input) - pointer to the nlp structure
178 * ftp (input) - pointer to the traverse parameters
180 * Returns:
181 * 0: on success
182 * != 0: otherwise
185 traverse(ndmpd_session_t *session, ndmp_lbr_params_t *nlp,
186 fs_traverse_t *ftp)
188 int rv;
189 time_t s, e;
191 if (!session || !nlp || !ftp) {
192 NDMP_LOG(LOG_DEBUG, "Invalid argument");
193 return (-1);
195 NDMP_LOG(LOG_DEBUG, "Processing directories of \"%s\"",
196 nlp->nlp_backup_path);
198 (void) time(&s);
199 if (traverse_post(ftp) != 0) {
200 rv = -1;
201 if (!session->ns_data.dd_abort && !NLP_ISSET(nlp,
202 NLPF_ABORTED)) {
203 NDMP_LOG(LOG_DEBUG,
204 "Traversing backup path hierarchy \"%s\"",
205 nlp->nlp_backup_path);
207 } else {
208 (void) dbm_setone(nlp->nlp_bkmap, (u_longlong_t)ROOT_INODE);
209 rv = 0;
210 (void) time(&e);
211 NDMP_LOG(LOG_DEBUG,
212 "\"%s\" traversed in %u sec", nlp->nlp_backup_path,
213 (uint_t)(e-s));
215 count_set_bits(nlp->nlp_backup_path, nlp->nlp_bkmap);
218 return (rv);
223 * mark_cb
225 * The callback function, called by traverse_post to mark bits
226 * in the bitmap.
228 * Set the bit of the entry if it's been modified (obviously
229 * should be backed up) plus its parent directory.
231 * If the entry is a directory and is not modified itself,
232 * but it's marked, then there is something below it that
233 * is being backed up. It shows the the path, leads to
234 * an object that will be backed up. So the path should
235 * be marked too.
237 * The backup path itself is always marked.
239 * Parameters:
240 * arg (input) - pointer to the mark parameter
241 * pnp (input) - pointer to the path node
242 * enp (input) - pointer to the entry node
244 * Returns:
245 * 0: as long as traversing should continue
246 * != 0: if traversing should stop
249 mark_cb(void *arg, fst_node_t *pnp, fst_node_t *enp)
251 int bmd;
252 int rv;
253 u_longlong_t bl;
254 time_t ddate;
255 fs_fhandle_t *pfhp, *efhp;
256 struct stat64 *pstp, *estp;
257 mark_param_t *mpp;
258 ndmp_lbr_params_t *nlp;
259 tlm_acls_t *tacl;
261 rv = 0;
262 mpp = (mark_param_t *)arg;
263 tacl = mpp->mp_tacl;
264 nlp = ndmp_get_nlp(mpp->mp_session);
265 if (!mpp) {
266 NDMP_LOG(LOG_DEBUG, "NULL argument passed");
267 rv = -1;
268 } else if (mpp->mp_session->ns_eof) {
269 NDMP_LOG(LOG_INFO, "Connection to the client is closed");
270 rv = -1;
271 } else if (mpp->mp_session->ns_data.dd_abort ||
272 (nlp && NLP_ISSET(nlp, NLPF_ABORTED))) {
273 NDMP_LOG(LOG_INFO, "Processing directories aborted.");
274 rv = -1;
277 if (rv != 0)
278 return (rv);
280 ddate = mpp->mp_ddate;
281 bmd = mpp->mp_bmd;
282 bl = dbm_getlen(bmd);
284 pfhp = pnp->tn_fh;
285 pstp = pnp->tn_st;
287 /* sanity check on fh and stat of the path passed */
288 if (pstp->st_ino > bl) {
289 NDMP_LOG(LOG_DEBUG, "Invalid path inode #%u",
290 (uint_t)pstp->st_ino);
291 return (-1);
293 if (pstp->st_ino != pfhp->fh_fid) {
294 NDMP_LOG(LOG_DEBUG, "Path ino mismatch %u %u",
295 (uint_t)pstp->st_ino, (uint_t)pfhp->fh_fid);
296 return (-1);
300 * Always mark the backup path inode number.
302 if (!enp->tn_path) {
303 (void) dbm_setone(bmd, pstp->st_ino);
304 return (0);
307 efhp = enp->tn_fh;
308 estp = enp->tn_st;
310 /* sanity check on fh and stat of the entry passed */
311 if (estp->st_ino > bl) {
312 NDMP_LOG(LOG_DEBUG, "Invalid entry inode #%u",
313 (uint_t)estp->st_ino);
314 return (-1);
316 if (estp->st_ino != efhp->fh_fid) {
317 NDMP_LOG(LOG_DEBUG, "Entry ino mismatch %u %u", estp->st_ino,
318 (uint_t)pfhp->fh_fid);
319 return (-1);
322 /* check the dates and mark the bitmap inode */
323 if (ddate == 0) {
324 /* base backup */
325 (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino);
326 (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino);
327 if (ndmpd_verbose_traverse) {
328 NDMP_LOG(LOG_DEBUG, "Base Backup");
329 NDMP_LOG(LOG_DEBUG, "\"%s/%s\"",
330 pnp->tn_path, enp->tn_path);
333 } else if (estp->st_mtime > ddate) {
334 (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino);
335 (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino);
336 if (ndmpd_verbose_traverse) {
337 NDMP_LOG(LOG_DEBUG,
338 "m(%u,%u,%u,%u)", (uint_t)pstp->st_ino,
339 (uint_t)estp->st_ino, (uint_t)estp->st_mtime,
340 (uint_t)ddate);
341 NDMP_LOG(LOG_DEBUG, "\"%s/%s\"",
342 pnp->tn_path, enp->tn_path);
344 } else if (iscreated(nlp, NULL, tacl, ddate)) {
345 (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino);
346 (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino);
347 if (ndmpd_verbose_traverse) {
348 NDMP_LOG(LOG_DEBUG,
349 "cr(%u,%u,%u,%u)", (uint_t)pstp->st_ino,
350 (uint_t)estp->st_ino, (uint_t)estp->st_mtime,
351 (uint_t)ddate);
352 NDMP_LOG(LOG_DEBUG, "\"%s/%s\"",
353 pnp->tn_path, enp->tn_path);
355 } else if (estp->st_ctime > ddate) {
356 if (!NLP_IGNCTIME(nlp)) {
357 (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino);
358 (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino);
360 if (ndmpd_verbose_traverse) {
361 if (NLP_IGNCTIME(nlp)) {
362 NDMP_LOG(LOG_DEBUG,
363 "ign c(%u,%u,%u,%u)", (uint_t)pstp->st_ino,
364 (uint_t)estp->st_ino,
365 (uint_t)estp->st_ctime, (uint_t)ddate);
366 } else {
367 NDMP_LOG(LOG_DEBUG,
368 "c(%u,%u,%u,%u)", (uint_t)pstp->st_ino,
369 (uint_t)estp->st_ino,
370 (uint_t)estp->st_ctime, (uint_t)ddate);
372 NDMP_LOG(LOG_DEBUG, "\"%s/%s\"",
373 pnp->tn_path, enp->tn_path);
375 } else if (S_ISDIR(estp->st_mode) &&
376 dbm_getone(bmd, (u_longlong_t)estp->st_ino)) {
377 (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino);
378 if (ndmpd_verbose_traverse) {
379 NDMP_LOG(LOG_DEBUG, "d(%u,%u)",
380 (uint_t)pstp->st_ino, (uint_t)estp->st_ino);
381 NDMP_LOG(LOG_DEBUG, "\"%s, %s\"",
382 pnp->tn_path, enp->tn_path);
386 return (0);
391 * mark_inodes_v2
393 * Traverse the file system in post-order and mark
394 * all the modified objects and also directories leading
395 * to them.
397 * Parameters:
398 * session (input) - pointer to the session
399 * nlp (input) - pointer to the nlp structure
400 * path (input) - the physical path to traverse
402 * Returns:
403 * 0: on success.
404 * != 0: on error.
407 mark_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path)
409 fs_traverse_t ft;
410 mark_param_t mp;
412 if (!session || !nlp || !path || !*path) {
413 NDMP_LOG(LOG_DEBUG, "Invalid argument");
414 return (-1);
417 NDMP_LOG(LOG_DEBUG, "path \"%s\"", path);
419 mp.mp_bmd = nlp->nlp_bkmap;
420 mp.mp_ddate = nlp->nlp_ldate;
421 mp.mp_session = session;
422 mp.mp_nlp = nlp;
424 ft.ft_path = path;
425 ft.ft_lpath = nlp->nlp_backup_path;
426 ft.ft_callbk = mark_cb;
427 ft.ft_arg = &mp;
428 ft.ft_logfp = (ft_log_t)ndmp_log;
429 ft.ft_flags = ndmpd_mark_flags;
431 return (traverse(session, nlp, &ft));
436 * create_bitmap
438 * Create a dbitmap and return its descriptor.
440 * Parameters:
441 * path (input) - path for which the bitmap should be created
442 * value (input) - the initial value for the bitmap
444 * Returns:
445 * the dbitmap descriptor
447 static int
448 create_bitmap(char *path, int value)
450 char bm_fname[PATH_MAX];
451 char buf[TLM_MAX_PATH_NAME];
452 char *livepath;
453 ulong_t ninode;
455 NDMP_LOG(LOG_DEBUG, "path \"%s\"", path);
457 if (fs_is_chkpntvol(path))
458 livepath = (char *)tlm_remove_checkpoint(path, buf);
459 else
460 livepath = path;
461 ninode = 1024 * 1024 * 1024;
462 if (ninode == 0)
463 return (-1);
464 (void) ndmpd_mk_temp(bm_fname);
466 NDMP_LOG(LOG_DEBUG, "path \"%s\"ninode %u bm_fname \"%s\"",
467 livepath, ninode, bm_fname);
469 return (dbm_alloc(bm_fname, (u_longlong_t)ninode, value));
474 * create_allset_bitmap
476 * A helper function to create a bitmap with all the
477 * values set to 1.
479 * Parameters:
480 * nlp (input) - pointer to the nlp structure
482 * Returns:
483 * the dbitmap descriptor
485 static int
486 create_allset_bitmap(ndmp_lbr_params_t *nlp)
488 int rv;
490 nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 1);
491 NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap);
493 if (nlp->nlp_bkmap < 0) {
494 NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap.");
495 rv = -1;
496 } else
497 rv = 0;
499 return (rv);
504 * mark_common_v2
506 * Create the inode bitmap. If last date of the the
507 * backup is epoch, then all the objects should be backed
508 * up; there is no need to traverse the backup hierarchy
509 * and mark the inodes. All the bits should be marked.
511 * Otherwise, the backup hierarchy should be traversed and
512 * the objects should be marked.
514 * Parameters:
515 * session (input) - pointer to the session
516 * nlp (input) - pointer to the nlp structure
518 * Returns:
519 * 0: on success.
520 * != 0: on error.
522 static int
523 mark_common_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp)
525 char buf[TLM_MAX_PATH_NAME], *chkpath;
526 int rv;
529 * Everything is needed for full backup.
531 if (nlp->nlp_ldate == (time_t)0)
532 return (create_allset_bitmap(nlp));
534 rv = 0;
535 nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0);
536 NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap);
538 if (nlp->nlp_bkmap < 0) {
539 NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap.");
540 rv = -1;
541 } else {
542 if (fs_is_chkpntvol(nlp->nlp_backup_path))
543 chkpath = nlp->nlp_backup_path;
544 else
545 chkpath = tlm_build_snapshot_name(
546 nlp->nlp_backup_path, buf,
547 nlp->nlp_jstat->js_job_name);
548 rv = mark_inodes_v2(session, nlp, chkpath);
549 (void) dbm_setone(nlp->nlp_bkmap, (u_longlong_t)ROOT_INODE);
552 return (rv);
557 * mark_tar_inodes_v2
559 * Create the bitmap for tar backup format.
561 * Parameters:
562 * session (input) - pointer to the session
563 * nlp (input) - pointer to the nlp structure
565 * Returns:
566 * 0: on success.
567 * != 0: on error.
569 static int
570 mark_tar_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp)
572 int rv;
574 if (ndmp_tar_force_traverse)
575 rv = mark_common_v2(session, nlp);
576 else
577 rv = create_allset_bitmap(nlp);
579 return (rv);
584 * mark_dump_inodes_v2
586 * Create the bitmap for dump backup format.
588 * Parameters:
589 * session (input) - pointer to the session
590 * nlp (input) - pointer to the nlp structure
592 * Returns:
593 * 0: on success.
594 * != 0: on error.
596 static int
597 mark_dump_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp)
599 return (mark_common_v2(session, nlp));
604 * ndmpd_mark_inodes_v2
606 * Mark the inodes of the backup hierarchy if necessary.
608 * Parameters:
609 * session (input) - pointer to the session
610 * nlp (input) - pointer to the nlp structure
612 * Returns:
613 * 0: on success.
614 * != 0: on error.
617 ndmpd_mark_inodes_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp)
619 int rv;
621 if (ndmp_skip_traverse) {
622 NDMP_LOG(LOG_INFO, "Skip processing directories \"%s\"",
623 nlp->nlp_backup_path);
624 rv = create_allset_bitmap(nlp);
625 } else {
626 if (NLP_ISTAR(nlp))
627 rv = mark_tar_inodes_v2(session, nlp);
628 else if (NLP_ISDUMP(nlp))
629 rv = mark_dump_inodes_v2(session, nlp);
630 else {
631 NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"",
632 nlp->nlp_backup_path);
633 rv = -1;
637 return (rv);
642 * ndmpd_abort_making_v2
644 * Abort the process of marking inodes.
646 * Parameters:
647 * session (input) - pointer to the session
649 * Returns:
650 * void
652 void
653 ndmpd_abort_marking_v2(ndmpd_session_t *session)
655 ndmp_lbr_params_t *nlp;
657 nlp = ndmp_get_nlp(session);
658 if (nlp)
659 NLP_SET(nlp, NLPF_ABORTED);
664 * mark_tokv3
666 * Traverse the backup hierarchy and mark the bits for the
667 * modified objects of directories leading to a modified
668 * object for the token-based backup.
670 * Parameters:
671 * session (input) - pointer to the session
672 * nlp (input) - pointer to the nlp structure
673 * path (input) - the physical path to traverse
675 * Returns:
676 * 0: on success
677 * != 0: otherwise
680 mark_tokv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path)
682 fs_traverse_t ft;
683 mark_param_t mp;
685 if (!session || !nlp || !path || !*path) {
686 NDMP_LOG(LOG_DEBUG, "Invalid argument");
687 return (-1);
689 if (nlp->nlp_tokdate == (time_t)0)
690 return (create_allset_bitmap(nlp));
692 nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0);
693 if (nlp->nlp_bkmap < 0) {
694 NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap.");
695 return (-1);
697 NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap);
699 mp.mp_bmd = nlp->nlp_bkmap;
700 mp.mp_ddate = nlp->nlp_tokdate;
701 mp.mp_session = session;
702 mp.mp_nlp = nlp;
704 ft.ft_path = path;
705 ft.ft_lpath = nlp->nlp_backup_path;
706 ft.ft_callbk = mark_cb;
707 ft.ft_arg = &mp;
708 ft.ft_logfp = (ft_log_t)ndmp_log;
709 ft.ft_flags = ndmpd_mark_flags;
711 return (traverse(session, nlp, &ft));
716 * marklbrv3_cb
718 * The callback function, called by traverse_post to mark
719 * bits in the bitmap.
721 * It's so much like mark_cb for time-based (token-based
722 * and level-type) backup types, except that it looks at
723 * the archive bit of the objects instead of their timestamp.
725 * Parameters:
726 * arg (input) - pointer to the mark parameter
727 * pnp (input) - pointer to the path node
728 * enp (input) - pointer to the entry node
730 * Returns:
731 * 0: as long as traversing should continue
732 * != 0: if traversing should stop
735 marklbrv3_cb(void *arg, fst_node_t *pnp, fst_node_t *enp)
737 int bmd;
738 u_longlong_t bl;
739 fs_fhandle_t *pfhp, *efhp;
740 struct stat64 *pstp, *estp;
741 mark_param_t *mpp;
742 ndmp_lbr_params_t *nlp;
744 mpp = (mark_param_t *)arg;
745 if (!mpp) {
746 NDMP_LOG(LOG_DEBUG, "NULL argument passed");
747 return (-1);
749 nlp = ndmp_get_nlp(mpp->mp_session);
750 if (mpp->mp_session->ns_data.dd_abort ||
751 (nlp && NLP_ISSET(nlp, NLPF_ABORTED))) {
752 NDMP_LOG(LOG_INFO, "Processing directories aborted.");
753 return (-1);
756 bmd = mpp->mp_bmd;
757 bl = dbm_getlen(bmd);
759 pfhp = pnp->tn_fh;
760 pstp = pnp->tn_st;
762 /* sanity check on fh and stat of the path passed */
763 if (pstp->st_ino > bl) {
764 NDMP_LOG(LOG_DEBUG, "Invalid path inode #%u",
765 (uint_t)pstp->st_ino);
766 return (-1);
768 if (pstp->st_ino != pfhp->fh_fid) {
769 NDMP_LOG(LOG_DEBUG, "Path ino mismatch %u %u",
770 (uint_t)pstp->st_ino, (uint_t)pfhp->fh_fid);
771 return (-1);
775 * Always mark the backup path inode number.
777 if (!enp->tn_path) {
778 (void) dbm_setone(bmd, pstp->st_ino);
779 if (ndmpd_verbose_traverse) {
780 NDMP_LOG(LOG_DEBUG, "d(%u)", (uint_t)pstp->st_ino);
781 NDMP_LOG(LOG_DEBUG, "\"%s\"", pnp->tn_path);
783 return (0);
786 efhp = enp->tn_fh;
787 estp = enp->tn_st;
789 /* sanity check on fh and stat of the entry passed */
790 if (estp->st_ino > bl) {
791 NDMP_LOG(LOG_DEBUG, "Invalid entry inode #%u",
792 (uint_t)estp->st_ino);
793 return (-1);
795 if (estp->st_ino != efhp->fh_fid) {
796 NDMP_LOG(LOG_DEBUG, "Entry ino mismatch %u %u", estp->st_ino,
797 (uint_t)pfhp->fh_fid);
798 return (-1);
801 if (S_ISDIR(estp->st_mode) &&
802 dbm_getone(bmd, (u_longlong_t)estp->st_ino)) {
803 (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino);
804 if (ndmpd_verbose_traverse) {
805 NDMP_LOG(LOG_DEBUG, "d(%u,%u)",
806 (uint_t)pstp->st_ino, (uint_t)estp->st_ino);
807 NDMP_LOG(LOG_DEBUG, "\"%s, %s\"",
808 pnp->tn_path, enp->tn_path);
812 return (0);
817 * mark_lbrv3
819 * Traverse the backup hierarchy and mark the bits for the
820 * modified objects of directories leading to a modified
821 * object for the LBR-type backup.
823 * Parameters:
824 * session (input) - pointer to the session
825 * nlp (input) - pointer to the nlp structure
826 * path (input) - the physical path to traverse
828 * Returns:
829 * 0: on success
830 * != 0: otherwise
833 mark_lbrv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path)
835 char c;
836 fs_traverse_t ft;
837 mark_param_t mp;
839 if (!session || !nlp || !path || !*path) {
840 NDMP_LOG(LOG_DEBUG, "Invalid argument");
841 return (-1);
843 /* full and archive backups backup everything */
844 c = toupper(nlp->nlp_clevel);
845 if (c == 'F' || c == 'A')
846 return (create_allset_bitmap(nlp));
848 nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0);
849 if (nlp->nlp_bkmap < 0) {
850 NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap.");
851 return (-1);
853 NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap);
855 mp.mp_bmd = nlp->nlp_bkmap;
856 mp.mp_ddate = 0;
857 mp.mp_session = session;
858 mp.mp_nlp = nlp;
860 ft.ft_path = path;
861 ft.ft_lpath = nlp->nlp_backup_path;
862 ft.ft_callbk = marklbrv3_cb;
863 ft.ft_arg = &mp;
864 ft.ft_logfp = (ft_log_t)ndmp_log;
865 ft.ft_flags = ndmpd_mark_flags;
867 return (traverse(session, nlp, &ft));
872 * mark_levelv3
874 * Traverse the backup hierarchy and mark the bits for the
875 * modified objects of directories leading to a modified
876 * object for the level-type backup.
878 * Parameters:
879 * session (input) - pointer to the session
880 * nlp (input) - pointer to the nlp structure
881 * path (input) - the physical path to traverse
883 * Returns:
884 * 0: on success
885 * != 0: otherwise
888 mark_levelv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp, char *path)
890 fs_traverse_t ft;
891 mark_param_t mp;
892 tlm_acls_t traverse_acl;
894 if (!session || !nlp || !path || !*path) {
895 NDMP_LOG(LOG_DEBUG, "Invalid argument");
896 return (-1);
898 if (nlp->nlp_ldate == (time_t)0)
899 return (create_allset_bitmap(nlp));
901 nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0);
902 if (nlp->nlp_bkmap < 0) {
903 NDMP_LOG(LOG_DEBUG, "Failed to allocate bitmap.");
904 return (-1);
906 NDMP_LOG(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap);
909 * We do not want to allocate memory for acl every time we
910 * process a file.
912 (void) memset(&traverse_acl, 0, sizeof (traverse_acl));
913 mp.mp_tacl = &traverse_acl;
915 mp.mp_bmd = nlp->nlp_bkmap;
916 mp.mp_ddate = nlp->nlp_ldate;
917 mp.mp_session = session;
918 mp.mp_nlp = nlp;
920 ft.ft_path = path;
921 ft.ft_lpath = nlp->nlp_backup_path;
922 ft.ft_callbk = mark_cb;
923 ft.ft_arg = &mp;
924 ft.ft_logfp = (ft_log_t)ndmp_log;
925 ft.ft_flags = ndmpd_mark_flags;
927 return (traverse(session, nlp, &ft));
932 * mark_commonv3
934 * Create the inode bitmap. If last date of the the
935 * backup is epoch, then all the objects should be backed
936 * up; there is no need to traverse the backup hierarchy
937 * and mark the inodes. All the bits should be marked.
939 * Otherwise, the backup hierarchy should be traversed and
940 * the objects should be marked.
942 * Parameters:
943 * session (input) - pointer to the session
944 * nlp (input) - pointer to the nlp structure
946 * Returns:
947 * 0: on success.
948 * != 0: on error.
951 mark_commonv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp)
953 char buf[TLM_MAX_PATH_NAME], *chkpath;
954 int rv;
956 if (NLP_ISCHKPNTED(nlp))
957 chkpath = nlp->nlp_backup_path;
958 else
959 chkpath = tlm_build_snapshot_name(nlp->nlp_backup_path, buf,
960 nlp->nlp_jstat->js_job_name);
962 if (NLP_ISSET(nlp, NLPF_TOKENBK))
963 rv = mark_tokv3(session, nlp, chkpath);
964 else if (NLP_ISSET(nlp, NLPF_LBRBK))
965 rv = mark_lbrv3(session, nlp, chkpath);
966 else if (NLP_ISSET(nlp, NLPF_LEVELBK)) {
967 rv = mark_levelv3(session, nlp, chkpath);
968 } else {
969 rv = -1;
970 NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"",
971 nlp->nlp_backup_path);
974 return (rv);
979 * mark_tar_inodesv3
981 * Mark bits for tar backup format of V3. Normally, the
982 * backup hierarchy is not traversed for tar format
983 * unless it's forced by setting the ndmp_tar_force_traverse
984 * to a non-zero value.
986 * Parameters:
987 * session (input) - pointer to the session
988 * nlp (input) - pointer to the nlp structure
990 * Returns:
991 * 0: on success
992 * != 0: otherwise
995 mark_tar_inodesv3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp)
997 int rv;
999 if (ndmp_tar_force_traverse)
1000 rv = mark_commonv3(session, nlp);
1001 else
1002 rv = create_allset_bitmap(nlp);
1004 return (rv);
1009 * ndmpd_mark_inodes_v3
1011 * Mark the inodes of the backup hierarchy if necessary.
1013 * Parameters:
1014 * session (input) - pointer to the session
1015 * nlp (input) - pointer to the nlp structure
1017 * Returns:
1018 * 0: on success.
1019 * != 0: on error.
1022 ndmpd_mark_inodes_v3(ndmpd_session_t *session, ndmp_lbr_params_t *nlp)
1024 int rv;
1026 if (ndmp_skip_traverse) {
1027 NDMP_LOG(LOG_INFO, "Skip processing directories \"%s\"",
1028 nlp->nlp_backup_path);
1029 rv = create_allset_bitmap(nlp);
1030 } else {
1031 if (NLP_ISTAR(nlp))
1032 rv = mark_tar_inodesv3(session, nlp);
1033 else if (NLP_ISDUMP(nlp)) {
1034 rv = mark_commonv3(session, nlp);
1035 } else {
1036 NDMP_LOG(LOG_DEBUG, "Unknown backup type for \"%s\"",
1037 nlp->nlp_backup_path);
1038 rv = -1;
1042 return (rv);