12654012fSReza Sabdar /*
2*8c4f9701SJanice Chang * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
32654012fSReza Sabdar */
42654012fSReza Sabdar
52654012fSReza Sabdar /*
62654012fSReza Sabdar * BSD 3 Clause License
72654012fSReza Sabdar *
82654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
92654012fSReza Sabdar *
102654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without
112654012fSReza Sabdar * modification, are permitted provided that the following conditions
122654012fSReza Sabdar * are met:
132654012fSReza Sabdar * - Redistributions of source code must retain the above copyright
142654012fSReza Sabdar * notice, this list of conditions and the following disclaimer.
152654012fSReza Sabdar *
162654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright
172654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in
182654012fSReza Sabdar * the documentation and/or other materials provided with the
192654012fSReza Sabdar * distribution.
202654012fSReza Sabdar *
212654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
222654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote
232654012fSReza Sabdar * products derived from this software without specific prior written
242654012fSReza Sabdar * permission.
252654012fSReza Sabdar *
262654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
272654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
282654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
292654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
302654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
312654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
322654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
332654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
342654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
352654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
362654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE.
372654012fSReza Sabdar */
382654012fSReza Sabdar /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
392654012fSReza Sabdar /* Copyright (c) 2007, The Storage Networking Industry Association. */
402654012fSReza Sabdar
412654012fSReza Sabdar /*
422654012fSReza Sabdar * File history callback functions called by backup modules. NDMP file history
432654012fSReza Sabdar * supports 2 file history models: path based and inode/directory based.
442654012fSReza Sabdar * Backup/recover modules similar to unix dump/restore utilize the
452654012fSReza Sabdar * inode/directory based model. During the filesystem scan pass,
462654012fSReza Sabdar * ndmpd_file_history_dir() is called. During the file backup pass,
472654012fSReza Sabdar * ndmpd_file_history_node() is called. This model is appropriate for
482654012fSReza Sabdar * modules whose code is structured such that file name and file attribute
492654012fSReza Sabdar * data is not available at the same time. Backup/recover modules similar
502654012fSReza Sabdar * to tar or cpio utilize the path based model. The simple dump/restore module
512654012fSReza Sabdar * included with the SDK uses the path based model.
522654012fSReza Sabdar */
532654012fSReza Sabdar
542654012fSReza Sabdar #include <sys/stat.h>
552654012fSReza Sabdar #include <sys/types.h>
562654012fSReza Sabdar #include <dirent.h>
572654012fSReza Sabdar #include <errno.h>
582654012fSReza Sabdar #include <stdlib.h>
592654012fSReza Sabdar #include <string.h>
602654012fSReza Sabdar #include "ndmpd.h"
612654012fSReza Sabdar #include <dirent.h>
622654012fSReza Sabdar #include <bitmap.h>
632654012fSReza Sabdar
642654012fSReza Sabdar
652654012fSReza Sabdar #define N_PATH_ENTRIES 1000
662654012fSReza Sabdar #define N_FILE_ENTRIES N_PATH_ENTRIES
672654012fSReza Sabdar #define N_DIR_ENTRIES 1000
682654012fSReza Sabdar #define N_NODE_ENTRIES 1000
692654012fSReza Sabdar
702654012fSReza Sabdar /* Figure an average of 32 bytes per path name */
712654012fSReza Sabdar #define PATH_NAMEBUF_SIZE (N_PATH_ENTRIES * 32)
722654012fSReza Sabdar
732654012fSReza Sabdar /* Figure an average of 16 bytes per file name */
742654012fSReza Sabdar #define DIR_NAMEBUF_SIZE (N_PATH_ENTRIES * 16)
752654012fSReza Sabdar
762654012fSReza Sabdar static boolean_t fh_requested(void *cookie);
772654012fSReza Sabdar static void ndmpd_file_history_cleanup_v2(ndmpd_session_t *session,
782654012fSReza Sabdar boolean_t send_flag);
792654012fSReza Sabdar static void ndmpd_file_history_cleanup_v3(ndmpd_session_t *session,
802654012fSReza Sabdar boolean_t send_flag);
812654012fSReza Sabdar static ndmpd_module_params_t *get_params(void *cookie);
822654012fSReza Sabdar
832654012fSReza Sabdar
842654012fSReza Sabdar /*
852654012fSReza Sabdar * Each file history as a separate message to the client.
862654012fSReza Sabdar */
872654012fSReza Sabdar static int ndmp_syncfh = 0;
882654012fSReza Sabdar
892654012fSReza Sabdar
902654012fSReza Sabdar /*
912654012fSReza Sabdar * ************************************************************************
922654012fSReza Sabdar * NDMP V2 HANDLERS
932654012fSReza Sabdar * ************************************************************************
942654012fSReza Sabdar */
952654012fSReza Sabdar
962654012fSReza Sabdar /*
972654012fSReza Sabdar * ndmpd_api_file_history_path_v2
982654012fSReza Sabdar *
992654012fSReza Sabdar * Add a file history path entry to the buffer.
1002654012fSReza Sabdar * History data is buffered until the buffer is filled.
1012654012fSReza Sabdar * Full buffers are then sent to the client.
1022654012fSReza Sabdar *
1032654012fSReza Sabdar * Parameters:
1042654012fSReza Sabdar * cookie (input) - session pointer.
1052654012fSReza Sabdar * name (input) - file name.
1062654012fSReza Sabdar * NULL forces buffered data to be sent.
1072654012fSReza Sabdar * file_stat (input) - file status pointer.
1082654012fSReza Sabdar * fh_info (input) - data stream position of file data used during
1092654012fSReza Sabdar * fast restore.
1102654012fSReza Sabdar *
1112654012fSReza Sabdar * Returns:
1122654012fSReza Sabdar * 0 - success
1132654012fSReza Sabdar * -1 - error
1142654012fSReza Sabdar */
1152654012fSReza Sabdar int
ndmpd_api_file_history_path_v2(void * cookie,char * name,struct stat64 * file_stat,u_longlong_t fh_info)1162654012fSReza Sabdar ndmpd_api_file_history_path_v2(void *cookie, char *name,
1172654012fSReza Sabdar struct stat64 *file_stat, u_longlong_t fh_info)
1182654012fSReza Sabdar {
1192654012fSReza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie;
1202654012fSReza Sabdar ndmp_fh_unix_path *entry;
1212654012fSReza Sabdar
1222654012fSReza Sabdar if (name == NULL && session->ns_fh.fh_path_index == 0)
1232654012fSReza Sabdar return (0);
1242654012fSReza Sabdar
1252654012fSReza Sabdar /*
1262654012fSReza Sabdar * If the buffer does not have space
1272654012fSReza Sabdar * for the current entry, send the buffered data to the client.
1282654012fSReza Sabdar * A NULL name indicates that any buffered data should be sent.
1292654012fSReza Sabdar */
1302654012fSReza Sabdar if (name == NULL ||
1312654012fSReza Sabdar (ndmp_syncfh && session->ns_fh.fh_path_index != 0) ||
1322654012fSReza Sabdar session->ns_fh.fh_path_index == N_PATH_ENTRIES ||
1332654012fSReza Sabdar session->ns_fh.fh_path_name_buf_index + strlen(name) + 1 >
1342654012fSReza Sabdar PATH_NAMEBUF_SIZE) {
1352654012fSReza Sabdar ndmp_fh_add_unix_path_request request;
1362654012fSReza Sabdar
1372654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
1382654012fSReza Sabdar "sending %ld entries", session->ns_fh.fh_path_index);
1392654012fSReza Sabdar
1402654012fSReza Sabdar request.paths.paths_val = session->ns_fh.fh_path_entries;
1412654012fSReza Sabdar request.paths.paths_len = session->ns_fh.fh_path_index;
1422654012fSReza Sabdar
1432654012fSReza Sabdar if (ndmp_send_request_lock(session->ns_connection,
1442654012fSReza Sabdar NDMP_FH_ADD_UNIX_PATH, NDMP_NO_ERR, (void *) &request,
1452654012fSReza Sabdar 0) < 0) {
1462654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Sending file history data");
1472654012fSReza Sabdar return (-1);
1482654012fSReza Sabdar }
1492654012fSReza Sabdar session->ns_fh.fh_path_index = 0;
1502654012fSReza Sabdar session->ns_fh.fh_path_name_buf_index = 0;
1512654012fSReza Sabdar }
1522654012fSReza Sabdar if (name == NULL)
1532654012fSReza Sabdar return (0);
1542654012fSReza Sabdar
1552654012fSReza Sabdar if (session->ns_fh.fh_path_entries == 0) {
1562654012fSReza Sabdar session->ns_fh.fh_path_entries = ndmp_malloc(N_PATH_ENTRIES *
1572654012fSReza Sabdar sizeof (ndmp_fh_unix_path));
1582654012fSReza Sabdar if (session->ns_fh.fh_path_entries == 0)
1592654012fSReza Sabdar return (-1);
1602654012fSReza Sabdar }
1612654012fSReza Sabdar if (session->ns_fh.fh_path_name_buf == 0) {
1622654012fSReza Sabdar session->ns_fh.fh_path_name_buf =
1632654012fSReza Sabdar ndmp_malloc(PATH_NAMEBUF_SIZE);
1642654012fSReza Sabdar if (session->ns_fh.fh_path_name_buf == 0)
1652654012fSReza Sabdar return (-1);
1662654012fSReza Sabdar }
1672654012fSReza Sabdar entry = &session->ns_fh.fh_path_entries[session->ns_fh.fh_path_index];
1682654012fSReza Sabdar ndmpd_get_file_entry_type(file_stat->st_mode, &entry->fstat.ftype);
1692654012fSReza Sabdar
1702654012fSReza Sabdar entry->name = &session->
1712654012fSReza Sabdar ns_fh.fh_path_name_buf[session->ns_fh.fh_path_name_buf_index];
1722654012fSReza Sabdar (void) strlcpy(entry->name, name, PATH_NAMEBUF_SIZE);
1732654012fSReza Sabdar session->ns_fh.fh_path_name_buf_index += strlen(name) + 1;
1742654012fSReza Sabdar entry->fstat.mtime = (ulong_t)file_stat->st_mtime;
1752654012fSReza Sabdar entry->fstat.atime = (ulong_t)file_stat->st_atime;
1762654012fSReza Sabdar entry->fstat.ctime = (ulong_t)file_stat->st_ctime;
1772654012fSReza Sabdar entry->fstat.uid = file_stat->st_uid;
1782654012fSReza Sabdar entry->fstat.gid = file_stat->st_gid;
1792654012fSReza Sabdar entry->fstat.mode = (file_stat->st_mode) & 0x0fff;
1802654012fSReza Sabdar entry->fstat.size = long_long_to_quad((u_longlong_t)file_stat->st_size);
1812654012fSReza Sabdar entry->fstat.fh_info = long_long_to_quad((u_longlong_t)fh_info);
1822654012fSReza Sabdar session->ns_fh.fh_path_index++;
1832654012fSReza Sabdar return (0);
1842654012fSReza Sabdar }
1852654012fSReza Sabdar
1862654012fSReza Sabdar
1872654012fSReza Sabdar /*
1882654012fSReza Sabdar * ndmpd_api_file_history_dir_v2
1892654012fSReza Sabdar *
1902654012fSReza Sabdar * Add a file history dir entry to the buffer.
1912654012fSReza Sabdar * History data is buffered until the buffer is filled.
1922654012fSReza Sabdar * Full buffers are then sent to the client.
1932654012fSReza Sabdar *
1942654012fSReza Sabdar * Parameters:
1952654012fSReza Sabdar * cookie (input) - session pointer.
1962654012fSReza Sabdar * name (input) - file name.
1972654012fSReza Sabdar * NULL forces buffered data to be sent.
1982654012fSReza Sabdar * node (input) - file inode.
1992654012fSReza Sabdar * parent (input) - file parent inode.
2002654012fSReza Sabdar * Should equal node if the file is the root of
2012654012fSReza Sabdar * the filesystem and has no parent.
2022654012fSReza Sabdar *
2032654012fSReza Sabdar * Returns:
2042654012fSReza Sabdar * 0 - success
2052654012fSReza Sabdar * -1 - error
2062654012fSReza Sabdar */
2072654012fSReza Sabdar int
ndmpd_api_file_history_dir_v2(void * cookie,char * name,ulong_t node,ulong_t parent)2082654012fSReza Sabdar ndmpd_api_file_history_dir_v2(void *cookie, char *name, ulong_t node,
2092654012fSReza Sabdar ulong_t parent)
2102654012fSReza Sabdar {
2112654012fSReza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie;
2122654012fSReza Sabdar ndmp_fh_unix_dir *entry;
2132654012fSReza Sabdar
2142654012fSReza Sabdar if (name == NULL && session->ns_fh.fh_dir_index == 0)
2152654012fSReza Sabdar return (0);
2162654012fSReza Sabdar
2172654012fSReza Sabdar /*
2182654012fSReza Sabdar * If the buffer does not have space for the current entry,
2192654012fSReza Sabdar * send the buffered data to the client. A NULL name indicates
2202654012fSReza Sabdar * that any buffered data should be sent.
2212654012fSReza Sabdar */
2222654012fSReza Sabdar if (name == NULL ||
2232654012fSReza Sabdar (ndmp_syncfh && session->ns_fh.fh_dir_index != 0) ||
2242654012fSReza Sabdar session->ns_fh.fh_dir_index == N_DIR_ENTRIES ||
2252654012fSReza Sabdar session->ns_fh.fh_dir_name_buf_index + strlen(name) + 1 >
2262654012fSReza Sabdar DIR_NAMEBUF_SIZE) {
2272654012fSReza Sabdar ndmp_fh_add_unix_dir_request request;
2282654012fSReza Sabdar
2292654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
2302654012fSReza Sabdar "sending %ld entries", session->ns_fh.fh_dir_index);
2312654012fSReza Sabdar
2322654012fSReza Sabdar request.dirs.dirs_val = session->ns_fh.fh_dir_entries;
2332654012fSReza Sabdar request.dirs.dirs_len = session->ns_fh.fh_dir_index;
2342654012fSReza Sabdar if (ndmp_send_request_lock(session->ns_connection,
2352654012fSReza Sabdar NDMP_FH_ADD_UNIX_DIR, NDMP_NO_ERR, (void *) &request,
2362654012fSReza Sabdar 0) < 0) {
2372654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Sending file history data");
2382654012fSReza Sabdar return (-1);
2392654012fSReza Sabdar }
2402654012fSReza Sabdar session->ns_fh.fh_dir_index = 0;
2412654012fSReza Sabdar session->ns_fh.fh_dir_name_buf_index = 0;
2422654012fSReza Sabdar }
2432654012fSReza Sabdar if (name == NULL)
2442654012fSReza Sabdar return (0);
2452654012fSReza Sabdar
2462654012fSReza Sabdar if (session->ns_fh.fh_dir_entries == 0) {
2472654012fSReza Sabdar session->ns_fh.fh_dir_entries = ndmp_malloc(N_DIR_ENTRIES
2482654012fSReza Sabdar * sizeof (ndmp_fh_unix_dir));
2492654012fSReza Sabdar if (session->ns_fh.fh_dir_entries == 0)
2502654012fSReza Sabdar return (-1);
2512654012fSReza Sabdar }
2522654012fSReza Sabdar if (session->ns_fh.fh_dir_name_buf == 0) {
2532654012fSReza Sabdar session->ns_fh.fh_dir_name_buf = ndmp_malloc(DIR_NAMEBUF_SIZE);
2542654012fSReza Sabdar if (session->ns_fh.fh_dir_name_buf == 0)
2552654012fSReza Sabdar return (-1);
2562654012fSReza Sabdar }
2572654012fSReza Sabdar entry = &session->ns_fh.fh_dir_entries[session->ns_fh.fh_dir_index];
2582654012fSReza Sabdar
2592654012fSReza Sabdar entry->name = &session->
2602654012fSReza Sabdar ns_fh.fh_dir_name_buf[session->ns_fh.fh_dir_name_buf_index];
2612654012fSReza Sabdar (void) strlcpy(&session->
2622654012fSReza Sabdar ns_fh.fh_dir_name_buf[session->ns_fh.fh_dir_name_buf_index],
2632654012fSReza Sabdar name, PATH_NAMEBUF_SIZE);
2642654012fSReza Sabdar session->ns_fh.fh_dir_name_buf_index += strlen(name) + 1;
2652654012fSReza Sabdar
2662654012fSReza Sabdar entry->node = node;
2672654012fSReza Sabdar entry->parent = parent;
2682654012fSReza Sabdar
2692654012fSReza Sabdar session->ns_fh.fh_dir_index++;
2702654012fSReza Sabdar return (0);
2712654012fSReza Sabdar }
2722654012fSReza Sabdar
2732654012fSReza Sabdar
2742654012fSReza Sabdar /*
2752654012fSReza Sabdar * ndmpd_api_file_history_node_v2
2762654012fSReza Sabdar *
2772654012fSReza Sabdar * Add a file history node entry to the buffer.
2782654012fSReza Sabdar * History data is buffered until the buffer is filled.
2792654012fSReza Sabdar * Full buffers are then sent to the client.
2802654012fSReza Sabdar *
2812654012fSReza Sabdar * Parameters:
2822654012fSReza Sabdar * cookie (input) - session pointer.
2832654012fSReza Sabdar * node (input) - file inode.
2842654012fSReza Sabdar * must match a node from a prior ndmpd_api_file_history_dir()
2852654012fSReza Sabdar * call.
2862654012fSReza Sabdar * file_stat (input) - file status pointer.
2872654012fSReza Sabdar * 0 forces buffered data to be sent.
2882654012fSReza Sabdar * fh_info (input) - data stream position of file data used during
2892654012fSReza Sabdar * fast restore.
2902654012fSReza Sabdar *
2912654012fSReza Sabdar * Returns:
2922654012fSReza Sabdar * 0 - success
2932654012fSReza Sabdar * -1 - error.
2942654012fSReza Sabdar */
2952654012fSReza Sabdar int
ndmpd_api_file_history_node_v2(void * cookie,ulong_t node,struct stat64 * file_stat,u_longlong_t fh_info)2962654012fSReza Sabdar ndmpd_api_file_history_node_v2(void *cookie, ulong_t node,
2972654012fSReza Sabdar struct stat64 *file_stat, u_longlong_t fh_info)
2982654012fSReza Sabdar {
2992654012fSReza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie;
3002654012fSReza Sabdar ndmp_fh_unix_node *entry;
3012654012fSReza Sabdar
3022654012fSReza Sabdar if (file_stat == NULL && session->ns_fh.fh_node_index == 0)
3032654012fSReza Sabdar return (-1);
3042654012fSReza Sabdar
3052654012fSReza Sabdar /*
3062654012fSReza Sabdar * If the buffer does not have space
3072654012fSReza Sabdar * for the current entry, send the buffered data to the client.
3082654012fSReza Sabdar * A 0 file_stat pointer indicates that any buffered data should
3092654012fSReza Sabdar * be sent.
3102654012fSReza Sabdar */
3112654012fSReza Sabdar if (file_stat == NULL ||
3122654012fSReza Sabdar (ndmp_syncfh && session->ns_fh.fh_node_index != 0) ||
3132654012fSReza Sabdar session->ns_fh.fh_node_index == N_NODE_ENTRIES) {
3142654012fSReza Sabdar ndmp_fh_add_unix_node_request request;
3152654012fSReza Sabdar
3162654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
3172654012fSReza Sabdar "sending %ld entries", session->ns_fh.fh_node_index);
3182654012fSReza Sabdar
3192654012fSReza Sabdar request.nodes.nodes_val = session->ns_fh.fh_node_entries;
3202654012fSReza Sabdar request.nodes.nodes_len = session->ns_fh.fh_node_index;
3212654012fSReza Sabdar /*
3222654012fSReza Sabdar * Need to send Dir entry as well. Since Dir entry is more than
3232654012fSReza Sabdar * Node entry, we may send a Node entry that hasn't have
3242654012fSReza Sabdar * its dir entry sent. Therefore, we need to flush Dir entry
3252654012fSReza Sabdar * as well everytime the Dir entry is send.
3262654012fSReza Sabdar */
3272654012fSReza Sabdar (void) ndmpd_api_file_history_dir_v2(session, 0, 0, 0);
3282654012fSReza Sabdar
3292654012fSReza Sabdar if (ndmp_send_request_lock(session->ns_connection,
3302654012fSReza Sabdar NDMP_FH_ADD_UNIX_NODE, NDMP_NO_ERR, (void *) &request,
3312654012fSReza Sabdar 0) < 0) {
3322654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Sending file history data");
3332654012fSReza Sabdar return (-1);
3342654012fSReza Sabdar }
3352654012fSReza Sabdar session->ns_fh.fh_node_index = 0;
3362654012fSReza Sabdar }
3372654012fSReza Sabdar if (file_stat == NULL)
3382654012fSReza Sabdar return (0);
3392654012fSReza Sabdar
3402654012fSReza Sabdar if (session->ns_fh.fh_node_entries == 0) {
3412654012fSReza Sabdar session->ns_fh.fh_node_entries = ndmp_malloc(N_NODE_ENTRIES
3422654012fSReza Sabdar * sizeof (ndmp_fh_unix_node));
3432654012fSReza Sabdar if (session->ns_fh.fh_node_entries == 0)
3442654012fSReza Sabdar return (-1);
3452654012fSReza Sabdar }
3462654012fSReza Sabdar entry = &session->ns_fh.fh_node_entries[session->ns_fh.fh_node_index];
3472654012fSReza Sabdar ndmpd_get_file_entry_type(file_stat->st_mode, &entry->fstat.ftype);
3482654012fSReza Sabdar
3492654012fSReza Sabdar entry->node = node;
3502654012fSReza Sabdar entry->fstat.mtime = (ulong_t)file_stat->st_mtime;
3512654012fSReza Sabdar entry->fstat.atime = (ulong_t)file_stat->st_atime;
3522654012fSReza Sabdar entry->fstat.ctime = (ulong_t)file_stat->st_ctime;
3532654012fSReza Sabdar entry->fstat.uid = file_stat->st_uid;
3542654012fSReza Sabdar entry->fstat.gid = file_stat->st_gid;
3552654012fSReza Sabdar entry->fstat.mode = (file_stat->st_mode) & 0x0fff;
3562654012fSReza Sabdar entry->fstat.size = long_long_to_quad((u_longlong_t)file_stat->st_size);
3572654012fSReza Sabdar entry->fstat.fh_info = long_long_to_quad(fh_info);
3582654012fSReza Sabdar
3592654012fSReza Sabdar session->ns_fh.fh_node_index++;
3602654012fSReza Sabdar return (0);
3612654012fSReza Sabdar }
3622654012fSReza Sabdar
3632654012fSReza Sabdar
3642654012fSReza Sabdar /*
3652654012fSReza Sabdar * ************************************************************************
3662654012fSReza Sabdar * NDMP V3 HANDLERS
3672654012fSReza Sabdar * ************************************************************************
3682654012fSReza Sabdar */
3692654012fSReza Sabdar
3702654012fSReza Sabdar /*
3712654012fSReza Sabdar * ndmpd_api_file_history_file_v3
3722654012fSReza Sabdar *
3732654012fSReza Sabdar * Add a file history file entry to the buffer.
3742654012fSReza Sabdar * History data is buffered until the buffer is filled.
3752654012fSReza Sabdar * Full buffers are then sent to the client.
3762654012fSReza Sabdar *
3772654012fSReza Sabdar * Parameters:
3782654012fSReza Sabdar * cookie (input) - session pointer.
3792654012fSReza Sabdar * name (input) - file name.
3802654012fSReza Sabdar * NULL forces buffered data to be sent.
3812654012fSReza Sabdar * file_stat (input) - file status pointer.
3822654012fSReza Sabdar * fh_info (input) - data stream position of file data used during
3832654012fSReza Sabdar * fast restore.
3842654012fSReza Sabdar *
3852654012fSReza Sabdar * Returns:
3862654012fSReza Sabdar * 0 - success
3872654012fSReza Sabdar * -1 - error
3882654012fSReza Sabdar */
3892654012fSReza Sabdar int
ndmpd_api_file_history_file_v3(void * cookie,char * name,struct stat64 * file_stat,u_longlong_t fh_info)3902654012fSReza Sabdar ndmpd_api_file_history_file_v3(void *cookie, char *name,
3912654012fSReza Sabdar struct stat64 *file_stat, u_longlong_t fh_info)
3922654012fSReza Sabdar {
3932654012fSReza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie;
3942654012fSReza Sabdar ndmp_file_v3 *file_entry;
3952654012fSReza Sabdar ndmp_file_name_v3 *file_name_entry;
3962654012fSReza Sabdar ndmp_file_stat_v3 *file_stat_entry;
3972654012fSReza Sabdar ndmp_fh_add_file_request_v3 request;
3982654012fSReza Sabdar
3992654012fSReza Sabdar if (name == NULL && session->ns_fh_v3.fh_file_index == 0)
4002654012fSReza Sabdar return (0);
4012654012fSReza Sabdar
4022654012fSReza Sabdar /*
4032654012fSReza Sabdar * If the buffer does not have space
4042654012fSReza Sabdar * for the current entry, send the buffered data to the client.
4052654012fSReza Sabdar * A NULL name indicates that any buffered data should be sent.
4062654012fSReza Sabdar */
4072654012fSReza Sabdar if (name == NULL ||
4082654012fSReza Sabdar session->ns_fh_v3.fh_file_index == N_FILE_ENTRIES ||
4092654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf_index + strlen(name) + 1 >
4102654012fSReza Sabdar PATH_NAMEBUF_SIZE) {
4112654012fSReza Sabdar
4122654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "sending %ld entries",
4132654012fSReza Sabdar session->ns_fh_v3.fh_file_index);
4142654012fSReza Sabdar
4152654012fSReza Sabdar request.files.files_len = session->ns_fh_v3.fh_file_index;
4162654012fSReza Sabdar request.files.files_val = session->ns_fh_v3.fh_files;
4172654012fSReza Sabdar
4182654012fSReza Sabdar if (ndmp_send_request_lock(session->ns_connection,
4192654012fSReza Sabdar NDMP_FH_ADD_FILE, NDMP_NO_ERR, (void *) &request, 0) < 0) {
4202654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
4212654012fSReza Sabdar "Sending ndmp_fh_add_file request");
4222654012fSReza Sabdar return (-1);
4232654012fSReza Sabdar }
4242654012fSReza Sabdar
4252654012fSReza Sabdar session->ns_fh_v3.fh_file_index = 0;
4262654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf_index = 0;
4272654012fSReza Sabdar }
4282654012fSReza Sabdar
4292654012fSReza Sabdar if (name == NULL)
4302654012fSReza Sabdar return (0);
4312654012fSReza Sabdar
4322654012fSReza Sabdar if (session->ns_fh_v3.fh_files == 0) {
4332654012fSReza Sabdar session->ns_fh_v3.fh_files = ndmp_malloc(sizeof (ndmp_file_v3) *
4342654012fSReza Sabdar N_FILE_ENTRIES);
4352654012fSReza Sabdar if (session->ns_fh_v3.fh_files == 0)
4362654012fSReza Sabdar return (-1);
4372654012fSReza Sabdar }
4382654012fSReza Sabdar
4392654012fSReza Sabdar if (session->ns_fh_v3.fh_file_names == 0) {
4402654012fSReza Sabdar session->ns_fh_v3.fh_file_names =
4412654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_file_name_v3) * N_FILE_ENTRIES);
4422654012fSReza Sabdar if (session->ns_fh_v3.fh_file_names == 0)
4432654012fSReza Sabdar return (-1);
4442654012fSReza Sabdar }
4452654012fSReza Sabdar
4462654012fSReza Sabdar if (session->ns_fh_v3.fh_file_name_buf == 0) {
4472654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf =
4482654012fSReza Sabdar ndmp_malloc(sizeof (char) * PATH_NAMEBUF_SIZE);
4492654012fSReza Sabdar if (session->ns_fh_v3.fh_file_name_buf == 0)
4502654012fSReza Sabdar return (-1);
4512654012fSReza Sabdar }
4522654012fSReza Sabdar
4532654012fSReza Sabdar if (session->ns_fh_v3.fh_file_stats == 0) {
4542654012fSReza Sabdar session->ns_fh_v3.fh_file_stats =
4552654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_file_stat_v3) * N_FILE_ENTRIES);
4562654012fSReza Sabdar if (session->ns_fh_v3.fh_file_stats == 0)
4572654012fSReza Sabdar return (-1);
4582654012fSReza Sabdar }
4592654012fSReza Sabdar
4602654012fSReza Sabdar file_entry =
4612654012fSReza Sabdar &session->ns_fh_v3.fh_files[session->ns_fh_v3.fh_file_index];
4622654012fSReza Sabdar file_name_entry =
4632654012fSReza Sabdar &session->ns_fh_v3.fh_file_names[session->ns_fh_v3.fh_file_index];
4642654012fSReza Sabdar file_stat_entry =
4652654012fSReza Sabdar &session->ns_fh_v3.fh_file_stats[session->ns_fh_v3.fh_file_index];
4662654012fSReza Sabdar file_entry->names.names_len = 1;
4672654012fSReza Sabdar file_entry->names.names_val = file_name_entry;
4682654012fSReza Sabdar file_entry->stats.stats_len = 1;
4692654012fSReza Sabdar file_entry->stats.stats_val = file_stat_entry;
4702654012fSReza Sabdar file_entry->node = long_long_to_quad(file_stat->st_ino);
4712654012fSReza Sabdar file_entry->fh_info = long_long_to_quad(fh_info);
4722654012fSReza Sabdar
4732654012fSReza Sabdar file_name_entry->fs_type = NDMP_FS_UNIX;
4742654012fSReza Sabdar file_name_entry->ndmp_file_name_v3_u.unix_name =
4752654012fSReza Sabdar &session->ns_fh_v3.fh_file_name_buf[session->
4762654012fSReza Sabdar ns_fh_v3.fh_file_name_buf_index];
4772654012fSReza Sabdar (void) strlcpy(&session->ns_fh_v3.fh_file_name_buf[session->
4782654012fSReza Sabdar ns_fh_v3.fh_file_name_buf_index], name, PATH_NAMEBUF_SIZE);
4792654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf_index += strlen(name) + 1;
4802654012fSReza Sabdar ndmpd_get_file_entry_type(file_stat->st_mode, &file_stat_entry->ftype);
4812654012fSReza Sabdar
4822654012fSReza Sabdar file_stat_entry->invalid = 0;
4832654012fSReza Sabdar file_stat_entry->fs_type = NDMP_FS_UNIX;
4842654012fSReza Sabdar file_stat_entry->mtime = file_stat->st_mtime;
4852654012fSReza Sabdar file_stat_entry->atime = file_stat->st_atime;
4862654012fSReza Sabdar file_stat_entry->ctime = file_stat->st_ctime;
4872654012fSReza Sabdar file_stat_entry->owner = file_stat->st_uid;
4882654012fSReza Sabdar file_stat_entry->group = file_stat->st_gid;
4892654012fSReza Sabdar file_stat_entry->fattr = file_stat->st_mode & 0x0fff;
4902654012fSReza Sabdar file_stat_entry->size =
4912654012fSReza Sabdar long_long_to_quad((u_longlong_t)file_stat->st_size);
4922654012fSReza Sabdar file_stat_entry->links = file_stat->st_nlink;
4932654012fSReza Sabdar
4942654012fSReza Sabdar session->ns_fh_v3.fh_file_index++;
4952654012fSReza Sabdar
4962654012fSReza Sabdar return (0);
4972654012fSReza Sabdar }
4982654012fSReza Sabdar
4992654012fSReza Sabdar
5002654012fSReza Sabdar /*
5012654012fSReza Sabdar * ndmpd_api_file_history_dir_v3
5022654012fSReza Sabdar *
5032654012fSReza Sabdar * Add a file history dir entry to the buffer.
5042654012fSReza Sabdar * History data is buffered until the buffer is filled.
5052654012fSReza Sabdar * Full buffers are then sent to the client.
5062654012fSReza Sabdar *
5072654012fSReza Sabdar * Parameters:
5082654012fSReza Sabdar * cookie (input) - session pointer.
5092654012fSReza Sabdar * name (input) - file name.
5102654012fSReza Sabdar * NULL forces buffered data to be sent.
5112654012fSReza Sabdar * node (input) - file inode.
5122654012fSReza Sabdar * parent (input) - file parent inode.
5132654012fSReza Sabdar * Should equal node if the file is the root of
5142654012fSReza Sabdar * the filesystem and has no parent.
5152654012fSReza Sabdar *
5162654012fSReza Sabdar * Returns:
5172654012fSReza Sabdar * 0 - success
5182654012fSReza Sabdar * -1 - error
5192654012fSReza Sabdar */
5202654012fSReza Sabdar int
ndmpd_api_file_history_dir_v3(void * cookie,char * name,ulong_t node,ulong_t parent)5212654012fSReza Sabdar ndmpd_api_file_history_dir_v3(void *cookie, char *name, ulong_t node,
5222654012fSReza Sabdar ulong_t parent)
5232654012fSReza Sabdar {
5242654012fSReza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie;
5252654012fSReza Sabdar ndmp_dir_v3 *dir_entry;
5262654012fSReza Sabdar ndmp_file_name_v3 *dir_name_entry;
5272654012fSReza Sabdar ndmp_fh_add_dir_request_v3 request;
5282654012fSReza Sabdar
5292654012fSReza Sabdar if (name == NULL && session->ns_fh_v3.fh_dir_index == 0)
5302654012fSReza Sabdar return (0);
5312654012fSReza Sabdar
5322654012fSReza Sabdar /*
5332654012fSReza Sabdar * If the buffer does not have space
5342654012fSReza Sabdar * for the current entry, send the buffered data to the client.
5352654012fSReza Sabdar * A NULL name indicates that any buffered data should be sent.
5362654012fSReza Sabdar */
5372654012fSReza Sabdar if (name == NULL ||
5382654012fSReza Sabdar session->ns_fh_v3.fh_dir_index == N_DIR_ENTRIES ||
5392654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf_index + strlen(name) + 1 >
5402654012fSReza Sabdar DIR_NAMEBUF_SIZE) {
5412654012fSReza Sabdar
5422654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "sending %ld entries",
5432654012fSReza Sabdar session->ns_fh_v3.fh_dir_index);
5442654012fSReza Sabdar
5452654012fSReza Sabdar request.dirs.dirs_val = session->ns_fh_v3.fh_dirs;
5462654012fSReza Sabdar request.dirs.dirs_len = session->ns_fh_v3.fh_dir_index;
5472654012fSReza Sabdar
5482654012fSReza Sabdar if (ndmp_send_request_lock(session->ns_connection,
5492654012fSReza Sabdar NDMP_FH_ADD_DIR, NDMP_NO_ERR, (void *) &request, 0) < 0) {
5502654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
5512654012fSReza Sabdar "Sending ndmp_fh_add_dir request");
5522654012fSReza Sabdar return (-1);
5532654012fSReza Sabdar }
5542654012fSReza Sabdar
5552654012fSReza Sabdar session->ns_fh_v3.fh_dir_index = 0;
5562654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf_index = 0;
5572654012fSReza Sabdar }
5582654012fSReza Sabdar
5592654012fSReza Sabdar if (name == NULL)
5602654012fSReza Sabdar return (0);
5612654012fSReza Sabdar
5622654012fSReza Sabdar if (session->ns_fh_v3.fh_dirs == 0) {
5632654012fSReza Sabdar session->ns_fh_v3.fh_dirs =
5642654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_dir_v3) * N_DIR_ENTRIES);
5652654012fSReza Sabdar if (session->ns_fh_v3.fh_dirs == 0)
5662654012fSReza Sabdar return (-1);
5672654012fSReza Sabdar }
5682654012fSReza Sabdar
5692654012fSReza Sabdar if (session->ns_fh_v3.fh_dir_names == 0) {
5702654012fSReza Sabdar session->ns_fh_v3.fh_dir_names =
5712654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_file_name_v3) * N_DIR_ENTRIES);
5722654012fSReza Sabdar if (session->ns_fh_v3.fh_dir_names == 0)
5732654012fSReza Sabdar return (-1);
5742654012fSReza Sabdar }
5752654012fSReza Sabdar
5762654012fSReza Sabdar if (session->ns_fh_v3.fh_dir_name_buf == 0) {
5772654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf =
5782654012fSReza Sabdar ndmp_malloc(sizeof (char) * DIR_NAMEBUF_SIZE);
5792654012fSReza Sabdar if (session->ns_fh_v3.fh_dir_name_buf == 0)
5802654012fSReza Sabdar return (-1);
5812654012fSReza Sabdar }
5822654012fSReza Sabdar
5832654012fSReza Sabdar dir_entry = &session->ns_fh_v3.fh_dirs[session->ns_fh_v3.fh_dir_index];
5842654012fSReza Sabdar dir_name_entry =
5852654012fSReza Sabdar &session->ns_fh_v3.fh_dir_names[session->ns_fh_v3.fh_dir_index];
5862654012fSReza Sabdar
5872654012fSReza Sabdar dir_name_entry->fs_type = NDMP_FS_UNIX;
5882654012fSReza Sabdar dir_name_entry->ndmp_file_name_v3_u.unix_name =
5892654012fSReza Sabdar &session->ns_fh_v3.fh_dir_name_buf[session->
5902654012fSReza Sabdar ns_fh_v3.fh_dir_name_buf_index];
5912654012fSReza Sabdar
5922654012fSReza Sabdar (void) strlcpy(&session->ns_fh_v3.fh_dir_name_buf[session->
5932654012fSReza Sabdar ns_fh_v3.fh_dir_name_buf_index], name, PATH_NAMEBUF_SIZE);
5942654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf_index += strlen(name) + 1;
5952654012fSReza Sabdar
5962654012fSReza Sabdar dir_entry->names.names_len = 1;
5972654012fSReza Sabdar dir_entry->names.names_val = dir_name_entry;
5982654012fSReza Sabdar dir_entry->node = long_long_to_quad(node);
5992654012fSReza Sabdar dir_entry->parent = long_long_to_quad(parent);
6002654012fSReza Sabdar
6012654012fSReza Sabdar session->ns_fh_v3.fh_dir_index++;
6022654012fSReza Sabdar
6032654012fSReza Sabdar return (0);
6042654012fSReza Sabdar }
6052654012fSReza Sabdar
6062654012fSReza Sabdar
6072654012fSReza Sabdar /*
6082654012fSReza Sabdar * ndmpd_api_file_history_node_v3
6092654012fSReza Sabdar *
6102654012fSReza Sabdar * Add a file history node entry to the buffer.
6112654012fSReza Sabdar * History data is buffered until the buffer is filled.
6122654012fSReza Sabdar * Full buffers are then sent to the client.
6132654012fSReza Sabdar *
6142654012fSReza Sabdar * Parameters:
6152654012fSReza Sabdar * cookie (input) - session pointer.
6162654012fSReza Sabdar * node (input) - file inode.
6172654012fSReza Sabdar * must match a node from a prior ndmpd_api_file_history_dir()
6182654012fSReza Sabdar * call.
6192654012fSReza Sabdar * file_stat (input) - file status pointer.
6202654012fSReza Sabdar * 0 forces buffered data to be sent.
6212654012fSReza Sabdar * fh_info (input) - data stream position of file data used during
6222654012fSReza Sabdar * fast restore.
6232654012fSReza Sabdar *
6242654012fSReza Sabdar * Returns:
6252654012fSReza Sabdar * 0 - success
6262654012fSReza Sabdar * -1 - error.
6272654012fSReza Sabdar */
6282654012fSReza Sabdar int
ndmpd_api_file_history_node_v3(void * cookie,ulong_t node,struct stat64 * file_stat,u_longlong_t fh_info)6292654012fSReza Sabdar ndmpd_api_file_history_node_v3(void *cookie, ulong_t node,
6302654012fSReza Sabdar struct stat64 *file_stat, u_longlong_t fh_info)
6312654012fSReza Sabdar {
6322654012fSReza Sabdar ndmpd_session_t *session = (ndmpd_session_t *)cookie;
6332654012fSReza Sabdar ndmp_node_v3 *node_entry;
6342654012fSReza Sabdar ndmp_file_stat_v3 *file_stat_entry;
6352654012fSReza Sabdar ndmp_fh_add_node_request_v3 request;
6362654012fSReza Sabdar
6372654012fSReza Sabdar if (file_stat == NULL && session->ns_fh_v3.fh_node_index == 0)
6382654012fSReza Sabdar return (0);
6392654012fSReza Sabdar
6402654012fSReza Sabdar /*
6412654012fSReza Sabdar * If the buffer does not have space
6422654012fSReza Sabdar * for the current entry, send the buffered data to the client.
6432654012fSReza Sabdar * A 0 file_stat pointer indicates that any buffered data should
6442654012fSReza Sabdar * be sent.
6452654012fSReza Sabdar */
6462654012fSReza Sabdar if (file_stat == NULL ||
6472654012fSReza Sabdar session->ns_fh_v3.fh_node_index == N_NODE_ENTRIES) {
6482654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "sending %ld entries",
6492654012fSReza Sabdar session->ns_fh_v3.fh_node_index);
6502654012fSReza Sabdar
6512654012fSReza Sabdar /*
6522654012fSReza Sabdar * Need to send Dir entry as well. Since Dir entry is more
6532654012fSReza Sabdar * than a Node entry, we may send a Node entry that hasn't
6542654012fSReza Sabdar * had its Dir entry sent. Therefore, we need to flush Dir
6552654012fSReza Sabdar * entry as well every time the Dir entry is sent.
6562654012fSReza Sabdar */
6572654012fSReza Sabdar (void) ndmpd_api_file_history_dir_v3(session, 0, 0, 0);
6582654012fSReza Sabdar
6592654012fSReza Sabdar request.nodes.nodes_len = session->ns_fh_v3.fh_node_index;
6602654012fSReza Sabdar request.nodes.nodes_val = session->ns_fh_v3.fh_nodes;
6612654012fSReza Sabdar
6622654012fSReza Sabdar if (ndmp_send_request_lock(session->ns_connection,
6632654012fSReza Sabdar NDMP_FH_ADD_NODE,
6642654012fSReza Sabdar NDMP_NO_ERR, (void *) &request, 0) < 0) {
6652654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
6662654012fSReza Sabdar "Sending ndmp_fh_add_node request");
6672654012fSReza Sabdar return (-1);
6682654012fSReza Sabdar }
6692654012fSReza Sabdar
6702654012fSReza Sabdar session->ns_fh_v3.fh_node_index = 0;
6712654012fSReza Sabdar }
6722654012fSReza Sabdar
6732654012fSReza Sabdar if (file_stat == NULL)
6742654012fSReza Sabdar return (0);
6752654012fSReza Sabdar
6762654012fSReza Sabdar if (session->ns_fh_v3.fh_nodes == 0) {
6772654012fSReza Sabdar session->ns_fh_v3.fh_nodes =
6782654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_node_v3) * N_NODE_ENTRIES);
6792654012fSReza Sabdar if (session->ns_fh_v3.fh_nodes == 0)
6802654012fSReza Sabdar return (-1);
6812654012fSReza Sabdar }
6822654012fSReza Sabdar
6832654012fSReza Sabdar if (session->ns_fh_v3.fh_node_stats == 0) {
6842654012fSReza Sabdar session->ns_fh_v3.fh_node_stats =
6852654012fSReza Sabdar ndmp_malloc(sizeof (ndmp_file_stat_v3) * N_NODE_ENTRIES);
6862654012fSReza Sabdar if (session->ns_fh_v3.fh_node_stats == 0)
6872654012fSReza Sabdar return (-1);
6882654012fSReza Sabdar }
6892654012fSReza Sabdar
6902654012fSReza Sabdar node_entry =
6912654012fSReza Sabdar &session->ns_fh_v3.fh_nodes[session->ns_fh_v3.fh_node_index];
6922654012fSReza Sabdar
6932654012fSReza Sabdar file_stat_entry =
6942654012fSReza Sabdar &session->ns_fh_v3.fh_node_stats[session->ns_fh_v3.fh_node_index];
6952654012fSReza Sabdar ndmpd_get_file_entry_type(file_stat->st_mode, &file_stat_entry->ftype);
6962654012fSReza Sabdar
6972654012fSReza Sabdar file_stat_entry->invalid = 0;
6982654012fSReza Sabdar file_stat_entry->fs_type = NDMP_FS_UNIX;
6992654012fSReza Sabdar file_stat_entry->mtime = file_stat->st_mtime;
7002654012fSReza Sabdar file_stat_entry->atime = file_stat->st_atime;
7012654012fSReza Sabdar file_stat_entry->ctime = file_stat->st_ctime;
7022654012fSReza Sabdar file_stat_entry->owner = file_stat->st_uid;
7032654012fSReza Sabdar file_stat_entry->group = file_stat->st_gid;
7042654012fSReza Sabdar file_stat_entry->fattr = file_stat->st_mode & 0x0fff;
7052654012fSReza Sabdar file_stat_entry->size =
7062654012fSReza Sabdar long_long_to_quad((u_longlong_t)file_stat->st_size);
7072654012fSReza Sabdar file_stat_entry->links = file_stat->st_nlink;
7082654012fSReza Sabdar
7092654012fSReza Sabdar node_entry->stats.stats_len = 1;
7102654012fSReza Sabdar node_entry->stats.stats_val = file_stat_entry;
7112654012fSReza Sabdar node_entry->node = long_long_to_quad((u_longlong_t)node);
7122654012fSReza Sabdar node_entry->fh_info = long_long_to_quad(fh_info);
7132654012fSReza Sabdar
7142654012fSReza Sabdar session->ns_fh_v3.fh_node_index++;
7152654012fSReza Sabdar
7162654012fSReza Sabdar return (0);
7172654012fSReza Sabdar }
7182654012fSReza Sabdar
7192654012fSReza Sabdar
7202654012fSReza Sabdar /*
7212654012fSReza Sabdar * ************************************************************************
7222654012fSReza Sabdar * NDMP V4 HANDLERS
7232654012fSReza Sabdar * ************************************************************************
7242654012fSReza Sabdar */
7252654012fSReza Sabdar
7262654012fSReza Sabdar
7272654012fSReza Sabdar /*
7282654012fSReza Sabdar * ndmpd_fhpath_v3_cb
7292654012fSReza Sabdar *
7302654012fSReza Sabdar * Callback function for file history path information
7312654012fSReza Sabdar */
7322654012fSReza Sabdar int
ndmpd_fhpath_v3_cb(lbr_fhlog_call_backs_t * cbp,char * path,struct stat64 * stp,u_longlong_t off)7332654012fSReza Sabdar ndmpd_fhpath_v3_cb(lbr_fhlog_call_backs_t *cbp, char *path, struct stat64 *stp,
7342654012fSReza Sabdar u_longlong_t off)
7352654012fSReza Sabdar {
7362654012fSReza Sabdar int err;
7372654012fSReza Sabdar ndmp_lbr_params_t *nlp;
7382654012fSReza Sabdar ndmpd_module_params_t *params;
7392654012fSReza Sabdar
7402654012fSReza Sabdar if (!cbp) {
7412654012fSReza Sabdar err = -1;
7422654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
7432654012fSReza Sabdar } else if (!cbp->fh_cookie) {
7442654012fSReza Sabdar err = -1;
7452654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cookie is NULL");
7462654012fSReza Sabdar } else if (!path) {
7472654012fSReza Sabdar err = -1;
7482654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "path is NULL");
7492654012fSReza Sabdar } else if (!(nlp = ndmp_get_nlp(cbp->fh_cookie))) {
7502654012fSReza Sabdar err = -1;
7512654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
7522654012fSReza Sabdar } else
7532654012fSReza Sabdar err = 0;
7542654012fSReza Sabdar
7552654012fSReza Sabdar if (err != 0)
7562654012fSReza Sabdar return (0);
7572654012fSReza Sabdar
7582654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "pname(%s)", path);
7592654012fSReza Sabdar
7602654012fSReza Sabdar err = 0;
7612654012fSReza Sabdar if (NLP_ISSET(nlp, NLPF_FH)) {
7622654012fSReza Sabdar if (!NLP_ISSET(nlp, NLPF_DIRECT)) {
7632654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "DAR NOT SET!");
7642654012fSReza Sabdar off = 0LL;
7652654012fSReza Sabdar }
7662654012fSReza Sabdar
7672654012fSReza Sabdar params = get_params(cbp->fh_cookie);
7682654012fSReza Sabdar if (!params || !params->mp_file_history_path_func) {
7692654012fSReza Sabdar err = -1;
7702654012fSReza Sabdar } else {
771*8c4f9701SJanice Chang char *p =
772*8c4f9701SJanice Chang ndmp_get_relative_path(get_backup_path_v3(params),
7732654012fSReza Sabdar path);
7742654012fSReza Sabdar if ((err = ndmpd_api_file_history_file_v3(cbp->
7752654012fSReza Sabdar fh_cookie, p, stp, off)) < 0)
7762654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s\" %d", path, err);
7772654012fSReza Sabdar }
7782654012fSReza Sabdar }
7792654012fSReza Sabdar
7802654012fSReza Sabdar return (err);
7812654012fSReza Sabdar }
7822654012fSReza Sabdar
7832654012fSReza Sabdar
7842654012fSReza Sabdar /*
7852654012fSReza Sabdar * ndmpd_fhdir_v3_cb
7862654012fSReza Sabdar *
7872654012fSReza Sabdar * Callback function for file history dir information
7882654012fSReza Sabdar */
7892654012fSReza Sabdar int
ndmpd_fhdir_v3_cb(lbr_fhlog_call_backs_t * cbp,char * dir,struct stat64 * stp)7902654012fSReza Sabdar ndmpd_fhdir_v3_cb(lbr_fhlog_call_backs_t *cbp, char *dir, struct stat64 *stp)
7912654012fSReza Sabdar {
7922654012fSReza Sabdar char nm[PATH_MAX+1];
7932654012fSReza Sabdar int nml;
7942654012fSReza Sabdar int err;
7952654012fSReza Sabdar ulong_t ino, pino;
7962654012fSReza Sabdar ulong_t pos;
7972654012fSReza Sabdar ndmp_lbr_params_t *nlp;
7982654012fSReza Sabdar ndmpd_module_params_t *params;
7992654012fSReza Sabdar DIR *dirp;
8002654012fSReza Sabdar char dirpath[PATH_MAX];
8012654012fSReza Sabdar
8022654012fSReza Sabdar if (!cbp) {
8032654012fSReza Sabdar err = -1;
8042654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
8052654012fSReza Sabdar } else if (!cbp->fh_cookie) {
8062654012fSReza Sabdar err = -1;
8072654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cookie is NULL");
8082654012fSReza Sabdar } else if (!dir) {
8092654012fSReza Sabdar err = -1;
8102654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dir is NULL");
8112654012fSReza Sabdar } else if (!(nlp = ndmp_get_nlp(cbp->fh_cookie))) {
8122654012fSReza Sabdar err = -1;
8132654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
8142654012fSReza Sabdar } else
8152654012fSReza Sabdar err = 0;
8162654012fSReza Sabdar
8172654012fSReza Sabdar if (err != 0)
8182654012fSReza Sabdar return (0);
8192654012fSReza Sabdar
8202654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "d(%s)", dir);
8212654012fSReza Sabdar
8222654012fSReza Sabdar if (!NLP_ISSET(nlp, NLPF_FH))
8232654012fSReza Sabdar return (0);
8242654012fSReza Sabdar
8252654012fSReza Sabdar /*
8262654012fSReza Sabdar * Veritas net_backup accepts only 2 as the inode number of the backup
8272654012fSReza Sabdar * root directory. The other way compares the path against the
8282654012fSReza Sabdar * backup path which is slower.
8292654012fSReza Sabdar */
8302654012fSReza Sabdar if (stp->st_ino == nlp->nlp_bkdirino)
8312654012fSReza Sabdar pino = ROOT_INODE;
8322654012fSReza Sabdar else
8332654012fSReza Sabdar pino = stp->st_ino;
8342654012fSReza Sabdar
8352654012fSReza Sabdar /*
8362654012fSReza Sabdar * There is nothing below this directory to be backed up.
8372654012fSReza Sabdar * If there was, the bit for this directory would have
8382654012fSReza Sabdar * been set. Backup root directory is exception. We
8392654012fSReza Sabdar * always send the dir file history records of it.
8402654012fSReza Sabdar */
8412654012fSReza Sabdar if (pino != ROOT_INODE &&
8422654012fSReza Sabdar !dbm_getone(nlp->nlp_bkmap, (u_longlong_t)stp->st_ino)) {
8432654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nothing below here");
8442654012fSReza Sabdar return (0);
8452654012fSReza Sabdar }
8462654012fSReza Sabdar
8472654012fSReza Sabdar params = nlp->nlp_params;
8482654012fSReza Sabdar if (!params || !params->mp_file_history_dir_func)
8492654012fSReza Sabdar return (-1);
8502654012fSReza Sabdar
8512654012fSReza Sabdar pos = 0;
8522654012fSReza Sabdar err = 0;
8532654012fSReza Sabdar
8542654012fSReza Sabdar dirp = opendir(dir);
8552654012fSReza Sabdar if (dirp == NULL)
8562654012fSReza Sabdar return (0);
8572654012fSReza Sabdar
8582654012fSReza Sabdar do {
8592654012fSReza Sabdar nml = PATH_MAX;
8602654012fSReza Sabdar err = dp_readdir(dirp, &pos, nm, &nml, &ino);
8612654012fSReza Sabdar if (err != 0) {
8622654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
8632654012fSReza Sabdar "%d reading pos %u dir \"%s\"", err, pos, dir);
8642654012fSReza Sabdar break;
8652654012fSReza Sabdar }
8662654012fSReza Sabdar if (nml == 0)
8672654012fSReza Sabdar break;
8682654012fSReza Sabdar nm[nml] = '\0';
8692654012fSReza Sabdar
8702654012fSReza Sabdar if (pino == ROOT_INODE) {
8712654012fSReza Sabdar if (rootfs_dot_or_dotdot(nm))
8722654012fSReza Sabdar ino = ROOT_INODE;
8732654012fSReza Sabdar } else if (ino == nlp->nlp_bkdirino && IS_DOTDOT(nm)) {
8742654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nm(%s): %lu", nm, ino);
8752654012fSReza Sabdar ino = ROOT_INODE;
8762654012fSReza Sabdar }
8772654012fSReza Sabdar
8782654012fSReza Sabdar if (!dbm_getone(nlp->nlp_bkmap, (u_longlong_t)ino))
8792654012fSReza Sabdar continue;
8802654012fSReza Sabdar
8812654012fSReza Sabdar /*
8822654012fSReza Sabdar * If the entry is on exclusion list dont send the info
8832654012fSReza Sabdar */
8842654012fSReza Sabdar if (tlm_is_excluded(dir, nm, ndmp_excl_list)) {
8852654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
8862654012fSReza Sabdar "name \"%s\" skipped", nm == 0 ? "nil" : nm);
8872654012fSReza Sabdar continue;
8882654012fSReza Sabdar }
8892654012fSReza Sabdar
8902654012fSReza Sabdar err = (*params->mp_file_history_dir_func)(cbp->fh_cookie, nm,
8912654012fSReza Sabdar ino, pino);
8922654012fSReza Sabdar if (err < 0) {
8932654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s\": %d", dir, err);
8942654012fSReza Sabdar break;
8952654012fSReza Sabdar }
8962654012fSReza Sabdar
8972654012fSReza Sabdar /*
8982654012fSReza Sabdar * This is a requirement by some DMA's (net_vault) that during
8992654012fSReza Sabdar * the incremental backup, the node info should also be sent
9002654012fSReza Sabdar * along with the dir info for all directories leading to a
9012654012fSReza Sabdar * backed up file.
9022654012fSReza Sabdar */
9032654012fSReza Sabdar if (ndmp_fhinode) {
9042654012fSReza Sabdar struct stat64 ret_attr;
9052654012fSReza Sabdar
9062654012fSReza Sabdar (void) strlcpy(dirpath, dir, PATH_MAX);
9072654012fSReza Sabdar (void) strlcat(dirpath, "/", PATH_MAX);
9082654012fSReza Sabdar (void) strlcat(dirpath, nm, PATH_MAX);
9092654012fSReza Sabdar err = stat64(dirpath, &ret_attr);
9102654012fSReza Sabdar if (err != 0) {
9112654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
9122654012fSReza Sabdar "Error looking up %s", nm);
9132654012fSReza Sabdar break;
9142654012fSReza Sabdar }
9152654012fSReza Sabdar
9162654012fSReza Sabdar if (S_ISDIR(ret_attr.st_mode)) {
9172654012fSReza Sabdar err = (*params->mp_file_history_node_func)(cbp->
9182654012fSReza Sabdar fh_cookie, ino, &ret_attr, 0);
9192654012fSReza Sabdar if (err < 0) {
9202654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/\": %d",
9212654012fSReza Sabdar dir, err);
9222654012fSReza Sabdar break;
9232654012fSReza Sabdar }
9242654012fSReza Sabdar }
9252654012fSReza Sabdar }
9262654012fSReza Sabdar } while (err == 0);
9272654012fSReza Sabdar
9282654012fSReza Sabdar (void) closedir(dirp);
9292654012fSReza Sabdar return (err);
9302654012fSReza Sabdar }
9312654012fSReza Sabdar
9322654012fSReza Sabdar
9332654012fSReza Sabdar /*
9342654012fSReza Sabdar * ndmpd_fhnode_v3_cb
9352654012fSReza Sabdar *
9362654012fSReza Sabdar * Callback function for file history node information
9372654012fSReza Sabdar */
9382654012fSReza Sabdar int
ndmpd_fhnode_v3_cb(lbr_fhlog_call_backs_t * cbp,char * dir,char * file,struct stat64 * stp,u_longlong_t off)9392654012fSReza Sabdar ndmpd_fhnode_v3_cb(lbr_fhlog_call_backs_t *cbp, char *dir, char *file,
9402654012fSReza Sabdar struct stat64 *stp, u_longlong_t off)
9412654012fSReza Sabdar {
9422654012fSReza Sabdar int err;
9432654012fSReza Sabdar ulong_t ino;
9442654012fSReza Sabdar ndmp_lbr_params_t *nlp;
9452654012fSReza Sabdar ndmpd_module_params_t *params;
9462654012fSReza Sabdar
9472654012fSReza Sabdar if (!cbp) {
9482654012fSReza Sabdar err = -1;
9492654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
9502654012fSReza Sabdar } else if (!cbp->fh_cookie) {
9512654012fSReza Sabdar err = -1;
9522654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cookie is NULL");
9532654012fSReza Sabdar } else if (!dir) {
9542654012fSReza Sabdar err = -1;
9552654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dir is NULL");
9562654012fSReza Sabdar } else if (!file) {
9572654012fSReza Sabdar err = -1;
9582654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "file is NULL");
9592654012fSReza Sabdar } else if (!stp) {
9602654012fSReza Sabdar err = -1;
9612654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "stp is NULL");
9622654012fSReza Sabdar } else if (!(nlp = ndmp_get_nlp(cbp->fh_cookie))) {
9632654012fSReza Sabdar err = -1;
9642654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
9652654012fSReza Sabdar } else {
9662654012fSReza Sabdar err = 0;
9672654012fSReza Sabdar }
9682654012fSReza Sabdar
9692654012fSReza Sabdar if (err != 0)
9702654012fSReza Sabdar return (0);
9712654012fSReza Sabdar
9722654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "d(%s), f(%s)", dir, file);
9732654012fSReza Sabdar
9742654012fSReza Sabdar err = 0;
9752654012fSReza Sabdar if (NLP_ISSET(nlp, NLPF_FH)) {
9762654012fSReza Sabdar if (!NLP_ISSET(nlp, NLPF_DIRECT))
9772654012fSReza Sabdar off = 0LL;
9782654012fSReza Sabdar if (stp->st_ino == nlp->nlp_bkdirino) {
9792654012fSReza Sabdar ino = ROOT_INODE;
9802654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
9812654012fSReza Sabdar "bkroot %d -> %d", stp->st_ino, ROOT_INODE);
9822654012fSReza Sabdar } else
9832654012fSReza Sabdar ino = stp->st_ino;
9842654012fSReza Sabdar
9852654012fSReza Sabdar params = nlp->nlp_params;
9862654012fSReza Sabdar if (!params || !params->mp_file_history_node_func)
9872654012fSReza Sabdar err = -1;
9882654012fSReza Sabdar else if ((err = (*params->mp_file_history_node_func)(cbp->
9892654012fSReza Sabdar fh_cookie, ino, stp, off)) < 0)
9902654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/%s\" %d", dir, file, err);
9912654012fSReza Sabdar }
9922654012fSReza Sabdar
9932654012fSReza Sabdar return (err);
9942654012fSReza Sabdar }
9952654012fSReza Sabdar
9962654012fSReza Sabdar
9972654012fSReza Sabdar /*
9982654012fSReza Sabdar * ndmp_send_recovery_stat_v3
9992654012fSReza Sabdar *
10002654012fSReza Sabdar * Send the recovery status to the DMA
10012654012fSReza Sabdar */
10022654012fSReza Sabdar int
ndmp_send_recovery_stat_v3(ndmpd_module_params_t * params,ndmp_lbr_params_t * nlp,int idx,int stat)10032654012fSReza Sabdar ndmp_send_recovery_stat_v3(ndmpd_module_params_t *params,
10042654012fSReza Sabdar ndmp_lbr_params_t *nlp, int idx, int stat)
10052654012fSReza Sabdar {
10062654012fSReza Sabdar int rv;
10072654012fSReza Sabdar mem_ndmp_name_v3_t *ep;
10082654012fSReza Sabdar
10092654012fSReza Sabdar rv = -1;
10102654012fSReza Sabdar if (!params) {
10112654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "params == NULL");
10122654012fSReza Sabdar } else if (!params->mp_file_recovered_func) {
10132654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "paramsfile_recovered_func == NULL");
10142654012fSReza Sabdar } else if (!nlp) {
10152654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL");
10162654012fSReza Sabdar } else if (idx < 0) {
10172654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "idx(%d) < 0", idx);
10182654012fSReza Sabdar } else if (!(ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, idx))) {
10192654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlist[%d] == NULL", idx);
10202654012fSReza Sabdar } else if (!ep->nm3_opath) {
10212654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlist[%d].nm3_opath == NULL", idx);
10222654012fSReza Sabdar } else {
10232654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
10242654012fSReza Sabdar "ep[%d].nm3_opath \"%s\"", idx, ep->nm3_opath);
10252654012fSReza Sabdar rv = MOD_FILERECOVERD(params, ep->nm3_opath, stat);
10262654012fSReza Sabdar }
10272654012fSReza Sabdar
10282654012fSReza Sabdar return (rv);
10292654012fSReza Sabdar }
10302654012fSReza Sabdar
10312654012fSReza Sabdar
10322654012fSReza Sabdar /*
10332654012fSReza Sabdar * ndmpd_path_restored_v3
10342654012fSReza Sabdar *
10352654012fSReza Sabdar * Send the recovery status and the information for the restored
10362654012fSReza Sabdar * path.
10372654012fSReza Sabdar */
10382654012fSReza Sabdar /*ARGSUSED*/
10392654012fSReza Sabdar int
ndmpd_path_restored_v3(lbr_fhlog_call_backs_t * cbp,char * name,struct stat64 * st,u_longlong_t ll_idx)10402654012fSReza Sabdar ndmpd_path_restored_v3(lbr_fhlog_call_backs_t *cbp, char *name,
10412654012fSReza Sabdar struct stat64 *st, u_longlong_t ll_idx)
10422654012fSReza Sabdar {
10432654012fSReza Sabdar int rv;
10442654012fSReza Sabdar ndmp_lbr_params_t *nlp;
10452654012fSReza Sabdar ndmpd_module_params_t *params;
10462654012fSReza Sabdar int idx = (int)ll_idx;
10472654012fSReza Sabdar
10482654012fSReza Sabdar if (!cbp) {
10492654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
10502654012fSReza Sabdar return (-1);
10512654012fSReza Sabdar }
10522654012fSReza Sabdar if (!name) {
10532654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "name is NULL");
10542654012fSReza Sabdar return (-1);
10552654012fSReza Sabdar }
10562654012fSReza Sabdar
10572654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "name: \"%s\", idx: %d", name, idx);
10582654012fSReza Sabdar
10592654012fSReza Sabdar nlp = ndmp_get_nlp(cbp->fh_cookie);
10602654012fSReza Sabdar if (!nlp) {
10612654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
10622654012fSReza Sabdar return (-1);
10632654012fSReza Sabdar }
10642654012fSReza Sabdar if (idx < 0 || idx >= nlp->nlp_nfiles) {
10652654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid idx: %d", idx);
10662654012fSReza Sabdar return (-1);
10672654012fSReza Sabdar }
10682654012fSReza Sabdar params = nlp->nlp_params;
10692654012fSReza Sabdar if (!params || !params->mp_file_recovered_func)
10702654012fSReza Sabdar return (-1);
10712654012fSReza Sabdar
10722654012fSReza Sabdar if (nlp->nlp_lastidx == -1)
10732654012fSReza Sabdar nlp->nlp_lastidx = idx;
10742654012fSReza Sabdar
10752654012fSReza Sabdar rv = 0;
10762654012fSReza Sabdar (void) bm_setone(nlp->nlp_rsbm, (u_longlong_t)idx);
10772654012fSReza Sabdar /*
10782654012fSReza Sabdar * Note: We should set the nm3_err here.
10792654012fSReza Sabdar */
10802654012fSReza Sabdar if (nlp->nlp_lastidx != idx) {
10812654012fSReza Sabdar rv = ndmp_send_recovery_stat_v3(params, nlp, nlp->nlp_lastidx,
10822654012fSReza Sabdar 0);
10832654012fSReza Sabdar nlp->nlp_lastidx = idx;
10842654012fSReza Sabdar }
10852654012fSReza Sabdar
10862654012fSReza Sabdar return (rv);
10872654012fSReza Sabdar }
10882654012fSReza Sabdar
10892654012fSReza Sabdar
10902654012fSReza Sabdar
10912654012fSReza Sabdar /*
10922654012fSReza Sabdar * ndmpd_file_history_init
10932654012fSReza Sabdar *
10942654012fSReza Sabdar * Initialize file history variables.
10952654012fSReza Sabdar * Note that the entry and name buffers are not allocated here.
10962654012fSReza Sabdar * Since it is not know if the backup module will be sending file history
10972654012fSReza Sabdar * data or what kind of data (path or dir/node), the entry and name
10982654012fSReza Sabdar * buffers are not allocated until the first call to one of the file history
10992654012fSReza Sabdar * entry functions is made. This way resources are only allocated as
11002654012fSReza Sabdar * needed.
11012654012fSReza Sabdar *
11022654012fSReza Sabdar * Parameters:
11032654012fSReza Sabdar * session (input) - session pointer.
11042654012fSReza Sabdar *
11052654012fSReza Sabdar * Returns:
11062654012fSReza Sabdar * void
11072654012fSReza Sabdar */
11082654012fSReza Sabdar void
ndmpd_file_history_init(ndmpd_session_t * session)11092654012fSReza Sabdar ndmpd_file_history_init(ndmpd_session_t *session)
11102654012fSReza Sabdar {
11112654012fSReza Sabdar session->ns_fh.fh_path_entries = 0;
11122654012fSReza Sabdar session->ns_fh.fh_dir_entries = 0;
11132654012fSReza Sabdar session->ns_fh.fh_node_entries = 0;
11142654012fSReza Sabdar session->ns_fh.fh_path_name_buf = 0;
11152654012fSReza Sabdar session->ns_fh.fh_dir_name_buf = 0;
11162654012fSReza Sabdar session->ns_fh.fh_path_index = 0;
11172654012fSReza Sabdar session->ns_fh.fh_dir_index = 0;
11182654012fSReza Sabdar session->ns_fh.fh_node_index = 0;
11192654012fSReza Sabdar session->ns_fh.fh_path_name_buf_index = 0;
11202654012fSReza Sabdar session->ns_fh.fh_dir_name_buf_index = 0;
11212654012fSReza Sabdar
11222654012fSReza Sabdar /*
11232654012fSReza Sabdar * V3.
11242654012fSReza Sabdar */
11252654012fSReza Sabdar session->ns_fh_v3.fh_files = 0;
11262654012fSReza Sabdar session->ns_fh_v3.fh_dirs = 0;
11272654012fSReza Sabdar session->ns_fh_v3.fh_nodes = 0;
11282654012fSReza Sabdar session->ns_fh_v3.fh_file_names = 0;
11292654012fSReza Sabdar session->ns_fh_v3.fh_dir_names = 0;
11302654012fSReza Sabdar session->ns_fh_v3.fh_file_stats = 0;
11312654012fSReza Sabdar session->ns_fh_v3.fh_node_stats = 0;
11322654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf = 0;
11332654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf = 0;
11342654012fSReza Sabdar session->ns_fh_v3.fh_file_index = 0;
11352654012fSReza Sabdar session->ns_fh_v3.fh_dir_index = 0;
11362654012fSReza Sabdar session->ns_fh_v3.fh_node_index = 0;
11372654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf_index = 0;
11382654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf_index = 0;
11392654012fSReza Sabdar }
11402654012fSReza Sabdar
11412654012fSReza Sabdar
11422654012fSReza Sabdar /*
11432654012fSReza Sabdar * ndmpd_file_history_cleanup_v2
11442654012fSReza Sabdar *
11452654012fSReza Sabdar * Send (or discard) any buffered file history entries.
11462654012fSReza Sabdar *
11472654012fSReza Sabdar * Parameters:
11482654012fSReza Sabdar * session (input) - session pointer.
11492654012fSReza Sabdar * send_flag (input) - if TRUE buffered entries are sent.
11502654012fSReza Sabdar * if FALSE buffered entries are discarded.
11512654012fSReza Sabdar *
11522654012fSReza Sabdar * Returns:
11532654012fSReza Sabdar * void
11542654012fSReza Sabdar */
11552654012fSReza Sabdar static void
ndmpd_file_history_cleanup_v2(ndmpd_session_t * session,boolean_t send_flag)11562654012fSReza Sabdar ndmpd_file_history_cleanup_v2(ndmpd_session_t *session, boolean_t send_flag)
11572654012fSReza Sabdar {
11582654012fSReza Sabdar if (send_flag == TRUE) {
11592654012fSReza Sabdar (void) ndmpd_api_file_history_path_v2(session, 0, 0, 0);
11602654012fSReza Sabdar (void) ndmpd_api_file_history_dir_v2(session, 0, 0, 0);
11612654012fSReza Sabdar (void) ndmpd_api_file_history_node_v2(session, 0, 0, 0);
11622654012fSReza Sabdar }
11632654012fSReza Sabdar
11642654012fSReza Sabdar if (session->ns_fh.fh_path_entries != 0) {
11652654012fSReza Sabdar free(session->ns_fh.fh_path_entries);
11662654012fSReza Sabdar session->ns_fh.fh_path_entries = 0;
11672654012fSReza Sabdar }
11682654012fSReza Sabdar if (session->ns_fh.fh_dir_entries != 0) {
11692654012fSReza Sabdar free(session->ns_fh.fh_dir_entries);
11702654012fSReza Sabdar session->ns_fh.fh_dir_entries = 0;
11712654012fSReza Sabdar }
11722654012fSReza Sabdar if (session->ns_fh.fh_node_entries != 0) {
11732654012fSReza Sabdar free(session->ns_fh.fh_node_entries);
11742654012fSReza Sabdar session->ns_fh.fh_node_entries = 0;
11752654012fSReza Sabdar }
11762654012fSReza Sabdar if (session->ns_fh.fh_path_name_buf != 0) {
11772654012fSReza Sabdar free(session->ns_fh.fh_path_name_buf);
11782654012fSReza Sabdar session->ns_fh.fh_path_name_buf = 0;
11792654012fSReza Sabdar }
11802654012fSReza Sabdar if (session->ns_fh.fh_dir_name_buf != 0) {
11812654012fSReza Sabdar free(session->ns_fh.fh_dir_name_buf);
11822654012fSReza Sabdar session->ns_fh.fh_dir_name_buf = 0;
11832654012fSReza Sabdar }
11842654012fSReza Sabdar session->ns_fh.fh_path_index = 0;
11852654012fSReza Sabdar session->ns_fh.fh_dir_index = 0;
11862654012fSReza Sabdar session->ns_fh.fh_node_index = 0;
11872654012fSReza Sabdar session->ns_fh.fh_path_name_buf_index = 0;
11882654012fSReza Sabdar session->ns_fh.fh_dir_name_buf_index = 0;
11892654012fSReza Sabdar }
11902654012fSReza Sabdar
11912654012fSReza Sabdar
11922654012fSReza Sabdar /*
11932654012fSReza Sabdar * ndmpd_file_history_cleanup_v3
11942654012fSReza Sabdar *
11952654012fSReza Sabdar * Send (or discard) any buffered file history entries.
11962654012fSReza Sabdar *
11972654012fSReza Sabdar * Parameters:
11982654012fSReza Sabdar * session (input) - session pointer.
11992654012fSReza Sabdar * send_flag (input) - if TRUE buffered entries are sent.
12002654012fSReza Sabdar * if FALSE buffered entries are discarded.
12012654012fSReza Sabdar *
12022654012fSReza Sabdar * Returns:
12032654012fSReza Sabdar * void
12042654012fSReza Sabdar */
12052654012fSReza Sabdar static void
ndmpd_file_history_cleanup_v3(ndmpd_session_t * session,boolean_t send_flag)12062654012fSReza Sabdar ndmpd_file_history_cleanup_v3(ndmpd_session_t *session, boolean_t send_flag)
12072654012fSReza Sabdar {
12082654012fSReza Sabdar if (send_flag == TRUE) {
12092654012fSReza Sabdar (void) ndmpd_api_file_history_file_v3(session, 0, 0, 0);
12102654012fSReza Sabdar (void) ndmpd_api_file_history_dir_v3(session, 0, 0, 0);
12112654012fSReza Sabdar (void) ndmpd_api_file_history_node_v3(session, 0, 0, 0);
12122654012fSReza Sabdar }
12132654012fSReza Sabdar
12142654012fSReza Sabdar if (session->ns_fh_v3.fh_files != 0) {
12152654012fSReza Sabdar free(session->ns_fh_v3.fh_files);
12162654012fSReza Sabdar session->ns_fh_v3.fh_files = 0;
12172654012fSReza Sabdar }
12182654012fSReza Sabdar if (session->ns_fh_v3.fh_dirs != 0) {
12192654012fSReza Sabdar free(session->ns_fh_v3.fh_dirs);
12202654012fSReza Sabdar session->ns_fh_v3.fh_dirs = 0;
12212654012fSReza Sabdar }
12222654012fSReza Sabdar if (session->ns_fh_v3.fh_nodes != 0) {
12232654012fSReza Sabdar free(session->ns_fh_v3.fh_nodes);
12242654012fSReza Sabdar session->ns_fh_v3.fh_nodes = 0;
12252654012fSReza Sabdar }
12262654012fSReza Sabdar if (session->ns_fh_v3.fh_file_names != 0) {
12272654012fSReza Sabdar free(session->ns_fh_v3.fh_file_names);
12282654012fSReza Sabdar session->ns_fh_v3.fh_file_names = 0;
12292654012fSReza Sabdar }
12302654012fSReza Sabdar if (session->ns_fh_v3.fh_dir_names != 0) {
12312654012fSReza Sabdar free(session->ns_fh_v3.fh_dir_names);
12322654012fSReza Sabdar session->ns_fh_v3.fh_dir_names = 0;
12332654012fSReza Sabdar }
12342654012fSReza Sabdar if (session->ns_fh_v3.fh_file_stats != 0) {
12352654012fSReza Sabdar free(session->ns_fh_v3.fh_file_stats);
12362654012fSReza Sabdar session->ns_fh_v3.fh_file_stats = 0;
12372654012fSReza Sabdar }
12382654012fSReza Sabdar if (session->ns_fh_v3.fh_node_stats != 0) {
12392654012fSReza Sabdar free(session->ns_fh_v3.fh_node_stats);
12402654012fSReza Sabdar session->ns_fh_v3.fh_node_stats = 0;
12412654012fSReza Sabdar }
12422654012fSReza Sabdar if (session->ns_fh_v3.fh_file_name_buf != 0) {
12432654012fSReza Sabdar free(session->ns_fh_v3.fh_file_name_buf);
12442654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf = 0;
12452654012fSReza Sabdar }
12462654012fSReza Sabdar if (session->ns_fh_v3.fh_dir_name_buf != 0) {
12472654012fSReza Sabdar free(session->ns_fh_v3.fh_dir_name_buf);
12482654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf = 0;
12492654012fSReza Sabdar }
12502654012fSReza Sabdar
12512654012fSReza Sabdar session->ns_fh_v3.fh_file_index = 0;
12522654012fSReza Sabdar session->ns_fh_v3.fh_dir_index = 0;
12532654012fSReza Sabdar session->ns_fh_v3.fh_node_index = 0;
12542654012fSReza Sabdar session->ns_fh_v3.fh_file_name_buf_index = 0;
12552654012fSReza Sabdar session->ns_fh_v3.fh_dir_name_buf_index = 0;
12562654012fSReza Sabdar }
12572654012fSReza Sabdar
12582654012fSReza Sabdar
12592654012fSReza Sabdar /*
12602654012fSReza Sabdar * ndmpd_file_history_cleanup
12612654012fSReza Sabdar *
12622654012fSReza Sabdar * Send any pending posts and clean up
12632654012fSReza Sabdar */
12642654012fSReza Sabdar void
ndmpd_file_history_cleanup(ndmpd_session_t * session,boolean_t send_flag)12652654012fSReza Sabdar ndmpd_file_history_cleanup(ndmpd_session_t *session, boolean_t send_flag)
12662654012fSReza Sabdar {
12672654012fSReza Sabdar switch (session->ns_protocol_version) {
12682654012fSReza Sabdar case 1:
12692654012fSReza Sabdar case 2:
12702654012fSReza Sabdar ndmpd_file_history_cleanup_v2(session, send_flag);
12712654012fSReza Sabdar break;
12722654012fSReza Sabdar case 3:
12732654012fSReza Sabdar case 4:
12742654012fSReza Sabdar ndmpd_file_history_cleanup_v3(session, send_flag);
12752654012fSReza Sabdar break;
12762654012fSReza Sabdar default:
12772654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Unknown version %d",
12782654012fSReza Sabdar session->ns_protocol_version);
12792654012fSReza Sabdar }
12802654012fSReza Sabdar }
12812654012fSReza Sabdar
12822654012fSReza Sabdar /*
12832654012fSReza Sabdar * get_params
12842654012fSReza Sabdar *
12852654012fSReza Sabdar * Callbacks from LBR.
12862654012fSReza Sabdar */
12872654012fSReza Sabdar static ndmpd_module_params_t *
get_params(void * cookie)12882654012fSReza Sabdar get_params(void *cookie)
12892654012fSReza Sabdar {
12902654012fSReza Sabdar ndmp_lbr_params_t *nlp;
12912654012fSReza Sabdar
12922654012fSReza Sabdar if ((nlp = ndmp_get_nlp(cookie)) == NULL)
12932654012fSReza Sabdar return (NULL);
12942654012fSReza Sabdar
12952654012fSReza Sabdar return (nlp->nlp_params);
12962654012fSReza Sabdar }
12972654012fSReza Sabdar
12982654012fSReza Sabdar
12992654012fSReza Sabdar /*
13002654012fSReza Sabdar * fh_requested
13012654012fSReza Sabdar *
13022654012fSReza Sabdar * Check in LB parameters if file history is requested
13032654012fSReza Sabdar */
13042654012fSReza Sabdar static boolean_t
fh_requested(void * cookie)13052654012fSReza Sabdar fh_requested(void *cookie)
13062654012fSReza Sabdar {
13072654012fSReza Sabdar ndmp_lbr_params_t *nlp;
13082654012fSReza Sabdar
13092654012fSReza Sabdar if ((nlp = ndmp_get_nlp(cookie)) == NULL) {
13102654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
13112654012fSReza Sabdar return (FALSE);
13122654012fSReza Sabdar }
13132654012fSReza Sabdar
13142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_fh %c", NDMP_YORN(NLP_ISSET(nlp, NLPF_FH)));
13152654012fSReza Sabdar
13162654012fSReza Sabdar return (NLP_ISSET(nlp, NLPF_FH));
13172654012fSReza Sabdar }
13182654012fSReza Sabdar
13192654012fSReza Sabdar
13202654012fSReza Sabdar /*
13212654012fSReza Sabdar * ndmpd_file_history_path
13222654012fSReza Sabdar *
13232654012fSReza Sabdar * Generates file history path information posts
13242654012fSReza Sabdar *
13252654012fSReza Sabdar * Note:
13262654012fSReza Sabdar * Action must be determined when the 'dir' and/or 'file'
13272654012fSReza Sabdar * arguments of ndmpd_file_history_path(), ndmpd_file_history_dir(), and
13282654012fSReza Sabdar * ndmpd_file_history_node() are NULL.
13292654012fSReza Sabdar */
13302654012fSReza Sabdar /*ARGSUSED*/
13312654012fSReza Sabdar int
ndmpd_file_history_path(lbr_fhlog_call_backs_t * cbp,char * path,struct stat64 * stp,u_longlong_t off)13322654012fSReza Sabdar ndmpd_file_history_path(lbr_fhlog_call_backs_t *cbp, char *path,
13332654012fSReza Sabdar struct stat64 *stp, u_longlong_t off)
13342654012fSReza Sabdar {
13352654012fSReza Sabdar int err;
13362654012fSReza Sabdar ndmpd_module_params_t *params;
13372654012fSReza Sabdar
13382654012fSReza Sabdar if (!cbp) {
13392654012fSReza Sabdar err = -1;
13402654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
13412654012fSReza Sabdar } else if (!cbp->fh_cookie) {
13422654012fSReza Sabdar err = -1;
13432654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cookie is NULL");
13442654012fSReza Sabdar } else if (!path) {
13452654012fSReza Sabdar err = -1;
13462654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "path is NULL");
13472654012fSReza Sabdar } else if (!stp) {
13482654012fSReza Sabdar err = -1;
13492654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "stp is NULL");
13502654012fSReza Sabdar } else
13512654012fSReza Sabdar err = 0;
13522654012fSReza Sabdar
13532654012fSReza Sabdar if (err != 0)
13542654012fSReza Sabdar return (0);
13552654012fSReza Sabdar
13562654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "path: \"%s\"", path);
13572654012fSReza Sabdar
13582654012fSReza Sabdar err = 0;
13592654012fSReza Sabdar if (fh_requested(cbp->fh_cookie)) {
13602654012fSReza Sabdar params = get_params(cbp->fh_cookie);
13612654012fSReza Sabdar if (params == NULL || params->mp_file_history_path_func == NULL)
13622654012fSReza Sabdar err = -1;
13632654012fSReza Sabdar else if ((err = (*params->mp_file_history_path_func)(cbp->
13642654012fSReza Sabdar fh_cookie, path, stp, 0)) < 0)
13652654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s\": %d", path, err);
13662654012fSReza Sabdar }
13672654012fSReza Sabdar
13682654012fSReza Sabdar return (err);
13692654012fSReza Sabdar }
13702654012fSReza Sabdar
13712654012fSReza Sabdar
13722654012fSReza Sabdar /*
13732654012fSReza Sabdar * ndmpd_file_history_dir
13742654012fSReza Sabdar *
13752654012fSReza Sabdar * Generate file history directory information posts
13762654012fSReza Sabdar */
13772654012fSReza Sabdar int
ndmpd_file_history_dir(lbr_fhlog_call_backs_t * cbp,char * dir,struct stat64 * stp)13782654012fSReza Sabdar ndmpd_file_history_dir(lbr_fhlog_call_backs_t *cbp, char *dir,
13792654012fSReza Sabdar struct stat64 *stp)
13802654012fSReza Sabdar {
13812654012fSReza Sabdar char nm[PATH_MAX+1];
13822654012fSReza Sabdar int nml;
13832654012fSReza Sabdar int err;
13842654012fSReza Sabdar ulong_t ino, pino;
13852654012fSReza Sabdar ulong_t pos;
13862654012fSReza Sabdar ndmp_lbr_params_t *nlp;
13872654012fSReza Sabdar ndmpd_module_params_t *params;
13882654012fSReza Sabdar DIR *dirp;
13892654012fSReza Sabdar char dirpath[PATH_MAX];
13902654012fSReza Sabdar
13912654012fSReza Sabdar if (!cbp) {
13922654012fSReza Sabdar err = -1;
13932654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
13942654012fSReza Sabdar } else if (!cbp->fh_cookie) {
13952654012fSReza Sabdar err = -1;
13962654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cookie is NULL");
13972654012fSReza Sabdar } else if (!dir) {
13982654012fSReza Sabdar err = -1;
13992654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dir is NULL");
14002654012fSReza Sabdar } else if (!stp) {
14012654012fSReza Sabdar err = -1;
14022654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "stp is NULL");
14032654012fSReza Sabdar } if (!(nlp = ndmp_get_nlp(cbp->fh_cookie))) {
14042654012fSReza Sabdar err = -1;
14052654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
14062654012fSReza Sabdar } else
14072654012fSReza Sabdar err = 0;
14082654012fSReza Sabdar
14092654012fSReza Sabdar if (err != 0)
14102654012fSReza Sabdar return (0);
14112654012fSReza Sabdar
14122654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dir: \"%s\"", dir);
14132654012fSReza Sabdar
14142654012fSReza Sabdar if (!fh_requested(cbp->fh_cookie))
14152654012fSReza Sabdar return (0);
14162654012fSReza Sabdar
14172654012fSReza Sabdar /*
14182654012fSReza Sabdar * Veritas net_backup accepts only 2 as the inode number of the backup
14192654012fSReza Sabdar * root directory. The other way compares the path against the
14202654012fSReza Sabdar * backup path which is slower.
14212654012fSReza Sabdar */
14222654012fSReza Sabdar if (stp->st_ino == nlp->nlp_bkdirino)
14232654012fSReza Sabdar pino = ROOT_INODE;
14242654012fSReza Sabdar else
14252654012fSReza Sabdar pino = stp->st_ino;
14262654012fSReza Sabdar
14272654012fSReza Sabdar /*
14282654012fSReza Sabdar * There is nothing below this directory to be backed up.
14292654012fSReza Sabdar * If there was, the bit for this directory would have
14302654012fSReza Sabdar * been set. Backup root directory is exception. We
14312654012fSReza Sabdar * always send the dir file history records of it.
14322654012fSReza Sabdar */
14332654012fSReza Sabdar if (pino != ROOT_INODE &&
14342654012fSReza Sabdar !dbm_getone(nlp->nlp_bkmap, (u_longlong_t)stp->st_ino)) {
14352654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nothing below here");
14362654012fSReza Sabdar return (0);
14372654012fSReza Sabdar }
14382654012fSReza Sabdar
14392654012fSReza Sabdar params = get_params(cbp->fh_cookie);
14402654012fSReza Sabdar if (params == NULL || params->mp_file_history_dir_func == NULL) {
14412654012fSReza Sabdar return (0);
14422654012fSReza Sabdar }
14432654012fSReza Sabdar
14442654012fSReza Sabdar pos = 0;
14452654012fSReza Sabdar err = 0;
14462654012fSReza Sabdar
14472654012fSReza Sabdar dirp = opendir(dir);
14482654012fSReza Sabdar if (dirp == NULL)
14492654012fSReza Sabdar return (0);
14502654012fSReza Sabdar
14512654012fSReza Sabdar do {
14522654012fSReza Sabdar nml = PATH_MAX;
14532654012fSReza Sabdar err = dp_readdir(dirp, &pos, nm, &nml, &ino);
14542654012fSReza Sabdar if (err != 0) {
14552654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
14562654012fSReza Sabdar "%d reading pos %u dir \"%s\"", err, pos, dir);
14572654012fSReza Sabdar break;
14582654012fSReza Sabdar }
14592654012fSReza Sabdar if (nml == 0)
14602654012fSReza Sabdar break;
14612654012fSReza Sabdar nm[nml] = '\0';
14622654012fSReza Sabdar
14632654012fSReza Sabdar if (pino == ROOT_INODE) {
14642654012fSReza Sabdar if (rootfs_dot_or_dotdot(nm))
14652654012fSReza Sabdar ino = ROOT_INODE;
14662654012fSReza Sabdar } else if (ino == nlp->nlp_bkdirino && IS_DOTDOT(nm)) {
14672654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nm(%s): %lu", nm, ino);
14682654012fSReza Sabdar ino = ROOT_INODE;
14692654012fSReza Sabdar }
14702654012fSReza Sabdar
14712654012fSReza Sabdar if (!dbm_getone(nlp->nlp_bkmap, (u_longlong_t)ino))
14722654012fSReza Sabdar continue;
14732654012fSReza Sabdar
14742654012fSReza Sabdar err = (*params->mp_file_history_dir_func)(cbp->fh_cookie, nm,
14752654012fSReza Sabdar ino, pino);
14762654012fSReza Sabdar if (err < 0) {
14772654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/%s\": %d", dir, nm, err);
14782654012fSReza Sabdar break;
14792654012fSReza Sabdar }
14802654012fSReza Sabdar
14812654012fSReza Sabdar /*
14822654012fSReza Sabdar * This is a requirement by some DMA's (net_vault) that during
14832654012fSReza Sabdar * the incremental backup, the node info should also be sent
14842654012fSReza Sabdar * along with the dir info for all directories leading to a
14852654012fSReza Sabdar * backed up file.
14862654012fSReza Sabdar */
14872654012fSReza Sabdar if (ndmp_fhinode) {
14882654012fSReza Sabdar struct stat64 ret_attr;
14892654012fSReza Sabdar
14902654012fSReza Sabdar (void) strlcpy(dirpath, dir, PATH_MAX);
14912654012fSReza Sabdar (void) strlcat(dirpath, "/", PATH_MAX);
14922654012fSReza Sabdar (void) strlcat(dirpath, nm, PATH_MAX);
14932654012fSReza Sabdar err = stat64(dirpath, &ret_attr);
14942654012fSReza Sabdar if (err != 0) {
14952654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
14962654012fSReza Sabdar "Error looking up %s", nm);
14972654012fSReza Sabdar break;
14982654012fSReza Sabdar }
14992654012fSReza Sabdar
15002654012fSReza Sabdar if (S_ISDIR(ret_attr.st_mode)) {
15012654012fSReza Sabdar err = (*params->mp_file_history_node_func)(cbp->
15022654012fSReza Sabdar fh_cookie, ino, &ret_attr, 0);
15032654012fSReza Sabdar if (err < 0) {
15042654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/\": %d",
15052654012fSReza Sabdar dir, err);
15062654012fSReza Sabdar break;
15072654012fSReza Sabdar }
15082654012fSReza Sabdar }
15092654012fSReza Sabdar }
15102654012fSReza Sabdar } while (err == 0);
15112654012fSReza Sabdar
15122654012fSReza Sabdar (void) closedir(dirp);
15132654012fSReza Sabdar return (err);
15142654012fSReza Sabdar }
15152654012fSReza Sabdar
15162654012fSReza Sabdar
15172654012fSReza Sabdar /*
15182654012fSReza Sabdar * ndmpd_file_history_node
15192654012fSReza Sabdar *
15202654012fSReza Sabdar * Generate file history node information posts
15212654012fSReza Sabdar */
15222654012fSReza Sabdar /*ARGSUSED*/
15232654012fSReza Sabdar int
ndmpd_file_history_node(lbr_fhlog_call_backs_t * cbp,char * dir,char * file,struct stat64 * stp,u_longlong_t off)15242654012fSReza Sabdar ndmpd_file_history_node(lbr_fhlog_call_backs_t *cbp, char *dir, char *file,
15252654012fSReza Sabdar struct stat64 *stp, u_longlong_t off)
15262654012fSReza Sabdar {
15272654012fSReza Sabdar int err;
15282654012fSReza Sabdar ulong_t ino;
15292654012fSReza Sabdar ndmp_lbr_params_t *nlp;
15302654012fSReza Sabdar ndmpd_module_params_t *params;
15312654012fSReza Sabdar
15322654012fSReza Sabdar if (!cbp) {
15332654012fSReza Sabdar err = -1;
15342654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
15352654012fSReza Sabdar } else if (!cbp->fh_cookie) {
15362654012fSReza Sabdar err = -1;
15372654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cookie is NULL");
15382654012fSReza Sabdar } else if (!dir) {
15392654012fSReza Sabdar err = -1;
15402654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dir is NULL");
15412654012fSReza Sabdar } else if (!file) {
15422654012fSReza Sabdar err = -1;
15432654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "file is NULL");
15442654012fSReza Sabdar } else if (!stp) {
15452654012fSReza Sabdar err = -1;
15462654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "stp is NULL");
15472654012fSReza Sabdar } else if (!(nlp = ndmp_get_nlp(cbp->fh_cookie))) {
15482654012fSReza Sabdar err = -1;
15492654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
15502654012fSReza Sabdar } else
15512654012fSReza Sabdar err = 0;
15522654012fSReza Sabdar
15532654012fSReza Sabdar if (err != 0)
15542654012fSReza Sabdar return (0);
15552654012fSReza Sabdar
15562654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "d(%s), f(%s)", dir, file);
15572654012fSReza Sabdar
15582654012fSReza Sabdar err = 0;
15592654012fSReza Sabdar if (fh_requested(cbp->fh_cookie) == TRUE) {
15602654012fSReza Sabdar if (stp->st_ino == nlp->nlp_bkdirino) {
15612654012fSReza Sabdar ino = ROOT_INODE;
15622654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
15632654012fSReza Sabdar "bkroot %d -> %d", stp->st_ino, ROOT_INODE);
15642654012fSReza Sabdar } else {
15652654012fSReza Sabdar ino = stp->st_ino;
15662654012fSReza Sabdar }
15672654012fSReza Sabdar
15682654012fSReza Sabdar params = get_params(cbp->fh_cookie);
15692654012fSReza Sabdar if (params == NULL || params->mp_file_history_node_func == NULL)
15702654012fSReza Sabdar err = -1;
15712654012fSReza Sabdar else if ((err = (*params->mp_file_history_node_func)(cbp->
15722654012fSReza Sabdar fh_cookie, ino, stp, 0)) < 0)
15732654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/\": %d", dir, file, err);
15742654012fSReza Sabdar
15752654012fSReza Sabdar }
15762654012fSReza Sabdar
15772654012fSReza Sabdar return (err);
15782654012fSReza Sabdar }
15792654012fSReza Sabdar
15802654012fSReza Sabdar
15812654012fSReza Sabdar /*
15822654012fSReza Sabdar * ndmpd_path_restored
15832654012fSReza Sabdar *
15842654012fSReza Sabdar * Mark the specified path as a restored path
15852654012fSReza Sabdar */
15862654012fSReza Sabdar /*ARGSUSED*/
15872654012fSReza Sabdar int
ndmpd_path_restored(lbr_fhlog_call_backs_t * cbp,char * name,struct stat64 * stp,u_longlong_t ll_pos)15882654012fSReza Sabdar ndmpd_path_restored(lbr_fhlog_call_backs_t *cbp, char *name, struct stat64 *stp,
15892654012fSReza Sabdar u_longlong_t ll_pos)
15902654012fSReza Sabdar {
15912654012fSReza Sabdar int rv;
15922654012fSReza Sabdar ndmp_name *entp;
15932654012fSReza Sabdar ndmp_lbr_params_t *nlp;
15942654012fSReza Sabdar ndmpd_module_params_t *params;
15952654012fSReza Sabdar int pos = (int)ll_pos;
15962654012fSReza Sabdar
15972654012fSReza Sabdar if (cbp == NULL) {
15982654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cbp is NULL");
15992654012fSReza Sabdar return (-1);
16002654012fSReza Sabdar }
16012654012fSReza Sabdar if (name == NULL) {
16022654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "name is NULL");
16032654012fSReza Sabdar return (-1);
16042654012fSReza Sabdar }
16052654012fSReza Sabdar
16062654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "name: \"%s\", pos: %d",
16072654012fSReza Sabdar name, pos);
16082654012fSReza Sabdar
16092654012fSReza Sabdar if ((nlp = ndmp_get_nlp(cbp->fh_cookie)) == NULL) {
16102654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp is NULL");
16112654012fSReza Sabdar return (-1);
16122654012fSReza Sabdar }
16132654012fSReza Sabdar if (pos < 0 || pos >= nlp->nlp_nfiles) {
16142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid pos: %d", pos);
16152654012fSReza Sabdar return (-1);
16162654012fSReza Sabdar }
16172654012fSReza Sabdar params = get_params(cbp->fh_cookie);
16182654012fSReza Sabdar if (params == NULL || params->mp_file_recovered_func == NULL)
16192654012fSReza Sabdar return (-1);
16202654012fSReza Sabdar
16212654012fSReza Sabdar rv = 0;
16222654012fSReza Sabdar if (!nlp->nlp_restored[pos]) {
16232654012fSReza Sabdar entp = (ndmp_name *)MOD_GETNAME(params, pos);
16242654012fSReza Sabdar if (entp && entp->name)
16252654012fSReza Sabdar name = entp->name;
16262654012fSReza Sabdar
16272654012fSReza Sabdar if ((rv = MOD_FILERECOVERD(params, name, 0)) >= 0)
16282654012fSReza Sabdar nlp->nlp_restored[pos] = TRUE;
16292654012fSReza Sabdar }
16302654012fSReza Sabdar
16312654012fSReza Sabdar return (rv);
16322654012fSReza Sabdar }
16332654012fSReza Sabdar
16342654012fSReza Sabdar
16352654012fSReza Sabdar /*
16362654012fSReza Sabdar * dp_readdir
16372654012fSReza Sabdar *
16382654012fSReza Sabdar * Reads the entry of the directory and provides other information
16392654012fSReza Sabdar * such as i-number, name, length and saves the dir entry position
16402654012fSReza Sabdar * in a cookie for future calls.
16412654012fSReza Sabdar */
16422654012fSReza Sabdar int
dp_readdir(DIR * dirp,unsigned long * cookiep,char * name,int * n_namep,unsigned long * fileidp)16432654012fSReza Sabdar dp_readdir(DIR *dirp, unsigned long *cookiep, char *name, int *n_namep,
16442654012fSReza Sabdar unsigned long *fileidp)
16452654012fSReza Sabdar {
16462654012fSReza Sabdar struct dirent *entp;
16472654012fSReza Sabdar int err = errno;
16482654012fSReza Sabdar
16492654012fSReza Sabdar if ((entp = readdir(dirp)) == 0) {
16502654012fSReza Sabdar if (err == errno) {
16512654012fSReza Sabdar *n_namep = 0;
16522654012fSReza Sabdar return (0);
16532654012fSReza Sabdar }
16542654012fSReza Sabdar return (errno);
16552654012fSReza Sabdar }
16562654012fSReza Sabdar
16572654012fSReza Sabdar *fileidp = entp->d_ino;
16582654012fSReza Sabdar (void) strlcpy(name, entp->d_name, *n_namep);
16592654012fSReza Sabdar *n_namep = entp->d_reclen + 1;
16602654012fSReza Sabdar *cookiep = telldir(dirp);
16612654012fSReza Sabdar return (0);
16622654012fSReza Sabdar }
1663