17917SReza.Sabdar@Sun.COM /* 2*8800SReza.Sabdar@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 37917SReza.Sabdar@Sun.COM * Use is subject to license terms. 47917SReza.Sabdar@Sun.COM */ 57917SReza.Sabdar@Sun.COM 67917SReza.Sabdar@Sun.COM /* 77917SReza.Sabdar@Sun.COM * BSD 3 Clause License 87917SReza.Sabdar@Sun.COM * 97917SReza.Sabdar@Sun.COM * Copyright (c) 2007, The Storage Networking Industry Association. 107917SReza.Sabdar@Sun.COM * 117917SReza.Sabdar@Sun.COM * Redistribution and use in source and binary forms, with or without 127917SReza.Sabdar@Sun.COM * modification, are permitted provided that the following conditions 137917SReza.Sabdar@Sun.COM * are met: 147917SReza.Sabdar@Sun.COM * - Redistributions of source code must retain the above copyright 157917SReza.Sabdar@Sun.COM * notice, this list of conditions and the following disclaimer. 167917SReza.Sabdar@Sun.COM * 177917SReza.Sabdar@Sun.COM * - Redistributions in binary form must reproduce the above copyright 187917SReza.Sabdar@Sun.COM * notice, this list of conditions and the following disclaimer in 197917SReza.Sabdar@Sun.COM * the documentation and/or other materials provided with the 207917SReza.Sabdar@Sun.COM * distribution. 217917SReza.Sabdar@Sun.COM * 227917SReza.Sabdar@Sun.COM * - Neither the name of The Storage Networking Industry Association (SNIA) 237917SReza.Sabdar@Sun.COM * nor the names of its contributors may be used to endorse or promote 247917SReza.Sabdar@Sun.COM * products derived from this software without specific prior written 257917SReza.Sabdar@Sun.COM * permission. 267917SReza.Sabdar@Sun.COM * 277917SReza.Sabdar@Sun.COM * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 287917SReza.Sabdar@Sun.COM * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 297917SReza.Sabdar@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 307917SReza.Sabdar@Sun.COM * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 317917SReza.Sabdar@Sun.COM * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 327917SReza.Sabdar@Sun.COM * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 337917SReza.Sabdar@Sun.COM * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 347917SReza.Sabdar@Sun.COM * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 357917SReza.Sabdar@Sun.COM * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 367917SReza.Sabdar@Sun.COM * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 377917SReza.Sabdar@Sun.COM * POSSIBILITY OF SUCH DAMAGE. 387917SReza.Sabdar@Sun.COM */ 397917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */ 407917SReza.Sabdar@Sun.COM 417917SReza.Sabdar@Sun.COM #include <sys/stat.h> 427917SReza.Sabdar@Sun.COM #include <sys/types.h> 437917SReza.Sabdar@Sun.COM #include <sys/socket.h> 447917SReza.Sabdar@Sun.COM #include <errno.h> 457917SReza.Sabdar@Sun.COM #include <stdio.h> 467917SReza.Sabdar@Sun.COM #include <string.h> 477917SReza.Sabdar@Sun.COM #include <unistd.h> 487917SReza.Sabdar@Sun.COM #include <time.h> 497917SReza.Sabdar@Sun.COM #include <cstack.h> 507917SReza.Sabdar@Sun.COM #include <dirent.h> 517917SReza.Sabdar@Sun.COM #include <traverse.h> 527917SReza.Sabdar@Sun.COM #include "bitmap.h" 537917SReza.Sabdar@Sun.COM #include "ndmpd.h" 547917SReza.Sabdar@Sun.COM #include "tlm_buffers.h" 557917SReza.Sabdar@Sun.COM 567917SReza.Sabdar@Sun.COM 577917SReza.Sabdar@Sun.COM typedef struct ndmp_run_args { 587917SReza.Sabdar@Sun.COM char *nr_chkp_nm; 597917SReza.Sabdar@Sun.COM char *nr_unchkp_nm; 607917SReza.Sabdar@Sun.COM char **nr_excls; 617917SReza.Sabdar@Sun.COM } ndmp_run_args_t; 627917SReza.Sabdar@Sun.COM 637917SReza.Sabdar@Sun.COM 647917SReza.Sabdar@Sun.COM /* 657917SReza.Sabdar@Sun.COM * backup_create_structs 667917SReza.Sabdar@Sun.COM * 677917SReza.Sabdar@Sun.COM * Allocate the structures before performing backup 687917SReza.Sabdar@Sun.COM * 697917SReza.Sabdar@Sun.COM * Parameters: 707917SReza.Sabdar@Sun.COM * sesison (input) - session handle 717917SReza.Sabdar@Sun.COM * jname (input) - backup job name 727917SReza.Sabdar@Sun.COM * 737917SReza.Sabdar@Sun.COM * Returns: 747917SReza.Sabdar@Sun.COM * 0: on success 757917SReza.Sabdar@Sun.COM * -1: otherwise 767917SReza.Sabdar@Sun.COM */ 777917SReza.Sabdar@Sun.COM static int 787917SReza.Sabdar@Sun.COM backup_create_structs(ndmpd_session_t *session, char *jname) 797917SReza.Sabdar@Sun.COM { 807917SReza.Sabdar@Sun.COM int n; 817917SReza.Sabdar@Sun.COM long xfer_size; 827917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 837917SReza.Sabdar@Sun.COM tlm_commands_t *cmds; 847917SReza.Sabdar@Sun.COM 857917SReza.Sabdar@Sun.COM if ((nlp = ndmp_get_nlp(session)) == NULL) { 867917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 877917SReza.Sabdar@Sun.COM return (-1); 887917SReza.Sabdar@Sun.COM } 897917SReza.Sabdar@Sun.COM 907917SReza.Sabdar@Sun.COM if ((nlp->nlp_jstat = tlm_new_job_stats(jname)) == NULL) { 917917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Creating job stats"); 927917SReza.Sabdar@Sun.COM return (-1); 937917SReza.Sabdar@Sun.COM } 947917SReza.Sabdar@Sun.COM 957917SReza.Sabdar@Sun.COM cmds = &nlp->nlp_cmds; 967917SReza.Sabdar@Sun.COM (void) memset(cmds, 0, sizeof (*cmds)); 977917SReza.Sabdar@Sun.COM 987917SReza.Sabdar@Sun.COM xfer_size = ndmp_buffer_get_size(session); 997917SReza.Sabdar@Sun.COM if (xfer_size < 512*KILOBYTE) { 1007917SReza.Sabdar@Sun.COM /* 1017917SReza.Sabdar@Sun.COM * Read multiple of mover_record_size near to 512K. This 1027917SReza.Sabdar@Sun.COM * will prevent the data being copied in the mover buffer 1037917SReza.Sabdar@Sun.COM * when we write the data. 1047917SReza.Sabdar@Sun.COM */ 1057917SReza.Sabdar@Sun.COM if ((n = (512 * KILOBYTE/xfer_size)) <= 0) 1067917SReza.Sabdar@Sun.COM n = 1; 1077917SReza.Sabdar@Sun.COM xfer_size *= n; 1087917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Adjusted read size: %d", xfer_size); 1097917SReza.Sabdar@Sun.COM } 1107917SReza.Sabdar@Sun.COM 1117917SReza.Sabdar@Sun.COM cmds->tcs_command = tlm_create_reader_writer_ipc(TRUE, xfer_size); 1127917SReza.Sabdar@Sun.COM if (cmds->tcs_command == NULL) { 1137917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Error creating ipc buffers"); 1147917SReza.Sabdar@Sun.COM tlm_un_ref_job_stats(jname); 1157917SReza.Sabdar@Sun.COM return (-1); 1167917SReza.Sabdar@Sun.COM } 1177917SReza.Sabdar@Sun.COM 1187917SReza.Sabdar@Sun.COM nlp->nlp_logcallbacks = lbrlog_callbacks_init(session, 1197917SReza.Sabdar@Sun.COM ndmpd_file_history_path, 1207917SReza.Sabdar@Sun.COM ndmpd_file_history_dir, 1217917SReza.Sabdar@Sun.COM ndmpd_file_history_node); 1227917SReza.Sabdar@Sun.COM if (nlp->nlp_logcallbacks == NULL) { 1237917SReza.Sabdar@Sun.COM tlm_release_reader_writer_ipc(cmds->tcs_command); 1247917SReza.Sabdar@Sun.COM tlm_un_ref_job_stats(jname); 1257917SReza.Sabdar@Sun.COM return (-1); 1267917SReza.Sabdar@Sun.COM } 1277917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_callbacks = (void *)(nlp->nlp_logcallbacks); 1287917SReza.Sabdar@Sun.COM 1297917SReza.Sabdar@Sun.COM return (0); 1307917SReza.Sabdar@Sun.COM } 1317917SReza.Sabdar@Sun.COM 1327917SReza.Sabdar@Sun.COM 1337917SReza.Sabdar@Sun.COM /* 1347917SReza.Sabdar@Sun.COM * restore_create_structs 1357917SReza.Sabdar@Sun.COM * 1367917SReza.Sabdar@Sun.COM * Allocate structures for performing a restore 1377917SReza.Sabdar@Sun.COM * 1387917SReza.Sabdar@Sun.COM * Parameters: 1397917SReza.Sabdar@Sun.COM * sesison (input) - session handle 1407917SReza.Sabdar@Sun.COM * jname (input) - backup job name 1417917SReza.Sabdar@Sun.COM * 1427917SReza.Sabdar@Sun.COM * Returns: 1437917SReza.Sabdar@Sun.COM * 0: on success 1447917SReza.Sabdar@Sun.COM * -1: otherwise 1457917SReza.Sabdar@Sun.COM */ 1467917SReza.Sabdar@Sun.COM static int 1477917SReza.Sabdar@Sun.COM restore_create_structs(ndmpd_session_t *session, char *jname) 1487917SReza.Sabdar@Sun.COM { 1497917SReza.Sabdar@Sun.COM int i; 1507917SReza.Sabdar@Sun.COM long xfer_size; 1517917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 1527917SReza.Sabdar@Sun.COM tlm_commands_t *cmds; 1537917SReza.Sabdar@Sun.COM 1547917SReza.Sabdar@Sun.COM if ((nlp = ndmp_get_nlp(session)) == NULL) { 1557917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1567917SReza.Sabdar@Sun.COM return (-1); 1577917SReza.Sabdar@Sun.COM } 1587917SReza.Sabdar@Sun.COM if ((nlp->nlp_jstat = tlm_new_job_stats(jname)) == NULL) { 1597917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Creating job stats"); 1607917SReza.Sabdar@Sun.COM return (-1); 1617917SReza.Sabdar@Sun.COM } 1627917SReza.Sabdar@Sun.COM 1637917SReza.Sabdar@Sun.COM cmds = &nlp->nlp_cmds; 1647917SReza.Sabdar@Sun.COM (void) memset(cmds, 0, sizeof (*cmds)); 1657917SReza.Sabdar@Sun.COM 1667917SReza.Sabdar@Sun.COM xfer_size = ndmp_buffer_get_size(session); 1677917SReza.Sabdar@Sun.COM cmds->tcs_command = tlm_create_reader_writer_ipc(FALSE, xfer_size); 1687917SReza.Sabdar@Sun.COM if (cmds->tcs_command == NULL) { 1697917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Error creating ipc buffers"); 1707917SReza.Sabdar@Sun.COM tlm_un_ref_job_stats(jname); 1717917SReza.Sabdar@Sun.COM return (-1); 1727917SReza.Sabdar@Sun.COM } 1737917SReza.Sabdar@Sun.COM 1747917SReza.Sabdar@Sun.COM nlp->nlp_logcallbacks = lbrlog_callbacks_init(session, 1757917SReza.Sabdar@Sun.COM ndmpd_path_restored, NULL, NULL); 1767917SReza.Sabdar@Sun.COM if (nlp->nlp_logcallbacks == NULL) { 1777917SReza.Sabdar@Sun.COM tlm_release_reader_writer_ipc(cmds->tcs_command); 1787917SReza.Sabdar@Sun.COM tlm_un_ref_job_stats(jname); 1797917SReza.Sabdar@Sun.COM return (-1); 1807917SReza.Sabdar@Sun.COM } 1817917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_callbacks = (void *)(nlp->nlp_logcallbacks); 1827917SReza.Sabdar@Sun.COM 1837917SReza.Sabdar@Sun.COM nlp->nlp_restored = ndmp_malloc(sizeof (boolean_t) * nlp->nlp_nfiles); 1847917SReza.Sabdar@Sun.COM if (nlp->nlp_restored == NULL) { 1857917SReza.Sabdar@Sun.COM lbrlog_callbacks_done(nlp->nlp_logcallbacks); 1867917SReza.Sabdar@Sun.COM tlm_release_reader_writer_ipc(cmds->tcs_command); 1877917SReza.Sabdar@Sun.COM tlm_un_ref_job_stats(jname); 1887917SReza.Sabdar@Sun.COM return (-1); 1897917SReza.Sabdar@Sun.COM } 1907917SReza.Sabdar@Sun.COM for (i = 0; i < (int)nlp->nlp_nfiles; i++) 1917917SReza.Sabdar@Sun.COM nlp->nlp_restored[i] = FALSE; 1927917SReza.Sabdar@Sun.COM 1937917SReza.Sabdar@Sun.COM return (0); 1947917SReza.Sabdar@Sun.COM } 1957917SReza.Sabdar@Sun.COM 1967917SReza.Sabdar@Sun.COM 1977917SReza.Sabdar@Sun.COM /* 1987917SReza.Sabdar@Sun.COM * send_unrecovered_list 1997917SReza.Sabdar@Sun.COM * 2007917SReza.Sabdar@Sun.COM * Creates a list of restored files 2017917SReza.Sabdar@Sun.COM * 2027917SReza.Sabdar@Sun.COM * Parameters: 2037917SReza.Sabdar@Sun.COM * params (input) - NDMP parameters 2047917SReza.Sabdar@Sun.COM * nlp (input) - NDMP/LBR parameters 2057917SReza.Sabdar@Sun.COM * 2067917SReza.Sabdar@Sun.COM * Returns: 2077917SReza.Sabdar@Sun.COM * 0: on success 2087917SReza.Sabdar@Sun.COM * -1: otherwise 2097917SReza.Sabdar@Sun.COM */ 2107917SReza.Sabdar@Sun.COM static int 2117917SReza.Sabdar@Sun.COM send_unrecovered_list(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp) 2127917SReza.Sabdar@Sun.COM { 2137917SReza.Sabdar@Sun.COM int i, rv; 2147917SReza.Sabdar@Sun.COM ndmp_name *ent; 2157917SReza.Sabdar@Sun.COM 2167917SReza.Sabdar@Sun.COM if (params == NULL) { 2177917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "params == NULL"); 2187917SReza.Sabdar@Sun.COM return (-1); 2197917SReza.Sabdar@Sun.COM } 2207917SReza.Sabdar@Sun.COM if (nlp == NULL) { 2217917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 2227917SReza.Sabdar@Sun.COM return (-1); 2237917SReza.Sabdar@Sun.COM } 2247917SReza.Sabdar@Sun.COM 2257917SReza.Sabdar@Sun.COM rv = 0; 2267917SReza.Sabdar@Sun.COM for (i = 0; i < (int)nlp->nlp_nfiles; i++) { 2277917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp->nlp_restored[%d]: %s", i, 2287917SReza.Sabdar@Sun.COM nlp->nlp_restored[i] ? "TRUE" : "FALSE"); 2297917SReza.Sabdar@Sun.COM 2307917SReza.Sabdar@Sun.COM if (!nlp->nlp_restored[i]) { 2317917SReza.Sabdar@Sun.COM ent = (ndmp_name *)MOD_GETNAME(params, i); 2327917SReza.Sabdar@Sun.COM if (ent == NULL) { 2337917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "ent == NULL"); 2347917SReza.Sabdar@Sun.COM rv = -1; 2357917SReza.Sabdar@Sun.COM break; 2367917SReza.Sabdar@Sun.COM } 2377917SReza.Sabdar@Sun.COM if (ent->name == NULL) { 2387917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "ent->name == NULL"); 2397917SReza.Sabdar@Sun.COM rv = -1; 2407917SReza.Sabdar@Sun.COM break; 2417917SReza.Sabdar@Sun.COM } 2427917SReza.Sabdar@Sun.COM 2437917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "ent.name: \"%s\"", ent->name); 2447917SReza.Sabdar@Sun.COM 2457917SReza.Sabdar@Sun.COM rv = MOD_FILERECOVERD(params, ent->name, ENOENT); 2467917SReza.Sabdar@Sun.COM if (rv < 0) 2477917SReza.Sabdar@Sun.COM break; 2487917SReza.Sabdar@Sun.COM } 2497917SReza.Sabdar@Sun.COM } 2507917SReza.Sabdar@Sun.COM 2517917SReza.Sabdar@Sun.COM return (rv); 2527917SReza.Sabdar@Sun.COM } 2537917SReza.Sabdar@Sun.COM 2547917SReza.Sabdar@Sun.COM 2557917SReza.Sabdar@Sun.COM /* 2567917SReza.Sabdar@Sun.COM * backup_release_structs 2577917SReza.Sabdar@Sun.COM * 2587917SReza.Sabdar@Sun.COM * Deallocated the NDMP/LBR specific parameters 2597917SReza.Sabdar@Sun.COM * 2607917SReza.Sabdar@Sun.COM * Parameters: 2617917SReza.Sabdar@Sun.COM * session (input) - session handle 2627917SReza.Sabdar@Sun.COM * 2637917SReza.Sabdar@Sun.COM * Returns: 2647917SReza.Sabdar@Sun.COM * void 2657917SReza.Sabdar@Sun.COM */ 2667917SReza.Sabdar@Sun.COM /*ARGSUSED*/ 2677917SReza.Sabdar@Sun.COM static void 2687917SReza.Sabdar@Sun.COM backup_release_structs(ndmpd_session_t *session) 2697917SReza.Sabdar@Sun.COM { 2707917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 2717917SReza.Sabdar@Sun.COM tlm_commands_t *cmds; 2727917SReza.Sabdar@Sun.COM 2737917SReza.Sabdar@Sun.COM if ((nlp = ndmp_get_nlp(session)) == NULL) { 2747917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 2757917SReza.Sabdar@Sun.COM return; 2767917SReza.Sabdar@Sun.COM } 2777917SReza.Sabdar@Sun.COM cmds = &nlp->nlp_cmds; 2787917SReza.Sabdar@Sun.COM if (cmds == NULL) { 2797917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 2807917SReza.Sabdar@Sun.COM return; 2817917SReza.Sabdar@Sun.COM } 2827917SReza.Sabdar@Sun.COM 2837917SReza.Sabdar@Sun.COM if (nlp->nlp_logcallbacks != NULL) { 2847917SReza.Sabdar@Sun.COM lbrlog_callbacks_done(nlp->nlp_logcallbacks); 2857917SReza.Sabdar@Sun.COM nlp->nlp_logcallbacks = NULL; 2867917SReza.Sabdar@Sun.COM } else { 2877917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "FH CALLBACKS == NULL"); 2887917SReza.Sabdar@Sun.COM } 2897917SReza.Sabdar@Sun.COM 2907917SReza.Sabdar@Sun.COM if (cmds->tcs_command != NULL) { 2917917SReza.Sabdar@Sun.COM if (cmds->tcs_command->tc_buffers != NULL) 2927917SReza.Sabdar@Sun.COM tlm_release_reader_writer_ipc(cmds->tcs_command); 2937917SReza.Sabdar@Sun.COM else 2947917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "BUFFERS == NULL"); 2957917SReza.Sabdar@Sun.COM cmds->tcs_command = NULL; 2967917SReza.Sabdar@Sun.COM } else { 2977917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "COMMAND == NULL"); 2987917SReza.Sabdar@Sun.COM } 2997917SReza.Sabdar@Sun.COM 3007917SReza.Sabdar@Sun.COM if (nlp->nlp_bkmap >= 0) { 3017917SReza.Sabdar@Sun.COM (void) dbm_free(nlp->nlp_bkmap); 3027917SReza.Sabdar@Sun.COM nlp->nlp_bkmap = -1; 3037917SReza.Sabdar@Sun.COM } 3047917SReza.Sabdar@Sun.COM 3057917SReza.Sabdar@Sun.COM if (session->ns_data.dd_operation == NDMP_DATA_OP_RECOVER && 3067917SReza.Sabdar@Sun.COM nlp->nlp_restored != NULL) { 3077917SReza.Sabdar@Sun.COM free(nlp->nlp_restored); 3087917SReza.Sabdar@Sun.COM nlp->nlp_restored = NULL; 3097917SReza.Sabdar@Sun.COM } else { 3107917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp_restored == NULL"); 3117917SReza.Sabdar@Sun.COM } 3127917SReza.Sabdar@Sun.COM } 3137917SReza.Sabdar@Sun.COM 3147917SReza.Sabdar@Sun.COM /* 3157917SReza.Sabdar@Sun.COM * ndmp_write_utf8magic 3167917SReza.Sabdar@Sun.COM * 3177917SReza.Sabdar@Sun.COM * Write a magic pattern to the tar header. This is used 3187917SReza.Sabdar@Sun.COM * as a crest to indicate that tape belongs to us. 3197917SReza.Sabdar@Sun.COM */ 3207917SReza.Sabdar@Sun.COM int 3217917SReza.Sabdar@Sun.COM ndmp_write_utf8magic(tlm_cmd_t *cmd) 3227917SReza.Sabdar@Sun.COM { 3237917SReza.Sabdar@Sun.COM char *cp; 3247917SReza.Sabdar@Sun.COM long actual_size; 3257917SReza.Sabdar@Sun.COM 3267917SReza.Sabdar@Sun.COM if (cmd->tc_buffers == NULL) { 3277917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "cmd->tc_buffers == NULL"); 3287917SReza.Sabdar@Sun.COM return (-1); 3297917SReza.Sabdar@Sun.COM } 3307917SReza.Sabdar@Sun.COM 3317917SReza.Sabdar@Sun.COM cp = tlm_get_write_buffer(RECORDSIZE, &actual_size, 3327917SReza.Sabdar@Sun.COM cmd->tc_buffers, TRUE); 3337917SReza.Sabdar@Sun.COM if (actual_size < RECORDSIZE) { 3347917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Couldn't get enough buffer"); 3357917SReza.Sabdar@Sun.COM return (-1); 3367917SReza.Sabdar@Sun.COM } 3377917SReza.Sabdar@Sun.COM 3387917SReza.Sabdar@Sun.COM (void) strlcpy(cp, NDMPUTF8MAGIC, RECORDSIZE); 3397917SReza.Sabdar@Sun.COM return (0); 3407917SReza.Sabdar@Sun.COM } 3417917SReza.Sabdar@Sun.COM 3427917SReza.Sabdar@Sun.COM 3437917SReza.Sabdar@Sun.COM /* 3447917SReza.Sabdar@Sun.COM * timecmp 3457917SReza.Sabdar@Sun.COM * 3467917SReza.Sabdar@Sun.COM * This callback function is used during backup. It checks 3477917SReza.Sabdar@Sun.COM * if the object specified by the 'attr' should be backed 3487917SReza.Sabdar@Sun.COM * up or not. 3497917SReza.Sabdar@Sun.COM * 3507917SReza.Sabdar@Sun.COM * Directories are backed up anyways for dump format. 3517917SReza.Sabdar@Sun.COM * If this function is called, then the directory is 3527917SReza.Sabdar@Sun.COM * marked in the bitmap vector, it shows that either the 3537917SReza.Sabdar@Sun.COM * directory itself is modified or there is something below 3547917SReza.Sabdar@Sun.COM * it that will be backed up. 3557917SReza.Sabdar@Sun.COM * 3567917SReza.Sabdar@Sun.COM * Directories for tar format are backed up if and only if 3577917SReza.Sabdar@Sun.COM * they are modified. 3587917SReza.Sabdar@Sun.COM * 3597917SReza.Sabdar@Sun.COM * By setting ndmp_force_bk_dirs global variable to a non-zero 3607917SReza.Sabdar@Sun.COM * value, directories are backed up anyways. 3617917SReza.Sabdar@Sun.COM * 3627917SReza.Sabdar@Sun.COM * Backing up the directories unconditionally, helps 3637917SReza.Sabdar@Sun.COM * restoring the metadata of directories as well, when one 3647917SReza.Sabdar@Sun.COM * of the objects below them are being restored. 3657917SReza.Sabdar@Sun.COM * 3667917SReza.Sabdar@Sun.COM * For non-directory objects, if the modification or change 3677917SReza.Sabdar@Sun.COM * time of the object is after the date specified by the 3687917SReza.Sabdar@Sun.COM * bk_selector_t, the the object must be backed up. 3697917SReza.Sabdar@Sun.COM * 3707917SReza.Sabdar@Sun.COM */ 3717917SReza.Sabdar@Sun.COM static boolean_t 3727917SReza.Sabdar@Sun.COM timecmp(bk_selector_t *bksp, 3737917SReza.Sabdar@Sun.COM struct stat64 *attr) 3747917SReza.Sabdar@Sun.COM { 3757917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 3767917SReza.Sabdar@Sun.COM 3777917SReza.Sabdar@Sun.COM nlp = (ndmp_lbr_params_t *)bksp->bs_cookie; 3787917SReza.Sabdar@Sun.COM if (S_ISDIR(attr->st_mode) && ndmp_force_bk_dirs) { 3797917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "d(%lu)", 3807917SReza.Sabdar@Sun.COM (uint_t)attr->st_ino); 3817917SReza.Sabdar@Sun.COM return (TRUE); 3827917SReza.Sabdar@Sun.COM } 3837917SReza.Sabdar@Sun.COM if (S_ISDIR(attr->st_mode) && 3847917SReza.Sabdar@Sun.COM dbm_getone(nlp->nlp_bkmap, (u_longlong_t)attr->st_ino) && 3857917SReza.Sabdar@Sun.COM ((NLP_ISDUMP(nlp) && ndmp_dump_path_node) || 3867917SReza.Sabdar@Sun.COM (NLP_ISTAR(nlp) && ndmp_tar_path_node))) { 3877917SReza.Sabdar@Sun.COM /* 3887917SReza.Sabdar@Sun.COM * If the object is a directory and it leads to a modified 3897917SReza.Sabdar@Sun.COM * object (that should be backed up) and for that type of 3907917SReza.Sabdar@Sun.COM * backup the path nodes should be backed up, then return 3917917SReza.Sabdar@Sun.COM * TRUE. 3927917SReza.Sabdar@Sun.COM * 3937917SReza.Sabdar@Sun.COM * This is required by some DMAs like Backup Express, which 3947917SReza.Sabdar@Sun.COM * needs to receive ADD_NODE (for dump) or ADD_PATH (for tar) 3957917SReza.Sabdar@Sun.COM * for the intermediate directories of a modified object. 3967917SReza.Sabdar@Sun.COM * Other DMAs, like net_backup and net_worker, do not have such 3977917SReza.Sabdar@Sun.COM * requirement. This requirement makes sense for dump format 3987917SReza.Sabdar@Sun.COM * but for 'tar' format, it does not. In provision to the 3997917SReza.Sabdar@Sun.COM * NDMP-v4 spec, for 'tar' format the intermediate directories 4007917SReza.Sabdar@Sun.COM * need not to be reported. 4017917SReza.Sabdar@Sun.COM */ 4027917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "p(%lu)", (u_longlong_t)attr->st_ino); 4037917SReza.Sabdar@Sun.COM return (TRUE); 4047917SReza.Sabdar@Sun.COM } 4057917SReza.Sabdar@Sun.COM if (attr->st_mtime > bksp->bs_ldate) { 4067917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "m(%lu): %lu > %lu", 4077917SReza.Sabdar@Sun.COM (uint_t)attr->st_ino, (uint_t)attr->st_mtime, 4087917SReza.Sabdar@Sun.COM (uint_t)bksp->bs_ldate); 4097917SReza.Sabdar@Sun.COM return (TRUE); 4107917SReza.Sabdar@Sun.COM } 4117917SReza.Sabdar@Sun.COM if (attr->st_ctime > bksp->bs_ldate) { 4127917SReza.Sabdar@Sun.COM if (NLP_IGNCTIME(nlp)) { 4137917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "ign c(%lu): %lu > %lu", 4147917SReza.Sabdar@Sun.COM (uint_t)attr->st_ino, (uint_t)attr->st_ctime, 4157917SReza.Sabdar@Sun.COM (uint_t)bksp->bs_ldate); 4167917SReza.Sabdar@Sun.COM return (FALSE); 4177917SReza.Sabdar@Sun.COM } 4187917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "c(%lu): %lu > %lu", 4197917SReza.Sabdar@Sun.COM (uint_t)attr->st_ino, (uint_t)attr->st_ctime, 4207917SReza.Sabdar@Sun.COM (uint_t)bksp->bs_ldate); 4217917SReza.Sabdar@Sun.COM return (TRUE); 4227917SReza.Sabdar@Sun.COM } 4237917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "mc(%lu): (%lu,%lu) < %lu", 4247917SReza.Sabdar@Sun.COM (uint_t)attr->st_ino, (uint_t)attr->st_mtime, 4257917SReza.Sabdar@Sun.COM (uint_t)attr->st_ctime, (uint_t)bksp->bs_ldate); 4267917SReza.Sabdar@Sun.COM return (FALSE); 4277917SReza.Sabdar@Sun.COM } 4287917SReza.Sabdar@Sun.COM 4297917SReza.Sabdar@Sun.COM 4307917SReza.Sabdar@Sun.COM /* 4317917SReza.Sabdar@Sun.COM * get_acl_info 4327917SReza.Sabdar@Sun.COM * 4337917SReza.Sabdar@Sun.COM * load up all the access and attribute info 4347917SReza.Sabdar@Sun.COM */ 4357917SReza.Sabdar@Sun.COM static int 4367917SReza.Sabdar@Sun.COM get_acl_info(char *name, tlm_acls_t *tlm_acls) 4377917SReza.Sabdar@Sun.COM { 4387917SReza.Sabdar@Sun.COM int erc; 4397917SReza.Sabdar@Sun.COM acl_t *aclp = NULL; 4407917SReza.Sabdar@Sun.COM char *acltp; 4417917SReza.Sabdar@Sun.COM 4427917SReza.Sabdar@Sun.COM erc = lstat64(name, &tlm_acls->acl_attr); 4437917SReza.Sabdar@Sun.COM if (erc != 0) { 4447917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Could not find file %s.", name); 4457917SReza.Sabdar@Sun.COM erc = TLM_NO_SOURCE_FILE; 4467917SReza.Sabdar@Sun.COM return (erc); 4477917SReza.Sabdar@Sun.COM } 4487917SReza.Sabdar@Sun.COM erc = acl_get(name, ACL_NO_TRIVIAL, &aclp); 4497917SReza.Sabdar@Sun.COM if (erc != 0) { 4507917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 4517917SReza.Sabdar@Sun.COM "Could not read ACL for file [%s]", name); 4527917SReza.Sabdar@Sun.COM erc = TLM_NO_SOURCE_FILE; 4537917SReza.Sabdar@Sun.COM return (erc); 4547917SReza.Sabdar@Sun.COM } 4557917SReza.Sabdar@Sun.COM if (aclp && (acltp = acl_totext(aclp, 4567917SReza.Sabdar@Sun.COM ACL_APPEND_ID | ACL_SID_FMT | ACL_COMPACT_FMT)) != NULL) { 4577917SReza.Sabdar@Sun.COM (void) strlcpy(tlm_acls->acl_info.attr_info, acltp, 4587917SReza.Sabdar@Sun.COM TLM_MAX_ACL_TXT); 4597917SReza.Sabdar@Sun.COM acl_free(aclp); 4607917SReza.Sabdar@Sun.COM free(acltp); 4617917SReza.Sabdar@Sun.COM } 4627917SReza.Sabdar@Sun.COM return (erc); 4637917SReza.Sabdar@Sun.COM } 4647917SReza.Sabdar@Sun.COM /* 4657917SReza.Sabdar@Sun.COM * get_dir_acl_info 4667917SReza.Sabdar@Sun.COM * 4677917SReza.Sabdar@Sun.COM * load up all ACL and attr info about a directory 4687917SReza.Sabdar@Sun.COM */ 4697917SReza.Sabdar@Sun.COM static int 4707917SReza.Sabdar@Sun.COM get_dir_acl_info(char *dir, tlm_acls_t *tlm_acls, tlm_job_stats_t *js) 4717917SReza.Sabdar@Sun.COM { 4727917SReza.Sabdar@Sun.COM int erc; 4737917SReza.Sabdar@Sun.COM char *checkpointed_dir; 4747917SReza.Sabdar@Sun.COM char root_dir[TLM_VOLNAME_MAX_LENGTH]; 4757917SReza.Sabdar@Sun.COM char *spot; 4767917SReza.Sabdar@Sun.COM char *fil; 4777917SReza.Sabdar@Sun.COM acl_t *aclp = NULL; 4787917SReza.Sabdar@Sun.COM char *acltp; 4797917SReza.Sabdar@Sun.COM 4807917SReza.Sabdar@Sun.COM checkpointed_dir = ndmp_malloc(TLM_MAX_PATH_NAME); 4817917SReza.Sabdar@Sun.COM if (checkpointed_dir == NULL) 4827917SReza.Sabdar@Sun.COM return (-1); 4837917SReza.Sabdar@Sun.COM 4847917SReza.Sabdar@Sun.COM if (tlm_acls->acl_checkpointed) 4857917SReza.Sabdar@Sun.COM fil = tlm_build_snapshot_name(dir, checkpointed_dir, 4867917SReza.Sabdar@Sun.COM js->js_job_name); 4877917SReza.Sabdar@Sun.COM else 4887917SReza.Sabdar@Sun.COM fil = dir; 4897917SReza.Sabdar@Sun.COM erc = lstat64(fil, &tlm_acls->acl_attr); 4907917SReza.Sabdar@Sun.COM if (erc != 0) { 4917917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Could not find directory %s.", dir); 4927917SReza.Sabdar@Sun.COM free(checkpointed_dir); 4937917SReza.Sabdar@Sun.COM return (-1); 4947917SReza.Sabdar@Sun.COM } 4957917SReza.Sabdar@Sun.COM 4967917SReza.Sabdar@Sun.COM spot = strchr(&fil[1], '/'); 4977917SReza.Sabdar@Sun.COM if (spot == NULL) { 4987917SReza.Sabdar@Sun.COM (void) strlcpy(root_dir, fil, TLM_VOLNAME_MAX_LENGTH); 4997917SReza.Sabdar@Sun.COM } else { 5007917SReza.Sabdar@Sun.COM *spot = 0; 5017917SReza.Sabdar@Sun.COM (void) strlcpy(root_dir, fil, TLM_VOLNAME_MAX_LENGTH); 5027917SReza.Sabdar@Sun.COM *spot = '/'; 5037917SReza.Sabdar@Sun.COM } 5047917SReza.Sabdar@Sun.COM if (strcmp(root_dir, tlm_acls->acl_root_dir) != 0) { 5057917SReza.Sabdar@Sun.COM struct stat64 attr; 5067917SReza.Sabdar@Sun.COM 5077917SReza.Sabdar@Sun.COM erc = lstat64(root_dir, &attr); 5087917SReza.Sabdar@Sun.COM if (erc != 0) { 5097917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Cannot find root directory %s.", 5107917SReza.Sabdar@Sun.COM root_dir); 5117917SReza.Sabdar@Sun.COM free(checkpointed_dir); 5127917SReza.Sabdar@Sun.COM return (-1); 5137917SReza.Sabdar@Sun.COM } 5147917SReza.Sabdar@Sun.COM (void) strlcpy(tlm_acls->acl_root_dir, root_dir, 5157917SReza.Sabdar@Sun.COM TLM_VOLNAME_MAX_LENGTH); 5167917SReza.Sabdar@Sun.COM } 5177917SReza.Sabdar@Sun.COM erc = acl_get(fil, ACL_NO_TRIVIAL, &aclp); 5187917SReza.Sabdar@Sun.COM if (erc != 0) { 5197917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 5207917SReza.Sabdar@Sun.COM "Could not read metadata for directory [%s]", dir); 5217917SReza.Sabdar@Sun.COM free(checkpointed_dir); 5227917SReza.Sabdar@Sun.COM return (-1); 5237917SReza.Sabdar@Sun.COM } 5247917SReza.Sabdar@Sun.COM if (aclp && (acltp = acl_totext(aclp, 5257917SReza.Sabdar@Sun.COM ACL_APPEND_ID | ACL_SID_FMT | ACL_COMPACT_FMT)) != NULL) { 5267917SReza.Sabdar@Sun.COM (void) strlcpy(tlm_acls->acl_info.attr_info, acltp, 5277917SReza.Sabdar@Sun.COM TLM_MAX_ACL_TXT); 5287917SReza.Sabdar@Sun.COM acl_free(aclp); 5297917SReza.Sabdar@Sun.COM free(acltp); 5307917SReza.Sabdar@Sun.COM } 5317917SReza.Sabdar@Sun.COM 5327917SReza.Sabdar@Sun.COM free(checkpointed_dir); 5337917SReza.Sabdar@Sun.COM return (0); 5347917SReza.Sabdar@Sun.COM } 5357917SReza.Sabdar@Sun.COM 5367917SReza.Sabdar@Sun.COM /* 5377917SReza.Sabdar@Sun.COM * backup_dir 5387917SReza.Sabdar@Sun.COM * 5397917SReza.Sabdar@Sun.COM * Create a TAR entry record for a directory 5407917SReza.Sabdar@Sun.COM */ 5417917SReza.Sabdar@Sun.COM static int 5427917SReza.Sabdar@Sun.COM backup_dir(char *dir, tlm_acls_t *tlm_acls, 5437917SReza.Sabdar@Sun.COM tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats, 5447917SReza.Sabdar@Sun.COM bk_selector_t *bksp) 5457917SReza.Sabdar@Sun.COM { 5467917SReza.Sabdar@Sun.COM int erc; 5477917SReza.Sabdar@Sun.COM 5487917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "\"%s\"", dir); 5497917SReza.Sabdar@Sun.COM 5507917SReza.Sabdar@Sun.COM erc = get_dir_acl_info(dir, tlm_acls, job_stats); 5517917SReza.Sabdar@Sun.COM if (erc != 0) { 5527917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 5537917SReza.Sabdar@Sun.COM "Could not read directory info for %s", dir); 5547917SReza.Sabdar@Sun.COM job_stats->js_errors++; 5557917SReza.Sabdar@Sun.COM } else { 5567917SReza.Sabdar@Sun.COM /* 5577917SReza.Sabdar@Sun.COM * See if the directory must be backed up. 5587917SReza.Sabdar@Sun.COM */ 5597917SReza.Sabdar@Sun.COM if (bksp && !(*bksp->bs_fn)(bksp, &tlm_acls->acl_attr)) { 5607917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "[%s] dir skipped", dir); 5617917SReza.Sabdar@Sun.COM return (erc); 5627917SReza.Sabdar@Sun.COM } 5637917SReza.Sabdar@Sun.COM 5647917SReza.Sabdar@Sun.COM if (tm_tar_ops.tm_putdir != NULL) 5657917SReza.Sabdar@Sun.COM (void) (tm_tar_ops.tm_putdir)(dir, tlm_acls, 5667917SReza.Sabdar@Sun.COM local_commands, job_stats); 5677917SReza.Sabdar@Sun.COM } 5687917SReza.Sabdar@Sun.COM 5697917SReza.Sabdar@Sun.COM return (erc); 5707917SReza.Sabdar@Sun.COM } 5717917SReza.Sabdar@Sun.COM 5727917SReza.Sabdar@Sun.COM 5737917SReza.Sabdar@Sun.COM /* 5747917SReza.Sabdar@Sun.COM * backup_file 5757917SReza.Sabdar@Sun.COM * 5767917SReza.Sabdar@Sun.COM * Create a TAR record entry for a file 5777917SReza.Sabdar@Sun.COM */ 5787917SReza.Sabdar@Sun.COM static longlong_t 5797917SReza.Sabdar@Sun.COM backup_file(char *dir, char *name, tlm_acls_t *tlm_acls, 5807917SReza.Sabdar@Sun.COM tlm_commands_t *commands, tlm_cmd_t *local_commands, 5817917SReza.Sabdar@Sun.COM tlm_job_stats_t *job_stats, bk_selector_t *bksp) 5827917SReza.Sabdar@Sun.COM { 5837917SReza.Sabdar@Sun.COM 5847917SReza.Sabdar@Sun.COM int erc; 5857917SReza.Sabdar@Sun.COM char buf[TLM_MAX_PATH_NAME]; 5867917SReza.Sabdar@Sun.COM longlong_t rv; 5877917SReza.Sabdar@Sun.COM 5887917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", dir, name); 5897917SReza.Sabdar@Sun.COM 5907917SReza.Sabdar@Sun.COM (void) strlcpy(buf, dir, sizeof (buf)); 5917917SReza.Sabdar@Sun.COM (void) strlcat(buf, "/", sizeof (buf)); 5927917SReza.Sabdar@Sun.COM (void) strlcat(buf, name, sizeof (buf)); 5937917SReza.Sabdar@Sun.COM 5947917SReza.Sabdar@Sun.COM /* 5957917SReza.Sabdar@Sun.COM * get_acl_info extracts file handle, attributes and ACLs of the file. 5967917SReza.Sabdar@Sun.COM * This is not efficient when the attributes and file handle of 5977917SReza.Sabdar@Sun.COM * the file is already known. 5987917SReza.Sabdar@Sun.COM */ 5997917SReza.Sabdar@Sun.COM erc = get_acl_info(buf, tlm_acls); 6007917SReza.Sabdar@Sun.COM if (erc != TLM_NO_ERRORS) { 6017917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Could not open file %s/%s.", dir, name); 6027917SReza.Sabdar@Sun.COM return (-ENOENT); 6037917SReza.Sabdar@Sun.COM } 6047917SReza.Sabdar@Sun.COM 6057917SReza.Sabdar@Sun.COM /* Should the file be backed up? */ 6067917SReza.Sabdar@Sun.COM if (!bksp) { 6077917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 6087917SReza.Sabdar@Sun.COM "[%s/%s] has no selection criteria", dir, name); 6097917SReza.Sabdar@Sun.COM 6107917SReza.Sabdar@Sun.COM } else if (!((*bksp->bs_fn)(bksp, &tlm_acls->acl_attr))) { 6117917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "[%s/%s] file skipped", dir, name); 6127917SReza.Sabdar@Sun.COM return (0); 6137917SReza.Sabdar@Sun.COM } 6147917SReza.Sabdar@Sun.COM 6157917SReza.Sabdar@Sun.COM /* Only the regular files and symbolic links can be backed up. */ 6167917SReza.Sabdar@Sun.COM if (!S_ISLNK(tlm_acls->acl_attr.st_mode) && 6177917SReza.Sabdar@Sun.COM !S_ISREG(tlm_acls->acl_attr.st_mode)) { 6187917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 6197917SReza.Sabdar@Sun.COM "Warning: skip backing up [%s][%s]", dir, name); 6207917SReza.Sabdar@Sun.COM return (-EINVAL); 6217917SReza.Sabdar@Sun.COM } 6227917SReza.Sabdar@Sun.COM 6237917SReza.Sabdar@Sun.COM 6247917SReza.Sabdar@Sun.COM if (tm_tar_ops.tm_putfile != NULL) 6257917SReza.Sabdar@Sun.COM rv = (tm_tar_ops.tm_putfile)(dir, name, tlm_acls, commands, 6267917SReza.Sabdar@Sun.COM local_commands, job_stats); 6277917SReza.Sabdar@Sun.COM 6287917SReza.Sabdar@Sun.COM return (rv); 6297917SReza.Sabdar@Sun.COM } 6307917SReza.Sabdar@Sun.COM 6317917SReza.Sabdar@Sun.COM 6327917SReza.Sabdar@Sun.COM 6337917SReza.Sabdar@Sun.COM /* 6347917SReza.Sabdar@Sun.COM * backup_work 6357917SReza.Sabdar@Sun.COM * 6367917SReza.Sabdar@Sun.COM * Start the NDMP backup (V2 only). 6377917SReza.Sabdar@Sun.COM */ 6387917SReza.Sabdar@Sun.COM int 6397917SReza.Sabdar@Sun.COM backup_work(char *bk_path, tlm_job_stats_t *job_stats, 6407917SReza.Sabdar@Sun.COM ndmp_run_args_t *np, tlm_commands_t *commands, 6417917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp) 6427917SReza.Sabdar@Sun.COM { 6437917SReza.Sabdar@Sun.COM struct full_dir_info dir_info; /* the blob to push/pop with cstack_t */ 6447917SReza.Sabdar@Sun.COM struct full_dir_info *t_dir_info, *p_dir_info; 6457917SReza.Sabdar@Sun.COM struct stat64 ret_attr; /* attributes of current file name */ 6467917SReza.Sabdar@Sun.COM fs_fhandle_t ret_fh; 6477917SReza.Sabdar@Sun.COM char *first_name; /* where the first name is located */ 6487917SReza.Sabdar@Sun.COM char *dname; 6497917SReza.Sabdar@Sun.COM int erc; 6507917SReza.Sabdar@Sun.COM int retval; 6517917SReza.Sabdar@Sun.COM cstack_t *stk; 6527917SReza.Sabdar@Sun.COM unsigned long fileid; 6537917SReza.Sabdar@Sun.COM tlm_acls_t tlm_acls; 6547917SReza.Sabdar@Sun.COM int dname_size; 6557917SReza.Sabdar@Sun.COM longlong_t fsize; 6567917SReza.Sabdar@Sun.COM bk_selector_t bks; 6577917SReza.Sabdar@Sun.COM tlm_cmd_t *local_commands; 6587917SReza.Sabdar@Sun.COM long dpos; 6597917SReza.Sabdar@Sun.COM 6607917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nr_chkpnted %d nr_ldate: %u bk_path: \"%s\"", 6617917SReza.Sabdar@Sun.COM NLP_ISCHKPNTED(nlp), nlp->nlp_ldate, bk_path); 6627917SReza.Sabdar@Sun.COM 6637917SReza.Sabdar@Sun.COM /* Get every name in this directory */ 6647917SReza.Sabdar@Sun.COM dname = ndmp_malloc(TLM_MAX_PATH_NAME); 6657917SReza.Sabdar@Sun.COM if (dname == NULL) 6667917SReza.Sabdar@Sun.COM return (-ENOMEM); 6677917SReza.Sabdar@Sun.COM 6687917SReza.Sabdar@Sun.COM local_commands = commands->tcs_command; 6697917SReza.Sabdar@Sun.COM retval = 0; 6707917SReza.Sabdar@Sun.COM (void) memset(&bks, 0, sizeof (bks)); 6717917SReza.Sabdar@Sun.COM bks.bs_cookie = (void *)nlp; 6727917SReza.Sabdar@Sun.COM bks.bs_level = nlp->nlp_clevel; 6737917SReza.Sabdar@Sun.COM bks.bs_ldate = nlp->nlp_ldate; 6747917SReza.Sabdar@Sun.COM bks.bs_fn = timecmp; 6757917SReza.Sabdar@Sun.COM 6767917SReza.Sabdar@Sun.COM /* 6777917SReza.Sabdar@Sun.COM * should we skip the whole thing? 6787917SReza.Sabdar@Sun.COM */ 6797917SReza.Sabdar@Sun.COM if (tlm_is_excluded("", bk_path, np->nr_excls)) { 6807917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "%s excluded", bk_path); 6817917SReza.Sabdar@Sun.COM free(dname); 6827917SReza.Sabdar@Sun.COM return (0); 6837917SReza.Sabdar@Sun.COM } 6847917SReza.Sabdar@Sun.COM 6857917SReza.Sabdar@Sun.COM /* 6867917SReza.Sabdar@Sun.COM * Search for the top-level file-directory 6877917SReza.Sabdar@Sun.COM */ 6887917SReza.Sabdar@Sun.COM if (NLP_ISCHKPNTED(nlp)) { 6897917SReza.Sabdar@Sun.COM first_name = np->nr_chkp_nm; 6907917SReza.Sabdar@Sun.COM (void) strlcpy(first_name, bk_path, TLM_MAX_PATH_NAME); 6917917SReza.Sabdar@Sun.COM } else { 6927917SReza.Sabdar@Sun.COM first_name = tlm_build_snapshot_name(bk_path, np->nr_chkp_nm, 6937917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_job_name); 6947917SReza.Sabdar@Sun.COM } 6957917SReza.Sabdar@Sun.COM 6967917SReza.Sabdar@Sun.COM (void) memset(&ret_fh, 0, sizeof (ret_fh)); 6977917SReza.Sabdar@Sun.COM erc = fs_getstat(first_name, &ret_fh, &ret_attr, NULL); 6987917SReza.Sabdar@Sun.COM if (erc != 0) { 6997917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_ERR, "Path %s not found.", first_name); 7007917SReza.Sabdar@Sun.COM free(dname); 7017917SReza.Sabdar@Sun.COM return (-EINVAL); 7027917SReza.Sabdar@Sun.COM } 7037917SReza.Sabdar@Sun.COM 7047917SReza.Sabdar@Sun.COM if ((stk = cstack_new()) == NULL) { 7057917SReza.Sabdar@Sun.COM free(dname); 7067917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "cstack_new failed"); 7077917SReza.Sabdar@Sun.COM return (-ENOMEM); 7087917SReza.Sabdar@Sun.COM } 7097917SReza.Sabdar@Sun.COM (void) strlcpy(dir_info.fd_dir_name, first_name, TLM_MAX_PATH_NAME); 7107917SReza.Sabdar@Sun.COM (void) memcpy(&dir_info.fd_dir_fh, &ret_fh, sizeof (fs_fhandle_t)); 7117917SReza.Sabdar@Sun.COM p_dir_info = dup_dir_info(&dir_info); 7127917SReza.Sabdar@Sun.COM 7137917SReza.Sabdar@Sun.COM /* 7147917SReza.Sabdar@Sun.COM * Push the first name onto the stack so that we can pop it back 7157917SReza.Sabdar@Sun.COM * off as part of the normal cycle 7167917SReza.Sabdar@Sun.COM */ 7177917SReza.Sabdar@Sun.COM if (cstack_push(stk, p_dir_info, 0)) { 7187917SReza.Sabdar@Sun.COM free(dname); 7197917SReza.Sabdar@Sun.COM free(p_dir_info); 7207917SReza.Sabdar@Sun.COM cstack_delete(stk); 7217917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "cstack_push failed"); 7227917SReza.Sabdar@Sun.COM return (-ENOMEM); 7237917SReza.Sabdar@Sun.COM } 7247917SReza.Sabdar@Sun.COM 7257917SReza.Sabdar@Sun.COM (void) memset(&tlm_acls, 0, sizeof (tlm_acls)); 7267917SReza.Sabdar@Sun.COM /* 7277917SReza.Sabdar@Sun.COM * Did NDMP create a checkpoint? 7287917SReza.Sabdar@Sun.COM */ 7297917SReza.Sabdar@Sun.COM if (NLP_ISCHKPNTED(nlp) || fs_is_rdonly(bk_path)) { 7307917SReza.Sabdar@Sun.COM tlm_acls.acl_checkpointed = FALSE; 7317917SReza.Sabdar@Sun.COM } else { 7327917SReza.Sabdar@Sun.COM /* Use the checkpoint created by NDMP */ 7337917SReza.Sabdar@Sun.COM tlm_acls.acl_checkpointed = TRUE; 7347917SReza.Sabdar@Sun.COM } 7357917SReza.Sabdar@Sun.COM 7367917SReza.Sabdar@Sun.COM /* 7377917SReza.Sabdar@Sun.COM * This is level-backup. It never resets the archive bit. 7387917SReza.Sabdar@Sun.COM */ 7397917SReza.Sabdar@Sun.COM tlm_acls.acl_clear_archive = FALSE; 7407917SReza.Sabdar@Sun.COM 7417917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "acls.chkpnt: %c acls.clear_arcbit: %c", 7427917SReza.Sabdar@Sun.COM NDMP_YORN(tlm_acls.acl_checkpointed), 7437917SReza.Sabdar@Sun.COM NDMP_YORN(tlm_acls.acl_clear_archive)); 7447917SReza.Sabdar@Sun.COM 7457917SReza.Sabdar@Sun.COM while (commands->tcs_reader == TLM_BACKUP_RUN && 7467917SReza.Sabdar@Sun.COM local_commands->tc_reader == TLM_BACKUP_RUN && 7477917SReza.Sabdar@Sun.COM cstack_pop(stk, (void **)&p_dir_info, 0) == 0) { 7487917SReza.Sabdar@Sun.COM 7497917SReza.Sabdar@Sun.COM if (NLP_ISCHKPNTED(nlp)) 7507917SReza.Sabdar@Sun.COM (void) strlcpy(np->nr_unchkp_nm, 7517917SReza.Sabdar@Sun.COM p_dir_info->fd_dir_name, TLM_MAX_PATH_NAME); 7527917SReza.Sabdar@Sun.COM else 7537917SReza.Sabdar@Sun.COM (void) tlm_remove_checkpoint(p_dir_info->fd_dir_name, 7547917SReza.Sabdar@Sun.COM np->nr_unchkp_nm); 7557917SReza.Sabdar@Sun.COM 7567917SReza.Sabdar@Sun.COM (void) backup_dir(np->nr_unchkp_nm, &tlm_acls, local_commands, 7577917SReza.Sabdar@Sun.COM job_stats, &bks); 7587917SReza.Sabdar@Sun.COM 7597917SReza.Sabdar@Sun.COM 7607917SReza.Sabdar@Sun.COM while (commands->tcs_reader == TLM_BACKUP_RUN && 7617917SReza.Sabdar@Sun.COM local_commands->tc_reader == TLM_BACKUP_RUN) { 7627917SReza.Sabdar@Sun.COM 7637917SReza.Sabdar@Sun.COM dname_size = TLM_MAX_PATH_NAME - 1; 7647917SReza.Sabdar@Sun.COM 7657917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 7667917SReza.Sabdar@Sun.COM "dir_name: %s", p_dir_info->fd_dir_name); 7677917SReza.Sabdar@Sun.COM 7687917SReza.Sabdar@Sun.COM (void) memset(&ret_fh, 0, sizeof (ret_fh)); 7697917SReza.Sabdar@Sun.COM erc = fs_readdir(&p_dir_info->fd_dir_fh, 7707917SReza.Sabdar@Sun.COM p_dir_info->fd_dir_name, &dpos, 7717917SReza.Sabdar@Sun.COM dname, &dname_size, &ret_fh, &ret_attr, 7727917SReza.Sabdar@Sun.COM NULL); 7737917SReza.Sabdar@Sun.COM if (erc == 0) { 7747917SReza.Sabdar@Sun.COM fileid = ret_fh.fh_fid; 7757917SReza.Sabdar@Sun.COM } else { 7767917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 7777917SReza.Sabdar@Sun.COM "Filesystem readdir in [%s]", 7787917SReza.Sabdar@Sun.COM p_dir_info->fd_dir_name); 7797917SReza.Sabdar@Sun.COM retval = -ENOENT; 7807917SReza.Sabdar@Sun.COM break; 7817917SReza.Sabdar@Sun.COM } 7827917SReza.Sabdar@Sun.COM 7837917SReza.Sabdar@Sun.COM /* an empty name size marks the end of the list */ 7847917SReza.Sabdar@Sun.COM if (dname_size == 0) 7857917SReza.Sabdar@Sun.COM break; 7867917SReza.Sabdar@Sun.COM dname[dname_size] = '\0'; 7877917SReza.Sabdar@Sun.COM 7887917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "dname: \"%s\"", dname); 7897917SReza.Sabdar@Sun.COM 7907917SReza.Sabdar@Sun.COM /* 7917917SReza.Sabdar@Sun.COM * If name refers to a directory, push its file 7927917SReza.Sabdar@Sun.COM * handle onto the stack (skip "." and ".."). 7937917SReza.Sabdar@Sun.COM */ 7947917SReza.Sabdar@Sun.COM if (rootfs_dot_or_dotdot(dname)) { 7957917SReza.Sabdar@Sun.COM fileid = 0; 7967917SReza.Sabdar@Sun.COM continue; 7977917SReza.Sabdar@Sun.COM } 7987917SReza.Sabdar@Sun.COM 7997917SReza.Sabdar@Sun.COM /* 8007917SReza.Sabdar@Sun.COM * Skip the: 8017917SReza.Sabdar@Sun.COM * non-dir entries which should not be backed up 8027917SReza.Sabdar@Sun.COM * Or 8037917SReza.Sabdar@Sun.COM * dir-type entries which have have nothing under 8047917SReza.Sabdar@Sun.COM * their hierarchy to be backed up. 8057917SReza.Sabdar@Sun.COM */ 8067917SReza.Sabdar@Sun.COM if (!dbm_getone(nlp->nlp_bkmap, (u_longlong_t)fileid)) { 8077917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Skipping %s/%s", 8087917SReza.Sabdar@Sun.COM p_dir_info->fd_dir_name, dname); 8097917SReza.Sabdar@Sun.COM fileid = 0; 8107917SReza.Sabdar@Sun.COM continue; 8117917SReza.Sabdar@Sun.COM } 8127917SReza.Sabdar@Sun.COM 8137917SReza.Sabdar@Sun.COM if (tlm_is_excluded(np->nr_unchkp_nm, dname, 8147917SReza.Sabdar@Sun.COM np->nr_excls)) { 8157917SReza.Sabdar@Sun.COM fileid = 0; 8167917SReza.Sabdar@Sun.COM continue; 8177917SReza.Sabdar@Sun.COM } 8187917SReza.Sabdar@Sun.COM if (S_ISDIR(ret_attr.st_mode)) { 8197917SReza.Sabdar@Sun.COM /* 8207917SReza.Sabdar@Sun.COM * only directories get pushed onto this stack, 8217917SReza.Sabdar@Sun.COM * so we do not have to test for regular files. 8227917SReza.Sabdar@Sun.COM */ 8237917SReza.Sabdar@Sun.COM t_dir_info = tlm_new_dir_info(&ret_fh, 8247917SReza.Sabdar@Sun.COM p_dir_info->fd_dir_name, dname); 8257917SReza.Sabdar@Sun.COM if (t_dir_info == NULL) { 8267917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 8277917SReza.Sabdar@Sun.COM "While backing up [%s][%s]", 8287917SReza.Sabdar@Sun.COM p_dir_info->fd_dir_name, dname); 8297917SReza.Sabdar@Sun.COM } else if (cstack_push(stk, t_dir_info, 8307917SReza.Sabdar@Sun.COM 0) != 0) { 8317917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 8327917SReza.Sabdar@Sun.COM "No enough memory stack_push"); 8337917SReza.Sabdar@Sun.COM retval = -ENOMEM; 8347917SReza.Sabdar@Sun.COM break; 8357917SReza.Sabdar@Sun.COM } 8367917SReza.Sabdar@Sun.COM } else if (S_ISREG(ret_attr.st_mode) || 8377917SReza.Sabdar@Sun.COM S_ISLNK(ret_attr.st_mode)) { 8387917SReza.Sabdar@Sun.COM 8397917SReza.Sabdar@Sun.COM fsize = backup_file(np->nr_unchkp_nm, dname, 8407917SReza.Sabdar@Sun.COM &tlm_acls, commands, local_commands, 8417917SReza.Sabdar@Sun.COM job_stats, &bks); 8427917SReza.Sabdar@Sun.COM 8437917SReza.Sabdar@Sun.COM if (fsize >= 0) { 8447917SReza.Sabdar@Sun.COM job_stats->js_files_so_far++; 8457917SReza.Sabdar@Sun.COM job_stats->js_bytes_total += fsize; 8467917SReza.Sabdar@Sun.COM } else 8477917SReza.Sabdar@Sun.COM job_stats->js_errors++; 8487917SReza.Sabdar@Sun.COM fileid = 0; 8497917SReza.Sabdar@Sun.COM } 8507917SReza.Sabdar@Sun.COM } 8517917SReza.Sabdar@Sun.COM fileid = 0; 8527917SReza.Sabdar@Sun.COM free(p_dir_info); 8537917SReza.Sabdar@Sun.COM if (retval != 0) 8547917SReza.Sabdar@Sun.COM break; 8557917SReza.Sabdar@Sun.COM } 8567917SReza.Sabdar@Sun.COM 8577917SReza.Sabdar@Sun.COM free(dname); 8587917SReza.Sabdar@Sun.COM 8597917SReza.Sabdar@Sun.COM while (cstack_pop(stk, (void **)&p_dir_info, 0) == 0) { 8607917SReza.Sabdar@Sun.COM free(p_dir_info); 8617917SReza.Sabdar@Sun.COM } 8627917SReza.Sabdar@Sun.COM 8637917SReza.Sabdar@Sun.COM cstack_delete(stk); 8647917SReza.Sabdar@Sun.COM return (retval); 8657917SReza.Sabdar@Sun.COM } 8667917SReza.Sabdar@Sun.COM 8677917SReza.Sabdar@Sun.COM 8687917SReza.Sabdar@Sun.COM /* 8697917SReza.Sabdar@Sun.COM * free_paths 8707917SReza.Sabdar@Sun.COM * 8717917SReza.Sabdar@Sun.COM * Free the path names 8727917SReza.Sabdar@Sun.COM */ 8737917SReza.Sabdar@Sun.COM static void 8747917SReza.Sabdar@Sun.COM free_paths(ndmp_run_args_t *np) 8757917SReza.Sabdar@Sun.COM { 8767917SReza.Sabdar@Sun.COM free(np->nr_chkp_nm); 8777917SReza.Sabdar@Sun.COM free(np->nr_unchkp_nm); 8787917SReza.Sabdar@Sun.COM free(np->nr_excls); 8797917SReza.Sabdar@Sun.COM } 8807917SReza.Sabdar@Sun.COM 8817917SReza.Sabdar@Sun.COM 8827917SReza.Sabdar@Sun.COM /* 8837917SReza.Sabdar@Sun.COM * malloc_paths 8847917SReza.Sabdar@Sun.COM * 8857917SReza.Sabdar@Sun.COM * Allocate the path names (direct and checkpointed paths) 8867917SReza.Sabdar@Sun.COM */ 8877917SReza.Sabdar@Sun.COM static boolean_t 8887917SReza.Sabdar@Sun.COM malloc_paths(ndmp_run_args_t *np) 8897917SReza.Sabdar@Sun.COM { 8907917SReza.Sabdar@Sun.COM boolean_t rv; 8917917SReza.Sabdar@Sun.COM 8927917SReza.Sabdar@Sun.COM rv = TRUE; 8937917SReza.Sabdar@Sun.COM np->nr_chkp_nm = ndmp_malloc(TLM_MAX_PATH_NAME); 8947917SReza.Sabdar@Sun.COM np->nr_unchkp_nm = ndmp_malloc(TLM_MAX_PATH_NAME); 8957917SReza.Sabdar@Sun.COM if (!np->nr_chkp_nm || !np->nr_unchkp_nm) { 8967917SReza.Sabdar@Sun.COM free_paths(np); 8977917SReza.Sabdar@Sun.COM rv = FALSE; 8987917SReza.Sabdar@Sun.COM } else if ((np->nr_excls = ndmpd_make_exc_list()) == NULL) { 8997917SReza.Sabdar@Sun.COM free_paths(np); 9007917SReza.Sabdar@Sun.COM rv = FALSE; 9017917SReza.Sabdar@Sun.COM } 9027917SReza.Sabdar@Sun.COM return (rv); 9037917SReza.Sabdar@Sun.COM } 9047917SReza.Sabdar@Sun.COM 9057917SReza.Sabdar@Sun.COM 9067917SReza.Sabdar@Sun.COM /* 9077917SReza.Sabdar@Sun.COM * ndmp_backup_reader 9087917SReza.Sabdar@Sun.COM * 9097917SReza.Sabdar@Sun.COM * Backup reader thread which uses backup_work to read and TAR 9107917SReza.Sabdar@Sun.COM * the files/dirs to be backed up (V2 only) 9117917SReza.Sabdar@Sun.COM */ 9127917SReza.Sabdar@Sun.COM static int 9137917SReza.Sabdar@Sun.COM ndmp_backup_reader(tlm_commands_t *commands, ndmp_lbr_params_t *nlp, 9147917SReza.Sabdar@Sun.COM char *job_name) 9157917SReza.Sabdar@Sun.COM { 9167917SReza.Sabdar@Sun.COM int retval; 9177917SReza.Sabdar@Sun.COM ndmp_run_args_t np; 9187917SReza.Sabdar@Sun.COM tlm_job_stats_t *job_stats; 9197917SReza.Sabdar@Sun.COM tlm_cmd_t *local_commands; 9207917SReza.Sabdar@Sun.COM 9217917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "bk_path: \"%s\"", nlp->nlp_backup_path); 9227917SReza.Sabdar@Sun.COM 9237917SReza.Sabdar@Sun.COM local_commands = commands->tcs_command; 9247917SReza.Sabdar@Sun.COM (void) memset(&np, 0, sizeof (np)); 9257917SReza.Sabdar@Sun.COM if (!malloc_paths(&np)) 9267917SReza.Sabdar@Sun.COM return (-1); 9277917SReza.Sabdar@Sun.COM local_commands->tc_ref++; 9287917SReza.Sabdar@Sun.COM commands->tcs_reader_count++; 9297917SReza.Sabdar@Sun.COM 9307917SReza.Sabdar@Sun.COM job_stats = tlm_ref_job_stats(job_name); 9317917SReza.Sabdar@Sun.COM 9327917SReza.Sabdar@Sun.COM retval = backup_work(nlp->nlp_backup_path, job_stats, &np, 9337917SReza.Sabdar@Sun.COM commands, nlp); 9347917SReza.Sabdar@Sun.COM write_tar_eof(local_commands); 9357917SReza.Sabdar@Sun.COM 9367917SReza.Sabdar@Sun.COM commands->tcs_reader_count--; 9377917SReza.Sabdar@Sun.COM local_commands->tc_writer = TLM_STOP; 9387917SReza.Sabdar@Sun.COM tlm_release_reader_writer_ipc(local_commands); 9397917SReza.Sabdar@Sun.COM tlm_un_ref_job_stats(job_name); 9407917SReza.Sabdar@Sun.COM 9417917SReza.Sabdar@Sun.COM free_paths(&np); 9427917SReza.Sabdar@Sun.COM return (retval); 9437917SReza.Sabdar@Sun.COM 9447917SReza.Sabdar@Sun.COM } 9457917SReza.Sabdar@Sun.COM 9467917SReza.Sabdar@Sun.COM 9477917SReza.Sabdar@Sun.COM /* 9487917SReza.Sabdar@Sun.COM * ndmp_tar_writer 9497917SReza.Sabdar@Sun.COM * 9507917SReza.Sabdar@Sun.COM * The backup writer thread that writes the TAR records to the 9517917SReza.Sabdar@Sun.COM * tape media (V2 only) 9527917SReza.Sabdar@Sun.COM */ 9537917SReza.Sabdar@Sun.COM int 9547917SReza.Sabdar@Sun.COM ndmp_tar_writer(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, 9557917SReza.Sabdar@Sun.COM tlm_commands_t *cmds) 9567917SReza.Sabdar@Sun.COM { 9577917SReza.Sabdar@Sun.COM int bidx, nw; 9587917SReza.Sabdar@Sun.COM int err; 9597917SReza.Sabdar@Sun.COM tlm_buffer_t *buf; 9607917SReza.Sabdar@Sun.COM tlm_buffers_t *bufs; 9617917SReza.Sabdar@Sun.COM tlm_cmd_t *lcmd; /* Local command */ 9627917SReza.Sabdar@Sun.COM 9637917SReza.Sabdar@Sun.COM err = 0; 9647917SReza.Sabdar@Sun.COM if (session == NULL) { 9657917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "session == NULL"); 9667917SReza.Sabdar@Sun.COM err = -1; 9677917SReza.Sabdar@Sun.COM } else if (mod_params == NULL) { 9687917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "mod_params == NULL"); 9697917SReza.Sabdar@Sun.COM err = -1; 9707917SReza.Sabdar@Sun.COM } else if (cmds == NULL) { 9717917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 9727917SReza.Sabdar@Sun.COM err = -1; 9737917SReza.Sabdar@Sun.COM } 9747917SReza.Sabdar@Sun.COM 9757917SReza.Sabdar@Sun.COM if (err != 0) 9767917SReza.Sabdar@Sun.COM return (err); 9777917SReza.Sabdar@Sun.COM 9787917SReza.Sabdar@Sun.COM lcmd = cmds->tcs_command; 9797917SReza.Sabdar@Sun.COM bufs = lcmd->tc_buffers; 9807917SReza.Sabdar@Sun.COM 9817917SReza.Sabdar@Sun.COM lcmd->tc_ref++; 9827917SReza.Sabdar@Sun.COM cmds->tcs_writer_count++; 9837917SReza.Sabdar@Sun.COM 9847917SReza.Sabdar@Sun.COM nw = 0; 9857917SReza.Sabdar@Sun.COM buf = tlm_buffer_out_buf(bufs, &bidx); 9867917SReza.Sabdar@Sun.COM while (cmds->tcs_writer != (int)TLM_ABORT && 9877917SReza.Sabdar@Sun.COM lcmd->tc_writer != (int)TLM_ABORT) { 9887917SReza.Sabdar@Sun.COM if (buf->tb_full) { 9897917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "w%d", bidx); 9907917SReza.Sabdar@Sun.COM 9917917SReza.Sabdar@Sun.COM if (MOD_WRITE(mod_params, buf->tb_buffer_data, 9927917SReza.Sabdar@Sun.COM buf->tb_buffer_size) != 0) { 9937917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 9947917SReza.Sabdar@Sun.COM "Writing buffer %d, pos: %lld", 9957917SReza.Sabdar@Sun.COM bidx, session->ns_mover.md_position); 9967917SReza.Sabdar@Sun.COM err = -1; 9977917SReza.Sabdar@Sun.COM break; 9987917SReza.Sabdar@Sun.COM } 9997917SReza.Sabdar@Sun.COM 10007917SReza.Sabdar@Sun.COM tlm_buffer_mark_empty(buf); 10017917SReza.Sabdar@Sun.COM (void) tlm_buffer_advance_out_idx(bufs); 10027917SReza.Sabdar@Sun.COM buf = tlm_buffer_out_buf(bufs, &bidx); 10037917SReza.Sabdar@Sun.COM tlm_buffer_release_out_buf(bufs); 10047917SReza.Sabdar@Sun.COM nw++; 10057917SReza.Sabdar@Sun.COM } else { 10067917SReza.Sabdar@Sun.COM if (lcmd->tc_writer != TLM_BACKUP_RUN) { 10077917SReza.Sabdar@Sun.COM /* No more data is comming; time to exit. */ 10087917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 10097917SReza.Sabdar@Sun.COM "tc_writer!=TLM_BACKUP_RUN; time to exit"); 10107917SReza.Sabdar@Sun.COM break; 10117917SReza.Sabdar@Sun.COM } else { 10127917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "W%d", bidx); 1013*8800SReza.Sabdar@Sun.COM tlm_buffer_in_buf_timed_wait(bufs, 100); 10147917SReza.Sabdar@Sun.COM } 10157917SReza.Sabdar@Sun.COM } 10167917SReza.Sabdar@Sun.COM } 10177917SReza.Sabdar@Sun.COM 10187917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nw: %d", nw); 10197917SReza.Sabdar@Sun.COM if (cmds->tcs_writer != (int)TLM_ABORT) { 10207917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "tcs_writer != TLM_ABORT"); 10217917SReza.Sabdar@Sun.COM } else { 10227917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "tcs_writer == TLM_ABORT"); 10237917SReza.Sabdar@Sun.COM } 10247917SReza.Sabdar@Sun.COM 10257917SReza.Sabdar@Sun.COM if (lcmd->tc_writer != (int)TLM_ABORT) { 10267917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "tc_writer != TLM_ABORT"); 10277917SReza.Sabdar@Sun.COM } else { 10287917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "tc_writer == TLM_ABORT"); 10297917SReza.Sabdar@Sun.COM } 10307917SReza.Sabdar@Sun.COM cmds->tcs_writer_count--; 10317917SReza.Sabdar@Sun.COM lcmd->tc_reader = TLM_STOP; 10327917SReza.Sabdar@Sun.COM lcmd->tc_ref--; 10337917SReza.Sabdar@Sun.COM 10347917SReza.Sabdar@Sun.COM return (err); 10357917SReza.Sabdar@Sun.COM } 10367917SReza.Sabdar@Sun.COM 10377917SReza.Sabdar@Sun.COM 10387917SReza.Sabdar@Sun.COM /* 10397917SReza.Sabdar@Sun.COM * read_one_buf 10407917SReza.Sabdar@Sun.COM * 10417917SReza.Sabdar@Sun.COM * Read one buffer from the tape 10427917SReza.Sabdar@Sun.COM */ 10437917SReza.Sabdar@Sun.COM static int 10447917SReza.Sabdar@Sun.COM read_one_buf(ndmpd_module_params_t *mod_params, tlm_buffers_t *bufs, 10457917SReza.Sabdar@Sun.COM tlm_buffer_t *buf) 10467917SReza.Sabdar@Sun.COM { 10477917SReza.Sabdar@Sun.COM int rv; 10487917SReza.Sabdar@Sun.COM 10497917SReza.Sabdar@Sun.COM if ((rv = MOD_READ(mod_params, buf->tb_buffer_data, 10507917SReza.Sabdar@Sun.COM bufs->tbs_data_transfer_size)) == 0) { 10517917SReza.Sabdar@Sun.COM buf->tb_eof = buf->tb_eot = FALSE; 10527917SReza.Sabdar@Sun.COM buf->tb_errno = 0; 10537917SReza.Sabdar@Sun.COM buf->tb_buffer_size = bufs->tbs_data_transfer_size; 10547917SReza.Sabdar@Sun.COM buf->tb_buffer_spot = 0; 10557917SReza.Sabdar@Sun.COM buf->tb_full = TRUE; 10567917SReza.Sabdar@Sun.COM (void) tlm_buffer_advance_in_idx(bufs); 10577917SReza.Sabdar@Sun.COM } 10587917SReza.Sabdar@Sun.COM 10597917SReza.Sabdar@Sun.COM return (rv); 10607917SReza.Sabdar@Sun.COM } 10617917SReza.Sabdar@Sun.COM 10627917SReza.Sabdar@Sun.COM 10637917SReza.Sabdar@Sun.COM /* 10647917SReza.Sabdar@Sun.COM * ndmp_tar_reader 10657917SReza.Sabdar@Sun.COM * 10667917SReza.Sabdar@Sun.COM * NDMP Tar reader thread. This threads keep reading the tar 10677917SReza.Sabdar@Sun.COM * file from the tape and wakes up the consumer thread to extract 10687917SReza.Sabdar@Sun.COM * it on the disk 10697917SReza.Sabdar@Sun.COM */ 10707917SReza.Sabdar@Sun.COM int 10717917SReza.Sabdar@Sun.COM ndmp_tar_reader(ndmp_tar_reader_arg_t *argp) 10727917SReza.Sabdar@Sun.COM { 10737917SReza.Sabdar@Sun.COM int bidx; 10747917SReza.Sabdar@Sun.COM int err; 10757917SReza.Sabdar@Sun.COM tlm_buffer_t *buf; 10767917SReza.Sabdar@Sun.COM tlm_buffers_t *bufs; 10777917SReza.Sabdar@Sun.COM tlm_cmd_t *lcmd; /* Local command */ 10787917SReza.Sabdar@Sun.COM ndmpd_session_t *session; 10797917SReza.Sabdar@Sun.COM ndmpd_module_params_t *mod_params; 10807917SReza.Sabdar@Sun.COM tlm_commands_t *cmds; 10817917SReza.Sabdar@Sun.COM 10827917SReza.Sabdar@Sun.COM if (!argp) 10837917SReza.Sabdar@Sun.COM return (-1); 10847917SReza.Sabdar@Sun.COM 10857917SReza.Sabdar@Sun.COM session = argp->tr_session; 10867917SReza.Sabdar@Sun.COM mod_params = argp->tr_mod_params; 10877917SReza.Sabdar@Sun.COM cmds = argp->tr_cmds; 10887917SReza.Sabdar@Sun.COM 10897917SReza.Sabdar@Sun.COM err = 0; 10907917SReza.Sabdar@Sun.COM if (session == NULL) { 10917917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "session == NULL"); 10927917SReza.Sabdar@Sun.COM err = -1; 10937917SReza.Sabdar@Sun.COM } else if (cmds == NULL) { 10947917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 10957917SReza.Sabdar@Sun.COM err = -1; 10967917SReza.Sabdar@Sun.COM } 10977917SReza.Sabdar@Sun.COM 10987917SReza.Sabdar@Sun.COM if (err != 0) { 10997917SReza.Sabdar@Sun.COM tlm_cmd_signal(cmds->tcs_command, TLM_TAR_READER); 11007917SReza.Sabdar@Sun.COM return (err); 11017917SReza.Sabdar@Sun.COM } 11027917SReza.Sabdar@Sun.COM 11037917SReza.Sabdar@Sun.COM lcmd = cmds->tcs_command; 11047917SReza.Sabdar@Sun.COM bufs = lcmd->tc_buffers; 11057917SReza.Sabdar@Sun.COM 11067917SReza.Sabdar@Sun.COM lcmd->tc_ref++; 11077917SReza.Sabdar@Sun.COM cmds->tcs_reader_count++; 11087917SReza.Sabdar@Sun.COM 11097917SReza.Sabdar@Sun.COM /* 11107917SReza.Sabdar@Sun.COM * Synchronize with our parent thread. 11117917SReza.Sabdar@Sun.COM */ 11127917SReza.Sabdar@Sun.COM tlm_cmd_signal(cmds->tcs_command, TLM_TAR_READER); 11137917SReza.Sabdar@Sun.COM 11147917SReza.Sabdar@Sun.COM buf = tlm_buffer_in_buf(bufs, &bidx); 11157917SReza.Sabdar@Sun.COM while (cmds->tcs_reader == TLM_RESTORE_RUN && 11167917SReza.Sabdar@Sun.COM lcmd->tc_reader == TLM_RESTORE_RUN) { 11177917SReza.Sabdar@Sun.COM 11187917SReza.Sabdar@Sun.COM if (buf->tb_full) { 11197917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "R%d", bidx); 11207917SReza.Sabdar@Sun.COM /* 11217917SReza.Sabdar@Sun.COM * The buffer is still full, wait for the consumer 11227917SReza.Sabdar@Sun.COM * thread to use it. 11237917SReza.Sabdar@Sun.COM */ 11247917SReza.Sabdar@Sun.COM tlm_buffer_out_buf_timed_wait(bufs, 100); 11257917SReza.Sabdar@Sun.COM buf = tlm_buffer_in_buf(bufs, NULL); 11267917SReza.Sabdar@Sun.COM } else { 11277917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "r%d", bidx); 11287917SReza.Sabdar@Sun.COM 11297917SReza.Sabdar@Sun.COM err = read_one_buf(mod_params, bufs, buf); 11307917SReza.Sabdar@Sun.COM if (err < 0) { 11317917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 11327917SReza.Sabdar@Sun.COM "Reading buffer %d, pos: %lld", 11337917SReza.Sabdar@Sun.COM bidx, session->ns_mover.md_position); 11347917SReza.Sabdar@Sun.COM 11357917SReza.Sabdar@Sun.COM /* Force the writer to stop. */ 11367917SReza.Sabdar@Sun.COM buf->tb_eot = buf->tb_eof = TRUE; 11377917SReza.Sabdar@Sun.COM break; 11387917SReza.Sabdar@Sun.COM } else if (err == 1) { 11397917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 11407917SReza.Sabdar@Sun.COM "operation aborted or session terminated"); 11417917SReza.Sabdar@Sun.COM err = 0; 11427917SReza.Sabdar@Sun.COM break; 11437917SReza.Sabdar@Sun.COM } 11447917SReza.Sabdar@Sun.COM 11457917SReza.Sabdar@Sun.COM buf = tlm_buffer_in_buf(bufs, &bidx); 11467917SReza.Sabdar@Sun.COM tlm_buffer_release_in_buf(bufs); 11477917SReza.Sabdar@Sun.COM } 11487917SReza.Sabdar@Sun.COM } 11497917SReza.Sabdar@Sun.COM 11507917SReza.Sabdar@Sun.COM /* 11517917SReza.Sabdar@Sun.COM * If the consumer is waiting for us, wake it up so that it detects 11527917SReza.Sabdar@Sun.COM * we're quiting. 11537917SReza.Sabdar@Sun.COM */ 11547917SReza.Sabdar@Sun.COM lcmd->tc_writer = TLM_STOP; 11557917SReza.Sabdar@Sun.COM tlm_buffer_release_in_buf(bufs); 11567917SReza.Sabdar@Sun.COM (void) usleep(1000); 11577917SReza.Sabdar@Sun.COM 11587917SReza.Sabdar@Sun.COM /* 11597917SReza.Sabdar@Sun.COM * Clean up. 11607917SReza.Sabdar@Sun.COM */ 11617917SReza.Sabdar@Sun.COM cmds->tcs_reader_count--; 11627917SReza.Sabdar@Sun.COM lcmd->tc_ref--; 11637917SReza.Sabdar@Sun.COM return (err); 11647917SReza.Sabdar@Sun.COM } 11657917SReza.Sabdar@Sun.COM 11667917SReza.Sabdar@Sun.COM 11677917SReza.Sabdar@Sun.COM /* 11687917SReza.Sabdar@Sun.COM * ndmpd_tar_backup 11697917SReza.Sabdar@Sun.COM * 11707917SReza.Sabdar@Sun.COM * Check must have been done that backup work directory exists, before 11717917SReza.Sabdar@Sun.COM * calling this function. 11727917SReza.Sabdar@Sun.COM */ 11737917SReza.Sabdar@Sun.COM static int 11747917SReza.Sabdar@Sun.COM ndmpd_tar_backup(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, 11757917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp) 11767917SReza.Sabdar@Sun.COM { 11777917SReza.Sabdar@Sun.COM char jname[TLM_MAX_BACKUP_JOB_NAME]; 11787917SReza.Sabdar@Sun.COM int err; 11797917SReza.Sabdar@Sun.COM tlm_commands_t *cmds; 11807917SReza.Sabdar@Sun.COM 11817917SReza.Sabdar@Sun.COM if (mod_params->mp_operation != NDMP_DATA_OP_BACKUP) { 11827917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 11837917SReza.Sabdar@Sun.COM "mod_params->mp_operation != NDMP_DATA_OP_BACKUP"); 11847917SReza.Sabdar@Sun.COM err = -1; 11857917SReza.Sabdar@Sun.COM } else { 11867917SReza.Sabdar@Sun.COM if (ndmpd_mark_inodes_v2(session, nlp) != 0) 11877917SReza.Sabdar@Sun.COM err = -1; 11887917SReza.Sabdar@Sun.COM else if (ndmp_get_bk_dir_ino(nlp)) 11897917SReza.Sabdar@Sun.COM err = -1; 11907917SReza.Sabdar@Sun.COM else 11917917SReza.Sabdar@Sun.COM err = 0; 11927917SReza.Sabdar@Sun.COM } 11937917SReza.Sabdar@Sun.COM 11947917SReza.Sabdar@Sun.COM if (err != 0) 11957917SReza.Sabdar@Sun.COM return (err); 11967917SReza.Sabdar@Sun.COM 11977917SReza.Sabdar@Sun.COM (void) ndmp_new_job_name(jname); 11987917SReza.Sabdar@Sun.COM if (backup_create_structs(session, jname) < 0) 11997917SReza.Sabdar@Sun.COM return (-1); 12007917SReza.Sabdar@Sun.COM 12017917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_start_ltime = time(NULL); 12027917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_start_time = nlp->nlp_jstat->js_start_ltime; 12037917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_chkpnt_time = nlp->nlp_cdate; 12047917SReza.Sabdar@Sun.COM 12057917SReza.Sabdar@Sun.COM if (!session->ns_data.dd_abort) { 12067917SReza.Sabdar@Sun.COM 12077917SReza.Sabdar@Sun.COM cmds = &nlp->nlp_cmds; 12087917SReza.Sabdar@Sun.COM cmds->tcs_reader = cmds->tcs_writer = TLM_BACKUP_RUN; 12097917SReza.Sabdar@Sun.COM cmds->tcs_command->tc_reader = TLM_BACKUP_RUN; 12107917SReza.Sabdar@Sun.COM cmds->tcs_command->tc_writer = TLM_BACKUP_RUN; 12117917SReza.Sabdar@Sun.COM 12127917SReza.Sabdar@Sun.COM if (ndmp_write_utf8magic(cmds->tcs_command) < 0) { 12137917SReza.Sabdar@Sun.COM backup_release_structs(session); 12147917SReza.Sabdar@Sun.COM return (-1); 12157917SReza.Sabdar@Sun.COM } 12167917SReza.Sabdar@Sun.COM 12177917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Backing up \"%s\" started.", 12187917SReza.Sabdar@Sun.COM nlp->nlp_backup_path); 12197917SReza.Sabdar@Sun.COM 12207917SReza.Sabdar@Sun.COM err = ndmp_backup_reader(cmds, nlp, jname); 12217917SReza.Sabdar@Sun.COM if (err != 0) { 12227917SReza.Sabdar@Sun.COM backup_release_structs(session); 12237917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Launch ndmp_backup_reader: %s", 12247917SReza.Sabdar@Sun.COM strerror(err)); 12257917SReza.Sabdar@Sun.COM return (-1); 12267917SReza.Sabdar@Sun.COM } 12277917SReza.Sabdar@Sun.COM 12287917SReza.Sabdar@Sun.COM /* Act as the writer thread. */ 12297917SReza.Sabdar@Sun.COM err = ndmp_tar_writer(session, mod_params, cmds); 12307917SReza.Sabdar@Sun.COM 12317917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_stop_time = time(NULL); 12327917SReza.Sabdar@Sun.COM 12337917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 12347917SReza.Sabdar@Sun.COM "Runtime [%s] %llu bytes (%llu): %d seconds", 12357917SReza.Sabdar@Sun.COM nlp->nlp_backup_path, session->ns_mover.md_data_written, 12367917SReza.Sabdar@Sun.COM session->ns_mover.md_data_written, 12377917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_stop_time - 12387917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_start_ltime); 12397917SReza.Sabdar@Sun.COM MOD_LOG(mod_params, 12407917SReza.Sabdar@Sun.COM "Runtime [%s] %llu bytes (%llu): %d seconds", 12417917SReza.Sabdar@Sun.COM nlp->nlp_backup_path, session->ns_mover.md_data_written, 12427917SReza.Sabdar@Sun.COM session->ns_mover.md_data_written, 12437917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_stop_time - 12447917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_start_ltime); 12457917SReza.Sabdar@Sun.COM 12467917SReza.Sabdar@Sun.COM if (session->ns_data.dd_abort) 12477917SReza.Sabdar@Sun.COM err = -1; 12487917SReza.Sabdar@Sun.COM 12497917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Backing up \"%s\" finished. (%d)", 12507917SReza.Sabdar@Sun.COM nlp->nlp_backup_path, err); 12517917SReza.Sabdar@Sun.COM } else { 12527917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_stop_time = time(NULL); 12537917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Backing up \"%s\" aborted.", 12547917SReza.Sabdar@Sun.COM nlp->nlp_backup_path); 12557917SReza.Sabdar@Sun.COM err = 0; 12567917SReza.Sabdar@Sun.COM } 12577917SReza.Sabdar@Sun.COM 12587917SReza.Sabdar@Sun.COM backup_release_structs(session); 12597917SReza.Sabdar@Sun.COM return (err); 12607917SReza.Sabdar@Sun.COM } 12617917SReza.Sabdar@Sun.COM 12627917SReza.Sabdar@Sun.COM 12637917SReza.Sabdar@Sun.COM /* 12647917SReza.Sabdar@Sun.COM * ndmpd_tar_restore 12657917SReza.Sabdar@Sun.COM * 12667917SReza.Sabdar@Sun.COM * Restore function that launches TAR reader thread to read from the 12677917SReza.Sabdar@Sun.COM * tape and writes the extracted files/dirs to the filesystem 12687917SReza.Sabdar@Sun.COM */ 12697917SReza.Sabdar@Sun.COM static int 12707917SReza.Sabdar@Sun.COM ndmpd_tar_restore(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, 12717917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp) 12727917SReza.Sabdar@Sun.COM { 12737917SReza.Sabdar@Sun.COM char jname[TLM_MAX_BACKUP_JOB_NAME]; 12747917SReza.Sabdar@Sun.COM char *rspath; 12757917SReza.Sabdar@Sun.COM int err; 12767917SReza.Sabdar@Sun.COM tlm_commands_t *cmds; 12777917SReza.Sabdar@Sun.COM ndmp_tar_reader_arg_t arg; 12787917SReza.Sabdar@Sun.COM tlm_backup_restore_arg_t tlm_arg; 12797917SReza.Sabdar@Sun.COM ndmp_name *ent; 12807917SReza.Sabdar@Sun.COM pthread_t rdtp, wrtp; 12817917SReza.Sabdar@Sun.COM int i; 12827917SReza.Sabdar@Sun.COM 12837917SReza.Sabdar@Sun.COM if (mod_params->mp_operation != NDMP_DATA_OP_RECOVER) { 12847917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 12857917SReza.Sabdar@Sun.COM "mod_params->mp_operation != NDMP_DATA_OP_RECOVER"); 12867917SReza.Sabdar@Sun.COM return (-1); 12877917SReza.Sabdar@Sun.COM } 12887917SReza.Sabdar@Sun.COM 12897917SReza.Sabdar@Sun.COM if (nlp->nlp_restore_path[0] != '\0') 12907917SReza.Sabdar@Sun.COM rspath = nlp->nlp_restore_path; 12917917SReza.Sabdar@Sun.COM else if (nlp->nlp_restore_bk_path[0] != '\0') 12927917SReza.Sabdar@Sun.COM rspath = nlp->nlp_restore_bk_path; 12937917SReza.Sabdar@Sun.COM else 12947917SReza.Sabdar@Sun.COM rspath = ""; 12957917SReza.Sabdar@Sun.COM 12967917SReza.Sabdar@Sun.COM (void) ndmp_new_job_name(jname); 12977917SReza.Sabdar@Sun.COM if (restore_create_structs(session, jname) < 0) 12987917SReza.Sabdar@Sun.COM return (-1); 12997917SReza.Sabdar@Sun.COM 13007917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_start_ltime = time(NULL); 13017917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_start_time = time(NULL); 13027917SReza.Sabdar@Sun.COM 13037917SReza.Sabdar@Sun.COM if (!session->ns_data.dd_abort) { 13047917SReza.Sabdar@Sun.COM cmds = &nlp->nlp_cmds; 13057917SReza.Sabdar@Sun.COM cmds->tcs_reader = cmds->tcs_writer = TLM_RESTORE_RUN; 13067917SReza.Sabdar@Sun.COM cmds->tcs_command->tc_reader = TLM_RESTORE_RUN; 13077917SReza.Sabdar@Sun.COM cmds->tcs_command->tc_writer = TLM_RESTORE_RUN; 13087917SReza.Sabdar@Sun.COM 13097917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" started.", rspath); 13107917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Restoring from %s tape(s).", 13117917SReza.Sabdar@Sun.COM ndmp_data_get_mover_mode(session)); 13127917SReza.Sabdar@Sun.COM 13137917SReza.Sabdar@Sun.COM arg.tr_session = session; 13147917SReza.Sabdar@Sun.COM arg.tr_mod_params = mod_params; 13157917SReza.Sabdar@Sun.COM arg.tr_cmds = cmds; 13167917SReza.Sabdar@Sun.COM 13177917SReza.Sabdar@Sun.COM err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader, 13187917SReza.Sabdar@Sun.COM (void *)&arg); 13197917SReza.Sabdar@Sun.COM if (err == 0) { 13207917SReza.Sabdar@Sun.COM tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER); 13217917SReza.Sabdar@Sun.COM } else { 13227917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Launch ndmp_tar_reader: %m"); 13237917SReza.Sabdar@Sun.COM return (-1); 13247917SReza.Sabdar@Sun.COM } 13257917SReza.Sabdar@Sun.COM 13267917SReza.Sabdar@Sun.COM if (!ndmp_check_utf8magic(cmds->tcs_command)) { 13277917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "UTF8Magic not found!"); 13287917SReza.Sabdar@Sun.COM } else { 13297917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "UTF8Magic found"); 13307917SReza.Sabdar@Sun.COM } 13317917SReza.Sabdar@Sun.COM 13327917SReza.Sabdar@Sun.COM (void) memset(&tlm_arg, 0, sizeof (tlm_backup_restore_arg_t)); 13337917SReza.Sabdar@Sun.COM (void) pthread_barrier_init(&tlm_arg.ba_barrier, 0, 2); 13347917SReza.Sabdar@Sun.COM 13357917SReza.Sabdar@Sun.COM /* 13367917SReza.Sabdar@Sun.COM * Set up restore parameters 13377917SReza.Sabdar@Sun.COM */ 13387917SReza.Sabdar@Sun.COM tlm_arg.ba_commands = cmds; 13397917SReza.Sabdar@Sun.COM tlm_arg.ba_cmd = cmds->tcs_command; 13407917SReza.Sabdar@Sun.COM tlm_arg.ba_job = nlp->nlp_jstat->js_job_name; 13417917SReza.Sabdar@Sun.COM tlm_arg.ba_dir = nlp->nlp_restore_path; 13427917SReza.Sabdar@Sun.COM for (i = 0; i < nlp->nlp_nfiles; i++) { 13437917SReza.Sabdar@Sun.COM ent = (ndmp_name *)MOD_GETNAME(mod_params, i); 13447917SReza.Sabdar@Sun.COM tlm_arg.ba_sels[i] = ent->name; 13457917SReza.Sabdar@Sun.COM } 13467917SReza.Sabdar@Sun.COM 13477917SReza.Sabdar@Sun.COM 13487917SReza.Sabdar@Sun.COM if (tm_tar_ops.tm_getfile != NULL) { 13497917SReza.Sabdar@Sun.COM err = pthread_create(&wrtp, NULL, 13507917SReza.Sabdar@Sun.COM (funct_t)tm_tar_ops.tm_getfile, (void *)&tlm_arg); 13517917SReza.Sabdar@Sun.COM } else { 13527917SReza.Sabdar@Sun.COM (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); 13537917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 13547917SReza.Sabdar@Sun.COM "Thread create tm_getfile: ops NULL"); 13557917SReza.Sabdar@Sun.COM return (-1); 13567917SReza.Sabdar@Sun.COM } 13577917SReza.Sabdar@Sun.COM if (err == 0) { 13587917SReza.Sabdar@Sun.COM (void) pthread_barrier_wait(&tlm_arg.ba_barrier); 13597917SReza.Sabdar@Sun.COM } else { 13607917SReza.Sabdar@Sun.COM (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); 13617917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "thread create tm_getfile: %m"); 13627917SReza.Sabdar@Sun.COM return (-1); 13637917SReza.Sabdar@Sun.COM } 13647917SReza.Sabdar@Sun.COM 13657917SReza.Sabdar@Sun.COM (void) pthread_join(rdtp, NULL); 13667917SReza.Sabdar@Sun.COM (void) pthread_join(wrtp, NULL); 13677917SReza.Sabdar@Sun.COM (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); 13687917SReza.Sabdar@Sun.COM 13697917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_stop_time = time(NULL); 13707917SReza.Sabdar@Sun.COM 13717917SReza.Sabdar@Sun.COM /* Send the list of un-recovered files/dirs to the client. */ 13727917SReza.Sabdar@Sun.COM (void) send_unrecovered_list(mod_params, nlp); 13737917SReza.Sabdar@Sun.COM 13747917SReza.Sabdar@Sun.COM ndmp_stop_local_reader(session, cmds); 13757917SReza.Sabdar@Sun.COM ndmp_wait_for_reader(cmds); 13767917SReza.Sabdar@Sun.COM ndmp_stop_remote_reader(session); 13777917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" finished. (%d)", 13787917SReza.Sabdar@Sun.COM rspath, err); 13797917SReza.Sabdar@Sun.COM } else { 13807917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_stop_time = time(NULL); 13817917SReza.Sabdar@Sun.COM 13827917SReza.Sabdar@Sun.COM /* nothing restored. */ 13837917SReza.Sabdar@Sun.COM (void) send_unrecovered_list(mod_params, nlp); 13847917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" aborted.", 13857917SReza.Sabdar@Sun.COM rspath); 13867917SReza.Sabdar@Sun.COM err = -1; 13877917SReza.Sabdar@Sun.COM } 13887917SReza.Sabdar@Sun.COM 13897917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_restore_path); 13907917SReza.Sabdar@Sun.COM backup_release_structs(session); 13917917SReza.Sabdar@Sun.COM 13927917SReza.Sabdar@Sun.COM return (err); 13937917SReza.Sabdar@Sun.COM } 13947917SReza.Sabdar@Sun.COM 13957917SReza.Sabdar@Sun.COM 13967917SReza.Sabdar@Sun.COM /* 13977917SReza.Sabdar@Sun.COM * prefixdir 13987917SReza.Sabdar@Sun.COM * 13997917SReza.Sabdar@Sun.COM * Extract the path for a given full path entry 14007917SReza.Sabdar@Sun.COM */ 14017917SReza.Sabdar@Sun.COM static char * 14027917SReza.Sabdar@Sun.COM prefixdir(char *dir, char *suffix) 14037917SReza.Sabdar@Sun.COM { 14047917SReza.Sabdar@Sun.COM static char tmp[TLM_MAX_PATH_NAME]; 14057917SReza.Sabdar@Sun.COM char *tend, *send; /* tmp and suffix end */ 14067917SReza.Sabdar@Sun.COM 14077917SReza.Sabdar@Sun.COM if (dir == NULL || suffix == NULL) 14087917SReza.Sabdar@Sun.COM return (NULL); 14097917SReza.Sabdar@Sun.COM 14107917SReza.Sabdar@Sun.COM if (*suffix == '\0') 14117917SReza.Sabdar@Sun.COM return (dir); 14127917SReza.Sabdar@Sun.COM 14137917SReza.Sabdar@Sun.COM if (*dir == '\0') 14147917SReza.Sabdar@Sun.COM return (NULL); 14157917SReza.Sabdar@Sun.COM 14167917SReza.Sabdar@Sun.COM (void) strlcpy(tmp, dir, TLM_MAX_PATH_NAME); 14177917SReza.Sabdar@Sun.COM tend = &tmp[strlen(tmp)]; 14187917SReza.Sabdar@Sun.COM send = &suffix[strlen(suffix)]; 14197917SReza.Sabdar@Sun.COM 14207917SReza.Sabdar@Sun.COM /* 14217917SReza.Sabdar@Sun.COM * Move backward as far as the last part of the dir and 14227917SReza.Sabdar@Sun.COM * the suffix match. 14237917SReza.Sabdar@Sun.COM */ 14247917SReza.Sabdar@Sun.COM while (tend >= tmp && send >= suffix) 14257917SReza.Sabdar@Sun.COM if (*tend == *send) 14267917SReza.Sabdar@Sun.COM tend--, send--; 14277917SReza.Sabdar@Sun.COM else 14287917SReza.Sabdar@Sun.COM break; 14297917SReza.Sabdar@Sun.COM 14307917SReza.Sabdar@Sun.COM *++tend = '\0'; 14317917SReza.Sabdar@Sun.COM return (tmp); 14327917SReza.Sabdar@Sun.COM } 14337917SReza.Sabdar@Sun.COM 14347917SReza.Sabdar@Sun.COM 14357917SReza.Sabdar@Sun.COM /* 14367917SReza.Sabdar@Sun.COM * get_backup_path 14377917SReza.Sabdar@Sun.COM * 14387917SReza.Sabdar@Sun.COM * Find the backup path from the environment variables 14397917SReza.Sabdar@Sun.COM */ 14407917SReza.Sabdar@Sun.COM static char * 14417917SReza.Sabdar@Sun.COM get_backup_path(ndmpd_module_params_t *params) 14427917SReza.Sabdar@Sun.COM { 14437917SReza.Sabdar@Sun.COM char *bkpath; 14447917SReza.Sabdar@Sun.COM 14457917SReza.Sabdar@Sun.COM bkpath = MOD_GETENV(params, "PREFIX"); 14467917SReza.Sabdar@Sun.COM if (bkpath == NULL) 14477917SReza.Sabdar@Sun.COM bkpath = MOD_GETENV(params, "FILESYSTEM"); 14487917SReza.Sabdar@Sun.COM 14497917SReza.Sabdar@Sun.COM if (bkpath == NULL) { 14507917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: restore path not specified.\n"); 14517917SReza.Sabdar@Sun.COM return (NULL); 14527917SReza.Sabdar@Sun.COM } 14537917SReza.Sabdar@Sun.COM 14547917SReza.Sabdar@Sun.COM if (*bkpath != '/') { 14557917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: relative backup path not allowed.\n"); 14567917SReza.Sabdar@Sun.COM return (NULL); 14577917SReza.Sabdar@Sun.COM } 14587917SReza.Sabdar@Sun.COM 14597917SReza.Sabdar@Sun.COM return (bkpath); 14607917SReza.Sabdar@Sun.COM } 14617917SReza.Sabdar@Sun.COM 14627917SReza.Sabdar@Sun.COM 14637917SReza.Sabdar@Sun.COM /* 14647917SReza.Sabdar@Sun.COM * get_nfiles 14657917SReza.Sabdar@Sun.COM * 14667917SReza.Sabdar@Sun.COM * Get the count of files to be restored 14677917SReza.Sabdar@Sun.COM */ 14687917SReza.Sabdar@Sun.COM static int 14697917SReza.Sabdar@Sun.COM get_nfiles(ndmpd_session_t *session, ndmpd_module_params_t *params) 14707917SReza.Sabdar@Sun.COM { 14717917SReza.Sabdar@Sun.COM if (session->ns_data.dd_nlist_len == 0) { 14727917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: nothing specified to be restored.\n"); 14737917SReza.Sabdar@Sun.COM return (-1); 14747917SReza.Sabdar@Sun.COM } 14757917SReza.Sabdar@Sun.COM 14767917SReza.Sabdar@Sun.COM return (session->ns_data.dd_nlist_len); 14777917SReza.Sabdar@Sun.COM } 14787917SReza.Sabdar@Sun.COM 14797917SReza.Sabdar@Sun.COM 14807917SReza.Sabdar@Sun.COM /* 14817917SReza.Sabdar@Sun.COM * get_restore_dest 14827917SReza.Sabdar@Sun.COM * 14837917SReza.Sabdar@Sun.COM * Get the full pathname of where the entries should be restored to. 14847917SReza.Sabdar@Sun.COM */ 14857917SReza.Sabdar@Sun.COM static char * 14867917SReza.Sabdar@Sun.COM get_restore_dest(ndmpd_module_params_t *params) 14877917SReza.Sabdar@Sun.COM { 14887917SReza.Sabdar@Sun.COM ndmp_name *ent; 14897917SReza.Sabdar@Sun.COM char *cp; 14907917SReza.Sabdar@Sun.COM 14917917SReza.Sabdar@Sun.COM /* 14927917SReza.Sabdar@Sun.COM * Destination of restore: 14937917SReza.Sabdar@Sun.COM * NetBackup of Veritas(C) sends the entries like this: 14947917SReza.Sabdar@Sun.COM * 14957917SReza.Sabdar@Sun.COM * ent[i].name: is the relative pathname of what is selected in 14967917SReza.Sabdar@Sun.COM * the GUI. 14977917SReza.Sabdar@Sun.COM * ent[i].dest: is the full pathname of where the dir/file must 14987917SReza.Sabdar@Sun.COM * be restored to. 14997917SReza.Sabdar@Sun.COM * ent[i].ssi: 0 15007917SReza.Sabdar@Sun.COM * ent[i].fh_info: 0 15017917SReza.Sabdar@Sun.COM * 15027917SReza.Sabdar@Sun.COM */ 15037917SReza.Sabdar@Sun.COM ent = (ndmp_name *)MOD_GETNAME(params, 0); 15047917SReza.Sabdar@Sun.COM cp = prefixdir(ent->dest, ent->name); 15057917SReza.Sabdar@Sun.COM if (cp == NULL) { 15067917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: empty restore path.\n"); 15077917SReza.Sabdar@Sun.COM return (NULL); 15087917SReza.Sabdar@Sun.COM } 15097917SReza.Sabdar@Sun.COM 15107917SReza.Sabdar@Sun.COM return (cp); 15117917SReza.Sabdar@Sun.COM } 15127917SReza.Sabdar@Sun.COM 15137917SReza.Sabdar@Sun.COM 15147917SReza.Sabdar@Sun.COM /* 15157917SReza.Sabdar@Sun.COM * correct_ents 15167917SReza.Sabdar@Sun.COM * 15177917SReza.Sabdar@Sun.COM * Correct the entries in the restore list by appending the appropriate 15187917SReza.Sabdar@Sun.COM * path to them 15197917SReza.Sabdar@Sun.COM */ 15207917SReza.Sabdar@Sun.COM static int 15217917SReza.Sabdar@Sun.COM correct_ents(ndmpd_module_params_t *params, int n, char *bkpath) 15227917SReza.Sabdar@Sun.COM { 15237917SReza.Sabdar@Sun.COM char *cp, *pathname; 15247917SReza.Sabdar@Sun.COM int i, len, rv; 15257917SReza.Sabdar@Sun.COM ndmp_name *ent; 15267917SReza.Sabdar@Sun.COM 15277917SReza.Sabdar@Sun.COM if ((pathname = ndmp_malloc(TLM_MAX_PATH_NAME)) == NULL) { 15287917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: insufficient memory.\n"); 15297917SReza.Sabdar@Sun.COM return (-1); 15307917SReza.Sabdar@Sun.COM } 15317917SReza.Sabdar@Sun.COM 15327917SReza.Sabdar@Sun.COM rv = 0; 15337917SReza.Sabdar@Sun.COM /* Append the backup path to all the "ent[].name"s. */ 15347917SReza.Sabdar@Sun.COM for (i = 0; i < n; i++) { 15357917SReza.Sabdar@Sun.COM ent = (ndmp_name *)MOD_GETNAME(params, i); 15367917SReza.Sabdar@Sun.COM 15377917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 15387917SReza.Sabdar@Sun.COM "Old: ent[%d].name: \"%s\"", i, ent->name); 15397917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 15407917SReza.Sabdar@Sun.COM "Old: ent[%d].dest: \"%s\"", i, ent->dest); 15417917SReza.Sabdar@Sun.COM 15427917SReza.Sabdar@Sun.COM /* remove trailing slash */ 15437917SReza.Sabdar@Sun.COM len = strlen(ent->name); 15447917SReza.Sabdar@Sun.COM if (ent->name[len - 1] == '/') 15457917SReza.Sabdar@Sun.COM ent->name[len - 1] = '\0'; 15467917SReza.Sabdar@Sun.COM 15477917SReza.Sabdar@Sun.COM if (!tlm_cat_path(pathname, bkpath, ent->name)) { 15487917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: path too long.\n"); 15497917SReza.Sabdar@Sun.COM rv = -1; 15507917SReza.Sabdar@Sun.COM break; 15517917SReza.Sabdar@Sun.COM } 15527917SReza.Sabdar@Sun.COM 15537917SReza.Sabdar@Sun.COM /* Make a copy of the new string and save it in ent->name. */ 15547917SReza.Sabdar@Sun.COM cp = strdup(pathname); 15557917SReza.Sabdar@Sun.COM if (cp == NULL) { 15567917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: insufficient memory.\n"); 15577917SReza.Sabdar@Sun.COM rv = -1; 15587917SReza.Sabdar@Sun.COM break; 15597917SReza.Sabdar@Sun.COM } 15607917SReza.Sabdar@Sun.COM free(ent->name); 15617917SReza.Sabdar@Sun.COM ent->name = cp; 15627917SReza.Sabdar@Sun.COM 15637917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 15647917SReza.Sabdar@Sun.COM "New: ent[%d].name: \"%s\"", i, ent->name); 15657917SReza.Sabdar@Sun.COM } 15667917SReza.Sabdar@Sun.COM 15677917SReza.Sabdar@Sun.COM free(pathname); 15687917SReza.Sabdar@Sun.COM return (rv); 15697917SReza.Sabdar@Sun.COM } 15707917SReza.Sabdar@Sun.COM 15717917SReza.Sabdar@Sun.COM 15727917SReza.Sabdar@Sun.COM /* 15737917SReza.Sabdar@Sun.COM * check_restore_paths 15747917SReza.Sabdar@Sun.COM * 15757917SReza.Sabdar@Sun.COM * Go through the restore list and check the validity of the 15767917SReza.Sabdar@Sun.COM * restore path. 15777917SReza.Sabdar@Sun.COM */ 15787917SReza.Sabdar@Sun.COM static int 15797917SReza.Sabdar@Sun.COM check_restore_paths(ndmpd_module_params_t *params, int n, char *rspath) 15807917SReza.Sabdar@Sun.COM { 15817917SReza.Sabdar@Sun.COM int i, rv; 15827917SReza.Sabdar@Sun.COM ndmp_name *ent; 15837917SReza.Sabdar@Sun.COM 15847917SReza.Sabdar@Sun.COM rv = 0; 15857917SReza.Sabdar@Sun.COM if (rspath != NULL && *rspath != '\0') { 15867917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "rspath: \"%s\"", rspath); 15877917SReza.Sabdar@Sun.COM if (!fs_volexist(rspath)) { 15887917SReza.Sabdar@Sun.COM MOD_LOG(params, 15897917SReza.Sabdar@Sun.COM "Error: Invalid volume name for restore."); 15907917SReza.Sabdar@Sun.COM rv = -1; 15917917SReza.Sabdar@Sun.COM } 15927917SReza.Sabdar@Sun.COM } else { 15937917SReza.Sabdar@Sun.COM for (i = 0; i < n; i++) { 15947917SReza.Sabdar@Sun.COM ent = (ndmp_name *)MOD_GETNAME(params, i); 15957917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 15967917SReza.Sabdar@Sun.COM "ent[%d].name: \"%s\"", i, ent->name); 15977917SReza.Sabdar@Sun.COM 15987917SReza.Sabdar@Sun.COM if (!fs_volexist(ent->name)) { 15997917SReza.Sabdar@Sun.COM MOD_LOG(params, 16007917SReza.Sabdar@Sun.COM "Error: Invalid volume name for restore.", 16017917SReza.Sabdar@Sun.COM ent->name); 16027917SReza.Sabdar@Sun.COM rv = -1; 16037917SReza.Sabdar@Sun.COM break; 16047917SReza.Sabdar@Sun.COM } 16057917SReza.Sabdar@Sun.COM } 16067917SReza.Sabdar@Sun.COM } 16077917SReza.Sabdar@Sun.COM 16087917SReza.Sabdar@Sun.COM return (rv); 16097917SReza.Sabdar@Sun.COM } 16107917SReza.Sabdar@Sun.COM 16117917SReza.Sabdar@Sun.COM 16127917SReza.Sabdar@Sun.COM /* 16137917SReza.Sabdar@Sun.COM * check_backup_dir_validity 16147917SReza.Sabdar@Sun.COM * 16157917SReza.Sabdar@Sun.COM * Check if the backup directory is valid. Make sure it exists and 16167917SReza.Sabdar@Sun.COM * is writable. Check for snapshot and readonly cases. 16177917SReza.Sabdar@Sun.COM */ 16187917SReza.Sabdar@Sun.COM static int 16197917SReza.Sabdar@Sun.COM check_backup_dir_validity(ndmpd_module_params_t *params, char *bkpath) 16207917SReza.Sabdar@Sun.COM { 16217917SReza.Sabdar@Sun.COM char *msg; 16227917SReza.Sabdar@Sun.COM int rv; 16237917SReza.Sabdar@Sun.COM struct stat64 st; 16247917SReza.Sabdar@Sun.COM 16257917SReza.Sabdar@Sun.COM rv = NDMP_NO_ERR; 16267917SReza.Sabdar@Sun.COM if (stat64(bkpath, &st) < 0) { 16277917SReza.Sabdar@Sun.COM msg = strerror(errno); 16287917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: stat(%s): %s.\n", bkpath, msg); 16297917SReza.Sabdar@Sun.COM rv = NDMP_ILLEGAL_ARGS_ERR; 16307917SReza.Sabdar@Sun.COM } else if (!S_ISDIR(st.st_mode)) { 16317917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: %s is not a directory.\n", bkpath); 16327917SReza.Sabdar@Sun.COM rv = NDMP_ILLEGAL_ARGS_ERR; 16337917SReza.Sabdar@Sun.COM } else if (ndmp_is_chkpnt_root(bkpath)) { 16347917SReza.Sabdar@Sun.COM /* It's a .chkpnt directory */ 16357917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: %s is a checkpoint root directory.\n", 16367917SReza.Sabdar@Sun.COM bkpath); 16377917SReza.Sabdar@Sun.COM rv = NDMP_BAD_FILE_ERR; 16387917SReza.Sabdar@Sun.COM } else if (fs_is_rdonly(bkpath) && !fs_is_chkpntvol(bkpath) && 16397917SReza.Sabdar@Sun.COM fs_is_chkpnt_enabled(bkpath)) { 16407917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: %s is not a checkpointed path.\n", 16417917SReza.Sabdar@Sun.COM bkpath); 16427917SReza.Sabdar@Sun.COM rv = NDMP_BAD_FILE_ERR; 16437917SReza.Sabdar@Sun.COM } 16447917SReza.Sabdar@Sun.COM 16457917SReza.Sabdar@Sun.COM return (rv); 16467917SReza.Sabdar@Sun.COM } 16477917SReza.Sabdar@Sun.COM 16487917SReza.Sabdar@Sun.COM 16497917SReza.Sabdar@Sun.COM /* 16507917SReza.Sabdar@Sun.COM * ndmp_backup_extract_params 16517917SReza.Sabdar@Sun.COM * 16527917SReza.Sabdar@Sun.COM * Go through the backup parameters and check the validity 16537917SReza.Sabdar@Sun.COM * for each one. Then set the NLP flags according to the parameters. 16547917SReza.Sabdar@Sun.COM */ 16557917SReza.Sabdar@Sun.COM int 16567917SReza.Sabdar@Sun.COM ndmp_backup_extract_params(ndmpd_session_t *session, 16577917SReza.Sabdar@Sun.COM ndmpd_module_params_t *params) 16587917SReza.Sabdar@Sun.COM { 16597917SReza.Sabdar@Sun.COM char *cp; 16607917SReza.Sabdar@Sun.COM int rv; 16617917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 16627917SReza.Sabdar@Sun.COM 16637917SReza.Sabdar@Sun.COM /* Extract directory to be backed up from env variables */ 16647917SReza.Sabdar@Sun.COM if ((nlp = ndmp_get_nlp(session)) == NULL) { 16657917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: Internal error: nlp == NULL.\n"); 16667917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 16677917SReza.Sabdar@Sun.COM } 16687917SReza.Sabdar@Sun.COM if ((nlp->nlp_backup_path = get_backup_path(params)) == NULL) 16697917SReza.Sabdar@Sun.COM return (NDMP_FILE_NOT_FOUND_ERR); 16707917SReza.Sabdar@Sun.COM 16717917SReza.Sabdar@Sun.COM if ((rv = check_backup_dir_validity(params, 16727917SReza.Sabdar@Sun.COM nlp->nlp_backup_path)) != NDMP_NO_ERR) 16737917SReza.Sabdar@Sun.COM return (rv); 16747917SReza.Sabdar@Sun.COM 16757917SReza.Sabdar@Sun.COM /* Should the st_ctime be ignored when backing up? */ 16767917SReza.Sabdar@Sun.COM if (ndmp_ignore_ctime) { 16777917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "ignoring st_ctime"); 16787917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_IGNCTIME); 16797917SReza.Sabdar@Sun.COM } else 16807917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_IGNCTIME); 16817917SReza.Sabdar@Sun.COM 16827917SReza.Sabdar@Sun.COM /* Should the st_lmtime be ignored when backing up? */ 16837917SReza.Sabdar@Sun.COM if (ndmp_include_lmtime) { 16847917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "including st_lmtime"); 16857917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_INCLMTIME); 16867917SReza.Sabdar@Sun.COM } else 16877917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_INCLMTIME); 16887917SReza.Sabdar@Sun.COM 16897917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "flags %x", nlp->nlp_flags); 16907917SReza.Sabdar@Sun.COM 16917917SReza.Sabdar@Sun.COM /* Is backup history requested? */ 16927917SReza.Sabdar@Sun.COM cp = MOD_GETENV(params, "HIST"); 16937917SReza.Sabdar@Sun.COM if (cp == NULL) { 16947917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "env(HIST) not specified"); 16957917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_FH); 16967917SReza.Sabdar@Sun.COM } else { 16977917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "env(HIST): \"%s\"", cp); 16987917SReza.Sabdar@Sun.COM 16997917SReza.Sabdar@Sun.COM if (strchr("t_ty_y", *cp)) 17007917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_FH); 17017917SReza.Sabdar@Sun.COM else 17027917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_FH); 17037917SReza.Sabdar@Sun.COM } 17047917SReza.Sabdar@Sun.COM 17057917SReza.Sabdar@Sun.COM nlp->nlp_clevel = 0; 17067917SReza.Sabdar@Sun.COM /* Is it an incremental backup? */ 17077917SReza.Sabdar@Sun.COM cp = MOD_GETENV(params, "LEVEL"); 17087917SReza.Sabdar@Sun.COM if (cp == NULL) { 17097917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 17107917SReza.Sabdar@Sun.COM "env(LEVEL) not specified, default to 0"); 17117917SReza.Sabdar@Sun.COM } else if (*cp < '0' || *cp > '9' || *(cp+1) != '\0') { 17127917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "Invalid backup level '%s'", cp); 17137917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 17147917SReza.Sabdar@Sun.COM } else 17157917SReza.Sabdar@Sun.COM nlp->nlp_clevel = *cp - '0'; 17167917SReza.Sabdar@Sun.COM 17177917SReza.Sabdar@Sun.COM /* Extract last backup time from the dumpdates file */ 17187917SReza.Sabdar@Sun.COM nlp->nlp_llevel = nlp->nlp_clevel; 17197917SReza.Sabdar@Sun.COM nlp->nlp_ldate = 0; 17207917SReza.Sabdar@Sun.COM if (ndmpd_get_dumptime(nlp->nlp_backup_path, &nlp->nlp_llevel, 17217917SReza.Sabdar@Sun.COM &nlp->nlp_ldate) < 0) { 17227917SReza.Sabdar@Sun.COM MOD_LOG(params, "Error: getting dumpdate for %s level %d\n", 17237917SReza.Sabdar@Sun.COM nlp->nlp_backup_path, nlp->nlp_clevel); 17247917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 17257917SReza.Sabdar@Sun.COM } 17267917SReza.Sabdar@Sun.COM 17277917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 17287917SReza.Sabdar@Sun.COM "Date of this level %d on \"%s\": %s", 17297917SReza.Sabdar@Sun.COM nlp->nlp_clevel, nlp->nlp_backup_path, cctime(&nlp->nlp_cdate)); 17307917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 17317917SReza.Sabdar@Sun.COM "Date of last level %d on \"%s\": %s", 17327917SReza.Sabdar@Sun.COM nlp->nlp_llevel, nlp->nlp_backup_path, cctime(&nlp->nlp_ldate)); 17337917SReza.Sabdar@Sun.COM 17347917SReza.Sabdar@Sun.COM /* Should the dumpdate file be updated? */ 17357917SReza.Sabdar@Sun.COM cp = MOD_GETENV(params, "UPDATE"); 17367917SReza.Sabdar@Sun.COM if (cp == NULL) { 17377917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, 17387917SReza.Sabdar@Sun.COM "env(UPDATE) not specified, default to TRUE"); 17397917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_UPDATE); 17407917SReza.Sabdar@Sun.COM } else { 17417917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "env(UPDATE): \"%s\"", cp); 17427917SReza.Sabdar@Sun.COM if (strchr("t_ty_y", *cp) != NULL) 17437917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_UPDATE); 17447917SReza.Sabdar@Sun.COM else 17457917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_UPDATE); 17467917SReza.Sabdar@Sun.COM } 17477917SReza.Sabdar@Sun.COM 17487917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 17497917SReza.Sabdar@Sun.COM } 17507917SReza.Sabdar@Sun.COM 17517917SReza.Sabdar@Sun.COM 17527917SReza.Sabdar@Sun.COM 17537917SReza.Sabdar@Sun.COM /* 17547917SReza.Sabdar@Sun.COM * log_bk_params_v2 17557917SReza.Sabdar@Sun.COM * 17567917SReza.Sabdar@Sun.COM * Dump the value of the parameters in the log file for debugging. 17577917SReza.Sabdar@Sun.COM */ 17587917SReza.Sabdar@Sun.COM void 17597917SReza.Sabdar@Sun.COM log_bk_params_v2(ndmpd_session_t *session, ndmpd_module_params_t *params, 17607917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp) 17617917SReza.Sabdar@Sun.COM { 17627917SReza.Sabdar@Sun.COM MOD_LOG(params, "Date of this level %d on \"%s\": %s\n", 17637917SReza.Sabdar@Sun.COM nlp->nlp_clevel, nlp->nlp_backup_path, cctime(&nlp->nlp_cdate)); 17647917SReza.Sabdar@Sun.COM MOD_LOG(params, "Date of last level %d on \"%s\": %s\n", 17657917SReza.Sabdar@Sun.COM nlp->nlp_llevel, nlp->nlp_backup_path, cctime(&nlp->nlp_ldate)); 17667917SReza.Sabdar@Sun.COM 17677917SReza.Sabdar@Sun.COM MOD_LOG(params, "Backing up: \"%s\".\n", nlp->nlp_backup_path); 17687917SReza.Sabdar@Sun.COM MOD_LOG(params, "Record size: %d\n", session->ns_mover.md_record_size); 17697917SReza.Sabdar@Sun.COM MOD_LOG(params, "File history: %c.\n", 17707917SReza.Sabdar@Sun.COM NDMP_YORN(NLP_ISSET(nlp, NLPF_FH))); 17717917SReza.Sabdar@Sun.COM MOD_LOG(params, "Update: %s\n", 17727917SReza.Sabdar@Sun.COM NLP_ISSET(nlp, NLPF_UPDATE) ? "TRUE" : "FALSE"); 17737917SReza.Sabdar@Sun.COM 17747917SReza.Sabdar@Sun.COM } 17757917SReza.Sabdar@Sun.COM 17767917SReza.Sabdar@Sun.COM 17777917SReza.Sabdar@Sun.COM /* 17787917SReza.Sabdar@Sun.COM * same_path 17797917SReza.Sabdar@Sun.COM * 17807917SReza.Sabdar@Sun.COM * Find out if the paths are the same regardless of the ending slash 17817917SReza.Sabdar@Sun.COM * 17827917SReza.Sabdar@Sun.COM * Examples : 17837917SReza.Sabdar@Sun.COM * /a/b/c == /a/b/c 17847917SReza.Sabdar@Sun.COM * /a/b/c/ == /a/b/c 17857917SReza.Sabdar@Sun.COM * /a/b/c == /a/b/c/ 17867917SReza.Sabdar@Sun.COM */ 17877917SReza.Sabdar@Sun.COM static boolean_t 17887917SReza.Sabdar@Sun.COM same_path(char *s, char *t) 17897917SReza.Sabdar@Sun.COM { 17907917SReza.Sabdar@Sun.COM boolean_t rv; 17917917SReza.Sabdar@Sun.COM int slen, tlen; 17927917SReza.Sabdar@Sun.COM 17937917SReza.Sabdar@Sun.COM rv = FALSE; 17947917SReza.Sabdar@Sun.COM slen = strlen(s); 17957917SReza.Sabdar@Sun.COM tlen = strlen(t); 17967917SReza.Sabdar@Sun.COM if (slen == tlen && strcmp(s, t) == 0) { 17977917SReza.Sabdar@Sun.COM rv = TRUE; 17987917SReza.Sabdar@Sun.COM } else { 17997917SReza.Sabdar@Sun.COM if (slen == tlen - 1) { 18007917SReza.Sabdar@Sun.COM if (strncmp(s, t, slen) == 0 && t[tlen - 1] == '/') 18017917SReza.Sabdar@Sun.COM rv = TRUE; 18027917SReza.Sabdar@Sun.COM } else if (tlen == slen -1) { 18037917SReza.Sabdar@Sun.COM if (strncmp(s, t, tlen) == 0 && s[slen - 1] == '/') 18047917SReza.Sabdar@Sun.COM rv = TRUE; 18057917SReza.Sabdar@Sun.COM } 18067917SReza.Sabdar@Sun.COM } 18077917SReza.Sabdar@Sun.COM 18087917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "rv: %d", rv); 18097917SReza.Sabdar@Sun.COM return (rv); 18107917SReza.Sabdar@Sun.COM } 18117917SReza.Sabdar@Sun.COM 18127917SReza.Sabdar@Sun.COM 18137917SReza.Sabdar@Sun.COM /* 18147917SReza.Sabdar@Sun.COM * ndmp_restore_extract_params 18157917SReza.Sabdar@Sun.COM * 18167917SReza.Sabdar@Sun.COM * Go through the restore parameters and check them and extract them 18177917SReza.Sabdar@Sun.COM * by setting NLP flags and other values. 18187917SReza.Sabdar@Sun.COM * 18197917SReza.Sabdar@Sun.COM * Parameters: 18207917SReza.Sabdar@Sun.COM * 18217917SReza.Sabdar@Sun.COM * Returns: 18227917SReza.Sabdar@Sun.COM * 0: on success 18237917SReza.Sabdar@Sun.COM * -1: otherwise 18247917SReza.Sabdar@Sun.COM */ 18257917SReza.Sabdar@Sun.COM int 18267917SReza.Sabdar@Sun.COM ndmp_restore_extract_params(ndmpd_session_t *session, 18277917SReza.Sabdar@Sun.COM ndmpd_module_params_t *params) 18287917SReza.Sabdar@Sun.COM { 18297917SReza.Sabdar@Sun.COM char *bkpath, *rspath; 18307917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 18317917SReza.Sabdar@Sun.COM 18327917SReza.Sabdar@Sun.COM if ((nlp = ndmp_get_nlp(session)) == NULL) { 18337917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 18347917SReza.Sabdar@Sun.COM return (-1); 18357917SReza.Sabdar@Sun.COM } 18367917SReza.Sabdar@Sun.COM 18377917SReza.Sabdar@Sun.COM /* Extract directory from where the backup was made. */ 18387917SReza.Sabdar@Sun.COM if ((bkpath = get_backup_path(params)) == NULL) 18397917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 18407917SReza.Sabdar@Sun.COM 18417917SReza.Sabdar@Sun.COM nlp->nlp_restore_bk_path = bkpath; 18427917SReza.Sabdar@Sun.COM 18437917SReza.Sabdar@Sun.COM /* The number of the selections. */ 18447917SReza.Sabdar@Sun.COM if ((nlp->nlp_nfiles = get_nfiles(session, params)) == 0) 18457917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 18467917SReza.Sabdar@Sun.COM 18477917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "nfiles: %d", nlp->nlp_nfiles); 18487917SReza.Sabdar@Sun.COM 18497917SReza.Sabdar@Sun.COM if ((rspath = get_restore_dest(params)) == NULL) 18507917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 18517917SReza.Sabdar@Sun.COM 18527917SReza.Sabdar@Sun.COM if (fs_is_rdonly(rspath)) { 18537917SReza.Sabdar@Sun.COM MOD_LOG(params, 18547917SReza.Sabdar@Sun.COM "Error: Can't restore to a read-only volume: \"%s\"\n", 18557917SReza.Sabdar@Sun.COM rspath); 18567917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 18577917SReza.Sabdar@Sun.COM } 18587917SReza.Sabdar@Sun.COM if (fs_is_chkpntvol(rspath)) { 18597917SReza.Sabdar@Sun.COM MOD_LOG(params, 18607917SReza.Sabdar@Sun.COM "Error: Can't restore to a checkpoint: \"%s\"\n", rspath); 18617917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 18627917SReza.Sabdar@Sun.COM } 18637917SReza.Sabdar@Sun.COM 18647917SReza.Sabdar@Sun.COM if (same_path(bkpath, rspath)) 18657917SReza.Sabdar@Sun.COM rspath = ""; 18667917SReza.Sabdar@Sun.COM 18677917SReza.Sabdar@Sun.COM if ((nlp->nlp_restore_path = strdup(rspath)) == NULL) 18687917SReza.Sabdar@Sun.COM return (NDMP_NO_MEM_ERR); 18697917SReza.Sabdar@Sun.COM 18707917SReza.Sabdar@Sun.COM bkpath = trim_name(bkpath); 18717917SReza.Sabdar@Sun.COM if (correct_ents(params, nlp->nlp_nfiles, bkpath) < 0) { 18727917SReza.Sabdar@Sun.COM free(nlp->nlp_restore_path); 18737917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 18747917SReza.Sabdar@Sun.COM } 18757917SReza.Sabdar@Sun.COM 18767917SReza.Sabdar@Sun.COM if (check_restore_paths(params, nlp->nlp_nfiles, rspath) < 0) { 18777917SReza.Sabdar@Sun.COM free(nlp->nlp_restore_path); 18787917SReza.Sabdar@Sun.COM return (NDMP_ILLEGAL_ARGS_ERR); 18797917SReza.Sabdar@Sun.COM } 18807917SReza.Sabdar@Sun.COM 18817917SReza.Sabdar@Sun.COM MOD_LOG(params, "Restoring %d files.\n", nlp->nlp_nfiles); 18827917SReza.Sabdar@Sun.COM MOD_LOG(params, "Restoring to: \"%s\".\n", nlp->nlp_restore_path); 18837917SReza.Sabdar@Sun.COM MOD_LOG(params, "Record size: %d\n", session->ns_mover.md_record_size); 18847917SReza.Sabdar@Sun.COM 18857917SReza.Sabdar@Sun.COM return (NDMP_NO_ERR); 18867917SReza.Sabdar@Sun.COM } 18877917SReza.Sabdar@Sun.COM 18887917SReza.Sabdar@Sun.COM /* 18897917SReza.Sabdar@Sun.COM * ndmpd_tar_backup_starter (V2 only) 18907917SReza.Sabdar@Sun.COM * 18917917SReza.Sabdar@Sun.COM * The main backup starter function. It creates a snapshot if necessary 18927917SReza.Sabdar@Sun.COM * and calls ndmp_tar_backup to perform the actual backup. It does the cleanup 18937917SReza.Sabdar@Sun.COM * and release the snapshot at the end. 18947917SReza.Sabdar@Sun.COM */ 18957917SReza.Sabdar@Sun.COM int 18967917SReza.Sabdar@Sun.COM ndmpd_tar_backup_starter(ndmpd_module_params_t *mod_params) 18977917SReza.Sabdar@Sun.COM { 18987917SReza.Sabdar@Sun.COM int err; 18997917SReza.Sabdar@Sun.COM ndmpd_session_t *session; 19007917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 19017917SReza.Sabdar@Sun.COM 19027917SReza.Sabdar@Sun.COM session = (ndmpd_session_t *)(mod_params->mp_daemon_cookie); 19037917SReza.Sabdar@Sun.COM *(mod_params->mp_module_cookie) = nlp = ndmp_get_nlp(session); 19047917SReza.Sabdar@Sun.COM ndmp_session_ref(session); 19057917SReza.Sabdar@Sun.COM 19067917SReza.Sabdar@Sun.COM err = 0; 19077917SReza.Sabdar@Sun.COM if (fs_is_chkpntvol(nlp->nlp_backup_path) || 19087917SReza.Sabdar@Sun.COM fs_is_rdonly(nlp->nlp_backup_path) || 19097917SReza.Sabdar@Sun.COM !fs_is_chkpnt_enabled(nlp->nlp_backup_path)) 19107917SReza.Sabdar@Sun.COM NLP_SET(nlp, NLPF_CHKPNTED_PATH); 19117917SReza.Sabdar@Sun.COM else { 19127917SReza.Sabdar@Sun.COM NLP_UNSET(nlp, NLPF_CHKPNTED_PATH); 19137917SReza.Sabdar@Sun.COM if (ndmp_start_check_point(nlp->nlp_backup_path, 19147917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_job_name) < 0) { 19157917SReza.Sabdar@Sun.COM MOD_LOG(mod_params, 19167917SReza.Sabdar@Sun.COM "Error: creating checkpoint on %s\n", 19177917SReza.Sabdar@Sun.COM nlp->nlp_backup_path); 19187917SReza.Sabdar@Sun.COM /* -1 causes halt reason to become internal error. */ 19197917SReza.Sabdar@Sun.COM err = -1; 19207917SReza.Sabdar@Sun.COM } 19217917SReza.Sabdar@Sun.COM } 19227917SReza.Sabdar@Sun.COM 19237917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "NLPF_CHKPNTED_PATH: %c", 19247917SReza.Sabdar@Sun.COM NDMP_YORN(NLP_ISCHKPNTED(nlp))); 19257917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "err: %d, update %c", 19267917SReza.Sabdar@Sun.COM err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp))); 19277917SReza.Sabdar@Sun.COM 19287917SReza.Sabdar@Sun.COM if (err == 0) { 19297917SReza.Sabdar@Sun.COM err = ndmp_get_cur_bk_time(nlp, &nlp->nlp_cdate, 19307917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_job_name); 19317917SReza.Sabdar@Sun.COM if (err != 0) { 19327917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "err %d", err); 19337917SReza.Sabdar@Sun.COM } else { 19347917SReza.Sabdar@Sun.COM log_bk_params_v2(session, mod_params, nlp); 19357917SReza.Sabdar@Sun.COM err = ndmpd_tar_backup(session, mod_params, nlp); 19367917SReza.Sabdar@Sun.COM } 19377917SReza.Sabdar@Sun.COM } 19387917SReza.Sabdar@Sun.COM 19397917SReza.Sabdar@Sun.COM if (nlp->nlp_bkmap >= 0) { 19407917SReza.Sabdar@Sun.COM (void) dbm_free(nlp->nlp_bkmap); 19417917SReza.Sabdar@Sun.COM nlp->nlp_bkmap = -1; 19427917SReza.Sabdar@Sun.COM } 19437917SReza.Sabdar@Sun.COM 19447917SReza.Sabdar@Sun.COM if (!NLP_ISCHKPNTED(nlp)) 19457917SReza.Sabdar@Sun.COM (void) ndmp_release_check_point(nlp->nlp_backup_path, 19467917SReza.Sabdar@Sun.COM nlp->nlp_jstat->js_job_name); 19477917SReza.Sabdar@Sun.COM 19487917SReza.Sabdar@Sun.COM NDMP_LOG(LOG_DEBUG, "err %d, update %c", 19497917SReza.Sabdar@Sun.COM err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp))); 19507917SReza.Sabdar@Sun.COM 19517917SReza.Sabdar@Sun.COM if (err == 0 && NLP_SHOULD_UPDATE(nlp)) { 19527917SReza.Sabdar@Sun.COM if (ndmpd_put_dumptime(nlp->nlp_backup_path, nlp->nlp_clevel, 19537917SReza.Sabdar@Sun.COM nlp->nlp_cdate) < 0) { 19547917SReza.Sabdar@Sun.COM err = EPERM; 19557917SReza.Sabdar@Sun.COM MOD_LOG(mod_params, 19567917SReza.Sabdar@Sun.COM "Error: updating the dumpdates file on %s\n", 19577917SReza.Sabdar@Sun.COM nlp->nlp_backup_path); 19587917SReza.Sabdar@Sun.COM } 19597917SReza.Sabdar@Sun.COM } 19607917SReza.Sabdar@Sun.COM 19617917SReza.Sabdar@Sun.COM MOD_DONE(mod_params, err); 19627917SReza.Sabdar@Sun.COM 19637917SReza.Sabdar@Sun.COM /* nlp_params is allocated in start_backup() */ 19647917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 19657917SReza.Sabdar@Sun.COM 19667917SReza.Sabdar@Sun.COM NS_DEC(nbk); 19677917SReza.Sabdar@Sun.COM ndmp_session_unref(session); 19687917SReza.Sabdar@Sun.COM return (err); 19697917SReza.Sabdar@Sun.COM } 19707917SReza.Sabdar@Sun.COM 19717917SReza.Sabdar@Sun.COM 19727917SReza.Sabdar@Sun.COM /* 19737917SReza.Sabdar@Sun.COM * ndmpd_tar_backup_abort 19747917SReza.Sabdar@Sun.COM * 19757917SReza.Sabdar@Sun.COM * Abort the running backup by stopping the reader thread (V2 only) 19767917SReza.Sabdar@Sun.COM */ 19777917SReza.Sabdar@Sun.COM int 19787917SReza.Sabdar@Sun.COM ndmpd_tar_backup_abort(void *module_cookie) 19797917SReza.Sabdar@Sun.COM { 19807917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 19817917SReza.Sabdar@Sun.COM 19827917SReza.Sabdar@Sun.COM nlp = (ndmp_lbr_params_t *)module_cookie; 19837917SReza.Sabdar@Sun.COM if (nlp != NULL && nlp->nlp_session != NULL) { 19847917SReza.Sabdar@Sun.COM if (nlp->nlp_session->ns_data.dd_mover.addr_type == 19857917SReza.Sabdar@Sun.COM NDMP_ADDR_TCP && nlp->nlp_session->ns_data.dd_sock != -1) { 19867917SReza.Sabdar@Sun.COM (void) close(nlp->nlp_session->ns_data.dd_sock); 19877917SReza.Sabdar@Sun.COM nlp->nlp_session->ns_data.dd_sock = -1; 19887917SReza.Sabdar@Sun.COM } 19897917SReza.Sabdar@Sun.COM ndmp_stop_reader_thread(nlp->nlp_session); 19907917SReza.Sabdar@Sun.COM } 19917917SReza.Sabdar@Sun.COM 19927917SReza.Sabdar@Sun.COM return (0); 19937917SReza.Sabdar@Sun.COM } 19947917SReza.Sabdar@Sun.COM 19957917SReza.Sabdar@Sun.COM /* 19967917SReza.Sabdar@Sun.COM * ndmpd_tar_restore_starter 19977917SReza.Sabdar@Sun.COM * 19987917SReza.Sabdar@Sun.COM * Starts the restore by running ndmpd_tar_restore function (V2 only) 19997917SReza.Sabdar@Sun.COM */ 20007917SReza.Sabdar@Sun.COM 20017917SReza.Sabdar@Sun.COM int 20027917SReza.Sabdar@Sun.COM ndmpd_tar_restore_starter(ndmpd_module_params_t *mod_params) 20037917SReza.Sabdar@Sun.COM { 20047917SReza.Sabdar@Sun.COM int err; 20057917SReza.Sabdar@Sun.COM ndmpd_session_t *session; 20067917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 20077917SReza.Sabdar@Sun.COM 20087917SReza.Sabdar@Sun.COM session = (ndmpd_session_t *)(mod_params->mp_daemon_cookie); 20097917SReza.Sabdar@Sun.COM *(mod_params->mp_module_cookie) = nlp = ndmp_get_nlp(session); 20107917SReza.Sabdar@Sun.COM ndmp_session_ref(session); 20117917SReza.Sabdar@Sun.COM 20127917SReza.Sabdar@Sun.COM err = ndmpd_tar_restore(session, mod_params, nlp); 20137917SReza.Sabdar@Sun.COM MOD_DONE(mod_params, err); 20147917SReza.Sabdar@Sun.COM 20157917SReza.Sabdar@Sun.COM /* nlp_params is allocated in start_recover() */ 20167917SReza.Sabdar@Sun.COM NDMP_FREE(nlp->nlp_params); 20177917SReza.Sabdar@Sun.COM 20187917SReza.Sabdar@Sun.COM NS_DEC(nrs); 20197917SReza.Sabdar@Sun.COM ndmp_session_unref(session); 20207917SReza.Sabdar@Sun.COM return (err); 20217917SReza.Sabdar@Sun.COM } 20227917SReza.Sabdar@Sun.COM 20237917SReza.Sabdar@Sun.COM 20247917SReza.Sabdar@Sun.COM /* 20257917SReza.Sabdar@Sun.COM * ndmpd_tar_restore_abort 20267917SReza.Sabdar@Sun.COM * 20277917SReza.Sabdar@Sun.COM * Aborts the restore operation by stopping the writer thread (V2 only) 20287917SReza.Sabdar@Sun.COM */ 20297917SReza.Sabdar@Sun.COM int 20307917SReza.Sabdar@Sun.COM ndmpd_tar_restore_abort(void *module_cookie) 20317917SReza.Sabdar@Sun.COM { 20327917SReza.Sabdar@Sun.COM ndmp_lbr_params_t *nlp; 20337917SReza.Sabdar@Sun.COM 20347917SReza.Sabdar@Sun.COM nlp = (ndmp_lbr_params_t *)module_cookie; 20357917SReza.Sabdar@Sun.COM if (nlp != NULL && nlp->nlp_session != NULL) { 20367917SReza.Sabdar@Sun.COM if (nlp->nlp_session->ns_data.dd_mover.addr_type == 20377917SReza.Sabdar@Sun.COM NDMP_ADDR_TCP && nlp->nlp_session->ns_data.dd_sock != -1) { 20387917SReza.Sabdar@Sun.COM (void) close(nlp->nlp_session->ns_data.dd_sock); 20397917SReza.Sabdar@Sun.COM nlp->nlp_session->ns_data.dd_sock = -1; 20407917SReza.Sabdar@Sun.COM } 20417917SReza.Sabdar@Sun.COM nlp_event_nw(nlp->nlp_session); 20427917SReza.Sabdar@Sun.COM ndmp_stop_writer_thread(nlp->nlp_session); 20437917SReza.Sabdar@Sun.COM } 20447917SReza.Sabdar@Sun.COM 20457917SReza.Sabdar@Sun.COM return (0); 20467917SReza.Sabdar@Sun.COM } 2047