xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c (revision 12904:aab2c5dd2abc)
17917SReza.Sabdar@Sun.COM /*
212186SJanice.Chang@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
37917SReza.Sabdar@Sun.COM  */
47917SReza.Sabdar@Sun.COM 
57917SReza.Sabdar@Sun.COM /*
67917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
77917SReza.Sabdar@Sun.COM  *
87917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
97917SReza.Sabdar@Sun.COM  *
107917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
117917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
127917SReza.Sabdar@Sun.COM  * are met:
137917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
147917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
157917SReza.Sabdar@Sun.COM  *
167917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
177917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
187917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
197917SReza.Sabdar@Sun.COM  *	  distribution.
207917SReza.Sabdar@Sun.COM  *
217917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
227917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
237917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
247917SReza.Sabdar@Sun.COM  *	  permission.
257917SReza.Sabdar@Sun.COM  *
267917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
277917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
287917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
297917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
307917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
317917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
327917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
337917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
347917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
357917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
367917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
377917SReza.Sabdar@Sun.COM  */
3812186SJanice.Chang@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */
3912186SJanice.Chang@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
407917SReza.Sabdar@Sun.COM #include <sys/stat.h>
417917SReza.Sabdar@Sun.COM #include <sys/types.h>
427917SReza.Sabdar@Sun.COM #include <sys/time.h>
437917SReza.Sabdar@Sun.COM #include <ctype.h>
447917SReza.Sabdar@Sun.COM #include <sys/socket.h>
457917SReza.Sabdar@Sun.COM #include <sys/acl.h>
467917SReza.Sabdar@Sun.COM #include <netinet/in.h>
477917SReza.Sabdar@Sun.COM #include <arpa/inet.h>
487917SReza.Sabdar@Sun.COM #include <errno.h>
497917SReza.Sabdar@Sun.COM #include <stdio.h>
507917SReza.Sabdar@Sun.COM #include <string.h>
517917SReza.Sabdar@Sun.COM #include <time.h>
527917SReza.Sabdar@Sun.COM #include <cstack.h>
537917SReza.Sabdar@Sun.COM #include "ndmp.h"
547917SReza.Sabdar@Sun.COM #include "ndmpd.h"
557917SReza.Sabdar@Sun.COM #include <bitmap.h>
567917SReza.Sabdar@Sun.COM #include <traverse.h>
577917SReza.Sabdar@Sun.COM 
587917SReza.Sabdar@Sun.COM 
597917SReza.Sabdar@Sun.COM /*
607917SReza.Sabdar@Sun.COM  * Maximum length of the string-representation of u_longlong_t type.
617917SReza.Sabdar@Sun.COM  */
627917SReza.Sabdar@Sun.COM #define	QUAD_DECIMAL_LEN	20
637917SReza.Sabdar@Sun.COM 
647917SReza.Sabdar@Sun.COM 
6510038SReza.Sabdar@Sun.COM /* Is Y=yes or T=true */
667917SReza.Sabdar@Sun.COM #define	IS_YORT(c)	(strchr("YT", toupper(c)))
677917SReza.Sabdar@Sun.COM 
6810038SReza.Sabdar@Sun.COM /* Is F=file format (vs D=node-dir format) */
6910038SReza.Sabdar@Sun.COM #define	IS_F(c)		(toupper(c) == 'F')
707917SReza.Sabdar@Sun.COM 
717917SReza.Sabdar@Sun.COM /*
727917SReza.Sabdar@Sun.COM  * If path is defined.
737917SReza.Sabdar@Sun.COM  */
747917SReza.Sabdar@Sun.COM #define	ISDEFINED(cp)	((cp) && *(cp))
757917SReza.Sabdar@Sun.COM #define	SHOULD_LBRBK(bpp)	(!((bpp)->bp_opr & TLM_OP_CHOOSE_ARCHIVE))
767917SReza.Sabdar@Sun.COM 
777917SReza.Sabdar@Sun.COM /*
787917SReza.Sabdar@Sun.COM  * Component boundary means end of path or on a '/'.  At this
797917SReza.Sabdar@Sun.COM  * point both paths should be on component boundary.
807917SReza.Sabdar@Sun.COM  */
817917SReza.Sabdar@Sun.COM #define	COMPBNDRY(p)	(!*(p) || (*p) == '/')
827917SReza.Sabdar@Sun.COM 
837917SReza.Sabdar@Sun.COM typedef struct bk_param_v3 {
847917SReza.Sabdar@Sun.COM 	ndmpd_session_t *bp_session;
857917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *bp_nlp;
867917SReza.Sabdar@Sun.COM 	tlm_job_stats_t *bp_js;
877917SReza.Sabdar@Sun.COM 	tlm_cmd_t *bp_lcmd;
887917SReza.Sabdar@Sun.COM 	tlm_commands_t *bp_cmds;
897917SReza.Sabdar@Sun.COM 	tlm_acls_t *bp_tlmacl;
907917SReza.Sabdar@Sun.COM 	int bp_opr;
917917SReza.Sabdar@Sun.COM 	char *bp_tmp;
927917SReza.Sabdar@Sun.COM 	char *bp_chkpnm;
937917SReza.Sabdar@Sun.COM 	char **bp_excls;
947917SReza.Sabdar@Sun.COM 	char *bp_unchkpnm;
957917SReza.Sabdar@Sun.COM } bk_param_v3_t;
967917SReza.Sabdar@Sun.COM 
977917SReza.Sabdar@Sun.COM 
987917SReza.Sabdar@Sun.COM /*
997917SReza.Sabdar@Sun.COM  * Multiple destination restore mode
1007917SReza.Sabdar@Sun.COM  */
1017917SReza.Sabdar@Sun.COM #define	MULTIPLE_DEST_DIRS 128
1027917SReza.Sabdar@Sun.COM 
1037917SReza.Sabdar@Sun.COM int multiple_dest_restore = 0;
1047917SReza.Sabdar@Sun.COM 
1057917SReza.Sabdar@Sun.COM /*
1067917SReza.Sabdar@Sun.COM  * Plug-in module ops
1077917SReza.Sabdar@Sun.COM  */
1087917SReza.Sabdar@Sun.COM ndmp_plugin_t *ndmp_pl;
1097917SReza.Sabdar@Sun.COM 
1107917SReza.Sabdar@Sun.COM /*
1117917SReza.Sabdar@Sun.COM  * NDMP exclusion list
1127917SReza.Sabdar@Sun.COM  */
1137917SReza.Sabdar@Sun.COM char **ndmp_excl_list = NULL;
1147917SReza.Sabdar@Sun.COM 
1157917SReza.Sabdar@Sun.COM /*
1167917SReza.Sabdar@Sun.COM  * split_env
1177917SReza.Sabdar@Sun.COM  *
1187917SReza.Sabdar@Sun.COM  * Splits the string into list of sections separated by the
1197917SReza.Sabdar@Sun.COM  * sep character.
1207917SReza.Sabdar@Sun.COM  *
1217917SReza.Sabdar@Sun.COM  * Parameters:
1227917SReza.Sabdar@Sun.COM  *   envp (input) - the environment variable that should be broken
1237917SReza.Sabdar@Sun.COM  *   sep (input) - the separator character
1247917SReza.Sabdar@Sun.COM  *
1257917SReza.Sabdar@Sun.COM  * Returns:
1267917SReza.Sabdar@Sun.COM  *   Array of character pointers: On success.  The array is allocated
1277917SReza.Sabdar@Sun.COM  *	as well as all its entries.  They all should be freed by the
1287917SReza.Sabdar@Sun.COM  *	caller.
1297917SReza.Sabdar@Sun.COM  *   NULL: on error
1307917SReza.Sabdar@Sun.COM  */
1317917SReza.Sabdar@Sun.COM static char **
split_env(char * envp,char sep)1327917SReza.Sabdar@Sun.COM split_env(char *envp, char sep)
1337917SReza.Sabdar@Sun.COM {
1347917SReza.Sabdar@Sun.COM 	char *bp, *cp, *ep;
1357917SReza.Sabdar@Sun.COM 	char *save;
1367917SReza.Sabdar@Sun.COM 	char **cpp;
1377917SReza.Sabdar@Sun.COM 	int n;
1387917SReza.Sabdar@Sun.COM 
1397917SReza.Sabdar@Sun.COM 	if (!envp)
1407917SReza.Sabdar@Sun.COM 		return (NULL);
1417917SReza.Sabdar@Sun.COM 
1427917SReza.Sabdar@Sun.COM 	while (isspace(*envp))
1437917SReza.Sabdar@Sun.COM 		envp++;
1447917SReza.Sabdar@Sun.COM 
1457917SReza.Sabdar@Sun.COM 	if (!*envp)
1467917SReza.Sabdar@Sun.COM 		return (NULL);
1477917SReza.Sabdar@Sun.COM 
1487917SReza.Sabdar@Sun.COM 	bp = save = strdup(envp);
1497917SReza.Sabdar@Sun.COM 	if (!bp)
1507917SReza.Sabdar@Sun.COM 		return (NULL);
1517917SReza.Sabdar@Sun.COM 
1527917SReza.Sabdar@Sun.COM 	/*
1537917SReza.Sabdar@Sun.COM 	 * Since the env variable is not empty, it contains at least one
1547917SReza.Sabdar@Sun.COM 	 * component
1557917SReza.Sabdar@Sun.COM 	 */
1567917SReza.Sabdar@Sun.COM 	n = 1;
1577917SReza.Sabdar@Sun.COM 	while ((cp = strchr(bp, sep))) {
1587917SReza.Sabdar@Sun.COM 		if (cp > save && *(cp-1) != '\\')
1597917SReza.Sabdar@Sun.COM 			n++;
1607917SReza.Sabdar@Sun.COM 
1617917SReza.Sabdar@Sun.COM 		bp = cp + 1;
1627917SReza.Sabdar@Sun.COM 	}
1637917SReza.Sabdar@Sun.COM 
1647917SReza.Sabdar@Sun.COM 	n++; /* for the terminating NULL pointer */
1657917SReza.Sabdar@Sun.COM 	cpp = ndmp_malloc(sizeof (char *) * n);
1667917SReza.Sabdar@Sun.COM 	if (!cpp) {
1677917SReza.Sabdar@Sun.COM 		free(save);
1687917SReza.Sabdar@Sun.COM 		return (NULL);
1697917SReza.Sabdar@Sun.COM 	}
1707917SReza.Sabdar@Sun.COM 
1717917SReza.Sabdar@Sun.COM 	(void) memset(cpp, 0, n * sizeof (char *));
1727917SReza.Sabdar@Sun.COM 	n = 0;
1737917SReza.Sabdar@Sun.COM 	cp = bp = ep = save;
1747917SReza.Sabdar@Sun.COM 	while (*cp)
1757917SReza.Sabdar@Sun.COM 		if (*cp == sep) {
1767917SReza.Sabdar@Sun.COM 			*ep = '\0';
1777917SReza.Sabdar@Sun.COM 			if (strlen(bp) > 0) {
1787917SReza.Sabdar@Sun.COM 				cpp[n] = strdup(bp);
1797917SReza.Sabdar@Sun.COM 				if (!cpp[n++]) {
1807917SReza.Sabdar@Sun.COM 					tlm_release_list(cpp);
1817917SReza.Sabdar@Sun.COM 					cpp = NULL;
1827917SReza.Sabdar@Sun.COM 					break;
1837917SReza.Sabdar@Sun.COM 				}
1847917SReza.Sabdar@Sun.COM 			}
1857917SReza.Sabdar@Sun.COM 			ep = bp = ++cp;
1867917SReza.Sabdar@Sun.COM 		} else if (*cp == '\\') {
1877917SReza.Sabdar@Sun.COM 			++cp;
1887917SReza.Sabdar@Sun.COM 			if (*cp == 'n') {	/* "\n" */
1897917SReza.Sabdar@Sun.COM 				*ep++ = '\n';
1907917SReza.Sabdar@Sun.COM 				cp++;
1917917SReza.Sabdar@Sun.COM 			} else if (*cp == 't') {	/* "\t" */
1927917SReza.Sabdar@Sun.COM 				*ep++ = '\t';
1937917SReza.Sabdar@Sun.COM 				cp++;
1947917SReza.Sabdar@Sun.COM 			} else
1957917SReza.Sabdar@Sun.COM 				*ep++ = *cp++;
1967917SReza.Sabdar@Sun.COM 		} else
1977917SReza.Sabdar@Sun.COM 			*ep++ = *cp++;
1987917SReza.Sabdar@Sun.COM 
1997917SReza.Sabdar@Sun.COM 	*ep = '\0';
2007917SReza.Sabdar@Sun.COM 	if (cpp) {
2017917SReza.Sabdar@Sun.COM 		if (strlen(bp) > 0) {
2027917SReza.Sabdar@Sun.COM 			cpp[n] = strdup(bp);
2037917SReza.Sabdar@Sun.COM 			if (!cpp[n++]) {
2047917SReza.Sabdar@Sun.COM 				tlm_release_list(cpp);
2057917SReza.Sabdar@Sun.COM 				cpp = NULL;
2067917SReza.Sabdar@Sun.COM 			} else
2077917SReza.Sabdar@Sun.COM 				cpp[n] = NULL;
2087917SReza.Sabdar@Sun.COM 		}
2097917SReza.Sabdar@Sun.COM 
2107917SReza.Sabdar@Sun.COM 		if (n == 0 && cpp != NULL) {
2117917SReza.Sabdar@Sun.COM 			tlm_release_list(cpp);
2127917SReza.Sabdar@Sun.COM 			cpp = NULL;
2137917SReza.Sabdar@Sun.COM 		}
2147917SReza.Sabdar@Sun.COM 	}
2157917SReza.Sabdar@Sun.COM 
2167917SReza.Sabdar@Sun.COM 	free(save);
2177917SReza.Sabdar@Sun.COM 	return (cpp);
2187917SReza.Sabdar@Sun.COM }
2197917SReza.Sabdar@Sun.COM 
2207917SReza.Sabdar@Sun.COM 
2217917SReza.Sabdar@Sun.COM /*
2227917SReza.Sabdar@Sun.COM  * prl
2237917SReza.Sabdar@Sun.COM  *
2247917SReza.Sabdar@Sun.COM  * Print the array of character pointers passed to it.  This is
2257917SReza.Sabdar@Sun.COM  * used for debugging purpose.
2267917SReza.Sabdar@Sun.COM  *
2277917SReza.Sabdar@Sun.COM  * Parameters:
2287917SReza.Sabdar@Sun.COM  *   lpp (input) - pointer to the array of strings
2297917SReza.Sabdar@Sun.COM  *
2307917SReza.Sabdar@Sun.COM  * Returns:
2317917SReza.Sabdar@Sun.COM  *   void
2327917SReza.Sabdar@Sun.COM  */
2337917SReza.Sabdar@Sun.COM static void
prl(char ** lpp)2347917SReza.Sabdar@Sun.COM prl(char **lpp)
2357917SReza.Sabdar@Sun.COM {
2367917SReza.Sabdar@Sun.COM 	if (!lpp) {
2377917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "empty");
2387917SReza.Sabdar@Sun.COM 		return;
2397917SReza.Sabdar@Sun.COM 	}
2407917SReza.Sabdar@Sun.COM 
2417917SReza.Sabdar@Sun.COM 	while (*lpp)
2427917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "\"%s\"", *lpp++);
2437917SReza.Sabdar@Sun.COM }
2447917SReza.Sabdar@Sun.COM 
2457917SReza.Sabdar@Sun.COM 
2467917SReza.Sabdar@Sun.COM /*
2477917SReza.Sabdar@Sun.COM  * inlist
2487917SReza.Sabdar@Sun.COM  *
2497917SReza.Sabdar@Sun.COM  * Looks through all the strings of the array to see if the ent
2507917SReza.Sabdar@Sun.COM  * matches any of the strings.  The strings are patterns.
2517917SReza.Sabdar@Sun.COM  *
2527917SReza.Sabdar@Sun.COM  * Parameters:
2537917SReza.Sabdar@Sun.COM  *   lpp (input) - pointer to the array of strings
2547917SReza.Sabdar@Sun.COM  *   ent (input) - the entry to be matched
2557917SReza.Sabdar@Sun.COM  *
2567917SReza.Sabdar@Sun.COM  * Returns:
2577917SReza.Sabdar@Sun.COM  *   TRUE: if there is a match
2587917SReza.Sabdar@Sun.COM  *   FALSE: invalid argument or no match
2597917SReza.Sabdar@Sun.COM  */
2607917SReza.Sabdar@Sun.COM static boolean_t
inlist(char ** lpp,char * ent)2617917SReza.Sabdar@Sun.COM inlist(char **lpp, char *ent)
2627917SReza.Sabdar@Sun.COM {
2637917SReza.Sabdar@Sun.COM 	if (!lpp || !ent) {
2647917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "empty list");
2657917SReza.Sabdar@Sun.COM 		return (FALSE);
2667917SReza.Sabdar@Sun.COM 	}
2677917SReza.Sabdar@Sun.COM 
2687917SReza.Sabdar@Sun.COM 	while (*lpp) {
2697917SReza.Sabdar@Sun.COM 		/*
2707917SReza.Sabdar@Sun.COM 		 * Fixing the sync_sort NDMPV3 problem, it sends the inclusion
2717917SReza.Sabdar@Sun.COM 		 * like "./" which we should skip the "./"
2727917SReza.Sabdar@Sun.COM 		 */
2737917SReza.Sabdar@Sun.COM 		char *pattern = *lpp;
2747917SReza.Sabdar@Sun.COM 		if (strncmp(pattern, "./", 2) == 0)
2757917SReza.Sabdar@Sun.COM 			pattern += 2;
2767917SReza.Sabdar@Sun.COM 
2777917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "pattern %s, ent %s", pattern, ent);
2787917SReza.Sabdar@Sun.COM 
2797917SReza.Sabdar@Sun.COM 		if (match(pattern, ent)) {
2807917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "match(%s,%s)", pattern, ent);
2817917SReza.Sabdar@Sun.COM 			return (TRUE);
2827917SReza.Sabdar@Sun.COM 		}
2837917SReza.Sabdar@Sun.COM 		lpp++;
2847917SReza.Sabdar@Sun.COM 	}
2857917SReza.Sabdar@Sun.COM 
2867917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "no match");
2877917SReza.Sabdar@Sun.COM 	return (FALSE);
2887917SReza.Sabdar@Sun.COM }
2897917SReza.Sabdar@Sun.COM 
2907917SReza.Sabdar@Sun.COM 
2917917SReza.Sabdar@Sun.COM /*
2927917SReza.Sabdar@Sun.COM  * inexl
2937917SReza.Sabdar@Sun.COM  *
2947917SReza.Sabdar@Sun.COM  * Checks if the entry is in the list.  This is used for exclusion
2957917SReza.Sabdar@Sun.COM  * list.  If the exclusion list is empty, FALSE should be returned
2967917SReza.Sabdar@Sun.COM  * showing that nothing should be excluded by default.
2977917SReza.Sabdar@Sun.COM  *
2987917SReza.Sabdar@Sun.COM  * Parameters:
2997917SReza.Sabdar@Sun.COM  *   lpp (input) - pointer to the array of strings
3007917SReza.Sabdar@Sun.COM  *   ent (input) - the entry to be matched
3017917SReza.Sabdar@Sun.COM  *
3027917SReza.Sabdar@Sun.COM  * Returns:
3037917SReza.Sabdar@Sun.COM  *   TRUE: if there is a match
3047917SReza.Sabdar@Sun.COM  *   FALSE: invalid argument or no match
3057917SReza.Sabdar@Sun.COM  *
3067917SReza.Sabdar@Sun.COM  */
3077917SReza.Sabdar@Sun.COM static boolean_t
inexl(char ** lpp,char * ent)3087917SReza.Sabdar@Sun.COM inexl(char **lpp, char *ent)
3097917SReza.Sabdar@Sun.COM {
3107917SReza.Sabdar@Sun.COM 	if (!lpp || !ent)
3117917SReza.Sabdar@Sun.COM 		return (FALSE);
3127917SReza.Sabdar@Sun.COM 
3137917SReza.Sabdar@Sun.COM 	return (inlist(lpp, ent));
3147917SReza.Sabdar@Sun.COM }
3157917SReza.Sabdar@Sun.COM 
3167917SReza.Sabdar@Sun.COM 
3177917SReza.Sabdar@Sun.COM /*
3187917SReza.Sabdar@Sun.COM  * ininc
3197917SReza.Sabdar@Sun.COM  *
3207917SReza.Sabdar@Sun.COM  * Checks if the entry is in the list.  This is used for inclusion
3217917SReza.Sabdar@Sun.COM  * list.  If the inclusion list is empty, TRUE should be returned
3227917SReza.Sabdar@Sun.COM  * showing that everything should be included by default.
3237917SReza.Sabdar@Sun.COM  *
3247917SReza.Sabdar@Sun.COM  * Parameters:
3257917SReza.Sabdar@Sun.COM  *   lpp (input) - pointer to the array of strings
3267917SReza.Sabdar@Sun.COM  *   ent (input) - the entry to be matched
3277917SReza.Sabdar@Sun.COM  *
3287917SReza.Sabdar@Sun.COM  * Returns:
3297917SReza.Sabdar@Sun.COM  *   TRUE: if there is a match or the list is empty
3307917SReza.Sabdar@Sun.COM  *   FALSE: no match
3317917SReza.Sabdar@Sun.COM  */
3327917SReza.Sabdar@Sun.COM static boolean_t
ininc(char ** lpp,char * ent)3337917SReza.Sabdar@Sun.COM ininc(char **lpp, char *ent)
3347917SReza.Sabdar@Sun.COM {
3357917SReza.Sabdar@Sun.COM 	if (!lpp || !ent || !*ent)
3367917SReza.Sabdar@Sun.COM 		return (TRUE);
3377917SReza.Sabdar@Sun.COM 
3387917SReza.Sabdar@Sun.COM 	return (inlist(lpp, ent));
3397917SReza.Sabdar@Sun.COM }
3407917SReza.Sabdar@Sun.COM 
3417917SReza.Sabdar@Sun.COM 
3427917SReza.Sabdar@Sun.COM /*
3437917SReza.Sabdar@Sun.COM  * setupsels
3447917SReza.Sabdar@Sun.COM  *
3457917SReza.Sabdar@Sun.COM  * Set up the selection list for Local B/R functions.  A new array of
3467917SReza.Sabdar@Sun.COM  * "char *" is created and the pointers point to the original paths of
3477917SReza.Sabdar@Sun.COM  * the Nlist.
3487917SReza.Sabdar@Sun.COM  *
3497917SReza.Sabdar@Sun.COM  * Parameters:
3507917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
3517917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
3527917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
3537917SReza.Sabdar@Sun.COM  *   index(input) - If not zero is the DAR entry position
3547917SReza.Sabdar@Sun.COM  *
3557917SReza.Sabdar@Sun.COM  * Returns:
3567917SReza.Sabdar@Sun.COM  *   list pointer: on success
3577917SReza.Sabdar@Sun.COM  *   NULL: on error
3587917SReza.Sabdar@Sun.COM  */
3597917SReza.Sabdar@Sun.COM /*ARGSUSED*/
3607917SReza.Sabdar@Sun.COM char **
setupsels(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp,int index)3617917SReza.Sabdar@Sun.COM setupsels(ndmpd_session_t *session, ndmpd_module_params_t *params,
3627917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp, int index)
3637917SReza.Sabdar@Sun.COM {
3647917SReza.Sabdar@Sun.COM 	char **lpp, **save;
3657917SReza.Sabdar@Sun.COM 	int i, n;
3667917SReza.Sabdar@Sun.COM 	int len;
3677917SReza.Sabdar@Sun.COM 	int start, end;
3687917SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
3697917SReza.Sabdar@Sun.COM 
3707917SReza.Sabdar@Sun.COM 	n = session->ns_data.dd_nlist_len;
3717917SReza.Sabdar@Sun.COM 
3727917SReza.Sabdar@Sun.COM 	save = lpp = ndmp_malloc(sizeof (char *) * (n + 1));
3737917SReza.Sabdar@Sun.COM 	if (!lpp) {
3747917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR, "Insufficient memory.\n");
3757917SReza.Sabdar@Sun.COM 		return (NULL);
3767917SReza.Sabdar@Sun.COM 	}
3777917SReza.Sabdar@Sun.COM 
3787917SReza.Sabdar@Sun.COM 	if (index) { /* DAR, just one entry */
3797917SReza.Sabdar@Sun.COM 		/*
3807917SReza.Sabdar@Sun.COM 		 * We have to setup a list of strings that will not match any
3817917SReza.Sabdar@Sun.COM 		 * file. One DAR entry will be added in the right position later
3827917SReza.Sabdar@Sun.COM 		 * in this function.
3837917SReza.Sabdar@Sun.COM 		 * When the match is called from tar_getdir the
3847917SReza.Sabdar@Sun.COM 		 * location of the selection that matches the entry is
3857917SReza.Sabdar@Sun.COM 		 * important
3867917SReza.Sabdar@Sun.COM 		 */
3877917SReza.Sabdar@Sun.COM 		for (i = 0; i < n; ++i)
3887917SReza.Sabdar@Sun.COM 			*(lpp+i) = " ";
3897917SReza.Sabdar@Sun.COM 		n = 1;
3907917SReza.Sabdar@Sun.COM 		start = index-1;
3917917SReza.Sabdar@Sun.COM 		end = start+1;
3927917SReza.Sabdar@Sun.COM 		lpp += start; /* Next selection entry will be in lpp[start] */
3937917SReza.Sabdar@Sun.COM 	} else {
3947917SReza.Sabdar@Sun.COM 		start = 0;
3957917SReza.Sabdar@Sun.COM 		end = n;
3967917SReza.Sabdar@Sun.COM 	}
3977917SReza.Sabdar@Sun.COM 
3987917SReza.Sabdar@Sun.COM 	for (i = start; i < end; i++) {
3997917SReza.Sabdar@Sun.COM 		ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, i);
4007917SReza.Sabdar@Sun.COM 		if (!ep)
4017917SReza.Sabdar@Sun.COM 			continue;
4027917SReza.Sabdar@Sun.COM 
4037917SReza.Sabdar@Sun.COM 		/*
4047917SReza.Sabdar@Sun.COM 		 * Check for clients that send original path as "."(like
4057917SReza.Sabdar@Sun.COM 		 * CA products). In this situation opath is something like
4067917SReza.Sabdar@Sun.COM 		 * "/v1/." and we should change it to "/v1/"
4077917SReza.Sabdar@Sun.COM 		 */
4087917SReza.Sabdar@Sun.COM 		len = strlen(ep->nm3_opath);
4097917SReza.Sabdar@Sun.COM 		if (len > 1 && ep->nm3_opath[len-2] == '/' &&
4107917SReza.Sabdar@Sun.COM 		    ep->nm3_opath[len-1] == '.') {
4117917SReza.Sabdar@Sun.COM 			ep->nm3_opath[len-1] = '\0';
4127917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG,
4137917SReza.Sabdar@Sun.COM 			    "nm3_opath changed from %s. to %s",
4147917SReza.Sabdar@Sun.COM 			    ep->nm3_opath, ep->nm3_opath);
4157917SReza.Sabdar@Sun.COM 		}
4167917SReza.Sabdar@Sun.COM 		*lpp++ = ep->nm3_opath;
4177917SReza.Sabdar@Sun.COM 	}
4187917SReza.Sabdar@Sun.COM 
4197917SReza.Sabdar@Sun.COM 	/* list termination indicator is a null pointer */
4207917SReza.Sabdar@Sun.COM 	*lpp = NULL;
4217917SReza.Sabdar@Sun.COM 
4227917SReza.Sabdar@Sun.COM 	return (save);
4237917SReza.Sabdar@Sun.COM }
4247917SReza.Sabdar@Sun.COM 
4257917SReza.Sabdar@Sun.COM 
4267917SReza.Sabdar@Sun.COM /*
4277917SReza.Sabdar@Sun.COM  * mkrsp
4287917SReza.Sabdar@Sun.COM  *
4297917SReza.Sabdar@Sun.COM  * Make Restore Path.
4307917SReza.Sabdar@Sun.COM  * It gets a path, a selection (with which the path has matched) a new
4317917SReza.Sabdar@Sun.COM  * name and makes a new name for the path.
4327917SReza.Sabdar@Sun.COM  * All the components of the path and the selection are skipped as long
4337917SReza.Sabdar@Sun.COM  * as they are the same.  If either of the path or selection are not on
4347917SReza.Sabdar@Sun.COM  * a component boundary, the match was reported falsefully and no new name
4357917SReza.Sabdar@Sun.COM  * is generated(Except the situation in which both path and selection
4367917SReza.Sabdar@Sun.COM  * end with trailing '/' and selection is the prefix of the path).
4377917SReza.Sabdar@Sun.COM  * Otherwise, the remaining of the path is appended to the
4387917SReza.Sabdar@Sun.COM  * new name.  The result is saved in the buffer passed.
4397917SReza.Sabdar@Sun.COM  *
4407917SReza.Sabdar@Sun.COM  * Parameters:
4417917SReza.Sabdar@Sun.COM  *   bp (output) - pointer to the result buffer
4427917SReza.Sabdar@Sun.COM  *   pp (input) - pointer to the path
4437917SReza.Sabdar@Sun.COM  *   sp (input) - pointer to the selection
4447917SReza.Sabdar@Sun.COM  *   np (input) - pointer to the new name
4457917SReza.Sabdar@Sun.COM  *
4467917SReza.Sabdar@Sun.COM  * Returns:
4477917SReza.Sabdar@Sun.COM  *   pointer to the bp: on success
4487917SReza.Sabdar@Sun.COM  *   NULL: otherwise
4497917SReza.Sabdar@Sun.COM  */
4507917SReza.Sabdar@Sun.COM char *
mkrsp(char * bp,char * pp,char * sp,char * np)4517917SReza.Sabdar@Sun.COM mkrsp(char *bp, char *pp, char *sp, char *np)
4527917SReza.Sabdar@Sun.COM {
4537917SReza.Sabdar@Sun.COM 	if (!bp || !pp)
4547917SReza.Sabdar@Sun.COM 		return (NULL);
4557917SReza.Sabdar@Sun.COM 
4567917SReza.Sabdar@Sun.COM 
4577917SReza.Sabdar@Sun.COM 	pp += strspn(pp, "/");
4587917SReza.Sabdar@Sun.COM 	if (sp) {
4597917SReza.Sabdar@Sun.COM 		sp += strspn(sp, "/");
4607917SReza.Sabdar@Sun.COM 
4617917SReza.Sabdar@Sun.COM 		/* skip as much as match */
4627917SReza.Sabdar@Sun.COM 		while (*sp && *pp && *sp == *pp) {
4637917SReza.Sabdar@Sun.COM 			sp++;
4647917SReza.Sabdar@Sun.COM 			pp++;
4657917SReza.Sabdar@Sun.COM 		}
4667917SReza.Sabdar@Sun.COM 
4677917SReza.Sabdar@Sun.COM 		if (!COMPBNDRY(pp) || !COMPBNDRY(sp))
4687917SReza.Sabdar@Sun.COM 			/* An exception to the boundary rule */
4697917SReza.Sabdar@Sun.COM 			/* (!(!*sp && (*(pp - 1)) == '/')) */
4707917SReza.Sabdar@Sun.COM 			if (*sp || (*(pp - 1)) != '/')
4717917SReza.Sabdar@Sun.COM 				return (NULL);
4727917SReza.Sabdar@Sun.COM 
4737917SReza.Sabdar@Sun.COM 		/* if pp shorter than sp, it should not be restored */
4747917SReza.Sabdar@Sun.COM 		if (!*pp && *sp) {
4757917SReza.Sabdar@Sun.COM 			sp += strspn(sp, "/");
4767917SReza.Sabdar@Sun.COM 			if (strlen(sp) > 0)
4777917SReza.Sabdar@Sun.COM 				return (NULL);
4787917SReza.Sabdar@Sun.COM 		}
4797917SReza.Sabdar@Sun.COM 	}
4807917SReza.Sabdar@Sun.COM 
4817917SReza.Sabdar@Sun.COM 	if (np)
4827917SReza.Sabdar@Sun.COM 		np += strspn(np, "/");
4837917SReza.Sabdar@Sun.COM 	else
4847917SReza.Sabdar@Sun.COM 		np = "";
4857917SReza.Sabdar@Sun.COM 
4867917SReza.Sabdar@Sun.COM 	if (!tlm_cat_path(bp, np, pp)) {
4877917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Restore path too long %s/%s.", np, pp);
4887917SReza.Sabdar@Sun.COM 		return (NULL);
4897917SReza.Sabdar@Sun.COM 	}
4907917SReza.Sabdar@Sun.COM 
4917917SReza.Sabdar@Sun.COM 	return (bp);
4927917SReza.Sabdar@Sun.COM }
4937917SReza.Sabdar@Sun.COM 
4947917SReza.Sabdar@Sun.COM 
4957917SReza.Sabdar@Sun.COM /*
4967917SReza.Sabdar@Sun.COM  * mknewname
4977917SReza.Sabdar@Sun.COM  *
4987917SReza.Sabdar@Sun.COM  * This is used as callback for creating the restore path. This function
4997917SReza.Sabdar@Sun.COM  * can handle both single destination and multiple restore paths.
5007917SReza.Sabdar@Sun.COM  *
5017917SReza.Sabdar@Sun.COM  * Make up the restore destination path for a particular file/directory, path,
5027917SReza.Sabdar@Sun.COM  * based on nm3_opath and nm3_dpath.  path should have matched nm3_opath
5037917SReza.Sabdar@Sun.COM  * in some way.
5047917SReza.Sabdar@Sun.COM  */
5057917SReza.Sabdar@Sun.COM char *
mknewname(struct rs_name_maker * rnp,char * buf,int idx,char * path)5067917SReza.Sabdar@Sun.COM mknewname(struct rs_name_maker *rnp, char *buf, int idx, char *path)
5077917SReza.Sabdar@Sun.COM {
5087917SReza.Sabdar@Sun.COM 	char *rv;
5097917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
5107917SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
5117917SReza.Sabdar@Sun.COM 
5127917SReza.Sabdar@Sun.COM 	rv = NULL;
5137917SReza.Sabdar@Sun.COM 	if (!buf) {
5147917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "buf is NULL");
5157917SReza.Sabdar@Sun.COM 	} else if (!path) {
5167917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "path is NULL");
5177917SReza.Sabdar@Sun.COM 	} else if ((nlp = rnp->rn_nlp) == 0) {
5187917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "rnp->rn_nlp is NULL");
5197917SReza.Sabdar@Sun.COM 	} else if (!nlp->nlp_params) {
5207917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp->nlp_params is NULL");
5217917SReza.Sabdar@Sun.COM 	} else
5227917SReza.Sabdar@Sun.COM 		if (!ndmp_full_restore_path) {
5237917SReza.Sabdar@Sun.COM 			if (idx < 0 || idx >= (int)nlp->nlp_nfiles) {
5247917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
5257917SReza.Sabdar@Sun.COM 				    "Invalid idx %d range (0, %d)",
5267917SReza.Sabdar@Sun.COM 				    idx, nlp->nlp_nfiles);
5277917SReza.Sabdar@Sun.COM 			} else if (!(ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(
5287917SReza.Sabdar@Sun.COM 			    nlp->nlp_params, idx))) {
5297917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
5307917SReza.Sabdar@Sun.COM 				    "nlist entry %d is NULL", idx);
5317917SReza.Sabdar@Sun.COM 			} else {
5327917SReza.Sabdar@Sun.COM 				rv = mkrsp(buf, path, ep->nm3_opath,
5337917SReza.Sabdar@Sun.COM 				    ep->nm3_dpath);
5347917SReza.Sabdar@Sun.COM 
5357917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
5367917SReza.Sabdar@Sun.COM 				    "idx %d org \"%s\" dst \"%s\"",
5377917SReza.Sabdar@Sun.COM 				    idx, ep->nm3_opath, ep->nm3_dpath);
5387917SReza.Sabdar@Sun.COM 				if (rv) {
5397917SReza.Sabdar@Sun.COM 					NDMP_LOG(LOG_DEBUG,
5407917SReza.Sabdar@Sun.COM 					    "path \"%s\": \"%s\"", path, rv);
5417917SReza.Sabdar@Sun.COM 				} else {
5427917SReza.Sabdar@Sun.COM 					NDMP_LOG(LOG_DEBUG,
5437917SReza.Sabdar@Sun.COM 					    "path \"%s\": NULL", path);
5447917SReza.Sabdar@Sun.COM 				}
5457917SReza.Sabdar@Sun.COM 			}
5467917SReza.Sabdar@Sun.COM 		} else {
5477917SReza.Sabdar@Sun.COM 			if (!tlm_cat_path(buf, nlp->nlp_restore_path, path)) {
5487917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_ERR, "Path too long %s/%s.",
5497917SReza.Sabdar@Sun.COM 				    nlp->nlp_restore_path, path);
5507917SReza.Sabdar@Sun.COM 				rv = NULL;
5517917SReza.Sabdar@Sun.COM 			} else {
5527917SReza.Sabdar@Sun.COM 				rv = buf;
5537917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
5547917SReza.Sabdar@Sun.COM 				    "path \"%s\": \"%s\"", path, rv);
5557917SReza.Sabdar@Sun.COM 			}
5567917SReza.Sabdar@Sun.COM 		}
5577917SReza.Sabdar@Sun.COM 
5587917SReza.Sabdar@Sun.COM 	return (rv);
5597917SReza.Sabdar@Sun.COM }
5607917SReza.Sabdar@Sun.COM 
5617917SReza.Sabdar@Sun.COM 
5627917SReza.Sabdar@Sun.COM /*
5637917SReza.Sabdar@Sun.COM  * chopslash
5647917SReza.Sabdar@Sun.COM  *
5657917SReza.Sabdar@Sun.COM  * Remove the slash from the end of the given path
5667917SReza.Sabdar@Sun.COM  */
5677917SReza.Sabdar@Sun.COM static void
chopslash(char * cp)5687917SReza.Sabdar@Sun.COM chopslash(char *cp)
5697917SReza.Sabdar@Sun.COM {
5707917SReza.Sabdar@Sun.COM 	int ln;
5717917SReza.Sabdar@Sun.COM 
5727917SReza.Sabdar@Sun.COM 	if (!cp || !*cp)
5737917SReza.Sabdar@Sun.COM 		return;
5747917SReza.Sabdar@Sun.COM 
5757917SReza.Sabdar@Sun.COM 	ln = strlen(cp);
5767917SReza.Sabdar@Sun.COM 	cp += ln - 1; /* end of the string */
5777917SReza.Sabdar@Sun.COM 	while (ln > 0 && *cp == '/') {
5787917SReza.Sabdar@Sun.COM 		*cp-- = '\0';
5797917SReza.Sabdar@Sun.COM 		ln--;
5807917SReza.Sabdar@Sun.COM 	}
5817917SReza.Sabdar@Sun.COM }
5827917SReza.Sabdar@Sun.COM 
5837917SReza.Sabdar@Sun.COM 
5847917SReza.Sabdar@Sun.COM /*
5857917SReza.Sabdar@Sun.COM  * joinpath
5867917SReza.Sabdar@Sun.COM  *
5877917SReza.Sabdar@Sun.COM  * Join two given paths
5887917SReza.Sabdar@Sun.COM  */
5897917SReza.Sabdar@Sun.COM static char *
joinpath(char * bp,char * pp,char * np)5907917SReza.Sabdar@Sun.COM joinpath(char *bp, char *pp, char *np)
5917917SReza.Sabdar@Sun.COM {
5927917SReza.Sabdar@Sun.COM 	if (pp && *pp) {
5937917SReza.Sabdar@Sun.COM 		if (np && *np)
5947917SReza.Sabdar@Sun.COM 			(void) tlm_cat_path(bp, pp, np);
5957917SReza.Sabdar@Sun.COM 		else
5967917SReza.Sabdar@Sun.COM 			(void) strlcpy(bp, pp, TLM_MAX_PATH_NAME);
5977917SReza.Sabdar@Sun.COM 	} else {
5987917SReza.Sabdar@Sun.COM 		if (np && *np)
5997917SReza.Sabdar@Sun.COM 			(void) strlcpy(bp, np, TLM_MAX_PATH_NAME);
6007917SReza.Sabdar@Sun.COM 		else
6017917SReza.Sabdar@Sun.COM 			bp = NULL;
6027917SReza.Sabdar@Sun.COM 	}
6037917SReza.Sabdar@Sun.COM 
6047917SReza.Sabdar@Sun.COM 	return (bp);
6057917SReza.Sabdar@Sun.COM }
6067917SReza.Sabdar@Sun.COM 
6077917SReza.Sabdar@Sun.COM 
6087917SReza.Sabdar@Sun.COM /*
6097917SReza.Sabdar@Sun.COM  * voliswr
6107917SReza.Sabdar@Sun.COM  *
6117917SReza.Sabdar@Sun.COM  * Is the volume writable?
6127917SReza.Sabdar@Sun.COM  */
6137917SReza.Sabdar@Sun.COM static int
voliswr(char * path)6147917SReza.Sabdar@Sun.COM voliswr(char *path)
6157917SReza.Sabdar@Sun.COM {
6167917SReza.Sabdar@Sun.COM 	int rv;
6177917SReza.Sabdar@Sun.COM 
6187917SReza.Sabdar@Sun.COM 	if (!path)
6197917SReza.Sabdar@Sun.COM 		return (0);
6207917SReza.Sabdar@Sun.COM 
6217917SReza.Sabdar@Sun.COM 	rv = !fs_is_rdonly(path) && !fs_is_chkpntvol(path);
6227917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "%d path \"%s\"", rv, path);
6237917SReza.Sabdar@Sun.COM 	return (rv);
6247917SReza.Sabdar@Sun.COM 
6257917SReza.Sabdar@Sun.COM }
6267917SReza.Sabdar@Sun.COM 
6277917SReza.Sabdar@Sun.COM 
6287917SReza.Sabdar@Sun.COM /*
6297917SReza.Sabdar@Sun.COM  * is_valid_backup_dir_v3
6307917SReza.Sabdar@Sun.COM  *
6317917SReza.Sabdar@Sun.COM  * Checks the validity of the backup path.  Backup path should
6327917SReza.Sabdar@Sun.COM  * have the following characteristics to be valid:
6337917SReza.Sabdar@Sun.COM  *	1) It should be an absolute path.
6347917SReza.Sabdar@Sun.COM  *	2) It should be a directory.
6357917SReza.Sabdar@Sun.COM  *	3) It should not be checkpoint root directory
6367917SReza.Sabdar@Sun.COM  *	4) If the file system is read-only, the backup path
6377917SReza.Sabdar@Sun.COM  *	    should be a checkpointed path.  Checkpoint cannot
6387917SReza.Sabdar@Sun.COM  *	    be created on a read-only file system.
6397917SReza.Sabdar@Sun.COM  *
6407917SReza.Sabdar@Sun.COM  * Parameters:
6417917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure.
6427917SReza.Sabdar@Sun.COM  *   bkpath (input) - the backup path
6437917SReza.Sabdar@Sun.COM  *
6447917SReza.Sabdar@Sun.COM  * Returns:
6457917SReza.Sabdar@Sun.COM  *   TRUE: if everything's OK
6467917SReza.Sabdar@Sun.COM  *   FALSE: otherwise.
6477917SReza.Sabdar@Sun.COM  */
6487917SReza.Sabdar@Sun.COM static boolean_t
is_valid_backup_dir_v3(ndmpd_module_params_t * params,char * bkpath)6497917SReza.Sabdar@Sun.COM is_valid_backup_dir_v3(ndmpd_module_params_t *params, char *bkpath)
6507917SReza.Sabdar@Sun.COM {
6517917SReza.Sabdar@Sun.COM 	char *msg;
6527917SReza.Sabdar@Sun.COM 	struct stat64 st;
6537917SReza.Sabdar@Sun.COM 
6547917SReza.Sabdar@Sun.COM 	if (*bkpath != '/') {
6557917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
6567917SReza.Sabdar@Sun.COM 		    "Relative backup path not allowed \"%s\".\n", bkpath);
6577917SReza.Sabdar@Sun.COM 		return (FALSE);
6587917SReza.Sabdar@Sun.COM 	}
6597917SReza.Sabdar@Sun.COM 	if (stat64(bkpath, &st) < 0) {
6607917SReza.Sabdar@Sun.COM 		msg = strerror(errno);
6617917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR, "\"%s\" %s.\n",
6627917SReza.Sabdar@Sun.COM 		    bkpath, msg);
6637917SReza.Sabdar@Sun.COM 		return (FALSE);
6647917SReza.Sabdar@Sun.COM 	}
6657917SReza.Sabdar@Sun.COM 	if (!S_ISDIR(st.st_mode)) {
6667917SReza.Sabdar@Sun.COM 		/* only directories can be specified as the backup path */
6677917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
6687917SReza.Sabdar@Sun.COM 		    "\"%s\" is not a directory.\n", bkpath);
6697917SReza.Sabdar@Sun.COM 		return (FALSE);
6707917SReza.Sabdar@Sun.COM 	}
6717917SReza.Sabdar@Sun.COM 	if (fs_is_rdonly(bkpath) && !fs_is_chkpntvol(bkpath) &&
6727917SReza.Sabdar@Sun.COM 	    fs_is_chkpnt_enabled(bkpath)) {
6737917SReza.Sabdar@Sun.COM 		/* it is not a chkpnted path */
6747917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
6757917SReza.Sabdar@Sun.COM 		    "\"%s\" is not a checkpointed path.\n", bkpath);
6767917SReza.Sabdar@Sun.COM 		return (FALSE);
6777917SReza.Sabdar@Sun.COM 	}
6787917SReza.Sabdar@Sun.COM 
6797917SReza.Sabdar@Sun.COM 	return (TRUE);
6807917SReza.Sabdar@Sun.COM }
6817917SReza.Sabdar@Sun.COM 
6827917SReza.Sabdar@Sun.COM 
6837917SReza.Sabdar@Sun.COM /*
6847917SReza.Sabdar@Sun.COM  * log_date_token_v3
6857917SReza.Sabdar@Sun.COM  *
6867917SReza.Sabdar@Sun.COM  * Log the token sequence number and also the date of the
6877917SReza.Sabdar@Sun.COM  * last backup for token-based backup in the system log
6887917SReza.Sabdar@Sun.COM  * and also send them as normal log to the client.
6897917SReza.Sabdar@Sun.COM  *
6907917SReza.Sabdar@Sun.COM  * Parameters:
6917917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
6927917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
6937917SReza.Sabdar@Sun.COM  *
6947917SReza.Sabdar@Sun.COM  * Returns:
6957917SReza.Sabdar@Sun.COM  *   void
6967917SReza.Sabdar@Sun.COM  */
6977917SReza.Sabdar@Sun.COM static void
log_date_token_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)6987917SReza.Sabdar@Sun.COM log_date_token_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
6997917SReza.Sabdar@Sun.COM {
7007917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL, "Token sequence counter: %d.\n",
7017917SReza.Sabdar@Sun.COM 	    nlp->nlp_tokseq);
7027917SReza.Sabdar@Sun.COM 
7037917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL, "Date of the last backup: %s.\n",
7047917SReza.Sabdar@Sun.COM 	    cctime(&nlp->nlp_tokdate));
7057917SReza.Sabdar@Sun.COM 
7067917SReza.Sabdar@Sun.COM 	if (nlp->nlp_dmpnm) {
7077917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL,
7087917SReza.Sabdar@Sun.COM 		    "Backup date log file name: \"%s\".\n", nlp->nlp_dmpnm);
7097917SReza.Sabdar@Sun.COM 	}
7107917SReza.Sabdar@Sun.COM }
7117917SReza.Sabdar@Sun.COM 
7127917SReza.Sabdar@Sun.COM 
7137917SReza.Sabdar@Sun.COM /*
7147917SReza.Sabdar@Sun.COM  * log_lbr_bk_v3
7157917SReza.Sabdar@Sun.COM  *
7167917SReza.Sabdar@Sun.COM  * Log the backup level and data of the backup for LBR-type
7177917SReza.Sabdar@Sun.COM  * backup in the system log and also send them as normal log
7187917SReza.Sabdar@Sun.COM  * to the client.
7197917SReza.Sabdar@Sun.COM  *
7207917SReza.Sabdar@Sun.COM  * Parameters:
7217917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
7227917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
7237917SReza.Sabdar@Sun.COM  *
7247917SReza.Sabdar@Sun.COM  * Returns:
7257917SReza.Sabdar@Sun.COM  *   void
7267917SReza.Sabdar@Sun.COM  */
7277917SReza.Sabdar@Sun.COM static void
log_lbr_bk_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)7287917SReza.Sabdar@Sun.COM log_lbr_bk_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
7297917SReza.Sabdar@Sun.COM {
7307917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL,
7317917SReza.Sabdar@Sun.COM 	    "Date of this level '%c': %s.\n", nlp->nlp_clevel,
7327917SReza.Sabdar@Sun.COM 	    cctime(&nlp->nlp_cdate));
7337917SReza.Sabdar@Sun.COM 
7347917SReza.Sabdar@Sun.COM 	if (nlp->nlp_dmpnm) {
7357917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL,
7367917SReza.Sabdar@Sun.COM 		    "Backup date log file name: \"%s\".\n", nlp->nlp_dmpnm);
7377917SReza.Sabdar@Sun.COM 	}
7387917SReza.Sabdar@Sun.COM }
7397917SReza.Sabdar@Sun.COM 
7407917SReza.Sabdar@Sun.COM 
7417917SReza.Sabdar@Sun.COM /*
7427917SReza.Sabdar@Sun.COM  * log_level_v3
7437917SReza.Sabdar@Sun.COM  *
7447917SReza.Sabdar@Sun.COM  * Log the backup level and date of the last and the current
7457917SReza.Sabdar@Sun.COM  * backup for level-type backup in the system log and also
7467917SReza.Sabdar@Sun.COM  * send them as normal log to the client.
7477917SReza.Sabdar@Sun.COM  *
7487917SReza.Sabdar@Sun.COM  * Parameters:
7497917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
7507917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
7517917SReza.Sabdar@Sun.COM  *
7527917SReza.Sabdar@Sun.COM  * Returns:
7537917SReza.Sabdar@Sun.COM  *   void
7547917SReza.Sabdar@Sun.COM  */
7557917SReza.Sabdar@Sun.COM static void
log_level_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)7567917SReza.Sabdar@Sun.COM log_level_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
7577917SReza.Sabdar@Sun.COM {
7587917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL,
7597917SReza.Sabdar@Sun.COM 	    "Date of the last level '%u': %s.\n", nlp->nlp_llevel,
7607917SReza.Sabdar@Sun.COM 	    cctime(&nlp->nlp_ldate));
7617917SReza.Sabdar@Sun.COM 
7627917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL,
7637917SReza.Sabdar@Sun.COM 	    "Date of this level '%u': %s.\n", nlp->nlp_clevel,
7647917SReza.Sabdar@Sun.COM 	    cctime(&nlp->nlp_cdate));
7657917SReza.Sabdar@Sun.COM 
7667917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL, "Update: %s.\n",
7677917SReza.Sabdar@Sun.COM 	    NDMP_TORF(NLP_ISSET(nlp, NLPF_UPDATE)));
7687917SReza.Sabdar@Sun.COM }
7697917SReza.Sabdar@Sun.COM 
7707917SReza.Sabdar@Sun.COM 
7717917SReza.Sabdar@Sun.COM /*
7727917SReza.Sabdar@Sun.COM  * log_bk_params_v3
7737917SReza.Sabdar@Sun.COM  *
7747917SReza.Sabdar@Sun.COM  * Dispatcher function which calls the appropriate function
7757917SReza.Sabdar@Sun.COM  * for logging the backup date and level in the system log
7767917SReza.Sabdar@Sun.COM  * and also send them as normal log message to the client.
7777917SReza.Sabdar@Sun.COM  *
7787917SReza.Sabdar@Sun.COM  * Parameters:
7797917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
7807917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
7817917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
7827917SReza.Sabdar@Sun.COM  *
7837917SReza.Sabdar@Sun.COM  * Returns:
7847917SReza.Sabdar@Sun.COM  *   void
7857917SReza.Sabdar@Sun.COM  */
7867917SReza.Sabdar@Sun.COM static void
log_bk_params_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)7877917SReza.Sabdar@Sun.COM log_bk_params_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
7887917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp)
7897917SReza.Sabdar@Sun.COM {
7907917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL, "Backing up \"%s\".\n",
7917917SReza.Sabdar@Sun.COM 	    nlp->nlp_backup_path);
7927917SReza.Sabdar@Sun.COM 
7937917SReza.Sabdar@Sun.COM 	if (session->ns_mover.md_data_addr.addr_type == NDMP_ADDR_LOCAL)
7947917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL,
7957917SReza.Sabdar@Sun.COM 		    "Tape record size: %d.\n",
7967917SReza.Sabdar@Sun.COM 		    session->ns_mover.md_record_size);
7977917SReza.Sabdar@Sun.COM 
7987917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL, "File history: %c.\n",
7997917SReza.Sabdar@Sun.COM 	    NDMP_YORN(NLP_ISSET(nlp, NLPF_FH)));
8007917SReza.Sabdar@Sun.COM 
8017917SReza.Sabdar@Sun.COM 	if (NLP_ISSET(nlp, NLPF_TOKENBK))
8027917SReza.Sabdar@Sun.COM 		log_date_token_v3(params, nlp);
8037917SReza.Sabdar@Sun.COM 	else if (NLP_ISSET(nlp, NLPF_LBRBK))
8047917SReza.Sabdar@Sun.COM 		log_lbr_bk_v3(params, nlp);
8057917SReza.Sabdar@Sun.COM 	else if (NLP_ISSET(nlp, NLPF_LEVELBK))
8067917SReza.Sabdar@Sun.COM 		log_level_v3(params, nlp);
8077917SReza.Sabdar@Sun.COM 	else {
8087917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
8097917SReza.Sabdar@Sun.COM 		    "Internal error: backup level not defined for \"%s\".\n",
8107917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path);
8117917SReza.Sabdar@Sun.COM 	}
8127917SReza.Sabdar@Sun.COM }
8137917SReza.Sabdar@Sun.COM 
8147917SReza.Sabdar@Sun.COM 
8157917SReza.Sabdar@Sun.COM /*
8167917SReza.Sabdar@Sun.COM  * get_update_env_v3
8177917SReza.Sabdar@Sun.COM  *
8187917SReza.Sabdar@Sun.COM  * Is the UPDATE environment variable specified?  If it is
8197917SReza.Sabdar@Sun.COM  * the corresponding flag is set in the flags field of the
8207917SReza.Sabdar@Sun.COM  * nlp structure, otherwise the flag is cleared.
8217917SReza.Sabdar@Sun.COM  *
8227917SReza.Sabdar@Sun.COM  * Parameters:
8237917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
8247917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
8257917SReza.Sabdar@Sun.COM  *
8267917SReza.Sabdar@Sun.COM  * Returns:
8277917SReza.Sabdar@Sun.COM  *   void
8287917SReza.Sabdar@Sun.COM  */
8297917SReza.Sabdar@Sun.COM static void
get_update_env_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)8307917SReza.Sabdar@Sun.COM get_update_env_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
8317917SReza.Sabdar@Sun.COM {
8327917SReza.Sabdar@Sun.COM 	char *envp;
8337917SReza.Sabdar@Sun.COM 
8347917SReza.Sabdar@Sun.COM 	envp = MOD_GETENV(params, "UPDATE");
8357917SReza.Sabdar@Sun.COM 	if (!envp) {
8367917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_UPDATE);
8377917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
8387917SReza.Sabdar@Sun.COM 		    "env(UPDATE) not defined, default to TRUE");
8397917SReza.Sabdar@Sun.COM 	} else {
8407917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(UPDATE): \"%s\"", envp);
8417917SReza.Sabdar@Sun.COM 		if (IS_YORT(*envp))
8427917SReza.Sabdar@Sun.COM 			NLP_SET(nlp, NLPF_UPDATE);
8437917SReza.Sabdar@Sun.COM 		else
8447917SReza.Sabdar@Sun.COM 			NLP_UNSET(nlp, NLPF_UPDATE);
8457917SReza.Sabdar@Sun.COM 	}
8467917SReza.Sabdar@Sun.COM }
8477917SReza.Sabdar@Sun.COM 
8487917SReza.Sabdar@Sun.COM 
8497917SReza.Sabdar@Sun.COM /*
8507917SReza.Sabdar@Sun.COM  * get_hist_env_v3
8517917SReza.Sabdar@Sun.COM  *
8527917SReza.Sabdar@Sun.COM  * Is backup history requested?  If it is, the corresponding
8537917SReza.Sabdar@Sun.COM  * flag is set in the flags field of the nlp structure, otherwise
8547917SReza.Sabdar@Sun.COM  * the flag is cleared.
8557917SReza.Sabdar@Sun.COM  *
8567917SReza.Sabdar@Sun.COM  * Parameters:
8577917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
8587917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
8597917SReza.Sabdar@Sun.COM  *
8607917SReza.Sabdar@Sun.COM  * Returns:
8617917SReza.Sabdar@Sun.COM  *   void
8627917SReza.Sabdar@Sun.COM  */
8637917SReza.Sabdar@Sun.COM static void
get_hist_env_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)8647917SReza.Sabdar@Sun.COM get_hist_env_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
8657917SReza.Sabdar@Sun.COM {
8667917SReza.Sabdar@Sun.COM 	char *envp;
8677917SReza.Sabdar@Sun.COM 
8687917SReza.Sabdar@Sun.COM 	envp = MOD_GETENV(params, "HIST");
8697917SReza.Sabdar@Sun.COM 	if (!envp) {
8707917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(HIST) not defined");
8717917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_FH);
8727917SReza.Sabdar@Sun.COM 	} else {
8737917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(HIST): \"%s\"", envp);
87410038SReza.Sabdar@Sun.COM 		if (IS_YORT(*envp) || IS_F(*envp))
8757917SReza.Sabdar@Sun.COM 			NLP_SET(nlp, NLPF_FH);
8767917SReza.Sabdar@Sun.COM 		else
8777917SReza.Sabdar@Sun.COM 			NLP_UNSET(nlp, NLPF_FH);
87810038SReza.Sabdar@Sun.COM 
87910038SReza.Sabdar@Sun.COM 		/* Force file format if specified */
88010038SReza.Sabdar@Sun.COM 		if (IS_F(*envp)) {
88110038SReza.Sabdar@Sun.COM 			params->mp_file_history_path_func =
88210038SReza.Sabdar@Sun.COM 			    ndmpd_api_file_history_file_v3;
88310038SReza.Sabdar@Sun.COM 			params->mp_file_history_dir_func = 0;
88410038SReza.Sabdar@Sun.COM 			params->mp_file_history_node_func = 0;
88510038SReza.Sabdar@Sun.COM 		}
8867917SReza.Sabdar@Sun.COM 	}
8877917SReza.Sabdar@Sun.COM }
8887917SReza.Sabdar@Sun.COM 
8897917SReza.Sabdar@Sun.COM 
8907917SReza.Sabdar@Sun.COM /*
8917917SReza.Sabdar@Sun.COM  * get_exc_env_v3
8927917SReza.Sabdar@Sun.COM  *
8937917SReza.Sabdar@Sun.COM  * Gets the EXCLUDE environment variable and breaks it
8947917SReza.Sabdar@Sun.COM  * into strings.  The separator of the EXCLUDE environment
8957917SReza.Sabdar@Sun.COM  * variable is the ',' character.
8967917SReza.Sabdar@Sun.COM  *
8977917SReza.Sabdar@Sun.COM  * Parameters:
8987917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
8997917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
9007917SReza.Sabdar@Sun.COM  *
9017917SReza.Sabdar@Sun.COM  * Returns:
9027917SReza.Sabdar@Sun.COM  *   void
9037917SReza.Sabdar@Sun.COM  */
9047917SReza.Sabdar@Sun.COM static void
get_exc_env_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)9057917SReza.Sabdar@Sun.COM get_exc_env_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
9067917SReza.Sabdar@Sun.COM {
9077917SReza.Sabdar@Sun.COM 	char *envp;
9087917SReza.Sabdar@Sun.COM 
9097917SReza.Sabdar@Sun.COM 	envp = MOD_GETENV(params, "EXCLUDE");
9107917SReza.Sabdar@Sun.COM 	if (!envp) {
9117917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(EXCLUDE) not defined");
9127917SReza.Sabdar@Sun.COM 		nlp->nlp_exl = NULL;
9137917SReza.Sabdar@Sun.COM 	} else {
9147917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(EXCLUDE): \"%s\"", envp);
9157917SReza.Sabdar@Sun.COM 		nlp->nlp_exl = split_env(envp, ',');
9167917SReza.Sabdar@Sun.COM 		prl(nlp->nlp_exl);
9177917SReza.Sabdar@Sun.COM 	}
9187917SReza.Sabdar@Sun.COM }
9197917SReza.Sabdar@Sun.COM 
9207917SReza.Sabdar@Sun.COM 
9217917SReza.Sabdar@Sun.COM /*
9227917SReza.Sabdar@Sun.COM  * get_inc_env_v3
9237917SReza.Sabdar@Sun.COM  *
9247917SReza.Sabdar@Sun.COM  * Gets the FILES environment variable that shows which files
9257917SReza.Sabdar@Sun.COM  * should be backed up, and breaks it into strings.  The
9267917SReza.Sabdar@Sun.COM  * separator of the FILES environment variable is the space
9277917SReza.Sabdar@Sun.COM  * character.
9287917SReza.Sabdar@Sun.COM  *
9297917SReza.Sabdar@Sun.COM  * Parameters:
9307917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
9317917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
9327917SReza.Sabdar@Sun.COM  *
9337917SReza.Sabdar@Sun.COM  * Returns:
9347917SReza.Sabdar@Sun.COM  *   void
9357917SReza.Sabdar@Sun.COM  */
9367917SReza.Sabdar@Sun.COM static void
get_inc_env_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)9377917SReza.Sabdar@Sun.COM get_inc_env_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
9387917SReza.Sabdar@Sun.COM {
9397917SReza.Sabdar@Sun.COM 	char *envp;
9407917SReza.Sabdar@Sun.COM 
9417917SReza.Sabdar@Sun.COM 	envp = MOD_GETENV(params, "FILES");
9427917SReza.Sabdar@Sun.COM 	if (!envp) {
9437917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(FILES) not defined");
9447917SReza.Sabdar@Sun.COM 		nlp->nlp_inc = NULL;
9457917SReza.Sabdar@Sun.COM 	} else {
9467917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(FILES): \"%s\"", envp);
9477917SReza.Sabdar@Sun.COM 		nlp->nlp_inc = split_env(envp, ' ');
9487917SReza.Sabdar@Sun.COM 		prl(nlp->nlp_inc);
9497917SReza.Sabdar@Sun.COM 	}
9507917SReza.Sabdar@Sun.COM }
9517917SReza.Sabdar@Sun.COM 
9527917SReza.Sabdar@Sun.COM 
9537917SReza.Sabdar@Sun.COM /*
9547917SReza.Sabdar@Sun.COM  * get_direct_env_v3
9557917SReza.Sabdar@Sun.COM  *
9567917SReza.Sabdar@Sun.COM  * Gets the DIRECT environment variable that shows if the fh_info should
9577917SReza.Sabdar@Sun.COM  * be sent to the client or not.
9587917SReza.Sabdar@Sun.COM  *
9597917SReza.Sabdar@Sun.COM  * Parameters:
9607917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
9617917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
9627917SReza.Sabdar@Sun.COM  *
9637917SReza.Sabdar@Sun.COM  * Returns:
9647917SReza.Sabdar@Sun.COM  *   void
9657917SReza.Sabdar@Sun.COM  */
9667917SReza.Sabdar@Sun.COM static void
get_direct_env_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)9677917SReza.Sabdar@Sun.COM get_direct_env_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
9687917SReza.Sabdar@Sun.COM {
9697917SReza.Sabdar@Sun.COM 	char *envp;
9707917SReza.Sabdar@Sun.COM 
9717917SReza.Sabdar@Sun.COM 	/*
9727917SReza.Sabdar@Sun.COM 	 * We should send the fh_info to the DMA, unless it is specified
9737917SReza.Sabdar@Sun.COM 	 * in the request that we should not send fh_info.
9747917SReza.Sabdar@Sun.COM 	 * At the moment we do not support DAR on directories, so if the user
9757917SReza.Sabdar@Sun.COM 	 * needs to restore a directory they should disable the DAR.
9767917SReza.Sabdar@Sun.COM 	 */
9777917SReza.Sabdar@Sun.COM 	if (params->mp_operation == NDMP_DATA_OP_RECOVER && !ndmp_dar_support) {
9787917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Direct Access Restore Disabled");
9797917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_DIRECT);
9807917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL,
9817917SReza.Sabdar@Sun.COM 		    "DAR is disabled. Running Restore without DAR");
9827917SReza.Sabdar@Sun.COM 		return;
9837917SReza.Sabdar@Sun.COM 	}
9847917SReza.Sabdar@Sun.COM 
9857917SReza.Sabdar@Sun.COM 	/*
9867917SReza.Sabdar@Sun.COM 	 * Regardless of whether DIRECT is defined at backup time we send
9877917SReza.Sabdar@Sun.COM 	 * back the fh_info, for some clients do not use get_backup_attrs.
9887917SReza.Sabdar@Sun.COM 	 * If operation is restore we have to unset the DIRECT, for
9897917SReza.Sabdar@Sun.COM 	 * some clients do not set the MOVER window.
9907917SReza.Sabdar@Sun.COM 	 */
9917917SReza.Sabdar@Sun.COM 	if (params->mp_operation == NDMP_DATA_OP_BACKUP) {
9927917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "backup default env(DIRECT): YES");
9937917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_DIRECT);
9947917SReza.Sabdar@Sun.COM 	} else {
9957917SReza.Sabdar@Sun.COM 
9967917SReza.Sabdar@Sun.COM 		envp = MOD_GETENV(params, "DIRECT");
9977917SReza.Sabdar@Sun.COM 		if (!envp) {
9987917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "env(DIRECT) not defined");
9997917SReza.Sabdar@Sun.COM 			NLP_UNSET(nlp, NLPF_DIRECT);
10007917SReza.Sabdar@Sun.COM 		} else {
10017917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "env(DIRECT): \"%s\"", envp);
10027917SReza.Sabdar@Sun.COM 			if (IS_YORT(*envp)) {
10037917SReza.Sabdar@Sun.COM 				NLP_SET(nlp, NLPF_DIRECT);
10047917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
10057917SReza.Sabdar@Sun.COM 				    "Direct Access Restore Enabled");
10067917SReza.Sabdar@Sun.COM 			} else {
10077917SReza.Sabdar@Sun.COM 				NLP_UNSET(nlp, NLPF_DIRECT);
10087917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
10097917SReza.Sabdar@Sun.COM 				    "Direct Access Restore Disabled");
10107917SReza.Sabdar@Sun.COM 			}
10117917SReza.Sabdar@Sun.COM 		}
10127917SReza.Sabdar@Sun.COM 	}
10137917SReza.Sabdar@Sun.COM 
10147917SReza.Sabdar@Sun.COM 	if (NLP_ISSET(nlp, NLPF_DIRECT)) {
10157917SReza.Sabdar@Sun.COM 		if (params->mp_operation == NDMP_DATA_OP_BACKUP)
10167917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_NORMAL,
10177917SReza.Sabdar@Sun.COM 			    "Direct Access Restore information is supported");
10187917SReza.Sabdar@Sun.COM 		else
10197917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_NORMAL,
10207917SReza.Sabdar@Sun.COM 			    "Running Restore with Direct Access Restore");
10217917SReza.Sabdar@Sun.COM 	} else {
10227917SReza.Sabdar@Sun.COM 		if (params->mp_operation == NDMP_DATA_OP_BACKUP)
10237917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_NORMAL,
10247917SReza.Sabdar@Sun.COM 			    "Direct Access Restore is not supported");
10257917SReza.Sabdar@Sun.COM 		else
10267917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_NORMAL,
10277917SReza.Sabdar@Sun.COM 			    "Running Restore without Direct Access Restore");
10287917SReza.Sabdar@Sun.COM 	}
10297917SReza.Sabdar@Sun.COM }
10307917SReza.Sabdar@Sun.COM 
10317917SReza.Sabdar@Sun.COM 
10327917SReza.Sabdar@Sun.COM /*
10337917SReza.Sabdar@Sun.COM  * get_date_token_v3
10347917SReza.Sabdar@Sun.COM  *
10357917SReza.Sabdar@Sun.COM  * Parse the token passed as the argument.  Evaluate it and
10367917SReza.Sabdar@Sun.COM  * issue any warning or error if needed.  Save the date and
10377917SReza.Sabdar@Sun.COM  * token sequence in the nlp structure fields.  The sequence
10387917SReza.Sabdar@Sun.COM  * number in the token should be less than hard-limit.  If
10397917SReza.Sabdar@Sun.COM  * it's between soft and hard limit, a warning is issued.
10407917SReza.Sabdar@Sun.COM  * There is a configurable limit which should be less than
10417917SReza.Sabdar@Sun.COM  * the soft-limit saved in ndmp_max_tok_seq variable.
10427917SReza.Sabdar@Sun.COM  *
10437917SReza.Sabdar@Sun.COM  * The NLPF_TOKENBK flag is set in the nlp flags field to
10447917SReza.Sabdar@Sun.COM  * show that the backup type is token-based.
10457917SReza.Sabdar@Sun.COM  *
10467917SReza.Sabdar@Sun.COM  * Parameters:
10477917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
10487917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
10497917SReza.Sabdar@Sun.COM  *   basedate (input) - the value of the BASE_DATE environment
10507917SReza.Sabdar@Sun.COM  *	variable.
10517917SReza.Sabdar@Sun.COM  *
10527917SReza.Sabdar@Sun.COM  * Returns:
10537917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
10547917SReza.Sabdar@Sun.COM  *   != NDMP_NO_ERR: Otherwise
10557917SReza.Sabdar@Sun.COM  *
10567917SReza.Sabdar@Sun.COM  */
10577917SReza.Sabdar@Sun.COM static ndmp_error
get_date_token_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp,char * basedate)10587917SReza.Sabdar@Sun.COM get_date_token_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp,
10597917SReza.Sabdar@Sun.COM     char *basedate)
10607917SReza.Sabdar@Sun.COM {
10617917SReza.Sabdar@Sun.COM 	char *endp;
10627917SReza.Sabdar@Sun.COM 	uint_t seq;
10637917SReza.Sabdar@Sun.COM 	ndmp_error rv;
10647917SReza.Sabdar@Sun.COM 	time_t tstamp;
10657917SReza.Sabdar@Sun.COM 	u_longlong_t tok;
10667917SReza.Sabdar@Sun.COM 
10677917SReza.Sabdar@Sun.COM 	if (!params || !nlp || !basedate || !*basedate)
10687917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
10697917SReza.Sabdar@Sun.COM 
10707917SReza.Sabdar@Sun.COM 	if (MOD_GETENV(params, "LEVEL")) {
10717917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_WARNING,
10727917SReza.Sabdar@Sun.COM 		    "Both BASE_DATE and LEVEL environment variables "
10737917SReza.Sabdar@Sun.COM 		    "defined.\n");
10747917SReza.Sabdar@Sun.COM 		MOD_LOGCONTV3(params, NDMP_LOG_WARNING,
10757917SReza.Sabdar@Sun.COM 		    "BASE_DATE is being used for this backup.\n");
10767917SReza.Sabdar@Sun.COM 	}
10777917SReza.Sabdar@Sun.COM 
10787917SReza.Sabdar@Sun.COM 	tok = strtoll(basedate, &endp, 10);
10797917SReza.Sabdar@Sun.COM 	if (endp == basedate) {
10807917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
10817917SReza.Sabdar@Sun.COM 		    "Invalid BASE_DATE environment variable: \"%s\".\n",
10827917SReza.Sabdar@Sun.COM 		    basedate);
10837917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
10847917SReza.Sabdar@Sun.COM 	}
10857917SReza.Sabdar@Sun.COM 
10867917SReza.Sabdar@Sun.COM 	tstamp = tok & 0xffffffff;
10877917SReza.Sabdar@Sun.COM 	seq = (tok >> 32) & 0xffffffff;
10887917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "basedate \"%s\" %lld seq %u tstamp %u",
10897917SReza.Sabdar@Sun.COM 	    basedate, tok, seq, tstamp);
10907917SReza.Sabdar@Sun.COM 
10917917SReza.Sabdar@Sun.COM 	if ((int)seq > ndmp_get_max_tok_seq()) {
10927917SReza.Sabdar@Sun.COM 		rv = NDMP_ILLEGAL_ARGS_ERR;
10937917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
10947917SReza.Sabdar@Sun.COM 		    "The sequence counter of the token exceeds the "
10957917SReza.Sabdar@Sun.COM 		    "maximum permitted value.\n");
10967917SReza.Sabdar@Sun.COM 		MOD_LOGCONTV3(params, NDMP_LOG_ERROR,
10977917SReza.Sabdar@Sun.COM 		    "Token sequence: %u, maxiumum value: %u.\n",
10987917SReza.Sabdar@Sun.COM 		    seq, ndmp_get_max_tok_seq());
10997917SReza.Sabdar@Sun.COM 	} else if (seq >= NDMP_TOKSEQ_HLIMIT) {
11007917SReza.Sabdar@Sun.COM 		rv = NDMP_ILLEGAL_ARGS_ERR;
11017917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
11027917SReza.Sabdar@Sun.COM 		    "The sequence counter the of token exceeds the "
11037917SReza.Sabdar@Sun.COM 		    "hard-limit.\n");
11047917SReza.Sabdar@Sun.COM 		MOD_LOGCONTV3(params, NDMP_LOG_ERROR,
11057917SReza.Sabdar@Sun.COM 		    "Token sequence: %u, hard-limit: %u.\n",
11067917SReza.Sabdar@Sun.COM 		    seq, NDMP_TOKSEQ_HLIMIT);
11077917SReza.Sabdar@Sun.COM 	} else {
11087917SReza.Sabdar@Sun.COM 		rv = NDMP_NO_ERR;
11097917SReza.Sabdar@Sun.COM 		/*
11107917SReza.Sabdar@Sun.COM 		 * Issue a warning if the seq is equal to the maximum
11117917SReza.Sabdar@Sun.COM 		 * permitted seq number or equal to the soft-limit.
11127917SReza.Sabdar@Sun.COM 		 */
11137917SReza.Sabdar@Sun.COM 		if (seq == NDMP_TOKSEQ_SLIMIT) {
11147917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_WARNING,
11157917SReza.Sabdar@Sun.COM 			    "The sequence counter of the token has reached "
11167917SReza.Sabdar@Sun.COM 			    "the soft-limit.\n");
11177917SReza.Sabdar@Sun.COM 			MOD_LOGCONTV3(params, NDMP_LOG_WARNING,
11187917SReza.Sabdar@Sun.COM 			    "Token sequence: %u, soft-limit: %u.\n",
11197917SReza.Sabdar@Sun.COM 			    seq, NDMP_TOKSEQ_SLIMIT);
11207917SReza.Sabdar@Sun.COM 		} else if ((int)seq == ndmp_get_max_tok_seq()) {
11217917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_WARNING,
11227917SReza.Sabdar@Sun.COM 			    "The sequence counter of the token has reached "
11237917SReza.Sabdar@Sun.COM 			    "the maximum permitted value.\n");
11247917SReza.Sabdar@Sun.COM 			MOD_LOGCONTV3(params, NDMP_LOG_WARNING,
11257917SReza.Sabdar@Sun.COM 			    "Token sequence: %u, maxiumum value: %u.\n",
11267917SReza.Sabdar@Sun.COM 			    seq, ndmp_get_max_tok_seq());
11277917SReza.Sabdar@Sun.COM 		}
11287917SReza.Sabdar@Sun.COM 
11297917SReza.Sabdar@Sun.COM 		/*
11307917SReza.Sabdar@Sun.COM 		 * The current seq is equal to the seq field of the
11317917SReza.Sabdar@Sun.COM 		 * token.  It will be increased after successful backup
11327917SReza.Sabdar@Sun.COM 		 * before setting the DUMP_DATE environment variable.
11337917SReza.Sabdar@Sun.COM 		 */
11347917SReza.Sabdar@Sun.COM 		nlp->nlp_dmpnm = MOD_GETENV(params, "DMP_NAME");
11357917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_TOKENBK);
11367917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_LEVELBK);
11377917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_LBRBK);
11387917SReza.Sabdar@Sun.COM 		nlp->nlp_tokseq = seq;
11397917SReza.Sabdar@Sun.COM 		nlp->nlp_tokdate = tstamp;
11407917SReza.Sabdar@Sun.COM 		/*
11417917SReza.Sabdar@Sun.COM 		 * The value of nlp_cdate will be set to the checkpoint
11427917SReza.Sabdar@Sun.COM 		 * creation time after it is created.
11437917SReza.Sabdar@Sun.COM 		 */
11447917SReza.Sabdar@Sun.COM 	}
11457917SReza.Sabdar@Sun.COM 
11467917SReza.Sabdar@Sun.COM 	return (rv);
11477917SReza.Sabdar@Sun.COM }
11487917SReza.Sabdar@Sun.COM 
11497917SReza.Sabdar@Sun.COM 
11507917SReza.Sabdar@Sun.COM /*
11517917SReza.Sabdar@Sun.COM  * get_lbr_bk_v3
11527917SReza.Sabdar@Sun.COM  *
11537917SReza.Sabdar@Sun.COM  * Sets the level fields of the nlp structures for
11547917SReza.Sabdar@Sun.COM  * LBR-type backup.  The NLPF_LBRBK flag of the
11557917SReza.Sabdar@Sun.COM  * nlp flags is also set to show the backup type.
11567917SReza.Sabdar@Sun.COM  *
11577917SReza.Sabdar@Sun.COM  * Parameters:
11587917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
11597917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
11607917SReza.Sabdar@Sun.COM  *   type (input) - the backup level: 'F', 'A', 'I', 'D' or
11617917SReza.Sabdar@Sun.COM  *	their lower-case values.
11627917SReza.Sabdar@Sun.COM  *
11637917SReza.Sabdar@Sun.COM  * Returns:
11647917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
11657917SReza.Sabdar@Sun.COM  *   != NDMP_NO_ERR: Otherwise
11667917SReza.Sabdar@Sun.COM  */
11677917SReza.Sabdar@Sun.COM static ndmp_error
get_lbr_bk_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp,char * type)11687917SReza.Sabdar@Sun.COM get_lbr_bk_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp, char *type)
11697917SReza.Sabdar@Sun.COM {
11707917SReza.Sabdar@Sun.COM 	if (!params || !nlp || !type || !*type)
11717917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
11727917SReza.Sabdar@Sun.COM 
11737917SReza.Sabdar@Sun.COM 	NLP_SET(nlp, NLPF_LBRBK);
11747917SReza.Sabdar@Sun.COM 	NLP_UNSET(nlp, NLPF_TOKENBK);
11757917SReza.Sabdar@Sun.COM 	NLP_UNSET(nlp, NLPF_LEVELBK);
11767917SReza.Sabdar@Sun.COM 	nlp->nlp_dmpnm = MOD_GETENV(params, "DMP_NAME");
11777917SReza.Sabdar@Sun.COM 	nlp->nlp_llevel = toupper(*type);
11787917SReza.Sabdar@Sun.COM 	nlp->nlp_ldate = (time_t)0;
11797917SReza.Sabdar@Sun.COM 	nlp->nlp_clevel = nlp->nlp_llevel;
11807917SReza.Sabdar@Sun.COM 	(void) time(&nlp->nlp_cdate);
11817917SReza.Sabdar@Sun.COM 
11827917SReza.Sabdar@Sun.COM 	return (NDMP_NO_ERR);
11837917SReza.Sabdar@Sun.COM }
11847917SReza.Sabdar@Sun.COM 
11857917SReza.Sabdar@Sun.COM 
11867917SReza.Sabdar@Sun.COM /*
11877917SReza.Sabdar@Sun.COM  * get_backup_level_v3
11887917SReza.Sabdar@Sun.COM  *
11897917SReza.Sabdar@Sun.COM  * Gets the backup level from the environment variables.  If
11907917SReza.Sabdar@Sun.COM  * BASE_DATE is specified, it will be used, otherwise LEVEL
11917917SReza.Sabdar@Sun.COM  * will be used.  If neither is specified, LEVEL = '0' is
11927917SReza.Sabdar@Sun.COM  * assumed.
11937917SReza.Sabdar@Sun.COM  *
11947917SReza.Sabdar@Sun.COM  * Parameters:
11957917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
11967917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
11977917SReza.Sabdar@Sun.COM  *
11987917SReza.Sabdar@Sun.COM  * Returns:
11997917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
12007917SReza.Sabdar@Sun.COM  *   != NDMP_NO_ERR: Otherwise
12017917SReza.Sabdar@Sun.COM  */
12027917SReza.Sabdar@Sun.COM static ndmp_error
get_backup_level_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)12037917SReza.Sabdar@Sun.COM get_backup_level_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
12047917SReza.Sabdar@Sun.COM {
12057917SReza.Sabdar@Sun.COM 	char *envp;
12067917SReza.Sabdar@Sun.COM 	ndmp_error rv;
12077917SReza.Sabdar@Sun.COM 
12087917SReza.Sabdar@Sun.COM 	/*
12097917SReza.Sabdar@Sun.COM 	 * If the BASE_DATE env variable is specified use it, otherwise
12107917SReza.Sabdar@Sun.COM 	 * look to see if LEVEL is specified.  If LEVEL is not
12117917SReza.Sabdar@Sun.COM 	 * specified either, backup level '0' must be made. Level backup
12127917SReza.Sabdar@Sun.COM 	 * does not clear the archive bit.
12137917SReza.Sabdar@Sun.COM 	 *
12147917SReza.Sabdar@Sun.COM 	 * If LEVEL environment varaible is specified, values for
12157917SReza.Sabdar@Sun.COM 	 * 'F', 'D', 'I' and 'A' (for 'Full', 'Differential',
12167917SReza.Sabdar@Sun.COM 	 * 'Incremental', and 'Archive' is checked first.  Then
12177917SReza.Sabdar@Sun.COM 	 * level '0' to '9' will be checked.
12187917SReza.Sabdar@Sun.COM 	 *
12197917SReza.Sabdar@Sun.COM 	 * LEVEL environment variable can hold only one character.
12207917SReza.Sabdar@Sun.COM 	 * If its length is longer than 1, an error is returned.
12217917SReza.Sabdar@Sun.COM 	 */
12227917SReza.Sabdar@Sun.COM 	envp = MOD_GETENV(params, "BASE_DATE");
12237917SReza.Sabdar@Sun.COM 	if (envp)
12247917SReza.Sabdar@Sun.COM 		return (get_date_token_v3(params, nlp, envp));
12257917SReza.Sabdar@Sun.COM 
12267917SReza.Sabdar@Sun.COM 
12277917SReza.Sabdar@Sun.COM 	envp = MOD_GETENV(params, "LEVEL");
12287917SReza.Sabdar@Sun.COM 	if (!envp) {
12297917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "env(LEVEL) not defined, default to 0");
12307917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_LEVELBK);
12317917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_LBRBK);
12327917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_TOKENBK);
12337917SReza.Sabdar@Sun.COM 		nlp->nlp_llevel = 0;
12347917SReza.Sabdar@Sun.COM 		nlp->nlp_ldate = 0;
12357917SReza.Sabdar@Sun.COM 		nlp->nlp_clevel = 0;
12367917SReza.Sabdar@Sun.COM 		/*
12377917SReza.Sabdar@Sun.COM 		 * The value of nlp_cdate will be set to the checkpoint
12387917SReza.Sabdar@Sun.COM 		 * creation time after it is created.
12397917SReza.Sabdar@Sun.COM 		 */
12407917SReza.Sabdar@Sun.COM 		return (NDMP_NO_ERR);
12417917SReza.Sabdar@Sun.COM 	}
12427917SReza.Sabdar@Sun.COM 
12437917SReza.Sabdar@Sun.COM 	if (*(envp+1) != '\0') {
12447917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
12457917SReza.Sabdar@Sun.COM 		    "Invalid backup level \"%s\".\n", envp);
12467917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
12477917SReza.Sabdar@Sun.COM 	}
12487917SReza.Sabdar@Sun.COM 
12497917SReza.Sabdar@Sun.COM 	if (IS_LBR_BKTYPE(*envp))
12507917SReza.Sabdar@Sun.COM 		return (get_lbr_bk_v3(params, nlp, envp));
12517917SReza.Sabdar@Sun.COM 
12527917SReza.Sabdar@Sun.COM 	if (!isdigit(*envp)) {
12537917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
12547917SReza.Sabdar@Sun.COM 		    "Invalid backup level \"%s\".\n", envp);
12557917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
12567917SReza.Sabdar@Sun.COM 	}
12577917SReza.Sabdar@Sun.COM 
12587917SReza.Sabdar@Sun.COM 	NLP_SET(nlp, NLPF_LEVELBK);
12597917SReza.Sabdar@Sun.COM 	NLP_UNSET(nlp, NLPF_LBRBK);
12607917SReza.Sabdar@Sun.COM 	NLP_UNSET(nlp, NLPF_TOKENBK);
12617917SReza.Sabdar@Sun.COM 	nlp->nlp_llevel = *envp - '0';
12627917SReza.Sabdar@Sun.COM 	nlp->nlp_ldate = 0;
12637917SReza.Sabdar@Sun.COM 	nlp->nlp_clevel = nlp->nlp_llevel;
12647917SReza.Sabdar@Sun.COM 	/*
12657917SReza.Sabdar@Sun.COM 	 * The value of nlp_cdate will be set to the checkpoint
12667917SReza.Sabdar@Sun.COM 	 * creation time after it is created.
12677917SReza.Sabdar@Sun.COM 	 */
12687917SReza.Sabdar@Sun.COM 	if (ndmpd_get_dumptime(nlp->nlp_backup_path, &nlp->nlp_llevel,
12697917SReza.Sabdar@Sun.COM 	    &nlp->nlp_ldate) < 0) {
12707917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
12717917SReza.Sabdar@Sun.COM 		    "Getting dumpdates for %s level '%c'.\n",
12727917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path, *envp);
12737917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
12747917SReza.Sabdar@Sun.COM 	} else {
12757917SReza.Sabdar@Sun.COM 		get_update_env_v3(params, nlp);
12767917SReza.Sabdar@Sun.COM 		rv = NDMP_NO_ERR;
12777917SReza.Sabdar@Sun.COM 	}
12787917SReza.Sabdar@Sun.COM 
12797917SReza.Sabdar@Sun.COM 	return (rv);
12807917SReza.Sabdar@Sun.COM }
12817917SReza.Sabdar@Sun.COM 
12827917SReza.Sabdar@Sun.COM 
12837917SReza.Sabdar@Sun.COM /*
12847917SReza.Sabdar@Sun.COM  * save_date_token_v3
12857917SReza.Sabdar@Sun.COM  *
12867917SReza.Sabdar@Sun.COM  * Make the value of DUMP_DATE env variable and append the values
12877917SReza.Sabdar@Sun.COM  * of the current backup in the file specified with the DMP_NAME
12887917SReza.Sabdar@Sun.COM  * env variable if any file is specified.  The file will be
12897917SReza.Sabdar@Sun.COM  * relative name in the backup directory path.
12907917SReza.Sabdar@Sun.COM  *
12917917SReza.Sabdar@Sun.COM  * Parameters:
12927917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
12937917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
12947917SReza.Sabdar@Sun.COM  *
12957917SReza.Sabdar@Sun.COM  * Returns:
12967917SReza.Sabdar@Sun.COM  *   void
12977917SReza.Sabdar@Sun.COM  */
12987917SReza.Sabdar@Sun.COM static void
save_date_token_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)12997917SReza.Sabdar@Sun.COM save_date_token_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
13007917SReza.Sabdar@Sun.COM {
13017917SReza.Sabdar@Sun.COM 	char val[QUAD_DECIMAL_LEN];
13027917SReza.Sabdar@Sun.COM 	u_longlong_t tok;
13037917SReza.Sabdar@Sun.COM 
13047917SReza.Sabdar@Sun.COM 	if (!params || !nlp)
13057917SReza.Sabdar@Sun.COM 		return;
13067917SReza.Sabdar@Sun.COM 
13077917SReza.Sabdar@Sun.COM 	nlp->nlp_tokseq++;
13087917SReza.Sabdar@Sun.COM 	tok = ((u_longlong_t)nlp->nlp_tokseq << 32) | nlp->nlp_cdate;
13097917SReza.Sabdar@Sun.COM 	(void) snprintf(val, sizeof (val), "%llu", tok);
13107917SReza.Sabdar@Sun.COM 
13117917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "tok: %lld %s", tok, val);
13127917SReza.Sabdar@Sun.COM 
13137917SReza.Sabdar@Sun.COM 	if (MOD_SETENV(params, "DUMP_DATE", val) != 0) {
13147917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
13157917SReza.Sabdar@Sun.COM 		    "Could not set DUMP_DATE to %s", val);
13167917SReza.Sabdar@Sun.COM 	} else if (!nlp->nlp_dmpnm) {
13177917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "No log file defined");
13187917SReza.Sabdar@Sun.COM 	} else if (ndmpd_append_dumptime(nlp->nlp_dmpnm, nlp->nlp_backup_path,
13197917SReza.Sabdar@Sun.COM 	    nlp->nlp_tokseq, nlp->nlp_tokdate) < 0) {
13207917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
13217917SReza.Sabdar@Sun.COM 		    "Saving backup date for \"%s\" in \"%s\".\n",
13227917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path, nlp->nlp_dmpnm);
13237917SReza.Sabdar@Sun.COM 	}
13247917SReza.Sabdar@Sun.COM }
13257917SReza.Sabdar@Sun.COM 
13267917SReza.Sabdar@Sun.COM 
13277917SReza.Sabdar@Sun.COM /*
13287917SReza.Sabdar@Sun.COM  * save_lbr_bk_v3
13297917SReza.Sabdar@Sun.COM  *
13307917SReza.Sabdar@Sun.COM  * Append the backup type and date in the DMP_NAME file for
13317917SReza.Sabdar@Sun.COM  * LBR-type backup if any file is specified.
13327917SReza.Sabdar@Sun.COM  *
13337917SReza.Sabdar@Sun.COM  * Parameters:
13347917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
13357917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
13367917SReza.Sabdar@Sun.COM  *
13377917SReza.Sabdar@Sun.COM  * Returns:
13387917SReza.Sabdar@Sun.COM  *   void
13397917SReza.Sabdar@Sun.COM  */
13407917SReza.Sabdar@Sun.COM static void
save_lbr_bk_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)13417917SReza.Sabdar@Sun.COM save_lbr_bk_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
13427917SReza.Sabdar@Sun.COM {
13437917SReza.Sabdar@Sun.COM 	if (!params || !nlp)
13447917SReza.Sabdar@Sun.COM 		return;
13457917SReza.Sabdar@Sun.COM 
13467917SReza.Sabdar@Sun.COM 	if (!nlp->nlp_dmpnm) {
13477917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "No log file defined");
13487917SReza.Sabdar@Sun.COM 	} else if (ndmpd_append_dumptime(nlp->nlp_dmpnm, nlp->nlp_backup_path,
13497917SReza.Sabdar@Sun.COM 	    nlp->nlp_clevel, nlp->nlp_cdate) < 0) {
13507917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
13517917SReza.Sabdar@Sun.COM 		    "Saving backup date for \"%s\" in \"%s\".\n",
13527917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path, nlp->nlp_dmpnm);
13537917SReza.Sabdar@Sun.COM 	}
13547917SReza.Sabdar@Sun.COM }
13557917SReza.Sabdar@Sun.COM 
13567917SReza.Sabdar@Sun.COM 
13577917SReza.Sabdar@Sun.COM /*
13587917SReza.Sabdar@Sun.COM  * save_level_v3
13597917SReza.Sabdar@Sun.COM  *
13607917SReza.Sabdar@Sun.COM  * Save the date and level of the current backup in the dumpdates
13617917SReza.Sabdar@Sun.COM  * file.
13627917SReza.Sabdar@Sun.COM  *
13637917SReza.Sabdar@Sun.COM  * Parameters:
13647917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
13657917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
13667917SReza.Sabdar@Sun.COM  *
13677917SReza.Sabdar@Sun.COM  * Returns:
13687917SReza.Sabdar@Sun.COM  *   void
13697917SReza.Sabdar@Sun.COM  */
13707917SReza.Sabdar@Sun.COM static void
save_level_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)13717917SReza.Sabdar@Sun.COM save_level_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
13727917SReza.Sabdar@Sun.COM {
13737917SReza.Sabdar@Sun.COM 	if (!params || !nlp)
13747917SReza.Sabdar@Sun.COM 		return;
13757917SReza.Sabdar@Sun.COM 
13767917SReza.Sabdar@Sun.COM 	if (!NLP_SHOULD_UPDATE(nlp)) {
13777917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "update not requested");
13787917SReza.Sabdar@Sun.COM 	} else if (ndmpd_put_dumptime(nlp->nlp_backup_path, nlp->nlp_clevel,
13797917SReza.Sabdar@Sun.COM 	    nlp->nlp_cdate) < 0) {
13807917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR, "Logging backup date.\n");
13817917SReza.Sabdar@Sun.COM 	}
13827917SReza.Sabdar@Sun.COM }
13837917SReza.Sabdar@Sun.COM 
13847917SReza.Sabdar@Sun.COM 
13857917SReza.Sabdar@Sun.COM /*
13867917SReza.Sabdar@Sun.COM  * save_backup_date_v3
13877917SReza.Sabdar@Sun.COM  *
13887917SReza.Sabdar@Sun.COM  * A dispatcher function to call the corresponding save function
13897917SReza.Sabdar@Sun.COM  * based on the backup type.
13907917SReza.Sabdar@Sun.COM  *
13917917SReza.Sabdar@Sun.COM  * Parameters:
13927917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
13937917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
13947917SReza.Sabdar@Sun.COM  *
13957917SReza.Sabdar@Sun.COM  * Returns:
13967917SReza.Sabdar@Sun.COM  *   void
13977917SReza.Sabdar@Sun.COM  */
13987917SReza.Sabdar@Sun.COM static void
save_backup_date_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)13997917SReza.Sabdar@Sun.COM save_backup_date_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
14007917SReza.Sabdar@Sun.COM {
14017917SReza.Sabdar@Sun.COM 	if (!params || !nlp)
14027917SReza.Sabdar@Sun.COM 		return;
14037917SReza.Sabdar@Sun.COM 
14047917SReza.Sabdar@Sun.COM 	if (NLP_ISSET(nlp, NLPF_TOKENBK))
14057917SReza.Sabdar@Sun.COM 		save_date_token_v3(params, nlp);
14067917SReza.Sabdar@Sun.COM 	else if (NLP_ISSET(nlp, NLPF_LBRBK))
14077917SReza.Sabdar@Sun.COM 		save_lbr_bk_v3(params, nlp);
14087917SReza.Sabdar@Sun.COM 	else if (NLP_ISSET(nlp, NLPF_LEVELBK))
14097917SReza.Sabdar@Sun.COM 		save_level_v3(params, nlp);
14107917SReza.Sabdar@Sun.COM 	else {
14117917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
14127917SReza.Sabdar@Sun.COM 		    "Internal error: lost backup level type for \"%s\".\n",
14137917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path);
14147917SReza.Sabdar@Sun.COM 	}
14157917SReza.Sabdar@Sun.COM }
14167917SReza.Sabdar@Sun.COM 
14177917SReza.Sabdar@Sun.COM 
14187917SReza.Sabdar@Sun.COM /*
14197917SReza.Sabdar@Sun.COM  * backup_alloc_structs_v3
14207917SReza.Sabdar@Sun.COM  *
14217917SReza.Sabdar@Sun.COM  * Create the structures for V3 backup.  This includes:
14227917SReza.Sabdar@Sun.COM  *	Job stats
14237917SReza.Sabdar@Sun.COM  *	Reader writer IPC
14247917SReza.Sabdar@Sun.COM  *	File history callback structure
14257917SReza.Sabdar@Sun.COM  *
14267917SReza.Sabdar@Sun.COM  * Parameters:
14277917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
14287917SReza.Sabdar@Sun.COM  *   jname (input) - name assigned to the current backup for
14297917SReza.Sabdar@Sun.COM  *	job stats strucure
14307917SReza.Sabdar@Sun.COM  *
14317917SReza.Sabdar@Sun.COM  * Returns:
14327917SReza.Sabdar@Sun.COM  *   0: on success
14337917SReza.Sabdar@Sun.COM  *   -1: otherwise
14347917SReza.Sabdar@Sun.COM  */
14357917SReza.Sabdar@Sun.COM static int
backup_alloc_structs_v3(ndmpd_session_t * session,char * jname)14367917SReza.Sabdar@Sun.COM backup_alloc_structs_v3(ndmpd_session_t *session, char *jname)
14377917SReza.Sabdar@Sun.COM {
14387917SReza.Sabdar@Sun.COM 	int n;
14397917SReza.Sabdar@Sun.COM 	long xfer_size;
14407917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
14417917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
14427917SReza.Sabdar@Sun.COM 
14437917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
14447917SReza.Sabdar@Sun.COM 	if (!nlp) {
14457917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
14467917SReza.Sabdar@Sun.COM 		return (-1);
14477917SReza.Sabdar@Sun.COM 	}
14487917SReza.Sabdar@Sun.COM 
14497917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat = tlm_new_job_stats(jname);
14507917SReza.Sabdar@Sun.COM 	if (!nlp->nlp_jstat) {
14517917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Creating job stats");
14527917SReza.Sabdar@Sun.COM 		return (-1);
14537917SReza.Sabdar@Sun.COM 	}
14547917SReza.Sabdar@Sun.COM 
14557917SReza.Sabdar@Sun.COM 	cmds = &nlp->nlp_cmds;
14567917SReza.Sabdar@Sun.COM 	(void) memset(cmds, 0, sizeof (*cmds));
14577917SReza.Sabdar@Sun.COM 
14587917SReza.Sabdar@Sun.COM 	xfer_size = ndmp_buffer_get_size(session);
14597917SReza.Sabdar@Sun.COM 	if (xfer_size < 512*KILOBYTE) {
14607917SReza.Sabdar@Sun.COM 		/*
14617917SReza.Sabdar@Sun.COM 		 * Read multiple of mover_record_size near to 512K.  This
14627917SReza.Sabdar@Sun.COM 		 * will prevent the data being copied in the mover buffer
14637917SReza.Sabdar@Sun.COM 		 * when we write the data.
14647917SReza.Sabdar@Sun.COM 		 */
14657917SReza.Sabdar@Sun.COM 		n = 512 * KILOBYTE / xfer_size;
14667917SReza.Sabdar@Sun.COM 		if (n <= 0)
14677917SReza.Sabdar@Sun.COM 			n = 1;
14687917SReza.Sabdar@Sun.COM 		xfer_size *= n;
14697917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Adjusted read size: %d",
14707917SReza.Sabdar@Sun.COM 		    xfer_size);
14717917SReza.Sabdar@Sun.COM 	}
14727917SReza.Sabdar@Sun.COM 
14737917SReza.Sabdar@Sun.COM 	cmds->tcs_command = tlm_create_reader_writer_ipc(TRUE, xfer_size);
14747917SReza.Sabdar@Sun.COM 	if (!cmds->tcs_command) {
14757917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
14767917SReza.Sabdar@Sun.COM 		return (-1);
14777917SReza.Sabdar@Sun.COM 	}
14787917SReza.Sabdar@Sun.COM 
14797917SReza.Sabdar@Sun.COM 	nlp->nlp_logcallbacks = lbrlog_callbacks_init(session,
14807917SReza.Sabdar@Sun.COM 	    ndmpd_fhpath_v3_cb, ndmpd_fhdir_v3_cb, ndmpd_fhnode_v3_cb);
14817917SReza.Sabdar@Sun.COM 	if (!nlp->nlp_logcallbacks) {
14827917SReza.Sabdar@Sun.COM 		tlm_release_reader_writer_ipc(cmds->tcs_command);
14837917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
14847917SReza.Sabdar@Sun.COM 		return (-1);
14857917SReza.Sabdar@Sun.COM 	}
14867917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat->js_callbacks = (void *)(nlp->nlp_logcallbacks);
14877917SReza.Sabdar@Sun.COM 	nlp->nlp_restored = NULL;
14887917SReza.Sabdar@Sun.COM 
14897917SReza.Sabdar@Sun.COM 	return (0);
14907917SReza.Sabdar@Sun.COM }
14917917SReza.Sabdar@Sun.COM 
14927917SReza.Sabdar@Sun.COM 
14937917SReza.Sabdar@Sun.COM /*
14947917SReza.Sabdar@Sun.COM  * restore_alloc_structs_v3
14957917SReza.Sabdar@Sun.COM  *
14967917SReza.Sabdar@Sun.COM  * Create the structures for V3 Restore.  This includes:
14977917SReza.Sabdar@Sun.COM  *	Job stats
14987917SReza.Sabdar@Sun.COM  *	Reader writer IPC
14997917SReza.Sabdar@Sun.COM  *	File recovery callback structure
15007917SReza.Sabdar@Sun.COM  *
15017917SReza.Sabdar@Sun.COM  * Parameters:
15027917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
15037917SReza.Sabdar@Sun.COM  *   jname (input) - name assigned to the current backup for
15047917SReza.Sabdar@Sun.COM  *	job stats strucure
15057917SReza.Sabdar@Sun.COM  *
15067917SReza.Sabdar@Sun.COM  * Returns:
15077917SReza.Sabdar@Sun.COM  *   0: on success
15087917SReza.Sabdar@Sun.COM  *   -1: otherwise
15097917SReza.Sabdar@Sun.COM  */
15107917SReza.Sabdar@Sun.COM int
restore_alloc_structs_v3(ndmpd_session_t * session,char * jname)15117917SReza.Sabdar@Sun.COM restore_alloc_structs_v3(ndmpd_session_t *session, char *jname)
15127917SReza.Sabdar@Sun.COM {
15137917SReza.Sabdar@Sun.COM 	long xfer_size;
15147917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
15157917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
15167917SReza.Sabdar@Sun.COM 
15177917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
15187917SReza.Sabdar@Sun.COM 	if (!nlp) {
15197917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
15207917SReza.Sabdar@Sun.COM 		return (-1);
15217917SReza.Sabdar@Sun.COM 	}
15227917SReza.Sabdar@Sun.COM 
15237917SReza.Sabdar@Sun.COM 	/* this is used in ndmpd_path_restored_v3() */
15247917SReza.Sabdar@Sun.COM 	nlp->nlp_lastidx = -1;
15257917SReza.Sabdar@Sun.COM 
15267917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat = tlm_new_job_stats(jname);
15277917SReza.Sabdar@Sun.COM 	if (!nlp->nlp_jstat) {
15287917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Creating job stats");
15297917SReza.Sabdar@Sun.COM 		return (-1);
15307917SReza.Sabdar@Sun.COM 	}
15317917SReza.Sabdar@Sun.COM 
15327917SReza.Sabdar@Sun.COM 	cmds = &nlp->nlp_cmds;
15337917SReza.Sabdar@Sun.COM 	(void) memset(cmds, 0, sizeof (*cmds));
15347917SReza.Sabdar@Sun.COM 
15357917SReza.Sabdar@Sun.COM 	xfer_size = ndmp_buffer_get_size(session);
15367917SReza.Sabdar@Sun.COM 	cmds->tcs_command = tlm_create_reader_writer_ipc(FALSE, xfer_size);
15377917SReza.Sabdar@Sun.COM 	if (!cmds->tcs_command) {
15387917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
15397917SReza.Sabdar@Sun.COM 		return (-1);
15407917SReza.Sabdar@Sun.COM 	}
15417917SReza.Sabdar@Sun.COM 
15427917SReza.Sabdar@Sun.COM 	nlp->nlp_logcallbacks = lbrlog_callbacks_init(session,
15437917SReza.Sabdar@Sun.COM 	    ndmpd_path_restored_v3, NULL, NULL);
15447917SReza.Sabdar@Sun.COM 	if (!nlp->nlp_logcallbacks) {
15457917SReza.Sabdar@Sun.COM 		tlm_release_reader_writer_ipc(cmds->tcs_command);
15467917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
15477917SReza.Sabdar@Sun.COM 		return (-1);
15487917SReza.Sabdar@Sun.COM 	}
15497917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat->js_callbacks = (void *)(nlp->nlp_logcallbacks);
15507917SReza.Sabdar@Sun.COM 
15517917SReza.Sabdar@Sun.COM 	nlp->nlp_rsbm = bm_alloc(nlp->nlp_nfiles, 0);
15527917SReza.Sabdar@Sun.COM 	if (nlp->nlp_rsbm < 0) {
15537917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Out of memory.");
15547917SReza.Sabdar@Sun.COM 		lbrlog_callbacks_done(nlp->nlp_logcallbacks);
15557917SReza.Sabdar@Sun.COM 		tlm_release_reader_writer_ipc(cmds->tcs_command);
15567917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
15577917SReza.Sabdar@Sun.COM 		return (-1);
15587917SReza.Sabdar@Sun.COM 	}
15597917SReza.Sabdar@Sun.COM 
15607917SReza.Sabdar@Sun.COM 	return (0);
15617917SReza.Sabdar@Sun.COM }
15627917SReza.Sabdar@Sun.COM 
15637917SReza.Sabdar@Sun.COM 
15647917SReza.Sabdar@Sun.COM /*
15657917SReza.Sabdar@Sun.COM  * free_structs_v3
15667917SReza.Sabdar@Sun.COM  *
15677917SReza.Sabdar@Sun.COM  * Release the resources allocated by backup_alloc_structs_v3
15687917SReza.Sabdar@Sun.COM  * function.
15697917SReza.Sabdar@Sun.COM  *
15707917SReza.Sabdar@Sun.COM  * Parameters:
15717917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
15727917SReza.Sabdar@Sun.COM  *   jname (input) - name assigned to the current backup for
15737917SReza.Sabdar@Sun.COM  *	job stats strucure
15747917SReza.Sabdar@Sun.COM  *
15757917SReza.Sabdar@Sun.COM  * Returns:
15767917SReza.Sabdar@Sun.COM  *   void
15777917SReza.Sabdar@Sun.COM  */
15787917SReza.Sabdar@Sun.COM /*ARGSUSED*/
15797917SReza.Sabdar@Sun.COM static void
free_structs_v3(ndmpd_session_t * session,char * jname)15807917SReza.Sabdar@Sun.COM free_structs_v3(ndmpd_session_t *session, char *jname)
15817917SReza.Sabdar@Sun.COM {
15827917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
15837917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
15847917SReza.Sabdar@Sun.COM 
15857917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
15867917SReza.Sabdar@Sun.COM 	if (!nlp) {
15877917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
15887917SReza.Sabdar@Sun.COM 		return;
15897917SReza.Sabdar@Sun.COM 	}
15907917SReza.Sabdar@Sun.COM 	cmds = &nlp->nlp_cmds;
15917917SReza.Sabdar@Sun.COM 	if (!cmds) {
15927917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "cmds == NULL");
15937917SReza.Sabdar@Sun.COM 		return;
15947917SReza.Sabdar@Sun.COM 	}
15957917SReza.Sabdar@Sun.COM 
15967917SReza.Sabdar@Sun.COM 	if (nlp->nlp_logcallbacks) {
15977917SReza.Sabdar@Sun.COM 		lbrlog_callbacks_done(nlp->nlp_logcallbacks);
15987917SReza.Sabdar@Sun.COM 		nlp->nlp_logcallbacks = NULL;
15997917SReza.Sabdar@Sun.COM 	} else
16007917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "FH CALLBACKS == NULL");
16017917SReza.Sabdar@Sun.COM 
16027917SReza.Sabdar@Sun.COM 	if (cmds->tcs_command) {
16037917SReza.Sabdar@Sun.COM 		if (cmds->tcs_command->tc_buffers != NULL)
16047917SReza.Sabdar@Sun.COM 			tlm_release_reader_writer_ipc(cmds->tcs_command);
16057917SReza.Sabdar@Sun.COM 		else
16067917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "BUFFERS == NULL");
16077917SReza.Sabdar@Sun.COM 		cmds->tcs_command = NULL;
16087917SReza.Sabdar@Sun.COM 	} else
16097917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "COMMAND == NULL");
16107917SReza.Sabdar@Sun.COM 
16117917SReza.Sabdar@Sun.COM 	if (nlp->nlp_bkmap >= 0) {
16127917SReza.Sabdar@Sun.COM 		(void) dbm_free(nlp->nlp_bkmap);
16137917SReza.Sabdar@Sun.COM 		nlp->nlp_bkmap = -1;
16147917SReza.Sabdar@Sun.COM 	}
16157917SReza.Sabdar@Sun.COM 
16167917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_operation == NDMP_DATA_OP_RECOVER) {
16177917SReza.Sabdar@Sun.COM 		if (nlp->nlp_rsbm < 0) {
16187917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "nlp_rsbm < 0 %d", nlp->nlp_rsbm);
16197917SReza.Sabdar@Sun.COM 		} else {
16207917SReza.Sabdar@Sun.COM 			(void) bm_free(nlp->nlp_rsbm);
16217917SReza.Sabdar@Sun.COM 			nlp->nlp_rsbm = -1;
16227917SReza.Sabdar@Sun.COM 		}
16237917SReza.Sabdar@Sun.COM 	}
16247917SReza.Sabdar@Sun.COM }
16257917SReza.Sabdar@Sun.COM 
16267917SReza.Sabdar@Sun.COM 
16277917SReza.Sabdar@Sun.COM /*
16287917SReza.Sabdar@Sun.COM  * backup_dirv3
16297917SReza.Sabdar@Sun.COM  *
16307917SReza.Sabdar@Sun.COM  * Backup a directory and update the bytes processed field of the
16317917SReza.Sabdar@Sun.COM  * data server.
16327917SReza.Sabdar@Sun.COM  *
16337917SReza.Sabdar@Sun.COM  * Parameters:
16347917SReza.Sabdar@Sun.COM  *   bpp (input) - pointer to the backup parameters structure
16357917SReza.Sabdar@Sun.COM  *   pnp (input) - pointer to the path node
16367917SReza.Sabdar@Sun.COM  *   enp (input) - pointer to the entry node
16377917SReza.Sabdar@Sun.COM  *
16387917SReza.Sabdar@Sun.COM  * Returns:
16397917SReza.Sabdar@Sun.COM  *   0: on success
16407917SReza.Sabdar@Sun.COM  *   != 0: otherwise
16417917SReza.Sabdar@Sun.COM  */
16427917SReza.Sabdar@Sun.COM static int
backup_dirv3(bk_param_v3_t * bpp,fst_node_t * pnp,fst_node_t * enp)16437917SReza.Sabdar@Sun.COM backup_dirv3(bk_param_v3_t *bpp, fst_node_t *pnp,
16447917SReza.Sabdar@Sun.COM     fst_node_t *enp)
16457917SReza.Sabdar@Sun.COM {
16467917SReza.Sabdar@Sun.COM 	longlong_t apos, bpos;
16477917SReza.Sabdar@Sun.COM 	acl_t *aclp = NULL;
16487917SReza.Sabdar@Sun.COM 	char *acltp;
16497917SReza.Sabdar@Sun.COM 	struct stat64 st;
16507917SReza.Sabdar@Sun.COM 	char fullpath[TLM_MAX_PATH_NAME];
16517917SReza.Sabdar@Sun.COM 	char *p;
16527917SReza.Sabdar@Sun.COM 
16537917SReza.Sabdar@Sun.COM 	if (!bpp || !pnp || !enp) {
16547917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid argument");
16557917SReza.Sabdar@Sun.COM 		return (-1);
16567917SReza.Sabdar@Sun.COM 	}
16577917SReza.Sabdar@Sun.COM 
16587917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "d(%s)", bpp->bp_tmp);
16597917SReza.Sabdar@Sun.COM 
16607917SReza.Sabdar@Sun.COM 	if (lstat64(bpp->bp_tmp, &st) != 0)
16617917SReza.Sabdar@Sun.COM 		return (0);
16627917SReza.Sabdar@Sun.COM 
16637917SReza.Sabdar@Sun.COM 	if (acl_get(bpp->bp_tmp, ACL_NO_TRIVIAL, &aclp) != 0) {
16647917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "acl_get error errno=%d", errno);
16657917SReza.Sabdar@Sun.COM 		return (-1);
16667917SReza.Sabdar@Sun.COM 	}
16677917SReza.Sabdar@Sun.COM 	if (aclp && (acltp = acl_totext(aclp,
16687917SReza.Sabdar@Sun.COM 	    ACL_APPEND_ID | ACL_SID_FMT | ACL_COMPACT_FMT)) != NULL) {
16697917SReza.Sabdar@Sun.COM 		(void) strlcpy(bpp->bp_tlmacl->acl_info.attr_info,
16707917SReza.Sabdar@Sun.COM 		    acltp, TLM_MAX_ACL_TXT);
16717917SReza.Sabdar@Sun.COM 		acl_free(aclp);
16727917SReza.Sabdar@Sun.COM 		free(acltp);
16737917SReza.Sabdar@Sun.COM 	} else {
16747917SReza.Sabdar@Sun.COM 		*bpp->bp_tlmacl->acl_info.attr_info = '\0';
16757917SReza.Sabdar@Sun.COM 	}
16767917SReza.Sabdar@Sun.COM 
16777917SReza.Sabdar@Sun.COM 	bpos = tlm_get_data_offset(bpp->bp_lcmd);
16787917SReza.Sabdar@Sun.COM 
16797917SReza.Sabdar@Sun.COM 	p = bpp->bp_tmp + strlen(bpp->bp_chkpnm);
16808193SReza.Sabdar@Sun.COM 	if (*p == '/')
16818193SReza.Sabdar@Sun.COM 		(void) snprintf(fullpath, TLM_MAX_PATH_NAME, "%s%s",
16828193SReza.Sabdar@Sun.COM 		    bpp->bp_unchkpnm, p);
16838193SReza.Sabdar@Sun.COM 	else
16848193SReza.Sabdar@Sun.COM 		(void) snprintf(fullpath, TLM_MAX_PATH_NAME, "%s/%s",
16858193SReza.Sabdar@Sun.COM 		    bpp->bp_unchkpnm, p);
16867917SReza.Sabdar@Sun.COM 
16877917SReza.Sabdar@Sun.COM 	if (tm_tar_ops.tm_putdir != NULL)
16887917SReza.Sabdar@Sun.COM 		(void) (tm_tar_ops.tm_putdir)(fullpath, bpp->bp_tlmacl,
16897917SReza.Sabdar@Sun.COM 		    bpp->bp_lcmd, bpp->bp_js);
16907917SReza.Sabdar@Sun.COM 
16917917SReza.Sabdar@Sun.COM 	apos = tlm_get_data_offset(bpp->bp_lcmd);
16927917SReza.Sabdar@Sun.COM 	bpp->bp_session->ns_data.dd_module.dm_stats.ms_bytes_processed +=
16937917SReza.Sabdar@Sun.COM 	    apos - bpos;
16947917SReza.Sabdar@Sun.COM 
16957917SReza.Sabdar@Sun.COM 	return (0);
16967917SReza.Sabdar@Sun.COM }
16977917SReza.Sabdar@Sun.COM 
16987917SReza.Sabdar@Sun.COM 
16997917SReza.Sabdar@Sun.COM /*
17007917SReza.Sabdar@Sun.COM  * backup_filev3
17017917SReza.Sabdar@Sun.COM  *
17027917SReza.Sabdar@Sun.COM  * Backup a file and update the bytes processed field of the
17037917SReza.Sabdar@Sun.COM  * data server.
17047917SReza.Sabdar@Sun.COM  *
17057917SReza.Sabdar@Sun.COM  * Parameters:
17067917SReza.Sabdar@Sun.COM  *   bpp (input) - pointer to the backup parameters structure
17077917SReza.Sabdar@Sun.COM  *   pnp (input) - pointer to the path node
17087917SReza.Sabdar@Sun.COM  *   enp (input) - pointer to the entry node
17097917SReza.Sabdar@Sun.COM  *
17107917SReza.Sabdar@Sun.COM  * Returns:
17117917SReza.Sabdar@Sun.COM  *   0: on success
17127917SReza.Sabdar@Sun.COM  *   != 0: otherwise
17137917SReza.Sabdar@Sun.COM  */
17147917SReza.Sabdar@Sun.COM static int
backup_filev3(bk_param_v3_t * bpp,fst_node_t * pnp,fst_node_t * enp)17157917SReza.Sabdar@Sun.COM backup_filev3(bk_param_v3_t *bpp, fst_node_t *pnp,
17167917SReza.Sabdar@Sun.COM     fst_node_t *enp)
17177917SReza.Sabdar@Sun.COM {
17187917SReza.Sabdar@Sun.COM 	char *ent;
17197917SReza.Sabdar@Sun.COM 	longlong_t rv;
17207917SReza.Sabdar@Sun.COM 	longlong_t apos, bpos;
17217917SReza.Sabdar@Sun.COM 	acl_t *aclp = NULL;
17227917SReza.Sabdar@Sun.COM 	char *acltp;
17237917SReza.Sabdar@Sun.COM 	struct stat64 st;
17247917SReza.Sabdar@Sun.COM 	char fullpath[TLM_MAX_PATH_NAME];
17257917SReza.Sabdar@Sun.COM 	char *p;
17267917SReza.Sabdar@Sun.COM 
17277917SReza.Sabdar@Sun.COM 	if (!bpp || !pnp || !enp) {
17287917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid argument");
17297917SReza.Sabdar@Sun.COM 		return (-1);
17307917SReza.Sabdar@Sun.COM 	}
17317917SReza.Sabdar@Sun.COM 
17327917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "f(%s)", bpp->bp_tmp);
17337917SReza.Sabdar@Sun.COM 
17347917SReza.Sabdar@Sun.COM 	if (lstat64(bpp->bp_tmp, &st) != 0)
17357917SReza.Sabdar@Sun.COM 		return (0);
17367917SReza.Sabdar@Sun.COM 
17377917SReza.Sabdar@Sun.COM 	if (!S_ISLNK(bpp->bp_tlmacl->acl_attr.st_mode)) {
17387917SReza.Sabdar@Sun.COM 		if (acl_get(bpp->bp_tmp, ACL_NO_TRIVIAL, &aclp) != 0) {
17397917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "acl_get error");
17407917SReza.Sabdar@Sun.COM 			return (-1);
17417917SReza.Sabdar@Sun.COM 		}
17427917SReza.Sabdar@Sun.COM 
17437917SReza.Sabdar@Sun.COM 		if (aclp &&
17447917SReza.Sabdar@Sun.COM 		    (acltp = acl_totext(aclp,
17457917SReza.Sabdar@Sun.COM 		    ACL_APPEND_ID | ACL_SID_FMT | ACL_COMPACT_FMT)) != NULL) {
17467917SReza.Sabdar@Sun.COM 			(void) strlcpy(bpp->bp_tlmacl->acl_info.attr_info,
17477917SReza.Sabdar@Sun.COM 			    acltp, TLM_MAX_ACL_TXT);
17487917SReza.Sabdar@Sun.COM 			acl_free(aclp);
17497917SReza.Sabdar@Sun.COM 			free(acltp);
17507917SReza.Sabdar@Sun.COM 		} else {
17517917SReza.Sabdar@Sun.COM 			*bpp->bp_tlmacl->acl_info.attr_info = '\0';
17527917SReza.Sabdar@Sun.COM 		}
17537917SReza.Sabdar@Sun.COM 	}
17547917SReza.Sabdar@Sun.COM 
17557917SReza.Sabdar@Sun.COM 	bpos = tlm_get_data_offset(bpp->bp_lcmd);
17567917SReza.Sabdar@Sun.COM 	ent = enp->tn_path ? enp->tn_path : "";
17577917SReza.Sabdar@Sun.COM 
17587917SReza.Sabdar@Sun.COM 	p = pnp->tn_path + strlen(bpp->bp_chkpnm);
17598193SReza.Sabdar@Sun.COM 	if (*p == '/')
17608193SReza.Sabdar@Sun.COM 		(void) snprintf(fullpath, TLM_MAX_PATH_NAME, "%s%s",
17618193SReza.Sabdar@Sun.COM 		    bpp->bp_unchkpnm, p);
17628193SReza.Sabdar@Sun.COM 	else
17638193SReza.Sabdar@Sun.COM 		(void) snprintf(fullpath, TLM_MAX_PATH_NAME, "%s/%s",
17648193SReza.Sabdar@Sun.COM 		    bpp->bp_unchkpnm, p);
17657917SReza.Sabdar@Sun.COM 
17667917SReza.Sabdar@Sun.COM 	if (tm_tar_ops.tm_putfile != NULL)
17677917SReza.Sabdar@Sun.COM 		rv = (tm_tar_ops.tm_putfile)(fullpath, ent, pnp->tn_path,
17687917SReza.Sabdar@Sun.COM 		    bpp->bp_tlmacl, bpp->bp_cmds, bpp->bp_lcmd, bpp->bp_js,
17697917SReza.Sabdar@Sun.COM 		    bpp->bp_session->hardlink_q);
17707917SReza.Sabdar@Sun.COM 
17717917SReza.Sabdar@Sun.COM 	apos = tlm_get_data_offset(bpp->bp_lcmd);
17727917SReza.Sabdar@Sun.COM 	bpp->bp_session->ns_data.dd_module.dm_stats.ms_bytes_processed +=
17737917SReza.Sabdar@Sun.COM 	    apos - bpos;
17747917SReza.Sabdar@Sun.COM 
17757917SReza.Sabdar@Sun.COM 	return (rv < 0 ? rv : 0);
17767917SReza.Sabdar@Sun.COM }
17777917SReza.Sabdar@Sun.COM 
17787917SReza.Sabdar@Sun.COM 
17797917SReza.Sabdar@Sun.COM /*
17807917SReza.Sabdar@Sun.COM  * check_bk_args
17817917SReza.Sabdar@Sun.COM  *
17827917SReza.Sabdar@Sun.COM  * Check the argument of the bpp.  This is shared function between
17837917SReza.Sabdar@Sun.COM  * timebk_v3 and lbrbk_v3 functions.  The checks include:
17847917SReza.Sabdar@Sun.COM  *	- The bpp itself.
17857917SReza.Sabdar@Sun.COM  *	- If the session pointer of the bpp is valid.
17867917SReza.Sabdar@Sun.COM  *	- If the session connection to the DMA is closed.
17877917SReza.Sabdar@Sun.COM  *	- If the nlp pointer of the bpp is valid.
17887917SReza.Sabdar@Sun.COM  *	- If the backup is aborted.
17897917SReza.Sabdar@Sun.COM  *
17907917SReza.Sabdar@Sun.COM  * Parameters:
17917917SReza.Sabdar@Sun.COM  *   bpp (input) - pointer to the backup parameters structure
17927917SReza.Sabdar@Sun.COM  *
17937917SReza.Sabdar@Sun.COM  * Returns:
17947917SReza.Sabdar@Sun.COM  *   0: if everything's OK
17957917SReza.Sabdar@Sun.COM  *   != 0: otherwise
17967917SReza.Sabdar@Sun.COM  */
17977917SReza.Sabdar@Sun.COM static int
check_bk_args(bk_param_v3_t * bpp)17987917SReza.Sabdar@Sun.COM check_bk_args(bk_param_v3_t *bpp)
17997917SReza.Sabdar@Sun.COM {
18007917SReza.Sabdar@Sun.COM 	int rv;
18017917SReza.Sabdar@Sun.COM 
18027917SReza.Sabdar@Sun.COM 	if (!bpp) {
18037917SReza.Sabdar@Sun.COM 		rv = -1;
18047917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Lost bpp");
18057917SReza.Sabdar@Sun.COM 	} else if (!bpp->bp_session) {
18067917SReza.Sabdar@Sun.COM 		rv = -1;
18077917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Session is NULL");
18087917SReza.Sabdar@Sun.COM 	} else if (bpp->bp_session->ns_eof) {
18097917SReza.Sabdar@Sun.COM 		rv = -1;
18107917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_INFO,
18117917SReza.Sabdar@Sun.COM 		    "Connection client is closed for backup \"%s\"",
18127917SReza.Sabdar@Sun.COM 		    bpp->bp_nlp->nlp_backup_path);
18137917SReza.Sabdar@Sun.COM 	} else if (!bpp->bp_nlp) {
18147917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Lost nlp");
18157917SReza.Sabdar@Sun.COM 		return (-1);
18167917SReza.Sabdar@Sun.COM 	} else if (bpp->bp_session->ns_data.dd_abort) {
18177917SReza.Sabdar@Sun.COM 		rv = -1;
18187917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_INFO, "Backup aborted \"%s\"",
18197917SReza.Sabdar@Sun.COM 		    bpp->bp_nlp->nlp_backup_path);
18207917SReza.Sabdar@Sun.COM 	} else
18217917SReza.Sabdar@Sun.COM 		rv = 0;
18227917SReza.Sabdar@Sun.COM 
18237917SReza.Sabdar@Sun.COM 	return (rv);
18247917SReza.Sabdar@Sun.COM }
18257917SReza.Sabdar@Sun.COM 
18267917SReza.Sabdar@Sun.COM 
18277917SReza.Sabdar@Sun.COM /*
18287917SReza.Sabdar@Sun.COM  * shouldskip
18297917SReza.Sabdar@Sun.COM  *
18307917SReza.Sabdar@Sun.COM  * Determines if the current entry should be skipped or it
18317917SReza.Sabdar@Sun.COM  * should be backed up.
18327917SReza.Sabdar@Sun.COM  *
18337917SReza.Sabdar@Sun.COM  * Parameters:
18347917SReza.Sabdar@Sun.COM  *   bpp (input) - pointer to the backup parameters structure
18357917SReza.Sabdar@Sun.COM  *   pnp (input) - pointer to the path node
18367917SReza.Sabdar@Sun.COM  *   enp (input) - pointer to the entry node
18377917SReza.Sabdar@Sun.COM  *   errp (output) - pointer to the error value that should be
18387917SReza.Sabdar@Sun.COM  *	returned by the caller
18397917SReza.Sabdar@Sun.COM  *
18407917SReza.Sabdar@Sun.COM  * Returns:
18417917SReza.Sabdar@Sun.COM  *   TRUE: if the entry should not be backed up
18427917SReza.Sabdar@Sun.COM  *   FALSE: otherwise
18437917SReza.Sabdar@Sun.COM  */
18447917SReza.Sabdar@Sun.COM static boolean_t
shouldskip(bk_param_v3_t * bpp,fst_node_t * pnp,fst_node_t * enp,int * errp)18457917SReza.Sabdar@Sun.COM shouldskip(bk_param_v3_t *bpp, fst_node_t *pnp,
18467917SReza.Sabdar@Sun.COM     fst_node_t *enp, int *errp)
18477917SReza.Sabdar@Sun.COM {
18487917SReza.Sabdar@Sun.COM 	char *ent;
18497917SReza.Sabdar@Sun.COM 	boolean_t rv;
18507917SReza.Sabdar@Sun.COM 	struct stat64 *estp;
18517917SReza.Sabdar@Sun.COM 
18527917SReza.Sabdar@Sun.COM 	if (!bpp || !pnp || !enp || !errp) {
18537917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid argument");
18547917SReza.Sabdar@Sun.COM 		return (TRUE);
18557917SReza.Sabdar@Sun.COM 	}
18567917SReza.Sabdar@Sun.COM 
18577917SReza.Sabdar@Sun.COM 	if (!enp->tn_path) {
18587917SReza.Sabdar@Sun.COM 		ent = "";
18597917SReza.Sabdar@Sun.COM 		estp = pnp->tn_st;
18607917SReza.Sabdar@Sun.COM 	} else {
18617917SReza.Sabdar@Sun.COM 		ent = enp->tn_path;
18627917SReza.Sabdar@Sun.COM 		estp = enp->tn_st;
18637917SReza.Sabdar@Sun.COM 	}
18647917SReza.Sabdar@Sun.COM 
18657917SReza.Sabdar@Sun.COM 	/*
18667917SReza.Sabdar@Sun.COM 	 * When excluding or skipping entries, FST_SKIP should be
18677917SReza.Sabdar@Sun.COM 	 * returned, otherwise, 0 should be returned to
18687917SReza.Sabdar@Sun.COM 	 * get other entries in the directory of this entry.
18697917SReza.Sabdar@Sun.COM 	 */
18707917SReza.Sabdar@Sun.COM 	if (!dbm_getone(bpp->bp_nlp->nlp_bkmap, (u_longlong_t)estp->st_ino)) {
18717917SReza.Sabdar@Sun.COM 		rv = TRUE;
18727917SReza.Sabdar@Sun.COM 		*errp = S_ISDIR(estp->st_mode) ? FST_SKIP : 0;
18737917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Skipping %d %s/%s",
18747917SReza.Sabdar@Sun.COM 		    *errp, pnp->tn_path, ent);
18757917SReza.Sabdar@Sun.COM 	} else if (tlm_is_excluded(pnp->tn_path, ent, bpp->bp_excls)) {
18767917SReza.Sabdar@Sun.COM 		rv = TRUE;
18777917SReza.Sabdar@Sun.COM 		*errp = S_ISDIR(estp->st_mode) ? FST_SKIP : 0;
18787917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "excl %d \"%s/%s\"",
18797917SReza.Sabdar@Sun.COM 		    *errp, pnp->tn_path, ent);
18807917SReza.Sabdar@Sun.COM 	} else if (inexl(bpp->bp_nlp->nlp_exl, ent)) {
18817917SReza.Sabdar@Sun.COM 		rv = TRUE;
18827917SReza.Sabdar@Sun.COM 		*errp = S_ISDIR(estp->st_mode) ? FST_SKIP : 0;
18837917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "out %d \"%s/%s\"",
18847917SReza.Sabdar@Sun.COM 		    *errp, pnp->tn_path, ent);
18857917SReza.Sabdar@Sun.COM 	} else if (!S_ISDIR(estp->st_mode) &&
18867917SReza.Sabdar@Sun.COM 	    !ininc(bpp->bp_nlp->nlp_inc, ent)) {
18877917SReza.Sabdar@Sun.COM 		rv = TRUE;
18887917SReza.Sabdar@Sun.COM 		*errp = 0;
18897917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "!in \"%s/%s\"", pnp->tn_path, ent);
18907917SReza.Sabdar@Sun.COM 	} else
18917917SReza.Sabdar@Sun.COM 		rv = FALSE;
18927917SReza.Sabdar@Sun.COM 
18937917SReza.Sabdar@Sun.COM 	return (rv);
18947917SReza.Sabdar@Sun.COM }
18957917SReza.Sabdar@Sun.COM 
18967917SReza.Sabdar@Sun.COM 
18977917SReza.Sabdar@Sun.COM /*
18987917SReza.Sabdar@Sun.COM  * ischngd
18997917SReza.Sabdar@Sun.COM  *
19007917SReza.Sabdar@Sun.COM  * Check if the object specified should be backed up or not.
19017917SReza.Sabdar@Sun.COM  * If stp belongs to a directory and if it is marked in the
19027917SReza.Sabdar@Sun.COM  * bitmap vector, it shows that either the directory itself is
19037917SReza.Sabdar@Sun.COM  * modified or there is something below it that will be backed
19047917SReza.Sabdar@Sun.COM  * up.
19057917SReza.Sabdar@Sun.COM  *
19067917SReza.Sabdar@Sun.COM  * By setting ndmp_force_bk_dirs global variable to a non-zero
19077917SReza.Sabdar@Sun.COM  * value, directories are backed up anyways.
19087917SReza.Sabdar@Sun.COM  *
19097917SReza.Sabdar@Sun.COM  * Backing up the directories unconditionally helps
19107917SReza.Sabdar@Sun.COM  * restoring the metadata of directories as well, when one
19117917SReza.Sabdar@Sun.COM  * of the objects below them are being restored.
19127917SReza.Sabdar@Sun.COM  *
19137917SReza.Sabdar@Sun.COM  * For non-directory objects, if the modification or change
19147917SReza.Sabdar@Sun.COM  * time of the object is after the date specified by the
19157917SReza.Sabdar@Sun.COM  * bk_selector_t, the the object must be backed up.
19167917SReza.Sabdar@Sun.COM  */
19177917SReza.Sabdar@Sun.COM static boolean_t
ischngd(struct stat64 * stp,time_t t,ndmp_lbr_params_t * nlp)19187917SReza.Sabdar@Sun.COM ischngd(struct stat64 *stp, time_t t, ndmp_lbr_params_t *nlp)
19197917SReza.Sabdar@Sun.COM {
19207917SReza.Sabdar@Sun.COM 	boolean_t rv;
19217917SReza.Sabdar@Sun.COM 
19227917SReza.Sabdar@Sun.COM 	if (!stp) {
19237917SReza.Sabdar@Sun.COM 		rv = FALSE;
19247917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "stp is NULL");
19257917SReza.Sabdar@Sun.COM 	} else if (!nlp) {
19267917SReza.Sabdar@Sun.COM 		rv = FALSE;
19277917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp is NULL");
19287917SReza.Sabdar@Sun.COM 	} else if (t == 0) {
19297917SReza.Sabdar@Sun.COM 		/*
19307917SReza.Sabdar@Sun.COM 		 * if we are doing base backup then we do not need to
19317917SReza.Sabdar@Sun.COM 		 * check the time, for we should backup everything.
19327917SReza.Sabdar@Sun.COM 		 */
19337917SReza.Sabdar@Sun.COM 		rv = TRUE;
19347917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Base Backup");
19357917SReza.Sabdar@Sun.COM 	} else if (S_ISDIR(stp->st_mode) && ndmp_force_bk_dirs) {
19367917SReza.Sabdar@Sun.COM 		rv = TRUE;
19377917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "d(%lu)", (uint_t)stp->st_ino);
19387917SReza.Sabdar@Sun.COM 	} else if (S_ISDIR(stp->st_mode) &&
19397917SReza.Sabdar@Sun.COM 	    dbm_getone(nlp->nlp_bkmap, (u_longlong_t)stp->st_ino) &&
19407917SReza.Sabdar@Sun.COM 	    ((NLP_ISDUMP(nlp) && ndmp_dump_path_node) ||
19417917SReza.Sabdar@Sun.COM 	    (NLP_ISTAR(nlp) && ndmp_tar_path_node))) {
19427917SReza.Sabdar@Sun.COM 		/*
19437917SReza.Sabdar@Sun.COM 		 * If the object is a directory and it leads to a modified
19447917SReza.Sabdar@Sun.COM 		 * object (that should be backed up) and for that type of
19457917SReza.Sabdar@Sun.COM 		 * backup the path nodes should be backed up, then return
19467917SReza.Sabdar@Sun.COM 		 * TRUE.
19477917SReza.Sabdar@Sun.COM 		 *
19487917SReza.Sabdar@Sun.COM 		 * This is required by some DMAs like Backup Express, which
19497917SReza.Sabdar@Sun.COM 		 * needs to receive ADD_NODE (for dump) or ADD_PATH (for tar)
19507917SReza.Sabdar@Sun.COM 		 * for the intermediate directories of a modified object.
19517917SReza.Sabdar@Sun.COM 		 * Other DMAs, like net_backup and net_worker, do not have such
19527917SReza.Sabdar@Sun.COM 		 * requirement.  This requirement makes sense for dump format
19537917SReza.Sabdar@Sun.COM 		 * but for 'tar' format, it does not.  In provision to the
19547917SReza.Sabdar@Sun.COM 		 * NDMP-v4 spec, for 'tar' format the intermediate directories
19557917SReza.Sabdar@Sun.COM 		 * need not to be reported.
19567917SReza.Sabdar@Sun.COM 		 */
19577917SReza.Sabdar@Sun.COM 		rv = TRUE;
19587917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "p(%lu)", (u_longlong_t)stp->st_ino);
19597917SReza.Sabdar@Sun.COM 	} else if (stp->st_mtime > t) {
19607917SReza.Sabdar@Sun.COM 		rv = TRUE;
19617917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "m(%lu): %lu > %lu",
19627917SReza.Sabdar@Sun.COM 		    (uint_t)stp->st_ino, (uint_t)stp->st_mtime, (uint_t)t);
19637917SReza.Sabdar@Sun.COM 	} else if (stp->st_ctime > t) {
19647917SReza.Sabdar@Sun.COM 		if (NLP_IGNCTIME(nlp)) {
19657917SReza.Sabdar@Sun.COM 			rv = FALSE;
19667917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "ign c(%lu): %lu > %lu",
19677917SReza.Sabdar@Sun.COM 			    (uint_t)stp->st_ino, (uint_t)stp->st_ctime,
19687917SReza.Sabdar@Sun.COM 			    (uint_t)t);
19697917SReza.Sabdar@Sun.COM 		} else {
19707917SReza.Sabdar@Sun.COM 			rv = TRUE;
19717917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "c(%lu): %lu > %lu",
19727917SReza.Sabdar@Sun.COM 			    (uint_t)stp->st_ino, (uint_t)stp->st_ctime,
19737917SReza.Sabdar@Sun.COM 			    (uint_t)t);
19747917SReza.Sabdar@Sun.COM 		}
19757917SReza.Sabdar@Sun.COM 	} else {
19767917SReza.Sabdar@Sun.COM 		rv = FALSE;
19777917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "mc(%lu): (%lu,%lu) < %lu",
19787917SReza.Sabdar@Sun.COM 		    (uint_t)stp->st_ino, (uint_t)stp->st_mtime,
19797917SReza.Sabdar@Sun.COM 		    (uint_t)stp->st_ctime, (uint_t)t);
19807917SReza.Sabdar@Sun.COM 	}
19817917SReza.Sabdar@Sun.COM 
19827917SReza.Sabdar@Sun.COM 	return (rv);
19837917SReza.Sabdar@Sun.COM }
19847917SReza.Sabdar@Sun.COM 
19857917SReza.Sabdar@Sun.COM 
19867917SReza.Sabdar@Sun.COM /*
19877917SReza.Sabdar@Sun.COM  * iscreated
19887917SReza.Sabdar@Sun.COM  *
19897917SReza.Sabdar@Sun.COM  * This function is used to check last mtime (currently inside the ACL
19907917SReza.Sabdar@Sun.COM  * structure) instead of ctime for checking if the file is to be backed up
19917917SReza.Sabdar@Sun.COM  * or not. See option "inc.lmtime" for more details
19927917SReza.Sabdar@Sun.COM  */
19937917SReza.Sabdar@Sun.COM /*ARGSUSED*/
iscreated(ndmp_lbr_params_t * nlp,char * name,tlm_acls_t * tacl,time_t t)19947917SReza.Sabdar@Sun.COM int iscreated(ndmp_lbr_params_t *nlp, char *name, tlm_acls_t *tacl,
19957917SReza.Sabdar@Sun.COM     time_t t)
19967917SReza.Sabdar@Sun.COM {
19977917SReza.Sabdar@Sun.COM 	int ret;
19987917SReza.Sabdar@Sun.COM 	acl_t *aclp = NULL;
19997917SReza.Sabdar@Sun.COM 	char *acltp;
20007917SReza.Sabdar@Sun.COM 
20017917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "flags %x", nlp->nlp_flags);
20027917SReza.Sabdar@Sun.COM 	if (NLP_INCLMTIME(nlp) == FALSE)
20037917SReza.Sabdar@Sun.COM 		return (0);
20047917SReza.Sabdar@Sun.COM 
20057917SReza.Sabdar@Sun.COM 	ret = acl_get(name, ACL_NO_TRIVIAL, &aclp);
20067917SReza.Sabdar@Sun.COM 	if (ret != 0) {
20077917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
20087917SReza.Sabdar@Sun.COM 		    "Error getting the acl information: err %d", ret);
20097917SReza.Sabdar@Sun.COM 		return (0);
20107917SReza.Sabdar@Sun.COM 	}
20117917SReza.Sabdar@Sun.COM 	if (aclp && (acltp = acl_totext(aclp,
20127917SReza.Sabdar@Sun.COM 	    ACL_APPEND_ID | ACL_SID_FMT | ACL_COMPACT_FMT)) != NULL) {
20137917SReza.Sabdar@Sun.COM 		(void) strlcpy(tacl->acl_info.attr_info, acltp,
20147917SReza.Sabdar@Sun.COM 		    TLM_MAX_ACL_TXT);
20157917SReza.Sabdar@Sun.COM 		acl_free(aclp);
20167917SReza.Sabdar@Sun.COM 		free(acltp);
20177917SReza.Sabdar@Sun.COM 	}
20187917SReza.Sabdar@Sun.COM 
20197917SReza.Sabdar@Sun.COM 	/* Need to add support for last mtime */
20207917SReza.Sabdar@Sun.COM 
20217917SReza.Sabdar@Sun.COM 	return (0);
20227917SReza.Sabdar@Sun.COM }
20237917SReza.Sabdar@Sun.COM 
20247917SReza.Sabdar@Sun.COM /*
20257917SReza.Sabdar@Sun.COM  * size_cb
20267917SReza.Sabdar@Sun.COM  *
20277917SReza.Sabdar@Sun.COM  * The callback function for calculating the size of
20287917SReza.Sabdar@Sun.COM  * the backup path. This is used to get an estimate
20297917SReza.Sabdar@Sun.COM  * of the progress of backup during NDMP backup
20307917SReza.Sabdar@Sun.COM  */
20317917SReza.Sabdar@Sun.COM static int
size_cb(void * arg,fst_node_t * pnp,fst_node_t * enp)20327917SReza.Sabdar@Sun.COM size_cb(void *arg, fst_node_t *pnp, fst_node_t *enp)
20337917SReza.Sabdar@Sun.COM {
20347917SReza.Sabdar@Sun.COM 	struct stat64 *stp;
20357917SReza.Sabdar@Sun.COM 
20367917SReza.Sabdar@Sun.COM 	stp = enp->tn_path ? enp->tn_st : pnp->tn_st;
20377917SReza.Sabdar@Sun.COM 	*((u_longlong_t *)arg) += stp->st_size;
20387917SReza.Sabdar@Sun.COM 
20397917SReza.Sabdar@Sun.COM 	return (0);
20407917SReza.Sabdar@Sun.COM }
20417917SReza.Sabdar@Sun.COM 
20427917SReza.Sabdar@Sun.COM /*
20437917SReza.Sabdar@Sun.COM  * timebk_v3
20447917SReza.Sabdar@Sun.COM  *
20457917SReza.Sabdar@Sun.COM  * The callback function for backing up objects based on
20467917SReza.Sabdar@Sun.COM  * their time stamp.  This is shared between token-based
20477917SReza.Sabdar@Sun.COM  * and level-based backup, which look at the time stamps
20487917SReza.Sabdar@Sun.COM  * of the objects to determine if they should be backed
20497917SReza.Sabdar@Sun.COM  * up.
20507917SReza.Sabdar@Sun.COM  *
20517917SReza.Sabdar@Sun.COM  * Parameters:
20527917SReza.Sabdar@Sun.COM  *   arg (input) - pointer to the backup parameters structure
20537917SReza.Sabdar@Sun.COM  *   pnp (input) - pointer to the path node
20547917SReza.Sabdar@Sun.COM  *   enp (input) - pointer to the entry node
20557917SReza.Sabdar@Sun.COM  *
20567917SReza.Sabdar@Sun.COM  * Returns:
20577917SReza.Sabdar@Sun.COM  *   0: if backup should continue
20587917SReza.Sabdar@Sun.COM  *   -1: if the backup should be stopped
20597917SReza.Sabdar@Sun.COM  *   FST_SKIP: if backing up the current directory is enough
20607917SReza.Sabdar@Sun.COM  */
20617917SReza.Sabdar@Sun.COM static int
timebk_v3(void * arg,fst_node_t * pnp,fst_node_t * enp)20627917SReza.Sabdar@Sun.COM timebk_v3(void *arg, fst_node_t *pnp, fst_node_t *enp)
20637917SReza.Sabdar@Sun.COM {
20647917SReza.Sabdar@Sun.COM 	char *ent;
20657917SReza.Sabdar@Sun.COM 	int rv;
20667917SReza.Sabdar@Sun.COM 	time_t t;
20677917SReza.Sabdar@Sun.COM 	bk_param_v3_t *bpp;
20687917SReza.Sabdar@Sun.COM 	struct stat64 *stp;
20697917SReza.Sabdar@Sun.COM 	fs_fhandle_t *fhp;
20707917SReza.Sabdar@Sun.COM 
20717917SReza.Sabdar@Sun.COM 	bpp = (bk_param_v3_t *)arg;
20727917SReza.Sabdar@Sun.COM 
20737917SReza.Sabdar@Sun.COM 	rv = check_bk_args(bpp);
20747917SReza.Sabdar@Sun.COM 	if (rv != 0)
20757917SReza.Sabdar@Sun.COM 		return (rv);
20767917SReza.Sabdar@Sun.COM 
20777917SReza.Sabdar@Sun.COM 	stp = enp->tn_path ? enp->tn_st : pnp->tn_st;
20787917SReza.Sabdar@Sun.COM 	if (shouldskip(bpp, pnp, enp, &rv))
20797917SReza.Sabdar@Sun.COM 		return (rv);
20807917SReza.Sabdar@Sun.COM 
20817917SReza.Sabdar@Sun.COM 	if (enp->tn_path) {
20827917SReza.Sabdar@Sun.COM 		ent = enp->tn_path;
20837917SReza.Sabdar@Sun.COM 		stp = enp->tn_st;
20847917SReza.Sabdar@Sun.COM 		fhp = enp->tn_fh;
20857917SReza.Sabdar@Sun.COM 	} else {
20867917SReza.Sabdar@Sun.COM 		ent = "";
20877917SReza.Sabdar@Sun.COM 		stp = pnp->tn_st;
20887917SReza.Sabdar@Sun.COM 		fhp = pnp->tn_fh;
20897917SReza.Sabdar@Sun.COM 	}
20907917SReza.Sabdar@Sun.COM 
20917917SReza.Sabdar@Sun.COM 
20927917SReza.Sabdar@Sun.COM 	if (!tlm_cat_path(bpp->bp_tmp, pnp->tn_path, ent)) {
20937917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Path too long %s/%s.", pnp->tn_path, ent);
20947917SReza.Sabdar@Sun.COM 		return (FST_SKIP);
20957917SReza.Sabdar@Sun.COM 	}
20967917SReza.Sabdar@Sun.COM 	if (NLP_ISSET(bpp->bp_nlp, NLPF_TOKENBK))
20977917SReza.Sabdar@Sun.COM 		t = bpp->bp_nlp->nlp_tokdate;
20987917SReza.Sabdar@Sun.COM 	else if (NLP_ISSET(bpp->bp_nlp, NLPF_LEVELBK)) {
20997917SReza.Sabdar@Sun.COM 		t = bpp->bp_nlp->nlp_ldate;
21007917SReza.Sabdar@Sun.COM 	} else {
21017917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Unknown backup type on \"%s/%s\"",
21027917SReza.Sabdar@Sun.COM 		    pnp->tn_path, ent);
21037917SReza.Sabdar@Sun.COM 		return (-1);
21047917SReza.Sabdar@Sun.COM 	}
21057917SReza.Sabdar@Sun.COM 
21067917SReza.Sabdar@Sun.COM 	if (S_ISDIR(stp->st_mode)) {
21077917SReza.Sabdar@Sun.COM 		bpp->bp_tlmacl->acl_dir_fh = *fhp;
21087917SReza.Sabdar@Sun.COM 		(void) ndmpd_fhdir_v3_cb(bpp->bp_nlp->nlp_logcallbacks,
21097917SReza.Sabdar@Sun.COM 		    bpp->bp_tmp, stp);
21107917SReza.Sabdar@Sun.COM 
21117917SReza.Sabdar@Sun.COM 		if (ischngd(stp, t, bpp->bp_nlp)) {
21127917SReza.Sabdar@Sun.COM 			(void) memcpy(&bpp->bp_tlmacl->acl_attr, stp,
21137917SReza.Sabdar@Sun.COM 			    sizeof (struct stat64));
21147917SReza.Sabdar@Sun.COM 			rv = backup_dirv3(bpp, pnp, enp);
21157917SReza.Sabdar@Sun.COM 		}
21167917SReza.Sabdar@Sun.COM 	} else {
21177917SReza.Sabdar@Sun.COM 		if (ischngd(stp, t, bpp->bp_nlp) ||
21187917SReza.Sabdar@Sun.COM 		    iscreated(bpp->bp_nlp, bpp->bp_tmp, bpp->bp_tlmacl, t)) {
21197917SReza.Sabdar@Sun.COM 			rv = 0;
21207917SReza.Sabdar@Sun.COM 			(void) memcpy(&bpp->bp_tlmacl->acl_attr, stp,
21217917SReza.Sabdar@Sun.COM 			    sizeof (struct stat64));
21227917SReza.Sabdar@Sun.COM 			bpp->bp_tlmacl->acl_fil_fh = *fhp;
21237917SReza.Sabdar@Sun.COM 			(void) backup_filev3(bpp, pnp, enp);
21247917SReza.Sabdar@Sun.COM 		}
21257917SReza.Sabdar@Sun.COM 	}
21267917SReza.Sabdar@Sun.COM 
21277917SReza.Sabdar@Sun.COM 	return (rv);
21287917SReza.Sabdar@Sun.COM }
21297917SReza.Sabdar@Sun.COM 
21307917SReza.Sabdar@Sun.COM 
21317917SReza.Sabdar@Sun.COM /*
21327917SReza.Sabdar@Sun.COM  * lbrbk_v3
21337917SReza.Sabdar@Sun.COM  *
21347917SReza.Sabdar@Sun.COM  * The callback function for backing up objects based on
21357917SReza.Sabdar@Sun.COM  * their archive directory bit.  This is used in LBR-type
21367917SReza.Sabdar@Sun.COM  * backup.  In which the objects are backed up if their
21377917SReza.Sabdar@Sun.COM  * archive bit is set.
21387917SReza.Sabdar@Sun.COM  *
21397917SReza.Sabdar@Sun.COM  * Parameters:
21407917SReza.Sabdar@Sun.COM  *   arg (input) - pointer to the backup parameters structure
21417917SReza.Sabdar@Sun.COM  *   pnp (input) - pointer to the path node
21427917SReza.Sabdar@Sun.COM  *   enp (input) - pointer to the entry node
21437917SReza.Sabdar@Sun.COM  *
21447917SReza.Sabdar@Sun.COM  * Returns:
21457917SReza.Sabdar@Sun.COM  *   0: if backup should continue
21467917SReza.Sabdar@Sun.COM  *   -1: if the backup should be stopped
21477917SReza.Sabdar@Sun.COM  *   FST_SKIP: if backing up the current directory is enough
21487917SReza.Sabdar@Sun.COM  */
21497917SReza.Sabdar@Sun.COM static int
lbrbk_v3(void * arg,fst_node_t * pnp,fst_node_t * enp)21507917SReza.Sabdar@Sun.COM lbrbk_v3(void *arg, fst_node_t *pnp, fst_node_t *enp)
21517917SReza.Sabdar@Sun.COM {
21527917SReza.Sabdar@Sun.COM 	char *ent;
21537917SReza.Sabdar@Sun.COM 	int rv;
21547917SReza.Sabdar@Sun.COM 	bk_param_v3_t *bpp;
21557917SReza.Sabdar@Sun.COM 	struct stat64 *stp;
21567917SReza.Sabdar@Sun.COM 	fs_fhandle_t *fhp;
21577917SReza.Sabdar@Sun.COM 
21587917SReza.Sabdar@Sun.COM 	bpp = (bk_param_v3_t *)arg;
21597917SReza.Sabdar@Sun.COM 	rv = check_bk_args(bpp);
21607917SReza.Sabdar@Sun.COM 	if (rv != 0)
21617917SReza.Sabdar@Sun.COM 		return (rv);
21627917SReza.Sabdar@Sun.COM 
21637917SReza.Sabdar@Sun.COM 	stp = enp->tn_path ? enp->tn_st : pnp->tn_st;
21647917SReza.Sabdar@Sun.COM 	if (shouldskip(bpp, pnp, enp, &rv))
21657917SReza.Sabdar@Sun.COM 		return (rv);
21667917SReza.Sabdar@Sun.COM 
21677917SReza.Sabdar@Sun.COM 	if (enp->tn_path) {
21687917SReza.Sabdar@Sun.COM 		ent = enp->tn_path;
21697917SReza.Sabdar@Sun.COM 		stp = enp->tn_st;
21707917SReza.Sabdar@Sun.COM 		fhp = enp->tn_fh;
21717917SReza.Sabdar@Sun.COM 	} else {
21727917SReza.Sabdar@Sun.COM 		ent = "";
21737917SReza.Sabdar@Sun.COM 		stp = pnp->tn_st;
21747917SReza.Sabdar@Sun.COM 		fhp = pnp->tn_fh;
21757917SReza.Sabdar@Sun.COM 	}
21767917SReza.Sabdar@Sun.COM 
21777917SReza.Sabdar@Sun.COM 	if (!tlm_cat_path(bpp->bp_tmp, pnp->tn_path, ent)) {
21787917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Path too long %s/%s.", pnp->tn_path, ent);
21797917SReza.Sabdar@Sun.COM 		return (FST_SKIP);
21807917SReza.Sabdar@Sun.COM 	}
21817917SReza.Sabdar@Sun.COM 	if (!NLP_ISSET(bpp->bp_nlp, NLPF_LBRBK)) {
21827917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "!NLPF_LBRBK");
21837917SReza.Sabdar@Sun.COM 		return (-1);
21847917SReza.Sabdar@Sun.COM 	}
21857917SReza.Sabdar@Sun.COM 
21867917SReza.Sabdar@Sun.COM 	if (S_ISDIR(stp->st_mode)) {
21877917SReza.Sabdar@Sun.COM 		bpp->bp_tlmacl->acl_dir_fh = *fhp;
21887917SReza.Sabdar@Sun.COM 		(void) ndmpd_fhdir_v3_cb(bpp->bp_nlp->nlp_logcallbacks,
21897917SReza.Sabdar@Sun.COM 		    bpp->bp_tmp, stp);
21907917SReza.Sabdar@Sun.COM 
21917917SReza.Sabdar@Sun.COM 		if (SHOULD_LBRBK(bpp)) {
21927917SReza.Sabdar@Sun.COM 			bpp->bp_tlmacl->acl_attr = *stp;
21937917SReza.Sabdar@Sun.COM 			rv = backup_dirv3(bpp, pnp, enp);
21947917SReza.Sabdar@Sun.COM 		}
21957917SReza.Sabdar@Sun.COM 	} else if (SHOULD_LBRBK(bpp)) {
21967917SReza.Sabdar@Sun.COM 		rv = 0;
21977917SReza.Sabdar@Sun.COM 		bpp->bp_tlmacl->acl_attr = *stp;
21987917SReza.Sabdar@Sun.COM 		bpp->bp_tlmacl->acl_fil_fh = *fhp;
21997917SReza.Sabdar@Sun.COM 		(void) backup_filev3(bpp, pnp, enp);
22007917SReza.Sabdar@Sun.COM 	}
22017917SReza.Sabdar@Sun.COM 
22027917SReza.Sabdar@Sun.COM 	return (rv);
22037917SReza.Sabdar@Sun.COM }
22047917SReza.Sabdar@Sun.COM 
22057917SReza.Sabdar@Sun.COM 
22067917SReza.Sabdar@Sun.COM /*
22077917SReza.Sabdar@Sun.COM  * backup_reader_v3
22087917SReza.Sabdar@Sun.COM  *
22097917SReza.Sabdar@Sun.COM  * The reader thread for the backup.  It sets up the callback
22107917SReza.Sabdar@Sun.COM  * parameters and traverses the backup hierarchy in level-order
22117917SReza.Sabdar@Sun.COM  * way.
22127917SReza.Sabdar@Sun.COM  *
22137917SReza.Sabdar@Sun.COM  * Parameters:
22147917SReza.Sabdar@Sun.COM  *   jname (input) - name assigned to the current backup for
22157917SReza.Sabdar@Sun.COM  *	job stats strucure
22167917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
22177917SReza.Sabdar@Sun.COM  *   cmds (input) - pointer to the tlm_commands_t structure
22187917SReza.Sabdar@Sun.COM  *
22197917SReza.Sabdar@Sun.COM  * Returns:
22207917SReza.Sabdar@Sun.COM  *   0: on success
22217917SReza.Sabdar@Sun.COM  *   != 0: otherwise
22227917SReza.Sabdar@Sun.COM  */
22237917SReza.Sabdar@Sun.COM static int
backup_reader_v3(backup_reader_arg_t * argp)22247917SReza.Sabdar@Sun.COM backup_reader_v3(backup_reader_arg_t *argp)
22257917SReza.Sabdar@Sun.COM {
22267917SReza.Sabdar@Sun.COM 	int rv;
22277917SReza.Sabdar@Sun.COM 	tlm_cmd_t *lcmd;
22287917SReza.Sabdar@Sun.COM 	tlm_acls_t tlm_acls;
22297917SReza.Sabdar@Sun.COM 	longlong_t bpos, n;
22307917SReza.Sabdar@Sun.COM 	bk_param_v3_t bp;
22317917SReza.Sabdar@Sun.COM 	fs_traverse_t ft;
22327917SReza.Sabdar@Sun.COM 	char *jname;
22337917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
22347917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
22357917SReza.Sabdar@Sun.COM 
22367917SReza.Sabdar@Sun.COM 	if (!argp)
22377917SReza.Sabdar@Sun.COM 		return (-1);
22387917SReza.Sabdar@Sun.COM 
22397917SReza.Sabdar@Sun.COM 	jname = argp->br_jname;
22407917SReza.Sabdar@Sun.COM 	nlp = argp->br_nlp;
22417917SReza.Sabdar@Sun.COM 	cmds = argp->br_cmds;
22427917SReza.Sabdar@Sun.COM 
22437917SReza.Sabdar@Sun.COM 	rv = 0;
22447917SReza.Sabdar@Sun.COM 	lcmd = cmds->tcs_command;
22457917SReza.Sabdar@Sun.COM 	lcmd->tc_ref++;
22467917SReza.Sabdar@Sun.COM 	cmds->tcs_reader_count++;
22477917SReza.Sabdar@Sun.COM 
22487917SReza.Sabdar@Sun.COM 	(void) memset(&tlm_acls, 0, sizeof (tlm_acls));
22497917SReza.Sabdar@Sun.COM 
22507917SReza.Sabdar@Sun.COM 	/* NDMP parameters */
22517917SReza.Sabdar@Sun.COM 	bp.bp_session = nlp->nlp_session;
22527917SReza.Sabdar@Sun.COM 	bp.bp_nlp = nlp;
22537917SReza.Sabdar@Sun.COM 
22547917SReza.Sabdar@Sun.COM 	/* LBR-related parameters  */
22557917SReza.Sabdar@Sun.COM 	bp.bp_js = tlm_ref_job_stats(jname);
22567917SReza.Sabdar@Sun.COM 	bp.bp_cmds = cmds;
22577917SReza.Sabdar@Sun.COM 	bp.bp_lcmd = lcmd;
22587917SReza.Sabdar@Sun.COM 	bp.bp_tlmacl = &tlm_acls;
22597917SReza.Sabdar@Sun.COM 	bp.bp_opr = 0;
22607917SReza.Sabdar@Sun.COM 
22617917SReza.Sabdar@Sun.COM 	/* release the parent thread, after referencing the job stats */
22627917SReza.Sabdar@Sun.COM 	(void) pthread_barrier_wait(&argp->br_barrier);
22637917SReza.Sabdar@Sun.COM 
22647917SReza.Sabdar@Sun.COM 	bp.bp_tmp = ndmp_malloc(sizeof (char) * TLM_MAX_PATH_NAME);
22657917SReza.Sabdar@Sun.COM 	if (!bp.bp_tmp)
22667917SReza.Sabdar@Sun.COM 		return (-1);
22677917SReza.Sabdar@Sun.COM 
22687917SReza.Sabdar@Sun.COM 	/*
22697917SReza.Sabdar@Sun.COM 	 * Make the checkpointed paths for traversing the
22707917SReza.Sabdar@Sun.COM 	 * backup hierarchy, if we make the checkpoint.
22717917SReza.Sabdar@Sun.COM 	 */
22727917SReza.Sabdar@Sun.COM 	bp.bp_unchkpnm = nlp->nlp_backup_path;
22737917SReza.Sabdar@Sun.COM 	if (!NLP_ISCHKPNTED(nlp)) {
22747917SReza.Sabdar@Sun.COM 		tlm_acls.acl_checkpointed = TRUE;
22757917SReza.Sabdar@Sun.COM 		bp.bp_chkpnm = ndmp_malloc(sizeof (char) * TLM_MAX_PATH_NAME);
22767917SReza.Sabdar@Sun.COM 		if (!bp.bp_chkpnm) {
22777917SReza.Sabdar@Sun.COM 			NDMP_FREE(bp.bp_tmp);
22787917SReza.Sabdar@Sun.COM 			return (-1);
22797917SReza.Sabdar@Sun.COM 		}
22807917SReza.Sabdar@Sun.COM 		(void) tlm_build_snapshot_name(nlp->nlp_backup_path,
22817917SReza.Sabdar@Sun.COM 		    bp.bp_chkpnm, nlp->nlp_jstat->js_job_name);
22827917SReza.Sabdar@Sun.COM 	} else {
22837917SReza.Sabdar@Sun.COM 		tlm_acls.acl_checkpointed = FALSE;
22847917SReza.Sabdar@Sun.COM 		bp.bp_chkpnm = nlp->nlp_backup_path;
22857917SReza.Sabdar@Sun.COM 	}
22867917SReza.Sabdar@Sun.COM 	bp.bp_excls = ndmpd_make_exc_list();
22877917SReza.Sabdar@Sun.COM 
22887917SReza.Sabdar@Sun.COM 	/* set traversing arguments */
22897917SReza.Sabdar@Sun.COM 	ft.ft_path = nlp->nlp_backup_path;
22907917SReza.Sabdar@Sun.COM 	ft.ft_lpath = bp.bp_chkpnm;
22917917SReza.Sabdar@Sun.COM 
22927917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "path %s lpath %s", ft.ft_path, ft.ft_lpath);
22937917SReza.Sabdar@Sun.COM 	if (NLP_ISSET(nlp, NLPF_TOKENBK) || NLP_ISSET(nlp, NLPF_LEVELBK)) {
22947917SReza.Sabdar@Sun.COM 		ft.ft_callbk = timebk_v3;
22957917SReza.Sabdar@Sun.COM 		tlm_acls.acl_clear_archive = FALSE;
22967917SReza.Sabdar@Sun.COM 	} else if (NLP_ISSET(nlp, NLPF_LBRBK)) {
22977917SReza.Sabdar@Sun.COM 		ft.ft_callbk = lbrbk_v3;
22987917SReza.Sabdar@Sun.COM 		tlm_acls.acl_clear_archive = FALSE;
22997917SReza.Sabdar@Sun.COM 
23007917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "bp_opr %x clr_arc %c",
23017917SReza.Sabdar@Sun.COM 		    bp.bp_opr, NDMP_YORN(tlm_acls.acl_clear_archive));
23027917SReza.Sabdar@Sun.COM 	} else {
23037917SReza.Sabdar@Sun.COM 		rv = -1;
23047917SReza.Sabdar@Sun.COM 		MOD_LOGV3(nlp->nlp_params, NDMP_LOG_ERROR,
23057917SReza.Sabdar@Sun.COM 		    "Unknow backup type.\n");
23067917SReza.Sabdar@Sun.COM 	}
23077917SReza.Sabdar@Sun.COM 	ft.ft_arg = &bp;
23087917SReza.Sabdar@Sun.COM 	ft.ft_logfp = (ft_log_t)ndmp_log;
2309*12904SReza.Sabdar@Sun.COM 	ft.ft_flags = FST_VERBOSE | FST_STOP_ONERR;
23107917SReza.Sabdar@Sun.COM 
23117917SReza.Sabdar@Sun.COM 	/* take into account the header written to the stream so far */
23127917SReza.Sabdar@Sun.COM 	n = tlm_get_data_offset(lcmd);
23137917SReza.Sabdar@Sun.COM 	nlp->nlp_session->ns_data.dd_module.dm_stats.ms_bytes_processed = n;
23147917SReza.Sabdar@Sun.COM 
23157917SReza.Sabdar@Sun.COM 	if (rv == 0) {
23167917SReza.Sabdar@Sun.COM 		/* start traversing the hierarchy and actual backup */
23177917SReza.Sabdar@Sun.COM 		rv = traverse_level(&ft);
23187917SReza.Sabdar@Sun.COM 		if (rv == 0) {
23197917SReza.Sabdar@Sun.COM 			/* write the trailer and update the bytes processed */
23207917SReza.Sabdar@Sun.COM 			bpos = tlm_get_data_offset(lcmd);
23217917SReza.Sabdar@Sun.COM 			(void) write_tar_eof(lcmd);
23227917SReza.Sabdar@Sun.COM 			n = tlm_get_data_offset(lcmd) - bpos;
23237917SReza.Sabdar@Sun.COM 			nlp->nlp_session->
23247917SReza.Sabdar@Sun.COM 			    ns_data.dd_module.dm_stats.ms_bytes_processed += n;
2325*12904SReza.Sabdar@Sun.COM 		} else {
2326*12904SReza.Sabdar@Sun.COM 			MOD_LOGV3(nlp->nlp_params, NDMP_LOG_ERROR,
2327*12904SReza.Sabdar@Sun.COM 			    "Filesystem traverse error.\n");
2328*12904SReza.Sabdar@Sun.COM 			ndmpd_data_error(nlp->nlp_session,
2329*12904SReza.Sabdar@Sun.COM 			    NDMP_DATA_HALT_INTERNAL_ERROR);
23307917SReza.Sabdar@Sun.COM 		}
23317917SReza.Sabdar@Sun.COM 	}
23327917SReza.Sabdar@Sun.COM 
23337917SReza.Sabdar@Sun.COM 	if (!NLP_ISCHKPNTED(nlp))
23347917SReza.Sabdar@Sun.COM 		NDMP_FREE(bp.bp_chkpnm);
23357917SReza.Sabdar@Sun.COM 	NDMP_FREE(bp.bp_tmp);
23367917SReza.Sabdar@Sun.COM 	NDMP_FREE(bp.bp_excls);
23377917SReza.Sabdar@Sun.COM 
23387917SReza.Sabdar@Sun.COM 	cmds->tcs_reader_count--;
23397917SReza.Sabdar@Sun.COM 	lcmd->tc_writer = TLM_STOP;
23407917SReza.Sabdar@Sun.COM 	tlm_release_reader_writer_ipc(lcmd);
23417917SReza.Sabdar@Sun.COM 	tlm_un_ref_job_stats(jname);
23427917SReza.Sabdar@Sun.COM 	return (rv);
23437917SReza.Sabdar@Sun.COM 
23447917SReza.Sabdar@Sun.COM }
23457917SReza.Sabdar@Sun.COM 
23467917SReza.Sabdar@Sun.COM 
23477917SReza.Sabdar@Sun.COM /*
23487917SReza.Sabdar@Sun.COM  * tar_backup_v3
23497917SReza.Sabdar@Sun.COM  *
23507917SReza.Sabdar@Sun.COM  * Traverse the backup hierarchy if needed and make the bitmap.
23517917SReza.Sabdar@Sun.COM  * Then launch reader and writer threads to do the actual backup.
23527917SReza.Sabdar@Sun.COM  *
23537917SReza.Sabdar@Sun.COM  * Parameters:
23547917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
23557917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
23567917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
23577917SReza.Sabdar@Sun.COM  *   jname (input) - job name
23587917SReza.Sabdar@Sun.COM  *
23597917SReza.Sabdar@Sun.COM  * Returns:
23607917SReza.Sabdar@Sun.COM  *   0: on success
23617917SReza.Sabdar@Sun.COM  *   != 0: otherwise
23627917SReza.Sabdar@Sun.COM  */
23637917SReza.Sabdar@Sun.COM static int
tar_backup_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp,char * jname)23647917SReza.Sabdar@Sun.COM tar_backup_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
23657917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp, char *jname)
23667917SReza.Sabdar@Sun.COM {
23677917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
23687917SReza.Sabdar@Sun.COM 	backup_reader_arg_t arg;
23697917SReza.Sabdar@Sun.COM 	pthread_t rdtp;
23707917SReza.Sabdar@Sun.COM 	char info[256];
23717917SReza.Sabdar@Sun.COM 	int result;
23727917SReza.Sabdar@Sun.COM 	ndmp_context_t nctx;
23737917SReza.Sabdar@Sun.COM 	int err;
23747917SReza.Sabdar@Sun.COM 
23757917SReza.Sabdar@Sun.COM 	if (ndmp_get_bk_dir_ino(nlp))
23767917SReza.Sabdar@Sun.COM 		return (-1);
23777917SReza.Sabdar@Sun.COM 
23787917SReza.Sabdar@Sun.COM 	result = err = 0;
23797917SReza.Sabdar@Sun.COM 
23807917SReza.Sabdar@Sun.COM 	/* exit as if there was an internal error */
23817917SReza.Sabdar@Sun.COM 	if (session->ns_eof)
23827917SReza.Sabdar@Sun.COM 		return (-1);
23837917SReza.Sabdar@Sun.COM 
23847917SReza.Sabdar@Sun.COM 	if (!session->ns_data.dd_abort) {
23857917SReza.Sabdar@Sun.COM 		if (backup_alloc_structs_v3(session, jname) < 0) {
23867917SReza.Sabdar@Sun.COM 			nlp->nlp_bkmap = -1;
23877917SReza.Sabdar@Sun.COM 			return (-1);
23887917SReza.Sabdar@Sun.COM 		}
23897917SReza.Sabdar@Sun.COM 
23907917SReza.Sabdar@Sun.COM 		if (ndmpd_mark_inodes_v3(session, nlp) != 0) {
23917917SReza.Sabdar@Sun.COM 			if (nlp->nlp_bkmap != -1) {
23927917SReza.Sabdar@Sun.COM 				(void) dbm_free(nlp->nlp_bkmap);
23937917SReza.Sabdar@Sun.COM 				nlp->nlp_bkmap = -1;
23947917SReza.Sabdar@Sun.COM 			}
23957917SReza.Sabdar@Sun.COM 			free_structs_v3(session, jname);
23967917SReza.Sabdar@Sun.COM 			return (-1);
23977917SReza.Sabdar@Sun.COM 		}
23987917SReza.Sabdar@Sun.COM 
23997917SReza.Sabdar@Sun.COM 		nlp->nlp_jstat->js_start_ltime = time(NULL);
24007917SReza.Sabdar@Sun.COM 		nlp->nlp_jstat->js_start_time = nlp->nlp_jstat->js_start_ltime;
24017917SReza.Sabdar@Sun.COM 		nlp->nlp_jstat->js_chkpnt_time = nlp->nlp_cdate;
24027917SReza.Sabdar@Sun.COM 
24037917SReza.Sabdar@Sun.COM 		cmds = &nlp->nlp_cmds;
24047917SReza.Sabdar@Sun.COM 		cmds->tcs_reader = cmds->tcs_writer = TLM_BACKUP_RUN;
24057917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_reader = TLM_BACKUP_RUN;
24067917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_writer = TLM_BACKUP_RUN;
24077917SReza.Sabdar@Sun.COM 
24087917SReza.Sabdar@Sun.COM 		if (ndmp_write_utf8magic(cmds->tcs_command) < 0) {
24097917SReza.Sabdar@Sun.COM 			free_structs_v3(session, jname);
24107917SReza.Sabdar@Sun.COM 			return (-1);
24117917SReza.Sabdar@Sun.COM 		}
24127917SReza.Sabdar@Sun.COM 
24137917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
24147917SReza.Sabdar@Sun.COM 		    "Backing up \"%s\" started.", nlp->nlp_backup_path);
24157917SReza.Sabdar@Sun.COM 
24167917SReza.Sabdar@Sun.COM 		/* Plug-in module */
24177917SReza.Sabdar@Sun.COM 		if (ndmp_pl != NULL &&
24187917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_pre_backup != NULL) {
24197917SReza.Sabdar@Sun.COM 			(void) memset(&nctx, 0, sizeof (ndmp_context_t));
24207917SReza.Sabdar@Sun.COM 			nctx.nc_plversion = ndmp_pl->np_plversion;
24217917SReza.Sabdar@Sun.COM 			nctx.nc_plname = ndmpd_get_prop(NDMP_PLUGIN_PATH);
24227917SReza.Sabdar@Sun.COM 			nctx.nc_cmds = cmds;
242311170SReza.Sabdar@Sun.COM 			nctx.nc_params = params;
242412186SJanice.Chang@Sun.COM 			nctx.nc_ddata = (void *) session;
24257917SReza.Sabdar@Sun.COM 			if ((err = ndmp_pl->np_pre_backup(ndmp_pl, &nctx,
24267917SReza.Sabdar@Sun.COM 			    nlp->nlp_backup_path)) != 0) {
242711170SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_ERR, "Pre-backup plug-in: %m");
24287917SReza.Sabdar@Sun.COM 				goto backup_out;
24297917SReza.Sabdar@Sun.COM 			}
24307917SReza.Sabdar@Sun.COM 		}
24317917SReza.Sabdar@Sun.COM 
24327917SReza.Sabdar@Sun.COM 		(void) memset(&arg, 0, sizeof (backup_reader_arg_t));
24337917SReza.Sabdar@Sun.COM 		arg.br_jname = jname;
24347917SReza.Sabdar@Sun.COM 		arg.br_nlp = nlp;
24357917SReza.Sabdar@Sun.COM 		arg.br_cmds = cmds;
24367917SReza.Sabdar@Sun.COM 
24377917SReza.Sabdar@Sun.COM 		(void) pthread_barrier_init(&arg.br_barrier, 0, 2);
24387917SReza.Sabdar@Sun.COM 
24397917SReza.Sabdar@Sun.COM 		err = pthread_create(&rdtp, NULL, (funct_t)backup_reader_v3,
24407917SReza.Sabdar@Sun.COM 		    (void *)&arg);
24417917SReza.Sabdar@Sun.COM 		if (err == 0) {
24427917SReza.Sabdar@Sun.COM 			(void) pthread_barrier_wait(&arg.br_barrier);
24437917SReza.Sabdar@Sun.COM 			(void) pthread_barrier_destroy(&arg.br_barrier);
24447917SReza.Sabdar@Sun.COM 		} else {
24457917SReza.Sabdar@Sun.COM 			(void) pthread_barrier_destroy(&arg.br_barrier);
24467917SReza.Sabdar@Sun.COM 			free_structs_v3(session, jname);
24477917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Launch backup_reader_v3: %m");
24487917SReza.Sabdar@Sun.COM 			return (-1);
24497917SReza.Sabdar@Sun.COM 		}
24507917SReza.Sabdar@Sun.COM 
24517917SReza.Sabdar@Sun.COM 		if ((err = ndmp_tar_writer(session, params, cmds)) != 0)
24527917SReza.Sabdar@Sun.COM 			result = EIO;
24537917SReza.Sabdar@Sun.COM 
24547917SReza.Sabdar@Sun.COM 		nlp->nlp_jstat->js_stop_time = time(NULL);
24557917SReza.Sabdar@Sun.COM 
24567917SReza.Sabdar@Sun.COM 		(void) snprintf(info, sizeof (info),
24577917SReza.Sabdar@Sun.COM 		    "Runtime [%s] %llu bytes (%llu): %d seconds\n",
24587917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path,
24597917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_module.dm_stats.ms_bytes_processed,
24607917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_module.dm_stats.ms_bytes_processed,
24617917SReza.Sabdar@Sun.COM 		    nlp->nlp_jstat->js_stop_time -
24627917SReza.Sabdar@Sun.COM 		    nlp->nlp_jstat->js_start_ltime);
24637917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL, info);
24647917SReza.Sabdar@Sun.COM 
24657917SReza.Sabdar@Sun.COM 		ndmp_wait_for_reader(cmds);
24667917SReza.Sabdar@Sun.COM 		(void) pthread_join(rdtp, NULL);
24677917SReza.Sabdar@Sun.COM 
24687917SReza.Sabdar@Sun.COM 		/* exit as if there was an internal error */
24697917SReza.Sabdar@Sun.COM 		if (session->ns_eof) {
24707917SReza.Sabdar@Sun.COM 			result = EPIPE;
24717917SReza.Sabdar@Sun.COM 			err = -1;
24727917SReza.Sabdar@Sun.COM 		}
24737917SReza.Sabdar@Sun.COM 		if (!session->ns_data.dd_abort) {
24747917SReza.Sabdar@Sun.COM 			ndmpd_audit_backup(session->ns_connection,
24757917SReza.Sabdar@Sun.COM 			    nlp->nlp_backup_path,
24767917SReza.Sabdar@Sun.COM 			    session->ns_data.dd_data_addr.addr_type,
24777917SReza.Sabdar@Sun.COM 			    session->ns_tape.td_adapter_name, result);
24787917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Backing up \"%s\" Finished.",
24797917SReza.Sabdar@Sun.COM 			    nlp->nlp_backup_path);
24807917SReza.Sabdar@Sun.COM 		}
24817917SReza.Sabdar@Sun.COM 	}
24827917SReza.Sabdar@Sun.COM 
24837917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_abort) {
24847917SReza.Sabdar@Sun.COM 		ndmpd_audit_backup(session->ns_connection,
24857917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path,
24867917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_data_addr.addr_type,
24877917SReza.Sabdar@Sun.COM 		    session->ns_tape.td_adapter_name, EINTR);
24887917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
24897917SReza.Sabdar@Sun.COM 		    "Backing up \"%s\" aborted.", nlp->nlp_backup_path);
24907917SReza.Sabdar@Sun.COM 		err = -1;
24917917SReza.Sabdar@Sun.COM 	} else {
24927917SReza.Sabdar@Sun.COM 
24937917SReza.Sabdar@Sun.COM backup_out:
24947917SReza.Sabdar@Sun.COM 		/* Plug-in module */
24957917SReza.Sabdar@Sun.COM 		if (ndmp_pl != NULL &&
24967917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_post_backup != NULL &&
24977917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_post_backup(ndmp_pl, &nctx, err) == -1) {
24987917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Post-backup plug-in: %m");
24997917SReza.Sabdar@Sun.COM 			return (-1);
25007917SReza.Sabdar@Sun.COM 		}
25017917SReza.Sabdar@Sun.COM 	}
25027917SReza.Sabdar@Sun.COM 
25037917SReza.Sabdar@Sun.COM 	free_structs_v3(session, jname);
25047917SReza.Sabdar@Sun.COM 	return (err);
25057917SReza.Sabdar@Sun.COM }
25067917SReza.Sabdar@Sun.COM 
25077917SReza.Sabdar@Sun.COM /*
25087917SReza.Sabdar@Sun.COM  * get_backup_size
25097917SReza.Sabdar@Sun.COM  *
25107917SReza.Sabdar@Sun.COM  * Find the estimate of backup size. This is used to get an estimate
25117917SReza.Sabdar@Sun.COM  * of the progress of backup during NDMP backup.
25127917SReza.Sabdar@Sun.COM  */
25137917SReza.Sabdar@Sun.COM void
get_backup_size(ndmp_bkup_size_arg_t * sarg)251410038SReza.Sabdar@Sun.COM get_backup_size(ndmp_bkup_size_arg_t *sarg)
25157917SReza.Sabdar@Sun.COM {
25167917SReza.Sabdar@Sun.COM 	fs_traverse_t ft;
25177917SReza.Sabdar@Sun.COM 	u_longlong_t bk_size;
251810038SReza.Sabdar@Sun.COM 	char spath[PATH_MAX];
25197917SReza.Sabdar@Sun.COM 	int rv;
25207917SReza.Sabdar@Sun.COM 
25217917SReza.Sabdar@Sun.COM 	bk_size = 0;
252210038SReza.Sabdar@Sun.COM 	if (fs_is_chkpntvol(sarg->bs_path)) {
252310038SReza.Sabdar@Sun.COM 		ft.ft_path = sarg->bs_path;
252410038SReza.Sabdar@Sun.COM 	} else {
252510038SReza.Sabdar@Sun.COM 		(void) tlm_build_snapshot_name(sarg->bs_path,
252610038SReza.Sabdar@Sun.COM 		    spath, sarg->bs_jname);
252710038SReza.Sabdar@Sun.COM 		ft.ft_path = spath;
252810038SReza.Sabdar@Sun.COM 	}
252910038SReza.Sabdar@Sun.COM 
253010038SReza.Sabdar@Sun.COM 	ft.ft_lpath = ft.ft_path;
25317917SReza.Sabdar@Sun.COM 	ft.ft_callbk = size_cb;
25327917SReza.Sabdar@Sun.COM 	ft.ft_arg = &bk_size;
25337917SReza.Sabdar@Sun.COM 	ft.ft_logfp = (ft_log_t)ndmp_log;
253410038SReza.Sabdar@Sun.COM 	ft.ft_flags = FST_VERBOSE;
25357917SReza.Sabdar@Sun.COM 
25367917SReza.Sabdar@Sun.COM 	if ((rv = traverse_level(&ft)) != 0) {
25377917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "bksize err=%d", rv);
25387917SReza.Sabdar@Sun.COM 		bk_size = 0;
25397917SReza.Sabdar@Sun.COM 	} else {
25407917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "bksize %lld, %lldKB, %lldMB\n",
25417917SReza.Sabdar@Sun.COM 		    bk_size, bk_size / 1024, bk_size /(1024 * 1024));
25427917SReza.Sabdar@Sun.COM 	}
254310038SReza.Sabdar@Sun.COM 	sarg->bs_session->ns_data.dd_data_size = bk_size;
25447917SReza.Sabdar@Sun.COM }
25457917SReza.Sabdar@Sun.COM 
25467917SReza.Sabdar@Sun.COM /*
25477917SReza.Sabdar@Sun.COM  * get_rs_path_v3
25487917SReza.Sabdar@Sun.COM  *
25497917SReza.Sabdar@Sun.COM  * Find the restore path
25507917SReza.Sabdar@Sun.COM  */
25517917SReza.Sabdar@Sun.COM ndmp_error
get_rs_path_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)25527917SReza.Sabdar@Sun.COM get_rs_path_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
25537917SReza.Sabdar@Sun.COM {
25547917SReza.Sabdar@Sun.COM 	char *dp;
25557917SReza.Sabdar@Sun.COM 	ndmp_error rv;
25567917SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
25577917SReza.Sabdar@Sun.COM 	int i, nm_cnt;
25587917SReza.Sabdar@Sun.COM 	char *nm_dpath_list[MULTIPLE_DEST_DIRS];
25597917SReza.Sabdar@Sun.COM 	static char mdest_buf[256];
25607917SReza.Sabdar@Sun.COM 
25617917SReza.Sabdar@Sun.COM 	*mdest_buf = 0;
25627917SReza.Sabdar@Sun.COM 	*nm_dpath_list = "";
25637917SReza.Sabdar@Sun.COM 	for (i = 0, nm_cnt = 0; i < (int)nlp->nlp_nfiles; i++) {
25647917SReza.Sabdar@Sun.COM 		ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, i);
25657917SReza.Sabdar@Sun.COM 		if (!ep) {
25667917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Can't get Nlist[%d]", i);
25677917SReza.Sabdar@Sun.COM 			return (NDMP_ILLEGAL_ARGS_ERR);
25687917SReza.Sabdar@Sun.COM 		}
25697917SReza.Sabdar@Sun.COM 		if (strcmp(nm_dpath_list[nm_cnt], ep->nm3_dpath) != 0 &&
25707917SReza.Sabdar@Sun.COM 		    nm_cnt < MULTIPLE_DEST_DIRS - 1)
25717917SReza.Sabdar@Sun.COM 			nm_dpath_list[++nm_cnt] = ep->nm3_dpath;
25727917SReza.Sabdar@Sun.COM 	}
25737917SReza.Sabdar@Sun.COM 
25747917SReza.Sabdar@Sun.COM 	multiple_dest_restore = (nm_cnt > 1);
25757917SReza.Sabdar@Sun.COM 	nlp->nlp_restore_path = mdest_buf;
25767917SReza.Sabdar@Sun.COM 
25777917SReza.Sabdar@Sun.COM 	for (i = 1; i < nm_cnt + 1; i++) {
25787917SReza.Sabdar@Sun.COM 		if (ISDEFINED(nm_dpath_list[i]))
25797917SReza.Sabdar@Sun.COM 			dp = nm_dpath_list[i];
25807917SReza.Sabdar@Sun.COM 		else
25817917SReza.Sabdar@Sun.COM 			/* the default destination path is backup directory */
25827917SReza.Sabdar@Sun.COM 			dp = nlp->nlp_backup_path;
25837917SReza.Sabdar@Sun.COM 
25847917SReza.Sabdar@Sun.COM 		/* check the destination directory exists and is writable */
25857917SReza.Sabdar@Sun.COM 		if (!fs_volexist(dp)) {
25867917SReza.Sabdar@Sun.COM 			rv = NDMP_ILLEGAL_ARGS_ERR;
25877917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
25887917SReza.Sabdar@Sun.COM 			    "Invalid destination path volume \"%s\".\n", dp);
25897917SReza.Sabdar@Sun.COM 		} else if (!voliswr(dp)) {
25907917SReza.Sabdar@Sun.COM 			rv = NDMP_ILLEGAL_ARGS_ERR;
25917917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
25927917SReza.Sabdar@Sun.COM 			    "The destination path volume"
25937917SReza.Sabdar@Sun.COM 			    " is not writable \"%s\".\n", dp);
25947917SReza.Sabdar@Sun.COM 		} else {
25957917SReza.Sabdar@Sun.COM 			rv = NDMP_NO_ERR;
25967917SReza.Sabdar@Sun.COM 			(void) strlcat(nlp->nlp_restore_path, dp,
25977917SReza.Sabdar@Sun.COM 			    sizeof (mdest_buf));
25987917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "rspath: \"%s\"", dp);
25997917SReza.Sabdar@Sun.COM 		}
26007917SReza.Sabdar@Sun.COM 
26017917SReza.Sabdar@Sun.COM 		/*
26027917SReza.Sabdar@Sun.COM 		 * Exit if there is an error or it is not a multiple
26037917SReza.Sabdar@Sun.COM 		 * destination restore mode
26047917SReza.Sabdar@Sun.COM 		 */
26057917SReza.Sabdar@Sun.COM 		if (rv != NDMP_NO_ERR || !multiple_dest_restore)
26067917SReza.Sabdar@Sun.COM 			break;
26077917SReza.Sabdar@Sun.COM 
26087917SReza.Sabdar@Sun.COM 		if (i < nm_cnt)
26097917SReza.Sabdar@Sun.COM 			(void) strlcat(nlp->nlp_restore_path, ", ",
26107917SReza.Sabdar@Sun.COM 			    sizeof (mdest_buf));
26117917SReza.Sabdar@Sun.COM 	}
26127917SReza.Sabdar@Sun.COM 
26137917SReza.Sabdar@Sun.COM 	return (rv);
26147917SReza.Sabdar@Sun.COM }
26157917SReza.Sabdar@Sun.COM 
26167917SReza.Sabdar@Sun.COM 
26177917SReza.Sabdar@Sun.COM /*
26187917SReza.Sabdar@Sun.COM  * fix_nlist_v3
26197917SReza.Sabdar@Sun.COM  *
26207917SReza.Sabdar@Sun.COM  * Check if the recovery list is valid and fix it if there are some
26217917SReza.Sabdar@Sun.COM  * unspecified entries in it. It checks for original, destination
26227917SReza.Sabdar@Sun.COM  * and new path for all NDMP names provided inside the list.
26237917SReza.Sabdar@Sun.COM  *
26247917SReza.Sabdar@Sun.COM  * V3: dpath is the destination directory.  If newnm is not NULL, the
26257917SReza.Sabdar@Sun.COM  * destination path is dpath/newnm.  Otherwise the destination path is
26267917SReza.Sabdar@Sun.COM  * dpath/opath_last_node, where opath_last_node is the last node in opath.
26277917SReza.Sabdar@Sun.COM  *
26287917SReza.Sabdar@Sun.COM  * V4: If newnm is not NULL, dpath is the destination directory, and
26297917SReza.Sabdar@Sun.COM  * dpath/newnm is the destination path.  If newnm is NULL, dpath is
26307917SReza.Sabdar@Sun.COM  * the destination path (opath is not involved in forming destination path).
26317917SReza.Sabdar@Sun.COM  */
26327917SReza.Sabdar@Sun.COM ndmp_error
fix_nlist_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)26337917SReza.Sabdar@Sun.COM fix_nlist_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
26347917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp)
26357917SReza.Sabdar@Sun.COM {
26367917SReza.Sabdar@Sun.COM 	char *cp, *buf, *bp;
26377917SReza.Sabdar@Sun.COM 	int i, n;
26387917SReza.Sabdar@Sun.COM 	int iswrbk;
26397917SReza.Sabdar@Sun.COM 	int bvexists;
26407917SReza.Sabdar@Sun.COM 	ndmp_error rv;
26417917SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
26427917SReza.Sabdar@Sun.COM 	char *dp;
26437917SReza.Sabdar@Sun.COM 	char *nm;
26447917SReza.Sabdar@Sun.COM 	int existsvol;
26457917SReza.Sabdar@Sun.COM 	int isrwdst;
26467917SReza.Sabdar@Sun.COM 
26477917SReza.Sabdar@Sun.COM 	buf = ndmp_malloc(TLM_MAX_PATH_NAME);
26487917SReza.Sabdar@Sun.COM 	if (!buf) {
26497917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR, "Insufficient memory.\n");
26507917SReza.Sabdar@Sun.COM 		return (NDMP_NO_MEM_ERR);
26517917SReza.Sabdar@Sun.COM 	}
26527917SReza.Sabdar@Sun.COM 
26537917SReza.Sabdar@Sun.COM 	bvexists = fs_volexist(nlp->nlp_backup_path);
26547917SReza.Sabdar@Sun.COM 	iswrbk = voliswr(nlp->nlp_backup_path);
26557917SReza.Sabdar@Sun.COM 
26567917SReza.Sabdar@Sun.COM 	rv = NDMP_NO_ERR;
26577917SReza.Sabdar@Sun.COM 	n = session->ns_data.dd_nlist_len;
26587917SReza.Sabdar@Sun.COM 	for (i = 0; i < n; i++) {
26597917SReza.Sabdar@Sun.COM 		ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, i);
26607917SReza.Sabdar@Sun.COM 		if (!ep)
26617917SReza.Sabdar@Sun.COM 			continue;
26627917SReza.Sabdar@Sun.COM 
26637917SReza.Sabdar@Sun.COM 		/* chop off the trailing slashes */
26647917SReza.Sabdar@Sun.COM 		chopslash(ep->nm3_opath);
26657917SReza.Sabdar@Sun.COM 
26667917SReza.Sabdar@Sun.COM 		chopslash(ep->nm3_dpath);
26677917SReza.Sabdar@Sun.COM 		chopslash(ep->nm3_newnm);
26687917SReza.Sabdar@Sun.COM 
26697917SReza.Sabdar@Sun.COM 		/* existing and non-empty destination path */
26707917SReza.Sabdar@Sun.COM 		if (ISDEFINED(ep->nm3_dpath)) {
26717917SReza.Sabdar@Sun.COM 			dp = ep->nm3_dpath;
26727917SReza.Sabdar@Sun.COM 			existsvol = fs_volexist(dp);
26737917SReza.Sabdar@Sun.COM 			isrwdst = voliswr(dp);
26747917SReza.Sabdar@Sun.COM 		} else {
26757917SReza.Sabdar@Sun.COM 			/* the default destination path is backup directory */
26767917SReza.Sabdar@Sun.COM 			dp = nlp->nlp_backup_path;
26777917SReza.Sabdar@Sun.COM 			existsvol = bvexists;
26787917SReza.Sabdar@Sun.COM 			isrwdst = iswrbk;
26797917SReza.Sabdar@Sun.COM 		}
26807917SReza.Sabdar@Sun.COM 
26817917SReza.Sabdar@Sun.COM 		/* check the destination directory exists and is writable */
26827917SReza.Sabdar@Sun.COM 		if (!existsvol) {
26837917SReza.Sabdar@Sun.COM 			rv = NDMP_ILLEGAL_ARGS_ERR;
26847917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
26857917SReza.Sabdar@Sun.COM 			    "Invalid destination path volume "
26867917SReza.Sabdar@Sun.COM 			    "\"%s\".\n", dp);
26877917SReza.Sabdar@Sun.COM 			break;
26887917SReza.Sabdar@Sun.COM 		}
26897917SReza.Sabdar@Sun.COM 		if (!isrwdst) {
26907917SReza.Sabdar@Sun.COM 			rv = NDMP_ILLEGAL_ARGS_ERR;
26917917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
26927917SReza.Sabdar@Sun.COM 			    "The destination path volume is not "
26937917SReza.Sabdar@Sun.COM 			    "writable \"%s\".\n", dp);
26947917SReza.Sabdar@Sun.COM 			break;
26957917SReza.Sabdar@Sun.COM 		}
26967917SReza.Sabdar@Sun.COM 
26977917SReza.Sabdar@Sun.COM 		/*
26987917SReza.Sabdar@Sun.COM 		 * If new name is not specified, the default new name is
26997917SReza.Sabdar@Sun.COM 		 * the last component of the original path, if any
27007917SReza.Sabdar@Sun.COM 		 * (except in V4).
27017917SReza.Sabdar@Sun.COM 		 */
270212035SReza.Sabdar@Sun.COM 		if (ISDEFINED(ep->nm3_newnm)) {
27037917SReza.Sabdar@Sun.COM 			nm = ep->nm3_newnm;
27047917SReza.Sabdar@Sun.COM 		} else {
270512035SReza.Sabdar@Sun.COM 			char *p, *q;
270612035SReza.Sabdar@Sun.COM 
270712035SReza.Sabdar@Sun.COM 			/*
270812035SReza.Sabdar@Sun.COM 			 * Find the last component of nm3_opath.
270912035SReza.Sabdar@Sun.COM 			 * nm3_opath has no trailing '/'.
271012035SReza.Sabdar@Sun.COM 			 */
271112035SReza.Sabdar@Sun.COM 			p = strrchr(ep->nm3_opath, '/');
271212035SReza.Sabdar@Sun.COM 			nm = p ? p + 1 : ep->nm3_opath;
271312035SReza.Sabdar@Sun.COM 
271412035SReza.Sabdar@Sun.COM 			/*
271512035SReza.Sabdar@Sun.COM 			 * In DDAR the last component could
271612035SReza.Sabdar@Sun.COM 			 * be repeated in nm3_dpath
271712035SReza.Sabdar@Sun.COM 			 */
271812035SReza.Sabdar@Sun.COM 			q = strrchr(ep->nm3_dpath, '/');
271912035SReza.Sabdar@Sun.COM 			q = q ? q + 1 : ep->nm3_dpath;
272012035SReza.Sabdar@Sun.COM 			if (strcmp(nm, q) == 0)
272112035SReza.Sabdar@Sun.COM 				nm = NULL;
272212035SReza.Sabdar@Sun.COM 
27237917SReza.Sabdar@Sun.COM 		}
27247917SReza.Sabdar@Sun.COM 
27257917SReza.Sabdar@Sun.COM 		bp = joinpath(buf, dp, nm);
27267917SReza.Sabdar@Sun.COM 		if (!bp) {
27277917SReza.Sabdar@Sun.COM 			/*
27287917SReza.Sabdar@Sun.COM 			 * Note: What should be done with this entry?
27297917SReza.Sabdar@Sun.COM 			 * We leave it untouched for now, hence no path in
27307917SReza.Sabdar@Sun.COM 			 * the backup image matches with this entry and will
27317917SReza.Sabdar@Sun.COM 			 * be reported as not found.
27327917SReza.Sabdar@Sun.COM 			 */
27337917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
27347917SReza.Sabdar@Sun.COM 			    "Destination path too long(%s/%s)", dp, nm);
27357917SReza.Sabdar@Sun.COM 			continue;
27367917SReza.Sabdar@Sun.COM 		}
27377917SReza.Sabdar@Sun.COM 		cp = strdup(bp);
27387917SReza.Sabdar@Sun.COM 		if (!cp) {
27397917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
27407917SReza.Sabdar@Sun.COM 			    "Insufficient memory.\n");
27417917SReza.Sabdar@Sun.COM 			rv = NDMP_NO_MEM_ERR;
27427917SReza.Sabdar@Sun.COM 			break;
27437917SReza.Sabdar@Sun.COM 		}
27447917SReza.Sabdar@Sun.COM 		free(ep->nm3_dpath);
27457917SReza.Sabdar@Sun.COM 		ep->nm3_dpath = cp;
27467917SReza.Sabdar@Sun.COM 		NDMP_FREE(ep->nm3_newnm);
27477917SReza.Sabdar@Sun.COM 
27487917SReza.Sabdar@Sun.COM 		bp = joinpath(buf, nlp->nlp_backup_path, ep->nm3_opath);
27497917SReza.Sabdar@Sun.COM 		if (!bp) {
27507917SReza.Sabdar@Sun.COM 			/*
27517917SReza.Sabdar@Sun.COM 			 * Note: The same problem of above with long path.
27527917SReza.Sabdar@Sun.COM 			 */
27537917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
27547917SReza.Sabdar@Sun.COM 			    "Path too long(%s/%s)",
27557917SReza.Sabdar@Sun.COM 			    nlp->nlp_backup_path, ep->nm3_opath);
27567917SReza.Sabdar@Sun.COM 			continue;
27577917SReza.Sabdar@Sun.COM 		}
27587917SReza.Sabdar@Sun.COM 		cp = strdup(bp);
27597917SReza.Sabdar@Sun.COM 		if (!cp) {
27607917SReza.Sabdar@Sun.COM 			MOD_LOGV3(params, NDMP_LOG_ERROR,
27617917SReza.Sabdar@Sun.COM 			    "Insufficient memory.\n");
27627917SReza.Sabdar@Sun.COM 			rv = NDMP_NO_MEM_ERR;
27637917SReza.Sabdar@Sun.COM 			break;
27647917SReza.Sabdar@Sun.COM 		}
27657917SReza.Sabdar@Sun.COM 		NDMP_FREE(ep->nm3_opath);
27667917SReza.Sabdar@Sun.COM 		ep->nm3_opath = cp;
27677917SReza.Sabdar@Sun.COM 
27687917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "orig[%d]: \"%s\"", i, ep->nm3_opath);
27697917SReza.Sabdar@Sun.COM 		if (ep->nm3_dpath) {
27707917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG,
27717917SReza.Sabdar@Sun.COM 			    "dest[%d]: \"%s\"", i, ep->nm3_dpath);
27727917SReza.Sabdar@Sun.COM 		} else {
27737917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "dest[%d]: \"%s\"", i, "NULL");
27747917SReza.Sabdar@Sun.COM 		}
27757917SReza.Sabdar@Sun.COM 	}
27767917SReza.Sabdar@Sun.COM 
27777917SReza.Sabdar@Sun.COM 	free(buf);
27787917SReza.Sabdar@Sun.COM 
27797917SReza.Sabdar@Sun.COM 	return (rv);
27807917SReza.Sabdar@Sun.COM }
27817917SReza.Sabdar@Sun.COM 
27827917SReza.Sabdar@Sun.COM 
27837917SReza.Sabdar@Sun.COM /*
27847917SReza.Sabdar@Sun.COM  * allvalidfh
27857917SReza.Sabdar@Sun.COM  *
27867917SReza.Sabdar@Sun.COM  * Run a sanity check on the file history info. The file history
27877917SReza.Sabdar@Sun.COM  * info is the offset of the record starting the entry on the tape
27887917SReza.Sabdar@Sun.COM  * and is used in DAR (direct access restore mode).
27897917SReza.Sabdar@Sun.COM  */
27907917SReza.Sabdar@Sun.COM static boolean_t
allvalidfh(ndmpd_session_t * session,ndmpd_module_params_t * params)27917917SReza.Sabdar@Sun.COM allvalidfh(ndmpd_session_t *session, ndmpd_module_params_t *params)
27927917SReza.Sabdar@Sun.COM {
27937917SReza.Sabdar@Sun.COM 	int i, n;
27947917SReza.Sabdar@Sun.COM 	boolean_t rv;
27957917SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
27967917SReza.Sabdar@Sun.COM 
27977917SReza.Sabdar@Sun.COM 	rv = TRUE;
27987917SReza.Sabdar@Sun.COM 	n = session->ns_data.dd_nlist_len;
27997917SReza.Sabdar@Sun.COM 	for (i = 0; i < n; i++) {
28007917SReza.Sabdar@Sun.COM 		ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, i);
28017917SReza.Sabdar@Sun.COM 		if (!ep)
28027917SReza.Sabdar@Sun.COM 			continue;
28037917SReza.Sabdar@Sun.COM 		/*
28047917SReza.Sabdar@Sun.COM 		 * The fh_info's sent from the client are multiples
28057917SReza.Sabdar@Sun.COM 		 * of RECORDSIZE which is 512 bytes.
28067917SReza.Sabdar@Sun.COM 		 *
28077917SReza.Sabdar@Sun.COM 		 * All our fh_info's are at the RECORDSIZE boundary.  If there
28087917SReza.Sabdar@Sun.COM 		 * is any fh_info that is less than RECORDSIZE (this covers 0
28097917SReza.Sabdar@Sun.COM 		 * and -1 values too), then the result is that DAR cannot be
28107917SReza.Sabdar@Sun.COM 		 * done.
28117917SReza.Sabdar@Sun.COM 		 */
28127917SReza.Sabdar@Sun.COM 		if (ep->nm3_fh_info < RECORDSIZE ||
28137917SReza.Sabdar@Sun.COM 		    ep->nm3_fh_info % RECORDSIZE != 0) {
28147917SReza.Sabdar@Sun.COM 			rv = FALSE;
28157917SReza.Sabdar@Sun.COM 			break;
28167917SReza.Sabdar@Sun.COM 		}
28177917SReza.Sabdar@Sun.COM 	}
28187917SReza.Sabdar@Sun.COM 
28197917SReza.Sabdar@Sun.COM 	return (rv);
28207917SReza.Sabdar@Sun.COM }
28217917SReza.Sabdar@Sun.COM 
28227917SReza.Sabdar@Sun.COM 
28237917SReza.Sabdar@Sun.COM /*
28247917SReza.Sabdar@Sun.COM  * log_rs_params_v3
28257917SReza.Sabdar@Sun.COM  *
28267917SReza.Sabdar@Sun.COM  * Log a copy of all values of the restore parameters
28277917SReza.Sabdar@Sun.COM  */
28287917SReza.Sabdar@Sun.COM void
log_rs_params_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)28297917SReza.Sabdar@Sun.COM log_rs_params_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
28307917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp)
28317917SReza.Sabdar@Sun.COM {
28327917SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, NDMP_LOG_NORMAL, "Restoring to \"%s\".\n",
28337917SReza.Sabdar@Sun.COM 	    (nlp->nlp_restore_path) ? nlp->nlp_restore_path : "NULL");
28347917SReza.Sabdar@Sun.COM 
28357917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_LOCAL) {
28367917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL, "Tape server: local.\n");
28377917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL,
28387917SReza.Sabdar@Sun.COM 		    "Tape record size: %d.\n",
28397917SReza.Sabdar@Sun.COM 		    session->ns_mover.md_record_size);
28407917SReza.Sabdar@Sun.COM 	} else if (session->ns_data.dd_data_addr.addr_type == NDMP_ADDR_TCP)
28417917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL,
28427917SReza.Sabdar@Sun.COM 		    "Tape server: remote at %s:%d.\n",
28437917SReza.Sabdar@Sun.COM 		    inet_ntoa(IN_ADDR(session->ns_data.dd_data_addr.tcp_ip_v3)),
28447917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_data_addr.tcp_port_v3);
28457917SReza.Sabdar@Sun.COM 	else
28467917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
28477917SReza.Sabdar@Sun.COM 		    "Unknown tape server address type.\n");
28487917SReza.Sabdar@Sun.COM 
28497917SReza.Sabdar@Sun.COM 	if (NLP_ISSET(nlp, NLPF_DIRECT))
28507917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_NORMAL,
28517917SReza.Sabdar@Sun.COM 		    "Direct Access Restore.\n");
28527917SReza.Sabdar@Sun.COM }
28537917SReza.Sabdar@Sun.COM 
28547917SReza.Sabdar@Sun.COM 
28557917SReza.Sabdar@Sun.COM /*
28567917SReza.Sabdar@Sun.COM  * send_unrecovered_list_v3
28577917SReza.Sabdar@Sun.COM  *
28587917SReza.Sabdar@Sun.COM  * Create the list of files that were in restore list but
28597917SReza.Sabdar@Sun.COM  * not recovered due to some errors.
28607917SReza.Sabdar@Sun.COM  */
28617917SReza.Sabdar@Sun.COM int
send_unrecovered_list_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)28627917SReza.Sabdar@Sun.COM send_unrecovered_list_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp)
28637917SReza.Sabdar@Sun.COM {
28647917SReza.Sabdar@Sun.COM 	int i, rv;
28657917SReza.Sabdar@Sun.COM 	int err;
28667917SReza.Sabdar@Sun.COM 
28677917SReza.Sabdar@Sun.COM 	if (!params) {
28687917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "params == NULL");
28697917SReza.Sabdar@Sun.COM 		return (-1);
28707917SReza.Sabdar@Sun.COM 	}
28717917SReza.Sabdar@Sun.COM 	if (!nlp) {
28727917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
28737917SReza.Sabdar@Sun.COM 		return (-1);
28747917SReza.Sabdar@Sun.COM 	}
28757917SReza.Sabdar@Sun.COM 
28767917SReza.Sabdar@Sun.COM 	if (nlp->nlp_lastidx != -1) {
28777917SReza.Sabdar@Sun.COM 		if (!bm_getone(nlp->nlp_rsbm, (u_longlong_t)nlp->nlp_lastidx))
28787917SReza.Sabdar@Sun.COM 			err = ENOENT;
28797917SReza.Sabdar@Sun.COM 		else
28807917SReza.Sabdar@Sun.COM 			err = 0;
28817917SReza.Sabdar@Sun.COM 		(void) ndmp_send_recovery_stat_v3(params, nlp,
28827917SReza.Sabdar@Sun.COM 		    nlp->nlp_lastidx, err);
28837917SReza.Sabdar@Sun.COM 		nlp->nlp_lastidx = -1;
28847917SReza.Sabdar@Sun.COM 	}
28857917SReza.Sabdar@Sun.COM 
28867917SReza.Sabdar@Sun.COM 	rv = 0;
28877917SReza.Sabdar@Sun.COM 	for (i = 0; i < (int)nlp->nlp_nfiles; i++) {
28887917SReza.Sabdar@Sun.COM 		if (!bm_getone(nlp->nlp_rsbm, (u_longlong_t)i)) {
28897917SReza.Sabdar@Sun.COM 			rv = ndmp_send_recovery_stat_v3(params, nlp, i, ENOENT);
28907917SReza.Sabdar@Sun.COM 			if (rv < 0)
28917917SReza.Sabdar@Sun.COM 				break;
28927917SReza.Sabdar@Sun.COM 		}
28937917SReza.Sabdar@Sun.COM 	}
28947917SReza.Sabdar@Sun.COM 
28957917SReza.Sabdar@Sun.COM 	return (rv);
28967917SReza.Sabdar@Sun.COM }
28977917SReza.Sabdar@Sun.COM 
28987917SReza.Sabdar@Sun.COM 
28997917SReza.Sabdar@Sun.COM 
29007917SReza.Sabdar@Sun.COM /*
29017917SReza.Sabdar@Sun.COM  * restore_dar_alloc_structs_v3
29027917SReza.Sabdar@Sun.COM  *
29037917SReza.Sabdar@Sun.COM  * Allocates the necessary structures for running DAR restore.
29047917SReza.Sabdar@Sun.COM  * It just creates the reader writer IPC.
29057917SReza.Sabdar@Sun.COM  * This function is called for each entry in the restore entry list.
29067917SReza.Sabdar@Sun.COM  *
29077917SReza.Sabdar@Sun.COM  * Parameters:
29087917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
29097917SReza.Sabdar@Sun.COM  *   jname (input) - Job name
29107917SReza.Sabdar@Sun.COM  *
29117917SReza.Sabdar@Sun.COM  * Returns:
29127917SReza.Sabdar@Sun.COM  *    0: on success
29137917SReza.Sabdar@Sun.COM  *   -1: on error
29147917SReza.Sabdar@Sun.COM  */
29157917SReza.Sabdar@Sun.COM int
restore_dar_alloc_structs_v3(ndmpd_session_t * session,char * jname)29167917SReza.Sabdar@Sun.COM restore_dar_alloc_structs_v3(ndmpd_session_t *session, char *jname)
29177917SReza.Sabdar@Sun.COM {
29187917SReza.Sabdar@Sun.COM 	long xfer_size;
29197917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
29207917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
29217917SReza.Sabdar@Sun.COM 
29227917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
29237917SReza.Sabdar@Sun.COM 	if (!nlp) {
29247917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
29257917SReza.Sabdar@Sun.COM 		return (-1);
29267917SReza.Sabdar@Sun.COM 	}
29277917SReza.Sabdar@Sun.COM 
29287917SReza.Sabdar@Sun.COM 	cmds = &nlp->nlp_cmds;
29297917SReza.Sabdar@Sun.COM 	(void) memset(cmds, 0, sizeof (*cmds));
29307917SReza.Sabdar@Sun.COM 
29317917SReza.Sabdar@Sun.COM 	xfer_size = ndmp_buffer_get_size(session);
29327917SReza.Sabdar@Sun.COM 	cmds->tcs_command = tlm_create_reader_writer_ipc(FALSE, xfer_size);
29337917SReza.Sabdar@Sun.COM 	if (!cmds->tcs_command) {
29347917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
29357917SReza.Sabdar@Sun.COM 		return (-1);
29367917SReza.Sabdar@Sun.COM 	}
29377917SReza.Sabdar@Sun.COM 
29387917SReza.Sabdar@Sun.COM 	return (0);
29397917SReza.Sabdar@Sun.COM }
29407917SReza.Sabdar@Sun.COM 
29417917SReza.Sabdar@Sun.COM 
29427917SReza.Sabdar@Sun.COM /*
29437917SReza.Sabdar@Sun.COM  * free_dar_structs_v3
29447917SReza.Sabdar@Sun.COM  *
29457917SReza.Sabdar@Sun.COM  * To free the structures were created by restore_dar_alloc_structs_v3.
29467917SReza.Sabdar@Sun.COM  * This funnction is called for each entry in restore entry list.
29477917SReza.Sabdar@Sun.COM  *
29487917SReza.Sabdar@Sun.COM  * Parameters:
29497917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
29507917SReza.Sabdar@Sun.COM  *   jname (input) - job name
29517917SReza.Sabdar@Sun.COM  *
29527917SReza.Sabdar@Sun.COM  * Returns:
29537917SReza.Sabdar@Sun.COM  *	NONE
29547917SReza.Sabdar@Sun.COM  */
29557917SReza.Sabdar@Sun.COM /*ARGSUSED*/
29567917SReza.Sabdar@Sun.COM static void
free_dar_structs_v3(ndmpd_session_t * session,char * jname)29577917SReza.Sabdar@Sun.COM free_dar_structs_v3(ndmpd_session_t *session, char *jname)
29587917SReza.Sabdar@Sun.COM {
29597917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
29607917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
29617917SReza.Sabdar@Sun.COM 
29627917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
29637917SReza.Sabdar@Sun.COM 	if (!nlp) {
29647917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
29657917SReza.Sabdar@Sun.COM 		return;
29667917SReza.Sabdar@Sun.COM 	}
29677917SReza.Sabdar@Sun.COM 	cmds = &nlp->nlp_cmds;
29687917SReza.Sabdar@Sun.COM 	if (!cmds) {
29697917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "cmds == NULL");
29707917SReza.Sabdar@Sun.COM 		return;
29717917SReza.Sabdar@Sun.COM 	}
29727917SReza.Sabdar@Sun.COM 
29737917SReza.Sabdar@Sun.COM 	if (cmds->tcs_command) {
29747917SReza.Sabdar@Sun.COM 		if (cmds->tcs_command->tc_buffers != NULL)
29757917SReza.Sabdar@Sun.COM 			tlm_release_reader_writer_ipc(cmds->tcs_command);
29767917SReza.Sabdar@Sun.COM 		else
29777917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "BUFFERS == NULL");
29787917SReza.Sabdar@Sun.COM 		cmds->tcs_command = NULL;
29797917SReza.Sabdar@Sun.COM 	} else
29807917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "COMMAND == NULL");
29817917SReza.Sabdar@Sun.COM }
29827917SReza.Sabdar@Sun.COM 
29837917SReza.Sabdar@Sun.COM 
29847917SReza.Sabdar@Sun.COM /*
29857917SReza.Sabdar@Sun.COM  * ndmp_dar_tar_init_v3
29867917SReza.Sabdar@Sun.COM  *
29877917SReza.Sabdar@Sun.COM  * Constructor for the DAR restore. Creates job name, allocates structures
29887917SReza.Sabdar@Sun.COM  * needed for keeping the statistics, and reports the start of restore action.
29897917SReza.Sabdar@Sun.COM  * It is called once for each DAR restore request.
29907917SReza.Sabdar@Sun.COM  *
29917917SReza.Sabdar@Sun.COM  * Parameters:
29927917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
29937917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
29947917SReza.Sabdar@Sun.COM  *
29957917SReza.Sabdar@Sun.COM  * Returns:
29967917SReza.Sabdar@Sun.COM  *   char pointer: on success
29977917SReza.Sabdar@Sun.COM  *   NULL: on error
29987917SReza.Sabdar@Sun.COM  */
ndmpd_dar_tar_init_v3(ndmpd_session_t * session,ndmp_lbr_params_t * nlp)29997917SReza.Sabdar@Sun.COM static char *ndmpd_dar_tar_init_v3(ndmpd_session_t *session,
30007917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp)
30017917SReza.Sabdar@Sun.COM {
30027917SReza.Sabdar@Sun.COM 	char *jname;
30037917SReza.Sabdar@Sun.COM 
30047917SReza.Sabdar@Sun.COM 	jname = ndmp_malloc(TLM_MAX_BACKUP_JOB_NAME);
30057917SReza.Sabdar@Sun.COM 
30067917SReza.Sabdar@Sun.COM 	if (!jname)
30077917SReza.Sabdar@Sun.COM 		return (NULL);
30087917SReza.Sabdar@Sun.COM 
30097917SReza.Sabdar@Sun.COM 	(void) ndmp_new_job_name(jname);
30107917SReza.Sabdar@Sun.COM 
30117917SReza.Sabdar@Sun.COM 	if (!nlp) {
30127917SReza.Sabdar@Sun.COM 		free(jname);
30137917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp == NULL");
30147917SReza.Sabdar@Sun.COM 		return (NULL);
30157917SReza.Sabdar@Sun.COM 	}
30167917SReza.Sabdar@Sun.COM 
30177917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat = tlm_new_job_stats(jname);
30187917SReza.Sabdar@Sun.COM 	if (!nlp->nlp_jstat) {
30197917SReza.Sabdar@Sun.COM 		free(jname);
30207917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Creating job stats");
30217917SReza.Sabdar@Sun.COM 		return (NULL);
30227917SReza.Sabdar@Sun.COM 	}
30237917SReza.Sabdar@Sun.COM 
30247917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat->js_start_ltime = time(NULL);
30257917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat->js_start_time = nlp->nlp_jstat->js_start_ltime;
30267917SReza.Sabdar@Sun.COM 
30277917SReza.Sabdar@Sun.COM 	nlp->nlp_logcallbacks = lbrlog_callbacks_init(session,
30287917SReza.Sabdar@Sun.COM 	    ndmpd_path_restored_v3, NULL, NULL);
30297917SReza.Sabdar@Sun.COM 	if (!nlp->nlp_logcallbacks) {
30307917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
30317917SReza.Sabdar@Sun.COM 		free(jname);
30327917SReza.Sabdar@Sun.COM 		return (NULL);
30337917SReza.Sabdar@Sun.COM 	}
30347917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat->js_callbacks = (void *)(nlp->nlp_logcallbacks);
30357917SReza.Sabdar@Sun.COM 
30367917SReza.Sabdar@Sun.COM 	nlp->nlp_rsbm = bm_alloc(nlp->nlp_nfiles, 0);
30377917SReza.Sabdar@Sun.COM 	if (nlp->nlp_rsbm < 0) {
30387917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Out of memory.");
30397917SReza.Sabdar@Sun.COM 		lbrlog_callbacks_done(nlp->nlp_logcallbacks);
30407917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
30417917SReza.Sabdar@Sun.COM 		free(jname);
30427917SReza.Sabdar@Sun.COM 		return (NULL);
30437917SReza.Sabdar@Sun.COM 	}
30447917SReza.Sabdar@Sun.COM 
30457917SReza.Sabdar@Sun.COM 	/* this is used in ndmpd_path_restored_v3() */
30467917SReza.Sabdar@Sun.COM 	nlp->nlp_lastidx = -1;
30477917SReza.Sabdar@Sun.COM 
30487917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "Restoring from %s tape(s).",
30497917SReza.Sabdar@Sun.COM 	    ndmp_data_get_mover_mode(session));
30507917SReza.Sabdar@Sun.COM 
30517917SReza.Sabdar@Sun.COM 	return (jname);
30527917SReza.Sabdar@Sun.COM }
30537917SReza.Sabdar@Sun.COM 
30547917SReza.Sabdar@Sun.COM /*
30557917SReza.Sabdar@Sun.COM  * ndmpd_dar_tar_end_v3
30567917SReza.Sabdar@Sun.COM  *
30577917SReza.Sabdar@Sun.COM  * Deconstructor for the DAR restore. This function is called once per
30587917SReza.Sabdar@Sun.COM  * DAR request. It deallocates memories allocated by ndmpd_dar_tar_init_v3.
30597917SReza.Sabdar@Sun.COM  *
30607917SReza.Sabdar@Sun.COM  * Parameters:
30617917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
30627917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
30637917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
30647917SReza.Sabdar@Sun.COM  *   jname(input) - job name
30657917SReza.Sabdar@Sun.COM  *
30667917SReza.Sabdar@Sun.COM  * Returns:
30677917SReza.Sabdar@Sun.COM  *   0: on success
30687917SReza.Sabdar@Sun.COM  *   -1: on error
30697917SReza.Sabdar@Sun.COM  */
ndmpd_dar_tar_end_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp,char * jname)30707917SReza.Sabdar@Sun.COM static int ndmpd_dar_tar_end_v3(ndmpd_session_t *session,
30717917SReza.Sabdar@Sun.COM     ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp, char *jname)
30727917SReza.Sabdar@Sun.COM {
30737917SReza.Sabdar@Sun.COM 	int err = 0;
30747917SReza.Sabdar@Sun.COM 
30757917SReza.Sabdar@Sun.COM 
30767917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "lastidx %d", nlp->nlp_lastidx);
30777917SReza.Sabdar@Sun.COM 
30787917SReza.Sabdar@Sun.COM 	/* nothing restored. */
30797917SReza.Sabdar@Sun.COM 	(void) send_unrecovered_list_v3(params, nlp);
30807917SReza.Sabdar@Sun.COM 
30817917SReza.Sabdar@Sun.COM 	if (nlp->nlp_jstat) {
30827917SReza.Sabdar@Sun.COM 		nlp->nlp_bytes_total =
30837917SReza.Sabdar@Sun.COM 		    (u_longlong_t)nlp->nlp_jstat->js_bytes_total;
30847917SReza.Sabdar@Sun.COM 		tlm_un_ref_job_stats(jname);
30857917SReza.Sabdar@Sun.COM 		nlp->nlp_jstat = NULL;
30867917SReza.Sabdar@Sun.COM 	} else {
30877917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "JSTAT == NULL");
30887917SReza.Sabdar@Sun.COM 	}
30897917SReza.Sabdar@Sun.COM 
30907917SReza.Sabdar@Sun.COM 	if (nlp->nlp_logcallbacks) {
30917917SReza.Sabdar@Sun.COM 		lbrlog_callbacks_done(nlp->nlp_logcallbacks);
30927917SReza.Sabdar@Sun.COM 		nlp->nlp_logcallbacks = NULL;
30937917SReza.Sabdar@Sun.COM 	} else {
30947917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "FH CALLBACKS == NULL");
30957917SReza.Sabdar@Sun.COM 	}
30967917SReza.Sabdar@Sun.COM 
30977917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_abort) {
30987917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" aborted.",
30997917SReza.Sabdar@Sun.COM 		    (nlp->nlp_restore_path) ? nlp->nlp_restore_path : "NULL");
31007917SReza.Sabdar@Sun.COM 		err = EINTR;
31017917SReza.Sabdar@Sun.COM 	} else {
31027917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" finished. (%d)",
31037917SReza.Sabdar@Sun.COM 		    (nlp->nlp_restore_path) ? nlp->nlp_restore_path :
31047917SReza.Sabdar@Sun.COM 		    "NULL", err);
31057917SReza.Sabdar@Sun.COM 	}
31067917SReza.Sabdar@Sun.COM 
31077917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_operation == NDMP_DATA_OP_RECOVER) {
31087917SReza.Sabdar@Sun.COM 		if (nlp->nlp_rsbm < 0) {
31097917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "nlp_rsbm < 0 %d", nlp->nlp_rsbm);
31107917SReza.Sabdar@Sun.COM 		} else {
31117917SReza.Sabdar@Sun.COM 			(void) bm_free(nlp->nlp_rsbm);
31127917SReza.Sabdar@Sun.COM 			nlp->nlp_rsbm = -1;
31137917SReza.Sabdar@Sun.COM 		}
31147917SReza.Sabdar@Sun.COM 	}
31157917SReza.Sabdar@Sun.COM 
31167917SReza.Sabdar@Sun.COM 	free(jname);
31177917SReza.Sabdar@Sun.COM 
31187917SReza.Sabdar@Sun.COM 	return (err);
31197917SReza.Sabdar@Sun.COM }
31207917SReza.Sabdar@Sun.COM 
31217917SReza.Sabdar@Sun.COM 
31227917SReza.Sabdar@Sun.COM /*
31237917SReza.Sabdar@Sun.COM  * ndmpd_dar_tar_v3
31247917SReza.Sabdar@Sun.COM  *
31257917SReza.Sabdar@Sun.COM  * This function is called for each entry in DAR entry list. The window
31267917SReza.Sabdar@Sun.COM  * is already located and we should be in the right position to read
31277917SReza.Sabdar@Sun.COM  * the data from the tape.
31287917SReza.Sabdar@Sun.COM  * For each entry we setup selection list; so that, if the file name from
31297917SReza.Sabdar@Sun.COM  * tape is not as the name client asked for, error be returned.
31307917SReza.Sabdar@Sun.COM  *
31317917SReza.Sabdar@Sun.COM  * Parameters:
31327917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
31337917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
31347917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
31357917SReza.Sabdar@Sun.COM  *   jname (input) - job name
31367917SReza.Sabdar@Sun.COM  *   dar_index(input) - Index of this entry in the restore list
31377917SReza.Sabdar@Sun.COM  *
31387917SReza.Sabdar@Sun.COM  * Returns:
31397917SReza.Sabdar@Sun.COM  *   0: on success
31407917SReza.Sabdar@Sun.COM  *   -1: on error
31417917SReza.Sabdar@Sun.COM  */
31427917SReza.Sabdar@Sun.COM static int
ndmpd_dar_tar_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp,char * jname,int dar_index)31437917SReza.Sabdar@Sun.COM ndmpd_dar_tar_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
31447917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp, char *jname, int dar_index)
31457917SReza.Sabdar@Sun.COM {
31467917SReza.Sabdar@Sun.COM 	char *excl;
31477917SReza.Sabdar@Sun.COM 	char **sels;
31487917SReza.Sabdar@Sun.COM 	int flags;
31497917SReza.Sabdar@Sun.COM 	int err;
31507917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
31517917SReza.Sabdar@Sun.COM 	struct rs_name_maker rn;
31527917SReza.Sabdar@Sun.COM 	int data_addr_type = session->ns_data.dd_data_addr.addr_type;
31537917SReza.Sabdar@Sun.COM 	ndmp_tar_reader_arg_t arg;
31547917SReza.Sabdar@Sun.COM 	pthread_t rdtp;
31557917SReza.Sabdar@Sun.COM 	ndmp_context_t nctx;
31568193SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
31577917SReza.Sabdar@Sun.COM 
31587917SReza.Sabdar@Sun.COM 	err = 0;
31597917SReza.Sabdar@Sun.COM 
31607917SReza.Sabdar@Sun.COM 	/*
31617917SReza.Sabdar@Sun.COM 	 * We have to allocate and deallocate buffers every time we
31627917SReza.Sabdar@Sun.COM 	 * run the restore, for we need to flush the buffers.
31637917SReza.Sabdar@Sun.COM 	 */
31647917SReza.Sabdar@Sun.COM 	if (restore_dar_alloc_structs_v3(session, jname) < 0)
31657917SReza.Sabdar@Sun.COM 		return (-1);
31667917SReza.Sabdar@Sun.COM 
31677917SReza.Sabdar@Sun.COM 	sels = setupsels(session, params, nlp, dar_index);
31687917SReza.Sabdar@Sun.COM 	if (!sels) {
31697917SReza.Sabdar@Sun.COM 		free_dar_structs_v3(session, jname);
31707917SReza.Sabdar@Sun.COM 		return (-1);
31717917SReza.Sabdar@Sun.COM 	}
31727917SReza.Sabdar@Sun.COM 	excl = NULL;
31737917SReza.Sabdar@Sun.COM 	flags = RSFLG_OVR_ALWAYS;
31747917SReza.Sabdar@Sun.COM 	rn.rn_nlp = nlp;
31757917SReza.Sabdar@Sun.COM 	rn.rn_fp = mknewname;
31767917SReza.Sabdar@Sun.COM 
31777917SReza.Sabdar@Sun.COM 	if (!session->ns_data.dd_abort) {
31787917SReza.Sabdar@Sun.COM 		cmds = &nlp->nlp_cmds;
31797917SReza.Sabdar@Sun.COM 		cmds->tcs_reader = cmds->tcs_writer = TLM_RESTORE_RUN;
31807917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_reader = TLM_RESTORE_RUN;
31817917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_writer = TLM_RESTORE_RUN;
31827917SReza.Sabdar@Sun.COM 
31837917SReza.Sabdar@Sun.COM 		arg.tr_session = session;
31847917SReza.Sabdar@Sun.COM 		arg.tr_mod_params = params;
31857917SReza.Sabdar@Sun.COM 		arg.tr_cmds = cmds;
31867917SReza.Sabdar@Sun.COM 
31877917SReza.Sabdar@Sun.COM 		err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader,
31887917SReza.Sabdar@Sun.COM 		    (void *)&arg);
31897917SReza.Sabdar@Sun.COM 		if (err == 0) {
31907917SReza.Sabdar@Sun.COM 			tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER);
31917917SReza.Sabdar@Sun.COM 		} else {
31927917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "launch ndmp_tar_reader: %m");
31937917SReza.Sabdar@Sun.COM 			return (-1);
31947917SReza.Sabdar@Sun.COM 		}
31957917SReza.Sabdar@Sun.COM 
31967917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_ref++;
31977917SReza.Sabdar@Sun.COM 		cmds->tcs_writer_count++;
31987917SReza.Sabdar@Sun.COM 
31997917SReza.Sabdar@Sun.COM 		/* Plug-in module */
32007917SReza.Sabdar@Sun.COM 		if (ndmp_pl != NULL &&
32017917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_pre_restore != NULL) {
320212186SJanice.Chang@Sun.COM 			(void) memset(&nctx, 0, sizeof (ndmp_context_t));
32037917SReza.Sabdar@Sun.COM 			nctx.nc_cmds = cmds;
320411170SReza.Sabdar@Sun.COM 			nctx.nc_params = params;
320512186SJanice.Chang@Sun.COM 			nctx.nc_ddata = (void *) session;
32068193SReza.Sabdar@Sun.COM 			ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params,
32078193SReza.Sabdar@Sun.COM 			    dar_index - 1);
32088193SReza.Sabdar@Sun.COM 
32097917SReza.Sabdar@Sun.COM 			if ((err = ndmp_pl->np_pre_restore(ndmp_pl, &nctx,
32108193SReza.Sabdar@Sun.COM 			    ep->nm3_opath, ep->nm3_dpath))
32117917SReza.Sabdar@Sun.COM 			    != 0) {
321211170SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_ERR, "Pre-restore plug-in: %m");
32137917SReza.Sabdar@Sun.COM 				cmds->tcs_command->tc_reader = TLM_STOP;
32147917SReza.Sabdar@Sun.COM 				ndmp_stop_local_reader(session, cmds);
32157917SReza.Sabdar@Sun.COM 				ndmp_wait_for_reader(cmds);
32167917SReza.Sabdar@Sun.COM 				(void) pthread_join(rdtp, NULL);
32177917SReza.Sabdar@Sun.COM 				ndmp_stop_remote_reader(session);
32187917SReza.Sabdar@Sun.COM 				goto restore_out;
32197917SReza.Sabdar@Sun.COM 			}
32207917SReza.Sabdar@Sun.COM 		}
32217917SReza.Sabdar@Sun.COM 
32227917SReza.Sabdar@Sun.COM 		if (tm_tar_ops.tm_getdir != NULL) {
32237917SReza.Sabdar@Sun.COM 			err = (tm_tar_ops.tm_getdir)(cmds, cmds->tcs_command,
32247917SReza.Sabdar@Sun.COM 			    nlp->nlp_jstat, &rn, 1, 1, sels, &excl, flags,
322511804SReza.Sabdar@Sun.COM 			    dar_index, nlp->nlp_backup_path,
322611804SReza.Sabdar@Sun.COM 			    session->hardlink_q);
32277917SReza.Sabdar@Sun.COM 		}
32287917SReza.Sabdar@Sun.COM 
32297917SReza.Sabdar@Sun.COM 		cmds->tcs_writer_count--;
32307917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_ref--;
32317917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_reader = TLM_STOP;
32327917SReza.Sabdar@Sun.COM 
32337917SReza.Sabdar@Sun.COM 
32347917SReza.Sabdar@Sun.COM 		/*
32357917SReza.Sabdar@Sun.COM 		 * If it is a two-way restore then we stop the reader.
32367917SReza.Sabdar@Sun.COM 		 */
32377917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "stop local reader.");
32387917SReza.Sabdar@Sun.COM 		ndmp_stop_local_reader(session, cmds);
32397917SReza.Sabdar@Sun.COM 
32407917SReza.Sabdar@Sun.COM 		ndmp_wait_for_reader(cmds);
32417917SReza.Sabdar@Sun.COM 		(void) pthread_join(rdtp, NULL);
32427917SReza.Sabdar@Sun.COM 
32437917SReza.Sabdar@Sun.COM 		/*
32447917SReza.Sabdar@Sun.COM 		 * If this is the last DAR entry and it is a three-way
32457917SReza.Sabdar@Sun.COM 		 * restore then we should close the connection.
32467917SReza.Sabdar@Sun.COM 		 */
32477917SReza.Sabdar@Sun.COM 		if ((data_addr_type == NDMP_ADDR_TCP) &&
32487917SReza.Sabdar@Sun.COM 		    (dar_index == (int)session->ns_data.dd_nlist_len)) {
32497917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "stop remote reader.");
32507917SReza.Sabdar@Sun.COM 			ndmp_stop_remote_reader(session);
32517917SReza.Sabdar@Sun.COM 		}
32527917SReza.Sabdar@Sun.COM 
32537917SReza.Sabdar@Sun.COM 		/* exit as if there was an internal error */
32547917SReza.Sabdar@Sun.COM 		if (session->ns_eof)
32557917SReza.Sabdar@Sun.COM 			err = -1;
32567917SReza.Sabdar@Sun.COM restore_out:
32577917SReza.Sabdar@Sun.COM 		/* Plug-in module */
32587917SReza.Sabdar@Sun.COM 		if (ndmp_pl != NULL &&
32597917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_post_restore != NULL &&
32607917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_post_restore(ndmp_pl, &nctx, err) == -1) {
32617917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Post-restore plug-in: %m");
32627917SReza.Sabdar@Sun.COM 			err = -1;
32637917SReza.Sabdar@Sun.COM 		}
32647917SReza.Sabdar@Sun.COM 	}
32657917SReza.Sabdar@Sun.COM 
32667917SReza.Sabdar@Sun.COM 	NDMP_FREE(sels);
32677917SReza.Sabdar@Sun.COM 
32687917SReza.Sabdar@Sun.COM 	free_dar_structs_v3(session, jname);
32697917SReza.Sabdar@Sun.COM 
32707917SReza.Sabdar@Sun.COM 	return (err);
32717917SReza.Sabdar@Sun.COM }
32727917SReza.Sabdar@Sun.COM 
32737917SReza.Sabdar@Sun.COM /*
32747917SReza.Sabdar@Sun.COM  * ndmpd_dar_locate_windwos_v3
32757917SReza.Sabdar@Sun.COM  *
32767917SReza.Sabdar@Sun.COM  * Locating the right window in which the requested file is backed up.
32777917SReza.Sabdar@Sun.COM  * We should go through windows to find the exact location, for the
32787917SReza.Sabdar@Sun.COM  * file can be located in for example 10th window after the current window.
32797917SReza.Sabdar@Sun.COM  *
32807917SReza.Sabdar@Sun.COM  * Parameters:
32817917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
32827917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
32837917SReza.Sabdar@Sun.COM  *   fh_info (input) - index from the beginning of the backup stream
32847917SReza.Sabdar@Sun.COM  *   len (input) - Length of the mover window
32857917SReza.Sabdar@Sun.COM  *
32867917SReza.Sabdar@Sun.COM  * Returns:
32877917SReza.Sabdar@Sun.COM  *   0: on success
32887917SReza.Sabdar@Sun.COM  *   -1: on error
32897917SReza.Sabdar@Sun.COM  */
32908193SReza.Sabdar@Sun.COM static int
ndmpd_dar_locate_window_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,u_longlong_t fh_info,u_longlong_t len)32918193SReza.Sabdar@Sun.COM ndmpd_dar_locate_window_v3(ndmpd_session_t *session,
32928193SReza.Sabdar@Sun.COM     ndmpd_module_params_t *params, u_longlong_t fh_info, u_longlong_t len)
32937917SReza.Sabdar@Sun.COM {
32947917SReza.Sabdar@Sun.COM 	int ret = 0;
32957917SReza.Sabdar@Sun.COM 
32967917SReza.Sabdar@Sun.COM 
32977917SReza.Sabdar@Sun.COM 	for (; ; ) {
32987917SReza.Sabdar@Sun.COM 		ret = (*params->mp_seek_func)(session, fh_info, len);
32997917SReza.Sabdar@Sun.COM 
33007917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "ret %d", ret);
33017917SReza.Sabdar@Sun.COM 		if (ret == 0) /* Seek was done successfully */
33027917SReza.Sabdar@Sun.COM 			break;
33037917SReza.Sabdar@Sun.COM 		else if (ret < 0) {
33047917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Seek error");
33057917SReza.Sabdar@Sun.COM 			break;
33067917SReza.Sabdar@Sun.COM 		}
33077917SReza.Sabdar@Sun.COM 
33087917SReza.Sabdar@Sun.COM 		/*
33097917SReza.Sabdar@Sun.COM 		 * DMA moved to a new window.
33107917SReza.Sabdar@Sun.COM 		 * If we are reading the remainig of the file from
33117917SReza.Sabdar@Sun.COM 		 * new window, seek is handled by ndmpd_local_read_v3.
33127917SReza.Sabdar@Sun.COM 		 * Here we should continue the seek inside the new
33137917SReza.Sabdar@Sun.COM 		 * window.
33147917SReza.Sabdar@Sun.COM 		 */
33157917SReza.Sabdar@Sun.COM 		continue;
33167917SReza.Sabdar@Sun.COM 	}
33177917SReza.Sabdar@Sun.COM 	return (ret);
33187917SReza.Sabdar@Sun.COM }
33197917SReza.Sabdar@Sun.COM 
33207917SReza.Sabdar@Sun.COM /*
33217917SReza.Sabdar@Sun.COM  * ndmpd_rs_dar_tar_v3
33227917SReza.Sabdar@Sun.COM  *
33237917SReza.Sabdar@Sun.COM  * Main DAR function. It calls the constructor, then for each entry it
33247917SReza.Sabdar@Sun.COM  * calls the locate_window_v3 to find the exact position of the file. Then
33257917SReza.Sabdar@Sun.COM  * it restores the file.
33267917SReza.Sabdar@Sun.COM  * When all restore requests are done it calls the deconstructor to clean
33277917SReza.Sabdar@Sun.COM  * everything up.
33287917SReza.Sabdar@Sun.COM  *
33297917SReza.Sabdar@Sun.COM  * Parameters:
33307917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
33317917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
33327917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
33337917SReza.Sabdar@Sun.COM  *
33347917SReza.Sabdar@Sun.COM  * Returns:
33357917SReza.Sabdar@Sun.COM  *   0: on success
33367917SReza.Sabdar@Sun.COM  *   -1: on error
33377917SReza.Sabdar@Sun.COM  */
33387917SReza.Sabdar@Sun.COM static int
ndmpd_rs_dar_tar_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)33397917SReza.Sabdar@Sun.COM ndmpd_rs_dar_tar_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
33407917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp)
33417917SReza.Sabdar@Sun.COM {
33427917SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
33437917SReza.Sabdar@Sun.COM 	u_longlong_t len;
33447917SReza.Sabdar@Sun.COM 	char *jname;
33457917SReza.Sabdar@Sun.COM 	int n = session->ns_data.dd_nlist_len;
33467917SReza.Sabdar@Sun.COM 	int i, ret = 0;
33477917SReza.Sabdar@Sun.COM 	int result = 0;
33487917SReza.Sabdar@Sun.COM 
33497917SReza.Sabdar@Sun.COM 	jname = ndmpd_dar_tar_init_v3(session, nlp);
33507917SReza.Sabdar@Sun.COM 
33517917SReza.Sabdar@Sun.COM 	if (!jname)
33527917SReza.Sabdar@Sun.COM 		return (-1);
33537917SReza.Sabdar@Sun.COM 
33547917SReza.Sabdar@Sun.COM 	/*
33557917SReza.Sabdar@Sun.COM 	 * We set the length = sizeof (tlm_tar_hdr_t)
33567917SReza.Sabdar@Sun.COM 	 * This is important for three-way DAR restore, for we should
33577917SReza.Sabdar@Sun.COM 	 * read the header first (If we ask for more data then we have
33587917SReza.Sabdar@Sun.COM 	 * to read and discard the remaining data in the socket)
33597917SReza.Sabdar@Sun.COM 	 */
33607917SReza.Sabdar@Sun.COM 	len = tlm_tarhdr_size();
33617917SReza.Sabdar@Sun.COM 
33627917SReza.Sabdar@Sun.COM 	for (i = 0; i < n; ++i) {
33637917SReza.Sabdar@Sun.COM 		ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, i);
33647917SReza.Sabdar@Sun.COM 		if (!ep) {
33657917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "ep NULL, i %d", i);
33667917SReza.Sabdar@Sun.COM 			continue;
33677917SReza.Sabdar@Sun.COM 		}
33687917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
33697917SReza.Sabdar@Sun.COM 		    "restoring opath %s, dpath %s, fh_info %lld",
33707917SReza.Sabdar@Sun.COM 		    ep->nm3_opath ? ep->nm3_opath : "NULL",
33717917SReza.Sabdar@Sun.COM 		    ep->nm3_dpath ? ep->nm3_dpath : "NULL",
33727917SReza.Sabdar@Sun.COM 		    ep->nm3_fh_info);
33737917SReza.Sabdar@Sun.COM 
33747917SReza.Sabdar@Sun.COM 		/*
33757917SReza.Sabdar@Sun.COM 		 * We should seek till finding the window in which file
33767917SReza.Sabdar@Sun.COM 		 * is located.
33777917SReza.Sabdar@Sun.COM 		 */
33787917SReza.Sabdar@Sun.COM 		ret = ndmpd_dar_locate_window_v3(session, params,
33797917SReza.Sabdar@Sun.COM 		    ep->nm3_fh_info, len);
33807917SReza.Sabdar@Sun.COM 
33817917SReza.Sabdar@Sun.COM 		if (ret < 0) /* If seek fails, restore should be aborted */
33827917SReza.Sabdar@Sun.COM 			break;
33837917SReza.Sabdar@Sun.COM 		/*
33847917SReza.Sabdar@Sun.COM 		 * We are inside the target window.
33857917SReza.Sabdar@Sun.COM 		 * for each restore we will use one entry as selection list
33867917SReza.Sabdar@Sun.COM 		 */
33877917SReza.Sabdar@Sun.COM 		if ((ret = ndmpd_dar_tar_v3(session, params, nlp, jname, i+1))
33887917SReza.Sabdar@Sun.COM 		    != 0)
33897917SReza.Sabdar@Sun.COM 			result = EIO;
33907917SReza.Sabdar@Sun.COM 		ndmpd_audit_restore(session->ns_connection,
33917917SReza.Sabdar@Sun.COM 		    ep->nm3_opath ? ep->nm3_opath : "NULL",
33927917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_data_addr.addr_type,
33937917SReza.Sabdar@Sun.COM 		    session->ns_tape.td_adapter_name, result);
33947917SReza.Sabdar@Sun.COM 	}
33957917SReza.Sabdar@Sun.COM 
33967917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "End of restore list");
33977917SReza.Sabdar@Sun.COM 
33987917SReza.Sabdar@Sun.COM 	(void) ndmpd_dar_tar_end_v3(session, params, nlp, jname);
33997917SReza.Sabdar@Sun.COM 
34007917SReza.Sabdar@Sun.COM 	return (ret);
34017917SReza.Sabdar@Sun.COM }
34027917SReza.Sabdar@Sun.COM 
34037917SReza.Sabdar@Sun.COM /*
34047917SReza.Sabdar@Sun.COM  * ndmp_plugin_pre_restore
34057917SReza.Sabdar@Sun.COM  *
34067917SReza.Sabdar@Sun.COM  * Wrapper for pre-restore callback with multiple path
34077917SReza.Sabdar@Sun.COM  */
34087917SReza.Sabdar@Sun.COM static int
ndmp_plugin_pre_restore(ndmp_context_t * ctxp,ndmpd_module_params_t * params,int ncount)34098193SReza.Sabdar@Sun.COM ndmp_plugin_pre_restore(ndmp_context_t *ctxp, ndmpd_module_params_t *params,
34108193SReza.Sabdar@Sun.COM     int ncount)
34117917SReza.Sabdar@Sun.COM {
34128193SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *ep;
34137917SReza.Sabdar@Sun.COM 	int err;
34148193SReza.Sabdar@Sun.COM 	int i;
34158193SReza.Sabdar@Sun.COM 
34168193SReza.Sabdar@Sun.COM 	for (i = 0; i < ncount; i++) {
34178193SReza.Sabdar@Sun.COM 		if (!(ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, i)))
34188193SReza.Sabdar@Sun.COM 			continue;
34197917SReza.Sabdar@Sun.COM 		if ((err = ndmp_pl->np_pre_restore(ndmp_pl, ctxp,
34208193SReza.Sabdar@Sun.COM 		    ep->nm3_opath, ep->nm3_dpath)) != 0)
34217917SReza.Sabdar@Sun.COM 			return (err);
34227917SReza.Sabdar@Sun.COM 	}
34238193SReza.Sabdar@Sun.COM 
34247917SReza.Sabdar@Sun.COM 	return (0);
34257917SReza.Sabdar@Sun.COM }
34267917SReza.Sabdar@Sun.COM 
342711170SReza.Sabdar@Sun.COM /*
342811804SReza.Sabdar@Sun.COM  * get_absolute_path
342911804SReza.Sabdar@Sun.COM  *
343011804SReza.Sabdar@Sun.COM  * Get resolved path name which does not involve ".", ".." or extra
343111804SReza.Sabdar@Sun.COM  * "/" or symbolic links.
343211804SReza.Sabdar@Sun.COM  *
343311804SReza.Sabdar@Sun.COM  * e.g.
343411804SReza.Sabdar@Sun.COM  *
343511804SReza.Sabdar@Sun.COM  * /backup/path/ -> /backup/path
343611804SReza.Sabdar@Sun.COM  * /backup/path/. -> /backup/path
343711804SReza.Sabdar@Sun.COM  * /backup/path/../path/ -> /backup/path
343811804SReza.Sabdar@Sun.COM  * /link-to-backup-path -> /backup/path
343911804SReza.Sabdar@Sun.COM  *
344011804SReza.Sabdar@Sun.COM  * Returns:
344111804SReza.Sabdar@Sun.COM  * 	Pointer to the new path (allocated)
344211804SReza.Sabdar@Sun.COM  * 	NULL if the path doesnt exist
344311804SReza.Sabdar@Sun.COM  */
344411804SReza.Sabdar@Sun.COM static char *
get_absolute_path(const char * bkpath)344511804SReza.Sabdar@Sun.COM get_absolute_path(const char *bkpath)
344611804SReza.Sabdar@Sun.COM {
344711804SReza.Sabdar@Sun.COM 	char *pbuf;
344811804SReza.Sabdar@Sun.COM 	char *rv;
344911804SReza.Sabdar@Sun.COM 
345011804SReza.Sabdar@Sun.COM 	if (!(pbuf = ndmp_malloc(TLM_MAX_PATH_NAME)))
345111804SReza.Sabdar@Sun.COM 		return (NULL);
345211804SReza.Sabdar@Sun.COM 
345311804SReza.Sabdar@Sun.COM 	if ((rv = realpath(bkpath, pbuf)) == NULL) {
345411804SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid path [%s] err=%d",
345511804SReza.Sabdar@Sun.COM 		    bkpath, errno);
345611804SReza.Sabdar@Sun.COM 	}
345711804SReza.Sabdar@Sun.COM 	return (rv);
345811804SReza.Sabdar@Sun.COM }
345911804SReza.Sabdar@Sun.COM 
346011804SReza.Sabdar@Sun.COM /*
346111170SReza.Sabdar@Sun.COM  * Expands the format string and logs the resulting message to the
346211170SReza.Sabdar@Sun.COM  * remote DMA
346311170SReza.Sabdar@Sun.COM  */
346411170SReza.Sabdar@Sun.COM void
ndmp_log_dma(ndmp_context_t * nctx,ndmp_log_dma_type_t lt,const char * fmt,...)346511170SReza.Sabdar@Sun.COM ndmp_log_dma(ndmp_context_t *nctx, ndmp_log_dma_type_t lt, const char *fmt, ...)
346611170SReza.Sabdar@Sun.COM {
346711170SReza.Sabdar@Sun.COM 	va_list ap;
346811170SReza.Sabdar@Sun.COM 	char buf[256];
346911170SReza.Sabdar@Sun.COM 	ndmpd_module_params_t *params;
347011170SReza.Sabdar@Sun.COM 
347111170SReza.Sabdar@Sun.COM 	if (nctx == NULL ||
347211170SReza.Sabdar@Sun.COM 	    (params = (ndmpd_module_params_t *)nctx->nc_params) == NULL)
347311170SReza.Sabdar@Sun.COM 		return;
347411170SReza.Sabdar@Sun.COM 
347511170SReza.Sabdar@Sun.COM 	va_start(ap, fmt);
347611170SReza.Sabdar@Sun.COM 	(void) vsnprintf(buf, sizeof (buf), fmt, ap);
347711170SReza.Sabdar@Sun.COM 	va_end(ap);
347811170SReza.Sabdar@Sun.COM 
347911170SReza.Sabdar@Sun.COM 	MOD_LOGV3(params, (ndmp_log_type)lt, "%s", buf);
348011170SReza.Sabdar@Sun.COM }
348111170SReza.Sabdar@Sun.COM 
34827917SReza.Sabdar@Sun.COM 
34837917SReza.Sabdar@Sun.COM /*
34847917SReza.Sabdar@Sun.COM  * ndmpd_rs_sar_tar_v3
34857917SReza.Sabdar@Sun.COM  *
34867917SReza.Sabdar@Sun.COM  * Main non-DAR restore function. It will try to restore all the entries
34877917SReza.Sabdar@Sun.COM  * that have been backed up.
34887917SReza.Sabdar@Sun.COM  *
34897917SReza.Sabdar@Sun.COM  * Parameters:
34907917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
34917917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
34927917SReza.Sabdar@Sun.COM  *   nlp (input) - pointer to the nlp structure
34937917SReza.Sabdar@Sun.COM  *
34947917SReza.Sabdar@Sun.COM  * Returns:
34957917SReza.Sabdar@Sun.COM  *   0: on success
34967917SReza.Sabdar@Sun.COM  *   -1: on error
34977917SReza.Sabdar@Sun.COM  */
34987917SReza.Sabdar@Sun.COM static int
ndmpd_rs_sar_tar_v3(ndmpd_session_t * session,ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp)34997917SReza.Sabdar@Sun.COM ndmpd_rs_sar_tar_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
35007917SReza.Sabdar@Sun.COM     ndmp_lbr_params_t *nlp)
35017917SReza.Sabdar@Sun.COM {
35027917SReza.Sabdar@Sun.COM 	char jname[TLM_MAX_BACKUP_JOB_NAME];
35037917SReza.Sabdar@Sun.COM 	char *excl;
35047917SReza.Sabdar@Sun.COM 	char **sels;
35057917SReza.Sabdar@Sun.COM 	int flags;
35067917SReza.Sabdar@Sun.COM 	int err;
35077917SReza.Sabdar@Sun.COM 	tlm_commands_t *cmds;
35087917SReza.Sabdar@Sun.COM 	struct rs_name_maker rn;
35097917SReza.Sabdar@Sun.COM 	ndmp_tar_reader_arg_t arg;
35107917SReza.Sabdar@Sun.COM 	pthread_t rdtp;
35117917SReza.Sabdar@Sun.COM 	int result;
35127917SReza.Sabdar@Sun.COM 	ndmp_context_t nctx;
35137917SReza.Sabdar@Sun.COM 
35147917SReza.Sabdar@Sun.COM 	result = err = 0;
35157917SReza.Sabdar@Sun.COM 	(void) ndmp_new_job_name(jname);
35167917SReza.Sabdar@Sun.COM 	if (restore_alloc_structs_v3(session, jname) < 0)
35177917SReza.Sabdar@Sun.COM 		return (-1);
35187917SReza.Sabdar@Sun.COM 
35197917SReza.Sabdar@Sun.COM 	sels = setupsels(session, params, nlp, 0);
35207917SReza.Sabdar@Sun.COM 	if (!sels) {
35217917SReza.Sabdar@Sun.COM 		free_structs_v3(session, jname);
35227917SReza.Sabdar@Sun.COM 		return (-1);
35237917SReza.Sabdar@Sun.COM 	}
35247917SReza.Sabdar@Sun.COM 	excl = NULL;
35257917SReza.Sabdar@Sun.COM 	flags = RSFLG_OVR_ALWAYS;
35267917SReza.Sabdar@Sun.COM 	rn.rn_nlp = nlp;
35277917SReza.Sabdar@Sun.COM 	rn.rn_fp = mknewname;
35287917SReza.Sabdar@Sun.COM 
35297917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat->js_start_ltime = time(NULL);
35307917SReza.Sabdar@Sun.COM 	nlp->nlp_jstat->js_start_time = nlp->nlp_jstat->js_start_ltime;
35317917SReza.Sabdar@Sun.COM 
35327917SReza.Sabdar@Sun.COM 	if (!session->ns_data.dd_abort && !session->ns_data.dd_abort) {
35337917SReza.Sabdar@Sun.COM 		cmds = &nlp->nlp_cmds;
35347917SReza.Sabdar@Sun.COM 		cmds->tcs_reader = cmds->tcs_writer = TLM_RESTORE_RUN;
35357917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_reader = TLM_RESTORE_RUN;
35367917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_writer = TLM_RESTORE_RUN;
35377917SReza.Sabdar@Sun.COM 
35387917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" started.",
35397917SReza.Sabdar@Sun.COM 		    (nlp->nlp_restore_path) ? nlp->nlp_restore_path : "NULL");
35407917SReza.Sabdar@Sun.COM 
35417917SReza.Sabdar@Sun.COM 		arg.tr_session = session;
35427917SReza.Sabdar@Sun.COM 		arg.tr_mod_params = params;
35437917SReza.Sabdar@Sun.COM 		arg.tr_cmds = cmds;
35447917SReza.Sabdar@Sun.COM 		err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader,
35457917SReza.Sabdar@Sun.COM 		    (void *)&arg);
35467917SReza.Sabdar@Sun.COM 		if (err == 0) {
35477917SReza.Sabdar@Sun.COM 			tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER);
35487917SReza.Sabdar@Sun.COM 		} else {
35497917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Launch ndmp_tar_reader: %m");
35507917SReza.Sabdar@Sun.COM 			free_structs_v3(session, jname);
35517917SReza.Sabdar@Sun.COM 			return (-1);
35527917SReza.Sabdar@Sun.COM 		}
35537917SReza.Sabdar@Sun.COM 
35547917SReza.Sabdar@Sun.COM 		if (!ndmp_check_utf8magic(cmds->tcs_command)) {
35557917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "UTF8Magic not found!");
35567917SReza.Sabdar@Sun.COM 		} else {
35577917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "UTF8Magic found");
35587917SReza.Sabdar@Sun.COM 		}
35597917SReza.Sabdar@Sun.COM 
35607917SReza.Sabdar@Sun.COM 		/* Plug-in module */
35617917SReza.Sabdar@Sun.COM 		if (ndmp_pl != NULL &&
35627917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_pre_restore != NULL) {
356312186SJanice.Chang@Sun.COM 			(void) memset(&nctx, 0, sizeof (ndmp_context_t));
35647917SReza.Sabdar@Sun.COM 			nctx.nc_cmds = cmds;
356511170SReza.Sabdar@Sun.COM 			nctx.nc_params = params;
356612186SJanice.Chang@Sun.COM 			nctx.nc_ddata = (void *) session;
35678193SReza.Sabdar@Sun.COM 			if ((err = ndmp_plugin_pre_restore(&nctx, params,
35688193SReza.Sabdar@Sun.COM 			    nlp->nlp_nfiles))
35697917SReza.Sabdar@Sun.COM 			    != 0) {
357011170SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_ERR, "Pre-restore plug-in: %m");
35717917SReza.Sabdar@Sun.COM 				cmds->tcs_command->tc_reader = TLM_STOP;
35727917SReza.Sabdar@Sun.COM 				ndmp_stop_local_reader(session, cmds);
35737917SReza.Sabdar@Sun.COM 				ndmp_wait_for_reader(cmds);
35747917SReza.Sabdar@Sun.COM 				(void) pthread_join(rdtp, NULL);
35757917SReza.Sabdar@Sun.COM 				ndmp_stop_remote_reader(session);
35767917SReza.Sabdar@Sun.COM 				goto restore_out;
35777917SReza.Sabdar@Sun.COM 			}
35787917SReza.Sabdar@Sun.COM 		}
35797917SReza.Sabdar@Sun.COM 
35807917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_ref++;
35817917SReza.Sabdar@Sun.COM 		cmds->tcs_writer_count++;
35827917SReza.Sabdar@Sun.COM 
35837917SReza.Sabdar@Sun.COM 		if (tm_tar_ops.tm_getdir != NULL)
35847917SReza.Sabdar@Sun.COM 			err = (tm_tar_ops.tm_getdir)(cmds, cmds->tcs_command,
35857917SReza.Sabdar@Sun.COM 			    nlp->nlp_jstat, &rn, 1, 1, sels, &excl, flags, 0,
358611804SReza.Sabdar@Sun.COM 			    nlp->nlp_backup_path, session->hardlink_q);
35877917SReza.Sabdar@Sun.COM 
35887917SReza.Sabdar@Sun.COM 		cmds->tcs_writer_count--;
35897917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_ref--;
35907917SReza.Sabdar@Sun.COM 		cmds->tcs_command->tc_reader = TLM_STOP;
35917917SReza.Sabdar@Sun.COM 		nlp->nlp_jstat->js_stop_time = time(NULL);
35927917SReza.Sabdar@Sun.COM 
35937917SReza.Sabdar@Sun.COM 		/* Send the list of un-recovered files/dirs to the client.  */
35947917SReza.Sabdar@Sun.COM 		(void) send_unrecovered_list_v3(params, nlp);
35957917SReza.Sabdar@Sun.COM 
35967917SReza.Sabdar@Sun.COM 		ndmp_stop_local_reader(session, cmds);
35977917SReza.Sabdar@Sun.COM 		ndmp_wait_for_reader(cmds);
35987917SReza.Sabdar@Sun.COM 		(void) pthread_join(rdtp, NULL);
35997917SReza.Sabdar@Sun.COM 
36007917SReza.Sabdar@Sun.COM 		ndmp_stop_remote_reader(session);
36017917SReza.Sabdar@Sun.COM 
36027917SReza.Sabdar@Sun.COM 		/* exit as if there was an internal error */
36037917SReza.Sabdar@Sun.COM 		if (session->ns_eof)
36047917SReza.Sabdar@Sun.COM 			err = -1;
36057917SReza.Sabdar@Sun.COM 		if (err == -1)
36067917SReza.Sabdar@Sun.COM 			result = EIO;
36077917SReza.Sabdar@Sun.COM 	}
36087917SReza.Sabdar@Sun.COM 
36097917SReza.Sabdar@Sun.COM 	(void) send_unrecovered_list_v3(params, nlp); /* nothing restored. */
36107917SReza.Sabdar@Sun.COM 	if (session->ns_data.dd_abort) {
36117917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" aborted.",
36127917SReza.Sabdar@Sun.COM 		    (nlp->nlp_restore_path) ? nlp->nlp_restore_path : "NULL");
36137917SReza.Sabdar@Sun.COM 		result = EINTR;
36147917SReza.Sabdar@Sun.COM 		ndmpd_audit_restore(session->ns_connection,
36157917SReza.Sabdar@Sun.COM 		    nlp->nlp_restore_path,
36167917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_data_addr.addr_type,
36177917SReza.Sabdar@Sun.COM 		    session->ns_tape.td_adapter_name, result);
36187917SReza.Sabdar@Sun.COM 		err = -1;
36197917SReza.Sabdar@Sun.COM 	} else {
36207917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" finished. (%d)",
36217917SReza.Sabdar@Sun.COM 		    (nlp->nlp_restore_path) ? nlp->nlp_restore_path : "NULL",
36227917SReza.Sabdar@Sun.COM 		    err);
36237917SReza.Sabdar@Sun.COM 		ndmpd_audit_restore(session->ns_connection,
36247917SReza.Sabdar@Sun.COM 		    nlp->nlp_restore_path,
36257917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_data_addr.addr_type,
36267917SReza.Sabdar@Sun.COM 		    session->ns_tape.td_adapter_name, result);
36277917SReza.Sabdar@Sun.COM 
36287917SReza.Sabdar@Sun.COM restore_out:
36297917SReza.Sabdar@Sun.COM 		/* Plug-in module */
36307917SReza.Sabdar@Sun.COM 		if (ndmp_pl != NULL &&
36317917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_post_restore != NULL &&
36327917SReza.Sabdar@Sun.COM 		    ndmp_pl->np_post_restore(ndmp_pl, &nctx, err) == -1) {
36337917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Post-restore plug-in: %m");
36347917SReza.Sabdar@Sun.COM 			err = -1;
36357917SReza.Sabdar@Sun.COM 		}
36367917SReza.Sabdar@Sun.COM 	}
36377917SReza.Sabdar@Sun.COM 
36387917SReza.Sabdar@Sun.COM 	NDMP_FREE(sels);
36397917SReza.Sabdar@Sun.COM 	free_structs_v3(session, jname);
36407917SReza.Sabdar@Sun.COM 
36417917SReza.Sabdar@Sun.COM 	return (err);
36427917SReza.Sabdar@Sun.COM }
36437917SReza.Sabdar@Sun.COM 
36447917SReza.Sabdar@Sun.COM 
36457917SReza.Sabdar@Sun.COM /*
36467917SReza.Sabdar@Sun.COM  * ndmp_backup_get_params_v3
36477917SReza.Sabdar@Sun.COM  *
36487917SReza.Sabdar@Sun.COM  * Get the backup parameters from the NDMP env variables
36497917SReza.Sabdar@Sun.COM  * and log them in the system log and as normal messages
36507917SReza.Sabdar@Sun.COM  * to the DMA.
36517917SReza.Sabdar@Sun.COM  *
36527917SReza.Sabdar@Sun.COM  * Parameters:
36537917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
36547917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
36557917SReza.Sabdar@Sun.COM  *
36567917SReza.Sabdar@Sun.COM  * Returns:
36577917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
36587917SReza.Sabdar@Sun.COM  *   != NDMP_NO_ERR: otherwise
36597917SReza.Sabdar@Sun.COM  */
36607917SReza.Sabdar@Sun.COM ndmp_error
ndmp_backup_get_params_v3(ndmpd_session_t * session,ndmpd_module_params_t * params)36617917SReza.Sabdar@Sun.COM ndmp_backup_get_params_v3(ndmpd_session_t *session,
36627917SReza.Sabdar@Sun.COM     ndmpd_module_params_t *params)
36637917SReza.Sabdar@Sun.COM {
36647917SReza.Sabdar@Sun.COM 	ndmp_error rv;
36657917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
36667917SReza.Sabdar@Sun.COM 
36677917SReza.Sabdar@Sun.COM 	if (!session || !params)
36687917SReza.Sabdar@Sun.COM 		return (NDMP_ILLEGAL_ARGS_ERR);
36697917SReza.Sabdar@Sun.COM 
36707917SReza.Sabdar@Sun.COM 	rv = NDMP_NO_ERR;
36717917SReza.Sabdar@Sun.COM 	nlp = ndmp_get_nlp(session);
36727917SReza.Sabdar@Sun.COM 	if (!nlp) {
36737917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
36747917SReza.Sabdar@Sun.COM 		    "Internal error: NULL nlp.\n");
36757917SReza.Sabdar@Sun.COM 		rv = NDMP_ILLEGAL_ARGS_ERR;
36767917SReza.Sabdar@Sun.COM 	} else {
367712186SJanice.Chang@Sun.COM 		if (!(nlp->nlp_backup_path = get_backup_path_v3(params)))
36787917SReza.Sabdar@Sun.COM 			rv = NDMP_FILE_NOT_FOUND_ERR;
36797917SReza.Sabdar@Sun.COM 		else if (!is_valid_backup_dir_v3(params, nlp->nlp_backup_path))
36807917SReza.Sabdar@Sun.COM 			rv = NDMP_ILLEGAL_ARGS_ERR;
36817917SReza.Sabdar@Sun.COM 	}
36827917SReza.Sabdar@Sun.COM 
368311804SReza.Sabdar@Sun.COM 	nlp->nlp_backup_path = get_absolute_path(nlp->nlp_backup_path);
368411804SReza.Sabdar@Sun.COM 	if (!nlp->nlp_backup_path)
368511804SReza.Sabdar@Sun.COM 		rv = NDMP_FILE_NOT_FOUND_ERR;
368611804SReza.Sabdar@Sun.COM 
36877917SReza.Sabdar@Sun.COM 	if (rv != NDMP_NO_ERR)
36887917SReza.Sabdar@Sun.COM 		return (rv);
36897917SReza.Sabdar@Sun.COM 
36907917SReza.Sabdar@Sun.COM 	if (fs_is_chkpntvol(nlp->nlp_backup_path) ||
36917917SReza.Sabdar@Sun.COM 	    fs_is_rdonly(nlp->nlp_backup_path) ||
36927917SReza.Sabdar@Sun.COM 	    !fs_is_chkpnt_enabled(nlp->nlp_backup_path))
36937917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_CHKPNTED_PATH);
36947917SReza.Sabdar@Sun.COM 	else
36957917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_CHKPNTED_PATH);
36967917SReza.Sabdar@Sun.COM 
36977917SReza.Sabdar@Sun.COM 	/* Should the st_ctime be ignored when backing up? */
36987917SReza.Sabdar@Sun.COM 	if (ndmp_ignore_ctime) {
36997917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "ignoring st_ctime");
37007917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_IGNCTIME);
37017917SReza.Sabdar@Sun.COM 	} else {
37027917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_IGNCTIME);
37037917SReza.Sabdar@Sun.COM 	}
37047917SReza.Sabdar@Sun.COM 
37057917SReza.Sabdar@Sun.COM 	if (ndmp_include_lmtime == TRUE) {
37067917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "including st_lmtime");
37077917SReza.Sabdar@Sun.COM 		NLP_SET(nlp, NLPF_INCLMTIME);
37087917SReza.Sabdar@Sun.COM 	} else {
37097917SReza.Sabdar@Sun.COM 		NLP_UNSET(nlp, NLPF_INCLMTIME);
37107917SReza.Sabdar@Sun.COM 	}
37117917SReza.Sabdar@Sun.COM 
37127917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "flags %x", nlp->nlp_flags);
37137917SReza.Sabdar@Sun.COM 
37147917SReza.Sabdar@Sun.COM 	get_hist_env_v3(params, nlp);
37157917SReza.Sabdar@Sun.COM 	get_exc_env_v3(params, nlp);
37167917SReza.Sabdar@Sun.COM 	get_inc_env_v3(params, nlp);
37177917SReza.Sabdar@Sun.COM 	get_direct_env_v3(params, nlp);
37187917SReza.Sabdar@Sun.COM 	rv = get_backup_level_v3(params, nlp);
37197917SReza.Sabdar@Sun.COM 
37207917SReza.Sabdar@Sun.COM 	return (rv);
37217917SReza.Sabdar@Sun.COM }
37227917SReza.Sabdar@Sun.COM 
37237917SReza.Sabdar@Sun.COM 
37247917SReza.Sabdar@Sun.COM /*
37257917SReza.Sabdar@Sun.COM  * ndmpd_tar_backup_starter_v3
37267917SReza.Sabdar@Sun.COM  *
37277917SReza.Sabdar@Sun.COM  * Create the checkpoint for the backup and do the backup,
37287917SReza.Sabdar@Sun.COM  * then remove the backup checkpoint if we created it.
37297917SReza.Sabdar@Sun.COM  * Save the backup time information based on the backup
37307917SReza.Sabdar@Sun.COM  * type and stop the data server.
37317917SReza.Sabdar@Sun.COM  *
37327917SReza.Sabdar@Sun.COM  * Parameters:
37337917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
37347917SReza.Sabdar@Sun.COM  *
37357917SReza.Sabdar@Sun.COM  * Returns:
37367917SReza.Sabdar@Sun.COM  *   0: on success
37377917SReza.Sabdar@Sun.COM  *   != 0: otherwise
37387917SReza.Sabdar@Sun.COM  */
37397917SReza.Sabdar@Sun.COM int
ndmpd_tar_backup_starter_v3(void * arg)374012186SJanice.Chang@Sun.COM ndmpd_tar_backup_starter_v3(void *arg)
37417917SReza.Sabdar@Sun.COM {
374212186SJanice.Chang@Sun.COM 	ndmpd_module_params_t *params = arg;
37437917SReza.Sabdar@Sun.COM 	int err;
37447917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
37457917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
37467917SReza.Sabdar@Sun.COM 	char jname[TLM_MAX_BACKUP_JOB_NAME];
374710038SReza.Sabdar@Sun.COM 	ndmp_bkup_size_arg_t sarg;
374810038SReza.Sabdar@Sun.COM 	pthread_t tid;
37497917SReza.Sabdar@Sun.COM 
37507917SReza.Sabdar@Sun.COM 	session = (ndmpd_session_t *)(params->mp_daemon_cookie);
37517917SReza.Sabdar@Sun.COM 	*(params->mp_module_cookie) = nlp = ndmp_get_nlp(session);
37527917SReza.Sabdar@Sun.COM 	ndmp_session_ref(session);
37537917SReza.Sabdar@Sun.COM 	(void) ndmp_new_job_name(jname);
37547917SReza.Sabdar@Sun.COM 
37557917SReza.Sabdar@Sun.COM 	err = 0;
37567917SReza.Sabdar@Sun.COM 	if (!NLP_ISCHKPNTED(nlp) &&
3757*12904SReza.Sabdar@Sun.COM 	    ndmp_create_snapshot(nlp->nlp_backup_path, jname) < 0) {
37587917SReza.Sabdar@Sun.COM 		MOD_LOGV3(params, NDMP_LOG_ERROR,
37597917SReza.Sabdar@Sun.COM 		    "Creating checkpoint on \"%s\".\n",
37607917SReza.Sabdar@Sun.COM 		    nlp->nlp_backup_path);
37617917SReza.Sabdar@Sun.COM 		err = -1;
37627917SReza.Sabdar@Sun.COM 	}
37637917SReza.Sabdar@Sun.COM 
37647917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "err %d, chkpnted %c",
37657917SReza.Sabdar@Sun.COM 	    err, NDMP_YORN(NLP_ISCHKPNTED(nlp)));
37667917SReza.Sabdar@Sun.COM 
37677917SReza.Sabdar@Sun.COM 	if (err == 0) {
376810038SReza.Sabdar@Sun.COM 		sarg.bs_session = session;
376910038SReza.Sabdar@Sun.COM 		sarg.bs_jname = jname;
377010038SReza.Sabdar@Sun.COM 		sarg.bs_path = nlp->nlp_backup_path;
377110038SReza.Sabdar@Sun.COM 
377210038SReza.Sabdar@Sun.COM 		/* Get an estimate of the data size */
377310038SReza.Sabdar@Sun.COM 		if (pthread_create(&tid, NULL, (funct_t)get_backup_size,
377410038SReza.Sabdar@Sun.COM 		    (void *)&sarg) == 0)
377510038SReza.Sabdar@Sun.COM 			(void) pthread_detach(tid);
377610038SReza.Sabdar@Sun.COM 
37777917SReza.Sabdar@Sun.COM 		err = ndmp_get_cur_bk_time(nlp, &nlp->nlp_cdate, jname);
37787917SReza.Sabdar@Sun.COM 		if (err != 0) {
37797917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "err %d", err);
37807917SReza.Sabdar@Sun.COM 		} else {
37817917SReza.Sabdar@Sun.COM 			log_bk_params_v3(session, params, nlp);
37827917SReza.Sabdar@Sun.COM 			err = tar_backup_v3(session, params, nlp, jname);
37837917SReza.Sabdar@Sun.COM 		}
37847917SReza.Sabdar@Sun.COM 	}
37857917SReza.Sabdar@Sun.COM 
37867917SReza.Sabdar@Sun.COM 	if (!NLP_ISCHKPNTED(nlp))
3787*12904SReza.Sabdar@Sun.COM 		(void) ndmp_remove_snapshot(nlp->nlp_backup_path, jname);
37887917SReza.Sabdar@Sun.COM 
37897917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "err %d, update %c",
37907917SReza.Sabdar@Sun.COM 	    err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp)));
37917917SReza.Sabdar@Sun.COM 
37927917SReza.Sabdar@Sun.COM 	if (err == 0)
37937917SReza.Sabdar@Sun.COM 		save_backup_date_v3(params, nlp);
37947917SReza.Sabdar@Sun.COM 
37957917SReza.Sabdar@Sun.COM 	MOD_DONE(params, err);
37967917SReza.Sabdar@Sun.COM 
37977917SReza.Sabdar@Sun.COM 	/* nlp_params is allocated in start_backup_v3() */
37987917SReza.Sabdar@Sun.COM 	NDMP_FREE(nlp->nlp_params);
379911804SReza.Sabdar@Sun.COM 	NDMP_FREE(nlp->nlp_backup_path);
38007917SReza.Sabdar@Sun.COM 
38017917SReza.Sabdar@Sun.COM 	NS_DEC(nbk);
38027917SReza.Sabdar@Sun.COM 	ndmp_session_unref(session);
38037917SReza.Sabdar@Sun.COM 	return (err);
38047917SReza.Sabdar@Sun.COM 
38057917SReza.Sabdar@Sun.COM }
38067917SReza.Sabdar@Sun.COM 
38077917SReza.Sabdar@Sun.COM 
38087917SReza.Sabdar@Sun.COM /*
38097917SReza.Sabdar@Sun.COM  * ndmpd_tar_backup_abort_v3
38107917SReza.Sabdar@Sun.COM  *
38117917SReza.Sabdar@Sun.COM  * Abort the backup operation and stop the reader thread.
38127917SReza.Sabdar@Sun.COM  *
38137917SReza.Sabdar@Sun.COM  * Parameters:
38147917SReza.Sabdar@Sun.COM  *   module_cookie (input) - pointer to the nlp structure
38157917SReza.Sabdar@Sun.COM  *
38167917SReza.Sabdar@Sun.COM  * Returns:
38177917SReza.Sabdar@Sun.COM  *   0: always
38187917SReza.Sabdar@Sun.COM  */
38197917SReza.Sabdar@Sun.COM int
ndmpd_tar_backup_abort_v3(void * module_cookie)38207917SReza.Sabdar@Sun.COM ndmpd_tar_backup_abort_v3(void *module_cookie)
38217917SReza.Sabdar@Sun.COM {
38227917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
38237917SReza.Sabdar@Sun.COM 
38247917SReza.Sabdar@Sun.COM 	nlp = (ndmp_lbr_params_t *)module_cookie;
38257917SReza.Sabdar@Sun.COM 	if (nlp && nlp->nlp_session) {
38267917SReza.Sabdar@Sun.COM 		if (nlp->nlp_session->ns_data.dd_data_addr.addr_type ==
38277917SReza.Sabdar@Sun.COM 		    NDMP_ADDR_TCP &&
38287917SReza.Sabdar@Sun.COM 		    nlp->nlp_session->ns_data.dd_sock != -1) {
38297917SReza.Sabdar@Sun.COM 			(void) close(nlp->nlp_session->ns_data.dd_sock);
38307917SReza.Sabdar@Sun.COM 			nlp->nlp_session->ns_data.dd_sock = -1;
38317917SReza.Sabdar@Sun.COM 		}
38327917SReza.Sabdar@Sun.COM 		ndmp_stop_reader_thread(nlp->nlp_session);
38337917SReza.Sabdar@Sun.COM 	}
38347917SReza.Sabdar@Sun.COM 
38357917SReza.Sabdar@Sun.COM 	return (0);
38367917SReza.Sabdar@Sun.COM }
38377917SReza.Sabdar@Sun.COM 
38387917SReza.Sabdar@Sun.COM 
38397917SReza.Sabdar@Sun.COM /*
38407917SReza.Sabdar@Sun.COM  * ndmp_restore_get_params_v3
38417917SReza.Sabdar@Sun.COM  *
38427917SReza.Sabdar@Sun.COM  * Get the parameters specified for recovery such as restore path, type
38437917SReza.Sabdar@Sun.COM  * of restore (DAR, non-DAR) etc
38447917SReza.Sabdar@Sun.COM  *
38457917SReza.Sabdar@Sun.COM  * Parameters:
38467917SReza.Sabdar@Sun.COM  *   session (input) - pointer to the session
38477917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
38487917SReza.Sabdar@Sun.COM  *
38497917SReza.Sabdar@Sun.COM  * Returns:
38507917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
38517917SReza.Sabdar@Sun.COM  *   != NDMP_NO_ERR: otherwise
38527917SReza.Sabdar@Sun.COM  */
38537917SReza.Sabdar@Sun.COM ndmp_error
ndmp_restore_get_params_v3(ndmpd_session_t * session,ndmpd_module_params_t * params)38547917SReza.Sabdar@Sun.COM ndmp_restore_get_params_v3(ndmpd_session_t *session,
38557917SReza.Sabdar@Sun.COM     ndmpd_module_params_t *params)
38567917SReza.Sabdar@Sun.COM {
38577917SReza.Sabdar@Sun.COM 	ndmp_error rv;
38587917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
38597917SReza.Sabdar@Sun.COM 
38607917SReza.Sabdar@Sun.COM 	if (!(nlp = ndmp_get_nlp(session))) {
38617917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nlp is NULL");
38627917SReza.Sabdar@Sun.COM 		rv = NDMP_ILLEGAL_ARGS_ERR;
386312186SJanice.Chang@Sun.COM 	} else if (!(nlp->nlp_backup_path = get_backup_path_v3(params)))
38647917SReza.Sabdar@Sun.COM 		rv = NDMP_ILLEGAL_ARGS_ERR;
38657917SReza.Sabdar@Sun.COM 	else if ((nlp->nlp_nfiles = session->ns_data.dd_nlist_len) == 0) {
38667917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "nfiles: %d", nlp->nlp_nfiles);
38677917SReza.Sabdar@Sun.COM 		rv = NDMP_ILLEGAL_ARGS_ERR;
38687917SReza.Sabdar@Sun.COM 	} else if (get_rs_path_v3(params, nlp) != NDMP_NO_ERR) {
38697917SReza.Sabdar@Sun.COM 		rv = NDMP_ILLEGAL_ARGS_ERR;
38707917SReza.Sabdar@Sun.COM 	} else if ((rv = fix_nlist_v3(session, params, nlp)) != NDMP_NO_ERR) {
38717917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "fix_nlist_v3: %d", rv);
38727917SReza.Sabdar@Sun.COM 	} else {
38737917SReza.Sabdar@Sun.COM 		rv = NDMP_NO_ERR;
38747917SReza.Sabdar@Sun.COM 		get_direct_env_v3(params, nlp);
38757917SReza.Sabdar@Sun.COM 		if (NLP_ISSET(nlp, NLPF_DIRECT)) {
38767917SReza.Sabdar@Sun.COM 			if (NLP_ISSET(nlp, NLPF_RECURSIVE)) {
38777917SReza.Sabdar@Sun.COM 				/* Currently we dont support DAR on directory */
38787917SReza.Sabdar@Sun.COM 				NDMP_LOG(LOG_DEBUG,
38797917SReza.Sabdar@Sun.COM 				    "Can't have RECURSIVE and DIRECT together");
38807917SReza.Sabdar@Sun.COM 				rv = NDMP_ILLEGAL_ARGS_ERR;
38817917SReza.Sabdar@Sun.COM 				return (rv);
38827917SReza.Sabdar@Sun.COM 			}
38837917SReza.Sabdar@Sun.COM 
38847917SReza.Sabdar@Sun.COM 			/*
38857917SReza.Sabdar@Sun.COM 			 * DAR can be done if all the fh_info's are valid.
38867917SReza.Sabdar@Sun.COM 			 */
38877917SReza.Sabdar@Sun.COM 			if (allvalidfh(session, params)) {
38887917SReza.Sabdar@Sun.COM 				ndmp_sort_nlist_v3(session);
38897917SReza.Sabdar@Sun.COM 			} else {
38907917SReza.Sabdar@Sun.COM 				MOD_LOGV3(params, NDMP_LOG_WARNING,
38917917SReza.Sabdar@Sun.COM 				    "Cannot do direct access recovery. "
38927917SReza.Sabdar@Sun.COM 				    "Some 'fh_info'es are not valid.\n");
38937917SReza.Sabdar@Sun.COM 				NLP_UNSET(nlp, NLPF_DIRECT);
38947917SReza.Sabdar@Sun.COM 			}
38957917SReza.Sabdar@Sun.COM 		}
38967917SReza.Sabdar@Sun.COM 
38977917SReza.Sabdar@Sun.COM 		log_rs_params_v3(session, params, nlp);
38987917SReza.Sabdar@Sun.COM 	}
38997917SReza.Sabdar@Sun.COM 
39007917SReza.Sabdar@Sun.COM 	return (rv);
39017917SReza.Sabdar@Sun.COM }
39027917SReza.Sabdar@Sun.COM 
39037917SReza.Sabdar@Sun.COM 
39047917SReza.Sabdar@Sun.COM /*
39057917SReza.Sabdar@Sun.COM  * ndmpd_tar_restore_starter_v3
39067917SReza.Sabdar@Sun.COM  *
39077917SReza.Sabdar@Sun.COM  * The main restore starter function. It will start a DAR or
39087917SReza.Sabdar@Sun.COM  * non-DAR recovery based on the parameters. (V3 and V4 only)
39097917SReza.Sabdar@Sun.COM  *
39107917SReza.Sabdar@Sun.COM  * Parameters:
39117917SReza.Sabdar@Sun.COM  *   params (input) - pointer to the parameters structure
39127917SReza.Sabdar@Sun.COM  *
39137917SReza.Sabdar@Sun.COM  * Returns:
39147917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
39157917SReza.Sabdar@Sun.COM  *   != NDMP_NO_ERR: otherwise
39167917SReza.Sabdar@Sun.COM  */
39177917SReza.Sabdar@Sun.COM int
ndmpd_tar_restore_starter_v3(void * arg)391812186SJanice.Chang@Sun.COM ndmpd_tar_restore_starter_v3(void *arg)
39197917SReza.Sabdar@Sun.COM {
392012186SJanice.Chang@Sun.COM 	ndmpd_module_params_t *params = arg;
39217917SReza.Sabdar@Sun.COM 	int err;
39227917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
39237917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
39247917SReza.Sabdar@Sun.COM 
39257917SReza.Sabdar@Sun.COM 
39267917SReza.Sabdar@Sun.COM 	session = (ndmpd_session_t *)(params->mp_daemon_cookie);
39277917SReza.Sabdar@Sun.COM 	*(params->mp_module_cookie) = nlp = ndmp_get_nlp(session);
39287917SReza.Sabdar@Sun.COM 	ndmp_session_ref(session);
39297917SReza.Sabdar@Sun.COM 
39307917SReza.Sabdar@Sun.COM 	if (NLP_ISSET(nlp, NLPF_DIRECT))
39317917SReza.Sabdar@Sun.COM 		err = ndmpd_rs_dar_tar_v3(session, params, nlp);
39327917SReza.Sabdar@Sun.COM 	else
39337917SReza.Sabdar@Sun.COM 		err = ndmpd_rs_sar_tar_v3(session, params, nlp);
39347917SReza.Sabdar@Sun.COM 
39357917SReza.Sabdar@Sun.COM 	MOD_DONE(params, err);
39367917SReza.Sabdar@Sun.COM 
39377917SReza.Sabdar@Sun.COM 	NS_DEC(nrs);
39387917SReza.Sabdar@Sun.COM 	/* nlp_params is allocated in start_recover() */
39397917SReza.Sabdar@Sun.COM 	NDMP_FREE(nlp->nlp_params);
39407917SReza.Sabdar@Sun.COM 	ndmp_session_unref(session);
39417917SReza.Sabdar@Sun.COM 	return (err);
39427917SReza.Sabdar@Sun.COM 
39437917SReza.Sabdar@Sun.COM }
39447917SReza.Sabdar@Sun.COM 
39457917SReza.Sabdar@Sun.COM 
39467917SReza.Sabdar@Sun.COM /*
39477917SReza.Sabdar@Sun.COM  * ndmp_tar_restore_abort_v3
39487917SReza.Sabdar@Sun.COM  *
39497917SReza.Sabdar@Sun.COM  * Restore abort function (V3 and V4 only)
39507917SReza.Sabdar@Sun.COM  *
39517917SReza.Sabdar@Sun.COM  * Parameters:
39527917SReza.Sabdar@Sun.COM  *   module_cookie (input) - pointer to nlp
39537917SReza.Sabdar@Sun.COM  *
39547917SReza.Sabdar@Sun.COM  * Returns:
39557917SReza.Sabdar@Sun.COM  *   0
39567917SReza.Sabdar@Sun.COM  */
39577917SReza.Sabdar@Sun.COM int
ndmpd_tar_restore_abort_v3(void * module_cookie)39587917SReza.Sabdar@Sun.COM ndmpd_tar_restore_abort_v3(void *module_cookie)
39597917SReza.Sabdar@Sun.COM {
39607917SReza.Sabdar@Sun.COM 	ndmp_lbr_params_t *nlp;
39617917SReza.Sabdar@Sun.COM 
39627917SReza.Sabdar@Sun.COM 	nlp = (ndmp_lbr_params_t *)module_cookie;
39637917SReza.Sabdar@Sun.COM 	if (nlp != NULL && nlp->nlp_session != NULL) {
39647917SReza.Sabdar@Sun.COM 		if (nlp->nlp_session->ns_data.dd_mover.addr_type ==
39657917SReza.Sabdar@Sun.COM 		    NDMP_ADDR_TCP &&
39667917SReza.Sabdar@Sun.COM 		    nlp->nlp_session->ns_data.dd_sock != -1) {
39677917SReza.Sabdar@Sun.COM 			(void) close(nlp->nlp_session->ns_data.dd_sock);
39687917SReza.Sabdar@Sun.COM 			nlp->nlp_session->ns_data.dd_sock = -1;
39697917SReza.Sabdar@Sun.COM 		}
39707917SReza.Sabdar@Sun.COM 		nlp_event_nw(nlp->nlp_session);
39717917SReza.Sabdar@Sun.COM 		ndmp_stop_writer_thread(nlp->nlp_session);
39727917SReza.Sabdar@Sun.COM 	}
39737917SReza.Sabdar@Sun.COM 
39747917SReza.Sabdar@Sun.COM 
39757917SReza.Sabdar@Sun.COM 	return (0);
39767917SReza.Sabdar@Sun.COM 
39777917SReza.Sabdar@Sun.COM }
3978