12654012fSReza Sabdar /* 28c4f9701SJanice Chang * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 32654012fSReza Sabdar */ 42654012fSReza Sabdar 52654012fSReza Sabdar /* 62654012fSReza Sabdar * BSD 3 Clause License 72654012fSReza Sabdar * 82654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 92654012fSReza Sabdar * 102654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 112654012fSReza Sabdar * modification, are permitted provided that the following conditions 122654012fSReza Sabdar * are met: 132654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 142654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 152654012fSReza Sabdar * 162654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 172654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 182654012fSReza Sabdar * the documentation and/or other materials provided with the 192654012fSReza Sabdar * distribution. 202654012fSReza Sabdar * 212654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 222654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 232654012fSReza Sabdar * products derived from this software without specific prior written 242654012fSReza Sabdar * permission. 252654012fSReza Sabdar * 262654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 272654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 282654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 292654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 302654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 312654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 322654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 332654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 342654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 352654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 362654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 372654012fSReza Sabdar */ 388c4f9701SJanice Chang /* Copyright (c) 2007, The Storage Networking Industry Association. */ 392654012fSReza Sabdar /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */ 40*a23888a3SJan Kryl /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ 412654012fSReza Sabdar 422654012fSReza Sabdar #include <sys/stat.h> 432654012fSReza Sabdar #include <sys/types.h> 442654012fSReza Sabdar #include <sys/socket.h> 452654012fSReza Sabdar #include <errno.h> 462654012fSReza Sabdar #include <stdio.h> 472654012fSReza Sabdar #include <string.h> 482654012fSReza Sabdar #include <unistd.h> 492654012fSReza Sabdar #include <time.h> 502654012fSReza Sabdar #include <cstack.h> 512654012fSReza Sabdar #include <dirent.h> 522654012fSReza Sabdar #include <traverse.h> 532654012fSReza Sabdar #include "bitmap.h" 542654012fSReza Sabdar #include "ndmpd.h" 552654012fSReza Sabdar #include "tlm_buffers.h" 562654012fSReza Sabdar 572654012fSReza Sabdar 582654012fSReza Sabdar typedef struct ndmp_run_args { 592654012fSReza Sabdar char *nr_chkp_nm; 602654012fSReza Sabdar char *nr_unchkp_nm; 612654012fSReza Sabdar char **nr_excls; 622654012fSReza Sabdar } ndmp_run_args_t; 632654012fSReza Sabdar 642654012fSReza Sabdar 652654012fSReza Sabdar /* 662654012fSReza Sabdar * backup_create_structs 672654012fSReza Sabdar * 682654012fSReza Sabdar * Allocate the structures before performing backup 692654012fSReza Sabdar * 702654012fSReza Sabdar * Parameters: 712654012fSReza Sabdar * sesison (input) - session handle 722654012fSReza Sabdar * jname (input) - backup job name 732654012fSReza Sabdar * 742654012fSReza Sabdar * Returns: 752654012fSReza Sabdar * 0: on success 762654012fSReza Sabdar * -1: otherwise 772654012fSReza Sabdar */ 782654012fSReza Sabdar static int 792654012fSReza Sabdar backup_create_structs(ndmpd_session_t *session, char *jname) 802654012fSReza Sabdar { 812654012fSReza Sabdar int n; 822654012fSReza Sabdar long xfer_size; 832654012fSReza Sabdar ndmp_lbr_params_t *nlp; 842654012fSReza Sabdar tlm_commands_t *cmds; 852654012fSReza Sabdar 862654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 872654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 882654012fSReza Sabdar return (-1); 892654012fSReza Sabdar } 902654012fSReza Sabdar 912654012fSReza Sabdar if ((nlp->nlp_jstat = tlm_new_job_stats(jname)) == NULL) { 922654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Creating job stats"); 932654012fSReza Sabdar return (-1); 942654012fSReza Sabdar } 952654012fSReza Sabdar 962654012fSReza Sabdar cmds = &nlp->nlp_cmds; 972654012fSReza Sabdar (void) memset(cmds, 0, sizeof (*cmds)); 982654012fSReza Sabdar 992654012fSReza Sabdar xfer_size = ndmp_buffer_get_size(session); 1002654012fSReza Sabdar if (xfer_size < 512*KILOBYTE) { 1012654012fSReza Sabdar /* 1022654012fSReza Sabdar * Read multiple of mover_record_size near to 512K. This 1032654012fSReza Sabdar * will prevent the data being copied in the mover buffer 1042654012fSReza Sabdar * when we write the data. 1052654012fSReza Sabdar */ 1062654012fSReza Sabdar if ((n = (512 * KILOBYTE/xfer_size)) <= 0) 1072654012fSReza Sabdar n = 1; 1082654012fSReza Sabdar xfer_size *= n; 1092654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Adjusted read size: %d", xfer_size); 1102654012fSReza Sabdar } 1112654012fSReza Sabdar 1122654012fSReza Sabdar cmds->tcs_command = tlm_create_reader_writer_ipc(TRUE, xfer_size); 1132654012fSReza Sabdar if (cmds->tcs_command == NULL) { 1142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Error creating ipc buffers"); 1152654012fSReza Sabdar tlm_un_ref_job_stats(jname); 1162654012fSReza Sabdar return (-1); 1172654012fSReza Sabdar } 1182654012fSReza Sabdar 1192654012fSReza Sabdar nlp->nlp_logcallbacks = lbrlog_callbacks_init(session, 1202654012fSReza Sabdar ndmpd_file_history_path, 1212654012fSReza Sabdar ndmpd_file_history_dir, 1222654012fSReza Sabdar ndmpd_file_history_node); 1232654012fSReza Sabdar if (nlp->nlp_logcallbacks == NULL) { 1242654012fSReza Sabdar tlm_release_reader_writer_ipc(cmds->tcs_command); 1252654012fSReza Sabdar tlm_un_ref_job_stats(jname); 1262654012fSReza Sabdar return (-1); 1272654012fSReza Sabdar } 1282654012fSReza Sabdar nlp->nlp_jstat->js_callbacks = (void *)(nlp->nlp_logcallbacks); 1292654012fSReza Sabdar 1302654012fSReza Sabdar return (0); 1312654012fSReza Sabdar } 1322654012fSReza Sabdar 1332654012fSReza Sabdar 1342654012fSReza Sabdar /* 1352654012fSReza Sabdar * restore_create_structs 1362654012fSReza Sabdar * 1372654012fSReza Sabdar * Allocate structures for performing a restore 1382654012fSReza Sabdar * 1392654012fSReza Sabdar * Parameters: 1402654012fSReza Sabdar * sesison (input) - session handle 1412654012fSReza Sabdar * jname (input) - backup job name 1422654012fSReza Sabdar * 1432654012fSReza Sabdar * Returns: 1442654012fSReza Sabdar * 0: on success 1452654012fSReza Sabdar * -1: otherwise 1462654012fSReza Sabdar */ 1472654012fSReza Sabdar static int 1482654012fSReza Sabdar restore_create_structs(ndmpd_session_t *session, char *jname) 1492654012fSReza Sabdar { 1502654012fSReza Sabdar int i; 1512654012fSReza Sabdar long xfer_size; 1522654012fSReza Sabdar ndmp_lbr_params_t *nlp; 1532654012fSReza Sabdar tlm_commands_t *cmds; 1542654012fSReza Sabdar 1552654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 1562654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 1572654012fSReza Sabdar return (-1); 1582654012fSReza Sabdar } 1592654012fSReza Sabdar if ((nlp->nlp_jstat = tlm_new_job_stats(jname)) == NULL) { 1602654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Creating job stats"); 1612654012fSReza Sabdar return (-1); 1622654012fSReza Sabdar } 1632654012fSReza Sabdar 1642654012fSReza Sabdar cmds = &nlp->nlp_cmds; 1652654012fSReza Sabdar (void) memset(cmds, 0, sizeof (*cmds)); 1662654012fSReza Sabdar 1672654012fSReza Sabdar xfer_size = ndmp_buffer_get_size(session); 1682654012fSReza Sabdar cmds->tcs_command = tlm_create_reader_writer_ipc(FALSE, xfer_size); 1692654012fSReza Sabdar if (cmds->tcs_command == NULL) { 1702654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Error creating ipc buffers"); 1712654012fSReza Sabdar tlm_un_ref_job_stats(jname); 1722654012fSReza Sabdar return (-1); 1732654012fSReza Sabdar } 1742654012fSReza Sabdar 1752654012fSReza Sabdar nlp->nlp_logcallbacks = lbrlog_callbacks_init(session, 1762654012fSReza Sabdar ndmpd_path_restored, NULL, NULL); 1772654012fSReza Sabdar if (nlp->nlp_logcallbacks == NULL) { 1782654012fSReza Sabdar tlm_release_reader_writer_ipc(cmds->tcs_command); 1792654012fSReza Sabdar tlm_un_ref_job_stats(jname); 1802654012fSReza Sabdar return (-1); 1812654012fSReza Sabdar } 1822654012fSReza Sabdar nlp->nlp_jstat->js_callbacks = (void *)(nlp->nlp_logcallbacks); 1832654012fSReza Sabdar 1842654012fSReza Sabdar nlp->nlp_restored = ndmp_malloc(sizeof (boolean_t) * nlp->nlp_nfiles); 1852654012fSReza Sabdar if (nlp->nlp_restored == NULL) { 1862654012fSReza Sabdar lbrlog_callbacks_done(nlp->nlp_logcallbacks); 1872654012fSReza Sabdar tlm_release_reader_writer_ipc(cmds->tcs_command); 1882654012fSReza Sabdar tlm_un_ref_job_stats(jname); 1892654012fSReza Sabdar return (-1); 1902654012fSReza Sabdar } 1912654012fSReza Sabdar for (i = 0; i < (int)nlp->nlp_nfiles; i++) 1922654012fSReza Sabdar nlp->nlp_restored[i] = FALSE; 1932654012fSReza Sabdar 1942654012fSReza Sabdar return (0); 1952654012fSReza Sabdar } 1962654012fSReza Sabdar 1972654012fSReza Sabdar 1982654012fSReza Sabdar /* 1992654012fSReza Sabdar * send_unrecovered_list 2002654012fSReza Sabdar * 2012654012fSReza Sabdar * Creates a list of restored files 2022654012fSReza Sabdar * 2032654012fSReza Sabdar * Parameters: 2042654012fSReza Sabdar * params (input) - NDMP parameters 2052654012fSReza Sabdar * nlp (input) - NDMP/LBR parameters 2062654012fSReza Sabdar * 2072654012fSReza Sabdar * Returns: 2082654012fSReza Sabdar * 0: on success 2092654012fSReza Sabdar * -1: otherwise 2102654012fSReza Sabdar */ 2112654012fSReza Sabdar static int 2122654012fSReza Sabdar send_unrecovered_list(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp) 2132654012fSReza Sabdar { 2142654012fSReza Sabdar int i, rv; 2152654012fSReza Sabdar ndmp_name *ent; 2162654012fSReza Sabdar 2172654012fSReza Sabdar if (params == NULL) { 2182654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "params == NULL"); 2192654012fSReza Sabdar return (-1); 2202654012fSReza Sabdar } 2212654012fSReza Sabdar if (nlp == NULL) { 2222654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 2232654012fSReza Sabdar return (-1); 2242654012fSReza Sabdar } 2252654012fSReza Sabdar 2262654012fSReza Sabdar rv = 0; 2272654012fSReza Sabdar for (i = 0; i < (int)nlp->nlp_nfiles; i++) { 2282654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp->nlp_restored[%d]: %s", i, 2292654012fSReza Sabdar nlp->nlp_restored[i] ? "TRUE" : "FALSE"); 2302654012fSReza Sabdar 2312654012fSReza Sabdar if (!nlp->nlp_restored[i]) { 2322654012fSReza Sabdar ent = (ndmp_name *)MOD_GETNAME(params, i); 2332654012fSReza Sabdar if (ent == NULL) { 2342654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ent == NULL"); 2352654012fSReza Sabdar rv = -1; 2362654012fSReza Sabdar break; 2372654012fSReza Sabdar } 2382654012fSReza Sabdar if (ent->name == NULL) { 2392654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ent->name == NULL"); 2402654012fSReza Sabdar rv = -1; 2412654012fSReza Sabdar break; 2422654012fSReza Sabdar } 2432654012fSReza Sabdar 2442654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ent.name: \"%s\"", ent->name); 2452654012fSReza Sabdar 2462654012fSReza Sabdar rv = MOD_FILERECOVERD(params, ent->name, ENOENT); 2472654012fSReza Sabdar if (rv < 0) 2482654012fSReza Sabdar break; 2492654012fSReza Sabdar } 2502654012fSReza Sabdar } 2512654012fSReza Sabdar 2522654012fSReza Sabdar return (rv); 2532654012fSReza Sabdar } 2542654012fSReza Sabdar 2552654012fSReza Sabdar 2562654012fSReza Sabdar /* 2572654012fSReza Sabdar * backup_release_structs 2582654012fSReza Sabdar * 2592654012fSReza Sabdar * Deallocated the NDMP/LBR specific parameters 2602654012fSReza Sabdar * 2612654012fSReza Sabdar * Parameters: 2622654012fSReza Sabdar * session (input) - session handle 2632654012fSReza Sabdar * 2642654012fSReza Sabdar * Returns: 2652654012fSReza Sabdar * void 2662654012fSReza Sabdar */ 2672654012fSReza Sabdar /*ARGSUSED*/ 2682654012fSReza Sabdar static void 2692654012fSReza Sabdar backup_release_structs(ndmpd_session_t *session) 2702654012fSReza Sabdar { 2712654012fSReza Sabdar ndmp_lbr_params_t *nlp; 2722654012fSReza Sabdar tlm_commands_t *cmds; 2732654012fSReza Sabdar 2742654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 2752654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 2762654012fSReza Sabdar return; 2772654012fSReza Sabdar } 2782654012fSReza Sabdar cmds = &nlp->nlp_cmds; 2792654012fSReza Sabdar if (cmds == NULL) { 2802654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 2812654012fSReza Sabdar return; 2822654012fSReza Sabdar } 2832654012fSReza Sabdar 2842654012fSReza Sabdar if (nlp->nlp_logcallbacks != NULL) { 2852654012fSReza Sabdar lbrlog_callbacks_done(nlp->nlp_logcallbacks); 2862654012fSReza Sabdar nlp->nlp_logcallbacks = NULL; 2872654012fSReza Sabdar } else { 2882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "FH CALLBACKS == NULL"); 2892654012fSReza Sabdar } 2902654012fSReza Sabdar 2912654012fSReza Sabdar if (cmds->tcs_command != NULL) { 2922654012fSReza Sabdar if (cmds->tcs_command->tc_buffers != NULL) 2932654012fSReza Sabdar tlm_release_reader_writer_ipc(cmds->tcs_command); 2942654012fSReza Sabdar else 2952654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "BUFFERS == NULL"); 2962654012fSReza Sabdar cmds->tcs_command = NULL; 2972654012fSReza Sabdar } else { 2982654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "COMMAND == NULL"); 2992654012fSReza Sabdar } 3002654012fSReza Sabdar 3012654012fSReza Sabdar if (nlp->nlp_bkmap >= 0) { 3022654012fSReza Sabdar (void) dbm_free(nlp->nlp_bkmap); 3032654012fSReza Sabdar nlp->nlp_bkmap = -1; 3042654012fSReza Sabdar } 3052654012fSReza Sabdar 3062654012fSReza Sabdar if (session->ns_data.dd_operation == NDMP_DATA_OP_RECOVER && 3072654012fSReza Sabdar nlp->nlp_restored != NULL) { 3082654012fSReza Sabdar free(nlp->nlp_restored); 3092654012fSReza Sabdar nlp->nlp_restored = NULL; 3102654012fSReza Sabdar } else { 3112654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp_restored == NULL"); 3122654012fSReza Sabdar } 3132654012fSReza Sabdar } 3142654012fSReza Sabdar 3152654012fSReza Sabdar /* 3162654012fSReza Sabdar * ndmp_write_utf8magic 3172654012fSReza Sabdar * 3182654012fSReza Sabdar * Write a magic pattern to the tar header. This is used 3192654012fSReza Sabdar * as a crest to indicate that tape belongs to us. 3202654012fSReza Sabdar */ 3212654012fSReza Sabdar int 3222654012fSReza Sabdar ndmp_write_utf8magic(tlm_cmd_t *cmd) 3232654012fSReza Sabdar { 3242654012fSReza Sabdar char *cp; 3252654012fSReza Sabdar long actual_size; 3262654012fSReza Sabdar 3272654012fSReza Sabdar if (cmd->tc_buffers == NULL) { 3282654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmd->tc_buffers == NULL"); 3292654012fSReza Sabdar return (-1); 3302654012fSReza Sabdar } 3312654012fSReza Sabdar 3322654012fSReza Sabdar cp = tlm_get_write_buffer(RECORDSIZE, &actual_size, 3332654012fSReza Sabdar cmd->tc_buffers, TRUE); 3342654012fSReza Sabdar if (actual_size < RECORDSIZE) { 3352654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Couldn't get enough buffer"); 3362654012fSReza Sabdar return (-1); 3372654012fSReza Sabdar } 3382654012fSReza Sabdar 3392654012fSReza Sabdar (void) strlcpy(cp, NDMPUTF8MAGIC, RECORDSIZE); 3402654012fSReza Sabdar return (0); 3412654012fSReza Sabdar } 3422654012fSReza Sabdar 3432654012fSReza Sabdar 3442654012fSReza Sabdar /* 3452654012fSReza Sabdar * timecmp 3462654012fSReza Sabdar * 3472654012fSReza Sabdar * This callback function is used during backup. It checks 3482654012fSReza Sabdar * if the object specified by the 'attr' should be backed 3492654012fSReza Sabdar * up or not. 3502654012fSReza Sabdar * 3512654012fSReza Sabdar * Directories are backed up anyways for dump format. 3522654012fSReza Sabdar * If this function is called, then the directory is 3532654012fSReza Sabdar * marked in the bitmap vector, it shows that either the 3542654012fSReza Sabdar * directory itself is modified or there is something below 3552654012fSReza Sabdar * it that will be backed up. 3562654012fSReza Sabdar * 3572654012fSReza Sabdar * Directories for tar format are backed up if and only if 3582654012fSReza Sabdar * they are modified. 3592654012fSReza Sabdar * 3602654012fSReza Sabdar * By setting ndmp_force_bk_dirs global variable to a non-zero 3612654012fSReza Sabdar * value, directories are backed up anyways. 3622654012fSReza Sabdar * 3632654012fSReza Sabdar * Backing up the directories unconditionally, helps 3642654012fSReza Sabdar * restoring the metadata of directories as well, when one 3652654012fSReza Sabdar * of the objects below them are being restored. 3662654012fSReza Sabdar * 3672654012fSReza Sabdar * For non-directory objects, if the modification or change 3682654012fSReza Sabdar * time of the object is after the date specified by the 3692654012fSReza Sabdar * bk_selector_t, the the object must be backed up. 3702654012fSReza Sabdar * 3712654012fSReza Sabdar */ 3722654012fSReza Sabdar static boolean_t 3732654012fSReza Sabdar timecmp(bk_selector_t *bksp, 3742654012fSReza Sabdar struct stat64 *attr) 3752654012fSReza Sabdar { 3762654012fSReza Sabdar ndmp_lbr_params_t *nlp; 3772654012fSReza Sabdar 3782654012fSReza Sabdar nlp = (ndmp_lbr_params_t *)bksp->bs_cookie; 3792654012fSReza Sabdar if (S_ISDIR(attr->st_mode) && ndmp_force_bk_dirs) { 3802654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "d(%lu)", 3812654012fSReza Sabdar (uint_t)attr->st_ino); 3822654012fSReza Sabdar return (TRUE); 3832654012fSReza Sabdar } 3842654012fSReza Sabdar if (S_ISDIR(attr->st_mode) && 3852654012fSReza Sabdar dbm_getone(nlp->nlp_bkmap, (u_longlong_t)attr->st_ino) && 3862654012fSReza Sabdar ((NLP_ISDUMP(nlp) && ndmp_dump_path_node) || 3872654012fSReza Sabdar (NLP_ISTAR(nlp) && ndmp_tar_path_node))) { 3882654012fSReza Sabdar /* 3892654012fSReza Sabdar * If the object is a directory and it leads to a modified 3902654012fSReza Sabdar * object (that should be backed up) and for that type of 3912654012fSReza Sabdar * backup the path nodes should be backed up, then return 3922654012fSReza Sabdar * TRUE. 3932654012fSReza Sabdar * 3942654012fSReza Sabdar * This is required by some DMAs like Backup Express, which 3952654012fSReza Sabdar * needs to receive ADD_NODE (for dump) or ADD_PATH (for tar) 3962654012fSReza Sabdar * for the intermediate directories of a modified object. 3972654012fSReza Sabdar * Other DMAs, like net_backup and net_worker, do not have such 3982654012fSReza Sabdar * requirement. This requirement makes sense for dump format 3992654012fSReza Sabdar * but for 'tar' format, it does not. In provision to the 4002654012fSReza Sabdar * NDMP-v4 spec, for 'tar' format the intermediate directories 4012654012fSReza Sabdar * need not to be reported. 4022654012fSReza Sabdar */ 4032654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "p(%lu)", (u_longlong_t)attr->st_ino); 4042654012fSReza Sabdar return (TRUE); 4052654012fSReza Sabdar } 4062654012fSReza Sabdar if (attr->st_mtime > bksp->bs_ldate) { 4072654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "m(%lu): %lu > %lu", 4082654012fSReza Sabdar (uint_t)attr->st_ino, (uint_t)attr->st_mtime, 4092654012fSReza Sabdar (uint_t)bksp->bs_ldate); 4102654012fSReza Sabdar return (TRUE); 4112654012fSReza Sabdar } 4122654012fSReza Sabdar if (attr->st_ctime > bksp->bs_ldate) { 4132654012fSReza Sabdar if (NLP_IGNCTIME(nlp)) { 4142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ign c(%lu): %lu > %lu", 4152654012fSReza Sabdar (uint_t)attr->st_ino, (uint_t)attr->st_ctime, 4162654012fSReza Sabdar (uint_t)bksp->bs_ldate); 4172654012fSReza Sabdar return (FALSE); 4182654012fSReza Sabdar } 4192654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "c(%lu): %lu > %lu", 4202654012fSReza Sabdar (uint_t)attr->st_ino, (uint_t)attr->st_ctime, 4212654012fSReza Sabdar (uint_t)bksp->bs_ldate); 4222654012fSReza Sabdar return (TRUE); 4232654012fSReza Sabdar } 4242654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "mc(%lu): (%lu,%lu) < %lu", 4252654012fSReza Sabdar (uint_t)attr->st_ino, (uint_t)attr->st_mtime, 4262654012fSReza Sabdar (uint_t)attr->st_ctime, (uint_t)bksp->bs_ldate); 4272654012fSReza Sabdar return (FALSE); 4282654012fSReza Sabdar } 4292654012fSReza Sabdar 4302654012fSReza Sabdar 4312654012fSReza Sabdar /* 4322654012fSReza Sabdar * get_acl_info 4332654012fSReza Sabdar * 4342654012fSReza Sabdar * load up all the access and attribute info 4352654012fSReza Sabdar */ 4362654012fSReza Sabdar static int 4372654012fSReza Sabdar get_acl_info(char *name, tlm_acls_t *tlm_acls) 4382654012fSReza Sabdar { 4392654012fSReza Sabdar int erc; 4402654012fSReza Sabdar acl_t *aclp = NULL; 4412654012fSReza Sabdar char *acltp; 4422654012fSReza Sabdar 4432654012fSReza Sabdar erc = lstat64(name, &tlm_acls->acl_attr); 4442654012fSReza Sabdar if (erc != 0) { 4452654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Could not find file %s.", name); 4462654012fSReza Sabdar erc = TLM_NO_SOURCE_FILE; 4472654012fSReza Sabdar return (erc); 4482654012fSReza Sabdar } 4492654012fSReza Sabdar erc = acl_get(name, ACL_NO_TRIVIAL, &aclp); 4502654012fSReza Sabdar if (erc != 0) { 4512654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 4522654012fSReza Sabdar "Could not read ACL for file [%s]", name); 4532654012fSReza Sabdar erc = TLM_NO_SOURCE_FILE; 4542654012fSReza Sabdar return (erc); 4552654012fSReza Sabdar } 4562654012fSReza Sabdar if (aclp && (acltp = acl_totext(aclp, 4572654012fSReza Sabdar ACL_APPEND_ID | ACL_SID_FMT | ACL_COMPACT_FMT)) != NULL) { 4582654012fSReza Sabdar (void) strlcpy(tlm_acls->acl_info.attr_info, acltp, 4592654012fSReza Sabdar TLM_MAX_ACL_TXT); 4602654012fSReza Sabdar acl_free(aclp); 4612654012fSReza Sabdar free(acltp); 4622654012fSReza Sabdar } 4632654012fSReza Sabdar return (erc); 4642654012fSReza Sabdar } 4652654012fSReza Sabdar /* 4662654012fSReza Sabdar * get_dir_acl_info 4672654012fSReza Sabdar * 4682654012fSReza Sabdar * load up all ACL and attr info about a directory 4692654012fSReza Sabdar */ 4702654012fSReza Sabdar static int 4712654012fSReza Sabdar get_dir_acl_info(char *dir, tlm_acls_t *tlm_acls, tlm_job_stats_t *js) 4722654012fSReza Sabdar { 4732654012fSReza Sabdar int erc; 4742654012fSReza Sabdar char *checkpointed_dir; 4752654012fSReza Sabdar char root_dir[TLM_VOLNAME_MAX_LENGTH]; 4762654012fSReza Sabdar char *spot; 4772654012fSReza Sabdar char *fil; 4782654012fSReza Sabdar acl_t *aclp = NULL; 4792654012fSReza Sabdar char *acltp; 4802654012fSReza Sabdar 4812654012fSReza Sabdar checkpointed_dir = ndmp_malloc(TLM_MAX_PATH_NAME); 4822654012fSReza Sabdar if (checkpointed_dir == NULL) 4832654012fSReza Sabdar return (-1); 4842654012fSReza Sabdar 4852654012fSReza Sabdar if (tlm_acls->acl_checkpointed) 4862654012fSReza Sabdar fil = tlm_build_snapshot_name(dir, checkpointed_dir, 4872654012fSReza Sabdar js->js_job_name); 4882654012fSReza Sabdar else 4892654012fSReza Sabdar fil = dir; 4902654012fSReza Sabdar erc = lstat64(fil, &tlm_acls->acl_attr); 4912654012fSReza Sabdar if (erc != 0) { 4922654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Could not find directory %s.", dir); 4932654012fSReza Sabdar free(checkpointed_dir); 4942654012fSReza Sabdar return (-1); 4952654012fSReza Sabdar } 4962654012fSReza Sabdar 4972654012fSReza Sabdar spot = strchr(&fil[1], '/'); 4982654012fSReza Sabdar if (spot == NULL) { 4992654012fSReza Sabdar (void) strlcpy(root_dir, fil, TLM_VOLNAME_MAX_LENGTH); 5002654012fSReza Sabdar } else { 5012654012fSReza Sabdar *spot = 0; 5022654012fSReza Sabdar (void) strlcpy(root_dir, fil, TLM_VOLNAME_MAX_LENGTH); 5032654012fSReza Sabdar *spot = '/'; 5042654012fSReza Sabdar } 5052654012fSReza Sabdar if (strcmp(root_dir, tlm_acls->acl_root_dir) != 0) { 5062654012fSReza Sabdar struct stat64 attr; 5072654012fSReza Sabdar 5082654012fSReza Sabdar erc = lstat64(root_dir, &attr); 5092654012fSReza Sabdar if (erc != 0) { 5102654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Cannot find root directory %s.", 5112654012fSReza Sabdar root_dir); 5122654012fSReza Sabdar free(checkpointed_dir); 5132654012fSReza Sabdar return (-1); 5142654012fSReza Sabdar } 5152654012fSReza Sabdar (void) strlcpy(tlm_acls->acl_root_dir, root_dir, 5162654012fSReza Sabdar TLM_VOLNAME_MAX_LENGTH); 5172654012fSReza Sabdar } 5182654012fSReza Sabdar erc = acl_get(fil, ACL_NO_TRIVIAL, &aclp); 5192654012fSReza Sabdar if (erc != 0) { 5202654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 5212654012fSReza Sabdar "Could not read metadata for directory [%s]", dir); 5222654012fSReza Sabdar free(checkpointed_dir); 5232654012fSReza Sabdar return (-1); 5242654012fSReza Sabdar } 5252654012fSReza Sabdar if (aclp && (acltp = acl_totext(aclp, 5262654012fSReza Sabdar ACL_APPEND_ID | ACL_SID_FMT | ACL_COMPACT_FMT)) != NULL) { 5272654012fSReza Sabdar (void) strlcpy(tlm_acls->acl_info.attr_info, acltp, 5282654012fSReza Sabdar TLM_MAX_ACL_TXT); 5292654012fSReza Sabdar acl_free(aclp); 5302654012fSReza Sabdar free(acltp); 5312654012fSReza Sabdar } 5322654012fSReza Sabdar 5332654012fSReza Sabdar free(checkpointed_dir); 5342654012fSReza Sabdar return (0); 5352654012fSReza Sabdar } 5362654012fSReza Sabdar 5372654012fSReza Sabdar /* 5382654012fSReza Sabdar * backup_dir 5392654012fSReza Sabdar * 5402654012fSReza Sabdar * Create a TAR entry record for a directory 5412654012fSReza Sabdar */ 5422654012fSReza Sabdar static int 5432654012fSReza Sabdar backup_dir(char *dir, tlm_acls_t *tlm_acls, 5442654012fSReza Sabdar tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats, 5452654012fSReza Sabdar bk_selector_t *bksp) 5462654012fSReza Sabdar { 5472654012fSReza Sabdar int erc; 5482654012fSReza Sabdar 5492654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s\"", dir); 5502654012fSReza Sabdar 5512654012fSReza Sabdar erc = get_dir_acl_info(dir, tlm_acls, job_stats); 5522654012fSReza Sabdar if (erc != 0) { 5532654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 5542654012fSReza Sabdar "Could not read directory info for %s", dir); 5552654012fSReza Sabdar job_stats->js_errors++; 5562654012fSReza Sabdar } else { 5572654012fSReza Sabdar /* 5582654012fSReza Sabdar * See if the directory must be backed up. 5592654012fSReza Sabdar */ 5602654012fSReza Sabdar if (bksp && !(*bksp->bs_fn)(bksp, &tlm_acls->acl_attr)) { 5612654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "[%s] dir skipped", dir); 5622654012fSReza Sabdar return (erc); 5632654012fSReza Sabdar } 5642654012fSReza Sabdar 5652654012fSReza Sabdar if (tm_tar_ops.tm_putdir != NULL) 5662654012fSReza Sabdar (void) (tm_tar_ops.tm_putdir)(dir, tlm_acls, 5672654012fSReza Sabdar local_commands, job_stats); 5682654012fSReza Sabdar } 5692654012fSReza Sabdar 5702654012fSReza Sabdar return (erc); 5712654012fSReza Sabdar } 5722654012fSReza Sabdar 5732654012fSReza Sabdar 5742654012fSReza Sabdar /* 5752654012fSReza Sabdar * backup_file 5762654012fSReza Sabdar * 5772654012fSReza Sabdar * Create a TAR record entry for a file 5782654012fSReza Sabdar */ 5792654012fSReza Sabdar static longlong_t 5802654012fSReza Sabdar backup_file(char *dir, char *name, tlm_acls_t *tlm_acls, 5812654012fSReza Sabdar tlm_commands_t *commands, tlm_cmd_t *local_commands, 5822654012fSReza Sabdar tlm_job_stats_t *job_stats, bk_selector_t *bksp) 5832654012fSReza Sabdar { 5842654012fSReza Sabdar 5852654012fSReza Sabdar int erc; 5862654012fSReza Sabdar char buf[TLM_MAX_PATH_NAME]; 5872654012fSReza Sabdar longlong_t rv; 5882654012fSReza Sabdar 5892654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "\"%s/%s\"", dir, name); 5902654012fSReza Sabdar 5912654012fSReza Sabdar (void) strlcpy(buf, dir, sizeof (buf)); 5922654012fSReza Sabdar (void) strlcat(buf, "/", sizeof (buf)); 5932654012fSReza Sabdar (void) strlcat(buf, name, sizeof (buf)); 5942654012fSReza Sabdar 5952654012fSReza Sabdar /* 5962654012fSReza Sabdar * get_acl_info extracts file handle, attributes and ACLs of the file. 5972654012fSReza Sabdar * This is not efficient when the attributes and file handle of 5982654012fSReza Sabdar * the file is already known. 5992654012fSReza Sabdar */ 6002654012fSReza Sabdar erc = get_acl_info(buf, tlm_acls); 6012654012fSReza Sabdar if (erc != TLM_NO_ERRORS) { 6022654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Could not open file %s/%s.", dir, name); 6032654012fSReza Sabdar return (-ENOENT); 6042654012fSReza Sabdar } 6052654012fSReza Sabdar 6062654012fSReza Sabdar /* Should the file be backed up? */ 6072654012fSReza Sabdar if (!bksp) { 6082654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 6092654012fSReza Sabdar "[%s/%s] has no selection criteria", dir, name); 6102654012fSReza Sabdar 6112654012fSReza Sabdar } else if (!((*bksp->bs_fn)(bksp, &tlm_acls->acl_attr))) { 6122654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "[%s/%s] file skipped", dir, name); 6132654012fSReza Sabdar return (0); 6142654012fSReza Sabdar } 6152654012fSReza Sabdar 6162654012fSReza Sabdar /* Only the regular files and symbolic links can be backed up. */ 6172654012fSReza Sabdar if (!S_ISLNK(tlm_acls->acl_attr.st_mode) && 6182654012fSReza Sabdar !S_ISREG(tlm_acls->acl_attr.st_mode)) { 6192654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 6202654012fSReza Sabdar "Warning: skip backing up [%s][%s]", dir, name); 6212654012fSReza Sabdar return (-EINVAL); 6222654012fSReza Sabdar } 6232654012fSReza Sabdar 6242654012fSReza Sabdar 6252654012fSReza Sabdar if (tm_tar_ops.tm_putfile != NULL) 6262654012fSReza Sabdar rv = (tm_tar_ops.tm_putfile)(dir, name, tlm_acls, commands, 6272654012fSReza Sabdar local_commands, job_stats); 6282654012fSReza Sabdar 6292654012fSReza Sabdar return (rv); 6302654012fSReza Sabdar } 6312654012fSReza Sabdar 6322654012fSReza Sabdar 6332654012fSReza Sabdar 6342654012fSReza Sabdar /* 6352654012fSReza Sabdar * backup_work 6362654012fSReza Sabdar * 6372654012fSReza Sabdar * Start the NDMP backup (V2 only). 6382654012fSReza Sabdar */ 6392654012fSReza Sabdar int 6402654012fSReza Sabdar backup_work(char *bk_path, tlm_job_stats_t *job_stats, 6412654012fSReza Sabdar ndmp_run_args_t *np, tlm_commands_t *commands, 6422654012fSReza Sabdar ndmp_lbr_params_t *nlp) 6432654012fSReza Sabdar { 6442654012fSReza Sabdar struct full_dir_info dir_info; /* the blob to push/pop with cstack_t */ 6452654012fSReza Sabdar struct full_dir_info *t_dir_info, *p_dir_info; 6462654012fSReza Sabdar struct stat64 ret_attr; /* attributes of current file name */ 6472654012fSReza Sabdar fs_fhandle_t ret_fh; 6482654012fSReza Sabdar char *first_name; /* where the first name is located */ 6492654012fSReza Sabdar char *dname; 6502654012fSReza Sabdar int erc; 6512654012fSReza Sabdar int retval; 6522654012fSReza Sabdar cstack_t *stk; 6532654012fSReza Sabdar unsigned long fileid; 6542654012fSReza Sabdar tlm_acls_t tlm_acls; 6552654012fSReza Sabdar int dname_size; 6562654012fSReza Sabdar longlong_t fsize; 6572654012fSReza Sabdar bk_selector_t bks; 6582654012fSReza Sabdar tlm_cmd_t *local_commands; 6592654012fSReza Sabdar long dpos; 6602654012fSReza Sabdar 6612654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nr_chkpnted %d nr_ldate: %u bk_path: \"%s\"", 6622654012fSReza Sabdar NLP_ISCHKPNTED(nlp), nlp->nlp_ldate, bk_path); 6632654012fSReza Sabdar 6642654012fSReza Sabdar /* Get every name in this directory */ 6652654012fSReza Sabdar dname = ndmp_malloc(TLM_MAX_PATH_NAME); 6662654012fSReza Sabdar if (dname == NULL) 6672654012fSReza Sabdar return (-ENOMEM); 6682654012fSReza Sabdar 6692654012fSReza Sabdar local_commands = commands->tcs_command; 6702654012fSReza Sabdar retval = 0; 6712654012fSReza Sabdar (void) memset(&bks, 0, sizeof (bks)); 6722654012fSReza Sabdar bks.bs_cookie = (void *)nlp; 6732654012fSReza Sabdar bks.bs_level = nlp->nlp_clevel; 6742654012fSReza Sabdar bks.bs_ldate = nlp->nlp_ldate; 6752654012fSReza Sabdar bks.bs_fn = timecmp; 6762654012fSReza Sabdar 6772654012fSReza Sabdar /* 6782654012fSReza Sabdar * should we skip the whole thing? 6792654012fSReza Sabdar */ 6802654012fSReza Sabdar if (tlm_is_excluded("", bk_path, np->nr_excls)) { 6812654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "%s excluded", bk_path); 6822654012fSReza Sabdar free(dname); 6832654012fSReza Sabdar return (0); 6842654012fSReza Sabdar } 6852654012fSReza Sabdar 6862654012fSReza Sabdar /* 6872654012fSReza Sabdar * Search for the top-level file-directory 6882654012fSReza Sabdar */ 6892654012fSReza Sabdar if (NLP_ISCHKPNTED(nlp)) { 6902654012fSReza Sabdar first_name = np->nr_chkp_nm; 6912654012fSReza Sabdar (void) strlcpy(first_name, bk_path, TLM_MAX_PATH_NAME); 6922654012fSReza Sabdar } else { 6932654012fSReza Sabdar first_name = tlm_build_snapshot_name(bk_path, np->nr_chkp_nm, 6942654012fSReza Sabdar nlp->nlp_jstat->js_job_name); 6952654012fSReza Sabdar } 6962654012fSReza Sabdar 6972654012fSReza Sabdar (void) memset(&ret_fh, 0, sizeof (ret_fh)); 69884bf06e9SReza Sabdar erc = fs_getstat(first_name, &ret_fh, &ret_attr); 6992654012fSReza Sabdar if (erc != 0) { 7002654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Path %s not found.", first_name); 7012654012fSReza Sabdar free(dname); 7022654012fSReza Sabdar return (-EINVAL); 7032654012fSReza Sabdar } 7042654012fSReza Sabdar 7052654012fSReza Sabdar if ((stk = cstack_new()) == NULL) { 7062654012fSReza Sabdar free(dname); 7072654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cstack_new failed"); 7082654012fSReza Sabdar return (-ENOMEM); 7092654012fSReza Sabdar } 7102654012fSReza Sabdar (void) strlcpy(dir_info.fd_dir_name, first_name, TLM_MAX_PATH_NAME); 7112654012fSReza Sabdar (void) memcpy(&dir_info.fd_dir_fh, &ret_fh, sizeof (fs_fhandle_t)); 7122654012fSReza Sabdar p_dir_info = dup_dir_info(&dir_info); 7132654012fSReza Sabdar 7142654012fSReza Sabdar /* 7152654012fSReza Sabdar * Push the first name onto the stack so that we can pop it back 7162654012fSReza Sabdar * off as part of the normal cycle 7172654012fSReza Sabdar */ 7182654012fSReza Sabdar if (cstack_push(stk, p_dir_info, 0)) { 7192654012fSReza Sabdar free(dname); 7202654012fSReza Sabdar free(p_dir_info); 7212654012fSReza Sabdar cstack_delete(stk); 7222654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cstack_push failed"); 7232654012fSReza Sabdar return (-ENOMEM); 7242654012fSReza Sabdar } 7252654012fSReza Sabdar 7262654012fSReza Sabdar (void) memset(&tlm_acls, 0, sizeof (tlm_acls)); 7272654012fSReza Sabdar /* 7282654012fSReza Sabdar * Did NDMP create a checkpoint? 7292654012fSReza Sabdar */ 7302654012fSReza Sabdar if (NLP_ISCHKPNTED(nlp) || fs_is_rdonly(bk_path)) { 7312654012fSReza Sabdar tlm_acls.acl_checkpointed = FALSE; 7322654012fSReza Sabdar } else { 7332654012fSReza Sabdar /* Use the checkpoint created by NDMP */ 7342654012fSReza Sabdar tlm_acls.acl_checkpointed = TRUE; 7352654012fSReza Sabdar } 7362654012fSReza Sabdar 7372654012fSReza Sabdar /* 7382654012fSReza Sabdar * This is level-backup. It never resets the archive bit. 7392654012fSReza Sabdar */ 7402654012fSReza Sabdar tlm_acls.acl_clear_archive = FALSE; 7412654012fSReza Sabdar 7422654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "acls.chkpnt: %c acls.clear_arcbit: %c", 7432654012fSReza Sabdar NDMP_YORN(tlm_acls.acl_checkpointed), 7442654012fSReza Sabdar NDMP_YORN(tlm_acls.acl_clear_archive)); 7452654012fSReza Sabdar 7462654012fSReza Sabdar while (commands->tcs_reader == TLM_BACKUP_RUN && 7472654012fSReza Sabdar local_commands->tc_reader == TLM_BACKUP_RUN && 7482654012fSReza Sabdar cstack_pop(stk, (void **)&p_dir_info, 0) == 0) { 7492654012fSReza Sabdar 7502654012fSReza Sabdar if (NLP_ISCHKPNTED(nlp)) 7512654012fSReza Sabdar (void) strlcpy(np->nr_unchkp_nm, 7522654012fSReza Sabdar p_dir_info->fd_dir_name, TLM_MAX_PATH_NAME); 7532654012fSReza Sabdar else 7542654012fSReza Sabdar (void) tlm_remove_checkpoint(p_dir_info->fd_dir_name, 7552654012fSReza Sabdar np->nr_unchkp_nm); 7562654012fSReza Sabdar 7572654012fSReza Sabdar (void) backup_dir(np->nr_unchkp_nm, &tlm_acls, local_commands, 7582654012fSReza Sabdar job_stats, &bks); 7592654012fSReza Sabdar 7602654012fSReza Sabdar 7612654012fSReza Sabdar while (commands->tcs_reader == TLM_BACKUP_RUN && 7622654012fSReza Sabdar local_commands->tc_reader == TLM_BACKUP_RUN) { 7632654012fSReza Sabdar 7642654012fSReza Sabdar dname_size = TLM_MAX_PATH_NAME - 1; 7652654012fSReza Sabdar 7662654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 7672654012fSReza Sabdar "dir_name: %s", p_dir_info->fd_dir_name); 7682654012fSReza Sabdar 7692654012fSReza Sabdar (void) memset(&ret_fh, 0, sizeof (ret_fh)); 7702654012fSReza Sabdar erc = fs_readdir(&p_dir_info->fd_dir_fh, 7712654012fSReza Sabdar p_dir_info->fd_dir_name, &dpos, 77284bf06e9SReza Sabdar dname, &dname_size, &ret_fh, &ret_attr); 7732654012fSReza Sabdar if (erc == 0) { 7742654012fSReza Sabdar fileid = ret_fh.fh_fid; 7752654012fSReza Sabdar } else { 7762654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 7772654012fSReza Sabdar "Filesystem readdir in [%s]", 7782654012fSReza Sabdar p_dir_info->fd_dir_name); 7792654012fSReza Sabdar retval = -ENOENT; 7802654012fSReza Sabdar break; 7812654012fSReza Sabdar } 7822654012fSReza Sabdar 7832654012fSReza Sabdar /* an empty name size marks the end of the list */ 7842654012fSReza Sabdar if (dname_size == 0) 7852654012fSReza Sabdar break; 7862654012fSReza Sabdar dname[dname_size] = '\0'; 7872654012fSReza Sabdar 7882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "dname: \"%s\"", dname); 7892654012fSReza Sabdar 7902654012fSReza Sabdar /* 7912654012fSReza Sabdar * If name refers to a directory, push its file 7922654012fSReza Sabdar * handle onto the stack (skip "." and ".."). 7932654012fSReza Sabdar */ 7942654012fSReza Sabdar if (rootfs_dot_or_dotdot(dname)) { 7952654012fSReza Sabdar fileid = 0; 7962654012fSReza Sabdar continue; 7972654012fSReza Sabdar } 7982654012fSReza Sabdar 7992654012fSReza Sabdar /* 8002654012fSReza Sabdar * Skip the: 8012654012fSReza Sabdar * non-dir entries which should not be backed up 8022654012fSReza Sabdar * Or 8032654012fSReza Sabdar * dir-type entries which have have nothing under 8042654012fSReza Sabdar * their hierarchy to be backed up. 8052654012fSReza Sabdar */ 8062654012fSReza Sabdar if (!dbm_getone(nlp->nlp_bkmap, (u_longlong_t)fileid)) { 8072654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Skipping %s/%s", 8082654012fSReza Sabdar p_dir_info->fd_dir_name, dname); 8092654012fSReza Sabdar fileid = 0; 8102654012fSReza Sabdar continue; 8112654012fSReza Sabdar } 8122654012fSReza Sabdar 8132654012fSReza Sabdar if (tlm_is_excluded(np->nr_unchkp_nm, dname, 8142654012fSReza Sabdar np->nr_excls)) { 8152654012fSReza Sabdar fileid = 0; 8162654012fSReza Sabdar continue; 8172654012fSReza Sabdar } 8182654012fSReza Sabdar if (S_ISDIR(ret_attr.st_mode)) { 8192654012fSReza Sabdar /* 8202654012fSReza Sabdar * only directories get pushed onto this stack, 8212654012fSReza Sabdar * so we do not have to test for regular files. 8222654012fSReza Sabdar */ 8232654012fSReza Sabdar t_dir_info = tlm_new_dir_info(&ret_fh, 8242654012fSReza Sabdar p_dir_info->fd_dir_name, dname); 8252654012fSReza Sabdar if (t_dir_info == NULL) { 8262654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 8272654012fSReza Sabdar "While backing up [%s][%s]", 8282654012fSReza Sabdar p_dir_info->fd_dir_name, dname); 8292654012fSReza Sabdar } else if (cstack_push(stk, t_dir_info, 8302654012fSReza Sabdar 0) != 0) { 8312654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 8322654012fSReza Sabdar "No enough memory stack_push"); 8332654012fSReza Sabdar retval = -ENOMEM; 8342654012fSReza Sabdar break; 8352654012fSReza Sabdar } 8362654012fSReza Sabdar } else if (S_ISREG(ret_attr.st_mode) || 8372654012fSReza Sabdar S_ISLNK(ret_attr.st_mode)) { 8382654012fSReza Sabdar 8392654012fSReza Sabdar fsize = backup_file(np->nr_unchkp_nm, dname, 8402654012fSReza Sabdar &tlm_acls, commands, local_commands, 8412654012fSReza Sabdar job_stats, &bks); 8422654012fSReza Sabdar 8432654012fSReza Sabdar if (fsize >= 0) { 8442654012fSReza Sabdar job_stats->js_files_so_far++; 8452654012fSReza Sabdar job_stats->js_bytes_total += fsize; 8462654012fSReza Sabdar } else 8472654012fSReza Sabdar job_stats->js_errors++; 8482654012fSReza Sabdar fileid = 0; 8492654012fSReza Sabdar } 8502654012fSReza Sabdar } 8512654012fSReza Sabdar fileid = 0; 8522654012fSReza Sabdar free(p_dir_info); 8532654012fSReza Sabdar if (retval != 0) 8542654012fSReza Sabdar break; 8552654012fSReza Sabdar } 8562654012fSReza Sabdar 8572654012fSReza Sabdar free(dname); 8582654012fSReza Sabdar 8592654012fSReza Sabdar while (cstack_pop(stk, (void **)&p_dir_info, 0) == 0) { 8602654012fSReza Sabdar free(p_dir_info); 8612654012fSReza Sabdar } 8622654012fSReza Sabdar 8632654012fSReza Sabdar cstack_delete(stk); 8642654012fSReza Sabdar return (retval); 8652654012fSReza Sabdar } 8662654012fSReza Sabdar 8672654012fSReza Sabdar 8682654012fSReza Sabdar /* 8692654012fSReza Sabdar * free_paths 8702654012fSReza Sabdar * 8712654012fSReza Sabdar * Free the path names 8722654012fSReza Sabdar */ 8732654012fSReza Sabdar static void 8742654012fSReza Sabdar free_paths(ndmp_run_args_t *np) 8752654012fSReza Sabdar { 8762654012fSReza Sabdar free(np->nr_chkp_nm); 8772654012fSReza Sabdar free(np->nr_unchkp_nm); 8782654012fSReza Sabdar free(np->nr_excls); 8792654012fSReza Sabdar } 8802654012fSReza Sabdar 8812654012fSReza Sabdar 8822654012fSReza Sabdar /* 8832654012fSReza Sabdar * malloc_paths 8842654012fSReza Sabdar * 8852654012fSReza Sabdar * Allocate the path names (direct and checkpointed paths) 8862654012fSReza Sabdar */ 8872654012fSReza Sabdar static boolean_t 8882654012fSReza Sabdar malloc_paths(ndmp_run_args_t *np) 8892654012fSReza Sabdar { 8902654012fSReza Sabdar boolean_t rv; 8912654012fSReza Sabdar 8922654012fSReza Sabdar rv = TRUE; 8932654012fSReza Sabdar np->nr_chkp_nm = ndmp_malloc(TLM_MAX_PATH_NAME); 8942654012fSReza Sabdar np->nr_unchkp_nm = ndmp_malloc(TLM_MAX_PATH_NAME); 8952654012fSReza Sabdar if (!np->nr_chkp_nm || !np->nr_unchkp_nm) { 8962654012fSReza Sabdar free_paths(np); 8972654012fSReza Sabdar rv = FALSE; 8982654012fSReza Sabdar } else if ((np->nr_excls = ndmpd_make_exc_list()) == NULL) { 8992654012fSReza Sabdar free_paths(np); 9002654012fSReza Sabdar rv = FALSE; 9012654012fSReza Sabdar } 9022654012fSReza Sabdar return (rv); 9032654012fSReza Sabdar } 9042654012fSReza Sabdar 9052654012fSReza Sabdar 9062654012fSReza Sabdar /* 9072654012fSReza Sabdar * ndmp_backup_reader 9082654012fSReza Sabdar * 9092654012fSReza Sabdar * Backup reader thread which uses backup_work to read and TAR 9102654012fSReza Sabdar * the files/dirs to be backed up (V2 only) 9112654012fSReza Sabdar */ 9122654012fSReza Sabdar static int 9132654012fSReza Sabdar ndmp_backup_reader(tlm_commands_t *commands, ndmp_lbr_params_t *nlp, 9142654012fSReza Sabdar char *job_name) 9152654012fSReza Sabdar { 9162654012fSReza Sabdar int retval; 9172654012fSReza Sabdar ndmp_run_args_t np; 9182654012fSReza Sabdar tlm_job_stats_t *job_stats; 9192654012fSReza Sabdar tlm_cmd_t *local_commands; 9202654012fSReza Sabdar 9212654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "bk_path: \"%s\"", nlp->nlp_backup_path); 9222654012fSReza Sabdar 9232654012fSReza Sabdar local_commands = commands->tcs_command; 9242654012fSReza Sabdar (void) memset(&np, 0, sizeof (np)); 9252654012fSReza Sabdar if (!malloc_paths(&np)) 9262654012fSReza Sabdar return (-1); 9272654012fSReza Sabdar local_commands->tc_ref++; 9282654012fSReza Sabdar commands->tcs_reader_count++; 9292654012fSReza Sabdar 9302654012fSReza Sabdar job_stats = tlm_ref_job_stats(job_name); 9312654012fSReza Sabdar 9322654012fSReza Sabdar retval = backup_work(nlp->nlp_backup_path, job_stats, &np, 9332654012fSReza Sabdar commands, nlp); 9342654012fSReza Sabdar write_tar_eof(local_commands); 9352654012fSReza Sabdar 9362654012fSReza Sabdar commands->tcs_reader_count--; 9372654012fSReza Sabdar local_commands->tc_writer = TLM_STOP; 9382654012fSReza Sabdar tlm_release_reader_writer_ipc(local_commands); 9392654012fSReza Sabdar tlm_un_ref_job_stats(job_name); 9402654012fSReza Sabdar 9412654012fSReza Sabdar free_paths(&np); 9422654012fSReza Sabdar return (retval); 9432654012fSReza Sabdar 9442654012fSReza Sabdar } 9452654012fSReza Sabdar 9462654012fSReza Sabdar 9472654012fSReza Sabdar /* 9482654012fSReza Sabdar * ndmp_tar_writer 9492654012fSReza Sabdar * 9502654012fSReza Sabdar * The backup writer thread that writes the TAR records to the 9512654012fSReza Sabdar * tape media (V2 only) 9522654012fSReza Sabdar */ 9532654012fSReza Sabdar int 9542654012fSReza Sabdar ndmp_tar_writer(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, 9552654012fSReza Sabdar tlm_commands_t *cmds) 9562654012fSReza Sabdar { 9572654012fSReza Sabdar int bidx, nw; 9582654012fSReza Sabdar int err; 9592654012fSReza Sabdar tlm_buffer_t *buf; 9602654012fSReza Sabdar tlm_buffers_t *bufs; 9612654012fSReza Sabdar tlm_cmd_t *lcmd; /* Local command */ 9622654012fSReza Sabdar 9632654012fSReza Sabdar err = 0; 9642654012fSReza Sabdar if (session == NULL) { 9652654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "session == NULL"); 9662654012fSReza Sabdar err = -1; 9672654012fSReza Sabdar } else if (mod_params == NULL) { 9682654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "mod_params == NULL"); 9692654012fSReza Sabdar err = -1; 9702654012fSReza Sabdar } else if (cmds == NULL) { 9712654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 9722654012fSReza Sabdar err = -1; 9732654012fSReza Sabdar } 9742654012fSReza Sabdar 9752654012fSReza Sabdar if (err != 0) 9762654012fSReza Sabdar return (err); 9772654012fSReza Sabdar 9782654012fSReza Sabdar lcmd = cmds->tcs_command; 9792654012fSReza Sabdar bufs = lcmd->tc_buffers; 9802654012fSReza Sabdar 9812654012fSReza Sabdar lcmd->tc_ref++; 9822654012fSReza Sabdar cmds->tcs_writer_count++; 9832654012fSReza Sabdar 9842654012fSReza Sabdar nw = 0; 9852654012fSReza Sabdar buf = tlm_buffer_out_buf(bufs, &bidx); 9862654012fSReza Sabdar while (cmds->tcs_writer != (int)TLM_ABORT && 9872654012fSReza Sabdar lcmd->tc_writer != (int)TLM_ABORT) { 9882654012fSReza Sabdar if (buf->tb_full) { 9892654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "w%d", bidx); 9902654012fSReza Sabdar 9912654012fSReza Sabdar if (MOD_WRITE(mod_params, buf->tb_buffer_data, 9922654012fSReza Sabdar buf->tb_buffer_size) != 0) { 9932654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 9942654012fSReza Sabdar "Writing buffer %d, pos: %lld", 9952654012fSReza Sabdar bidx, session->ns_mover.md_position); 9962654012fSReza Sabdar err = -1; 9972654012fSReza Sabdar break; 9982654012fSReza Sabdar } 9992654012fSReza Sabdar 10002654012fSReza Sabdar tlm_buffer_mark_empty(buf); 10012654012fSReza Sabdar (void) tlm_buffer_advance_out_idx(bufs); 10022654012fSReza Sabdar buf = tlm_buffer_out_buf(bufs, &bidx); 10032654012fSReza Sabdar tlm_buffer_release_out_buf(bufs); 10042654012fSReza Sabdar nw++; 10052654012fSReza Sabdar } else { 10062654012fSReza Sabdar if (lcmd->tc_writer != TLM_BACKUP_RUN) { 10072654012fSReza Sabdar /* No more data is comming; time to exit. */ 10082654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 10092654012fSReza Sabdar "tc_writer!=TLM_BACKUP_RUN; time to exit"); 10102654012fSReza Sabdar break; 10112654012fSReza Sabdar } else { 10122654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "W%d", bidx); 101386c48bbfSReza Sabdar tlm_buffer_in_buf_timed_wait(bufs, 100); 10142654012fSReza Sabdar } 10152654012fSReza Sabdar } 10162654012fSReza Sabdar } 10172654012fSReza Sabdar 10182654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nw: %d", nw); 10192654012fSReza Sabdar if (cmds->tcs_writer != (int)TLM_ABORT) { 10202654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "tcs_writer != TLM_ABORT"); 10212654012fSReza Sabdar } else { 10222654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "tcs_writer == TLM_ABORT"); 10232654012fSReza Sabdar } 10242654012fSReza Sabdar 10252654012fSReza Sabdar if (lcmd->tc_writer != (int)TLM_ABORT) { 10262654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "tc_writer != TLM_ABORT"); 10272654012fSReza Sabdar } else { 10282654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "tc_writer == TLM_ABORT"); 10292654012fSReza Sabdar } 10302654012fSReza Sabdar cmds->tcs_writer_count--; 10312654012fSReza Sabdar lcmd->tc_reader = TLM_STOP; 10322654012fSReza Sabdar lcmd->tc_ref--; 10332654012fSReza Sabdar 10342654012fSReza Sabdar return (err); 10352654012fSReza Sabdar } 10362654012fSReza Sabdar 10372654012fSReza Sabdar 10382654012fSReza Sabdar /* 10392654012fSReza Sabdar * read_one_buf 10402654012fSReza Sabdar * 10412654012fSReza Sabdar * Read one buffer from the tape 10422654012fSReza Sabdar */ 10432654012fSReza Sabdar static int 10442654012fSReza Sabdar read_one_buf(ndmpd_module_params_t *mod_params, tlm_buffers_t *bufs, 10452654012fSReza Sabdar tlm_buffer_t *buf) 10462654012fSReza Sabdar { 10472654012fSReza Sabdar int rv; 10482654012fSReza Sabdar 10492654012fSReza Sabdar if ((rv = MOD_READ(mod_params, buf->tb_buffer_data, 10502654012fSReza Sabdar bufs->tbs_data_transfer_size)) == 0) { 10512654012fSReza Sabdar buf->tb_eof = buf->tb_eot = FALSE; 10522654012fSReza Sabdar buf->tb_errno = 0; 10532654012fSReza Sabdar buf->tb_buffer_size = bufs->tbs_data_transfer_size; 10542654012fSReza Sabdar buf->tb_buffer_spot = 0; 10552654012fSReza Sabdar buf->tb_full = TRUE; 10562654012fSReza Sabdar (void) tlm_buffer_advance_in_idx(bufs); 10572654012fSReza Sabdar } 10582654012fSReza Sabdar 10592654012fSReza Sabdar return (rv); 10602654012fSReza Sabdar } 10612654012fSReza Sabdar 10622654012fSReza Sabdar 10632654012fSReza Sabdar /* 10642654012fSReza Sabdar * ndmp_tar_reader 10652654012fSReza Sabdar * 10662654012fSReza Sabdar * NDMP Tar reader thread. This threads keep reading the tar 10672654012fSReza Sabdar * file from the tape and wakes up the consumer thread to extract 10682654012fSReza Sabdar * it on the disk 10692654012fSReza Sabdar */ 10702654012fSReza Sabdar int 10712654012fSReza Sabdar ndmp_tar_reader(ndmp_tar_reader_arg_t *argp) 10722654012fSReza Sabdar { 10732654012fSReza Sabdar int bidx; 10742654012fSReza Sabdar int err; 10752654012fSReza Sabdar tlm_buffer_t *buf; 10762654012fSReza Sabdar tlm_buffers_t *bufs; 10772654012fSReza Sabdar tlm_cmd_t *lcmd; /* Local command */ 10782654012fSReza Sabdar ndmpd_session_t *session; 10792654012fSReza Sabdar ndmpd_module_params_t *mod_params; 10802654012fSReza Sabdar tlm_commands_t *cmds; 10812654012fSReza Sabdar 10822654012fSReza Sabdar if (!argp) 10832654012fSReza Sabdar return (-1); 10842654012fSReza Sabdar 10852654012fSReza Sabdar session = argp->tr_session; 10862654012fSReza Sabdar mod_params = argp->tr_mod_params; 10872654012fSReza Sabdar cmds = argp->tr_cmds; 10882654012fSReza Sabdar 10892654012fSReza Sabdar err = 0; 10902654012fSReza Sabdar if (session == NULL) { 10912654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "session == NULL"); 10922654012fSReza Sabdar err = -1; 10932654012fSReza Sabdar } else if (cmds == NULL) { 10942654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "cmds == NULL"); 10952654012fSReza Sabdar err = -1; 10962654012fSReza Sabdar } 10972654012fSReza Sabdar 10982654012fSReza Sabdar if (err != 0) { 10992654012fSReza Sabdar tlm_cmd_signal(cmds->tcs_command, TLM_TAR_READER); 11002654012fSReza Sabdar return (err); 11012654012fSReza Sabdar } 11022654012fSReza Sabdar 11032654012fSReza Sabdar lcmd = cmds->tcs_command; 11042654012fSReza Sabdar bufs = lcmd->tc_buffers; 11052654012fSReza Sabdar 11062654012fSReza Sabdar lcmd->tc_ref++; 11072654012fSReza Sabdar cmds->tcs_reader_count++; 11082654012fSReza Sabdar 11092654012fSReza Sabdar /* 11102654012fSReza Sabdar * Synchronize with our parent thread. 11112654012fSReza Sabdar */ 11122654012fSReza Sabdar tlm_cmd_signal(cmds->tcs_command, TLM_TAR_READER); 11132654012fSReza Sabdar 11142654012fSReza Sabdar buf = tlm_buffer_in_buf(bufs, &bidx); 11152654012fSReza Sabdar while (cmds->tcs_reader == TLM_RESTORE_RUN && 11162654012fSReza Sabdar lcmd->tc_reader == TLM_RESTORE_RUN) { 11172654012fSReza Sabdar 11182654012fSReza Sabdar if (buf->tb_full) { 11192654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "R%d", bidx); 11202654012fSReza Sabdar /* 11212654012fSReza Sabdar * The buffer is still full, wait for the consumer 11222654012fSReza Sabdar * thread to use it. 11232654012fSReza Sabdar */ 11242654012fSReza Sabdar tlm_buffer_out_buf_timed_wait(bufs, 100); 11252654012fSReza Sabdar buf = tlm_buffer_in_buf(bufs, NULL); 11262654012fSReza Sabdar } else { 11272654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "r%d", bidx); 11282654012fSReza Sabdar 11292654012fSReza Sabdar err = read_one_buf(mod_params, bufs, buf); 11302654012fSReza Sabdar if (err < 0) { 11312654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 11322654012fSReza Sabdar "Reading buffer %d, pos: %lld", 11332654012fSReza Sabdar bidx, session->ns_mover.md_position); 11342654012fSReza Sabdar 11352654012fSReza Sabdar /* Force the writer to stop. */ 11362654012fSReza Sabdar buf->tb_eot = buf->tb_eof = TRUE; 11372654012fSReza Sabdar break; 11382654012fSReza Sabdar } else if (err == 1) { 11392654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 11402654012fSReza Sabdar "operation aborted or session terminated"); 11412654012fSReza Sabdar err = 0; 11422654012fSReza Sabdar break; 11432654012fSReza Sabdar } 11442654012fSReza Sabdar 11452654012fSReza Sabdar buf = tlm_buffer_in_buf(bufs, &bidx); 11462654012fSReza Sabdar tlm_buffer_release_in_buf(bufs); 11472654012fSReza Sabdar } 11482654012fSReza Sabdar } 11492654012fSReza Sabdar 11502654012fSReza Sabdar /* 11512654012fSReza Sabdar * If the consumer is waiting for us, wake it up so that it detects 11522654012fSReza Sabdar * we're quiting. 11532654012fSReza Sabdar */ 11542654012fSReza Sabdar lcmd->tc_writer = TLM_STOP; 11552654012fSReza Sabdar tlm_buffer_release_in_buf(bufs); 11562654012fSReza Sabdar (void) usleep(1000); 11572654012fSReza Sabdar 11582654012fSReza Sabdar /* 11592654012fSReza Sabdar * Clean up. 11602654012fSReza Sabdar */ 11612654012fSReza Sabdar cmds->tcs_reader_count--; 11622654012fSReza Sabdar lcmd->tc_ref--; 11632654012fSReza Sabdar return (err); 11642654012fSReza Sabdar } 11652654012fSReza Sabdar 11662654012fSReza Sabdar 11672654012fSReza Sabdar /* 11682654012fSReza Sabdar * ndmpd_tar_backup 11692654012fSReza Sabdar * 11702654012fSReza Sabdar * Check must have been done that backup work directory exists, before 11712654012fSReza Sabdar * calling this function. 11722654012fSReza Sabdar */ 11732654012fSReza Sabdar static int 11742654012fSReza Sabdar ndmpd_tar_backup(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, 11752654012fSReza Sabdar ndmp_lbr_params_t *nlp) 11762654012fSReza Sabdar { 11772654012fSReza Sabdar char jname[TLM_MAX_BACKUP_JOB_NAME]; 11782654012fSReza Sabdar int err; 11792654012fSReza Sabdar tlm_commands_t *cmds; 11802654012fSReza Sabdar 11812654012fSReza Sabdar if (mod_params->mp_operation != NDMP_DATA_OP_BACKUP) { 11822654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 11832654012fSReza Sabdar "mod_params->mp_operation != NDMP_DATA_OP_BACKUP"); 11842654012fSReza Sabdar err = -1; 11852654012fSReza Sabdar } else { 11862654012fSReza Sabdar if (ndmpd_mark_inodes_v2(session, nlp) != 0) 11872654012fSReza Sabdar err = -1; 11882654012fSReza Sabdar else if (ndmp_get_bk_dir_ino(nlp)) 11892654012fSReza Sabdar err = -1; 11902654012fSReza Sabdar else 11912654012fSReza Sabdar err = 0; 11922654012fSReza Sabdar } 11932654012fSReza Sabdar 11942654012fSReza Sabdar if (err != 0) 11952654012fSReza Sabdar return (err); 11962654012fSReza Sabdar 11972654012fSReza Sabdar (void) ndmp_new_job_name(jname); 11982654012fSReza Sabdar if (backup_create_structs(session, jname) < 0) 11992654012fSReza Sabdar return (-1); 12002654012fSReza Sabdar 12012654012fSReza Sabdar nlp->nlp_jstat->js_start_ltime = time(NULL); 12022654012fSReza Sabdar nlp->nlp_jstat->js_start_time = nlp->nlp_jstat->js_start_ltime; 12032654012fSReza Sabdar nlp->nlp_jstat->js_chkpnt_time = nlp->nlp_cdate; 12042654012fSReza Sabdar 12052654012fSReza Sabdar if (!session->ns_data.dd_abort) { 12062654012fSReza Sabdar 12072654012fSReza Sabdar cmds = &nlp->nlp_cmds; 12082654012fSReza Sabdar cmds->tcs_reader = cmds->tcs_writer = TLM_BACKUP_RUN; 12092654012fSReza Sabdar cmds->tcs_command->tc_reader = TLM_BACKUP_RUN; 12102654012fSReza Sabdar cmds->tcs_command->tc_writer = TLM_BACKUP_RUN; 12112654012fSReza Sabdar 12122654012fSReza Sabdar if (ndmp_write_utf8magic(cmds->tcs_command) < 0) { 12132654012fSReza Sabdar backup_release_structs(session); 12142654012fSReza Sabdar return (-1); 12152654012fSReza Sabdar } 12162654012fSReza Sabdar 12172654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Backing up \"%s\" started.", 12182654012fSReza Sabdar nlp->nlp_backup_path); 12192654012fSReza Sabdar 12202654012fSReza Sabdar err = ndmp_backup_reader(cmds, nlp, jname); 12212654012fSReza Sabdar if (err != 0) { 12222654012fSReza Sabdar backup_release_structs(session); 12232654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Launch ndmp_backup_reader: %s", 12242654012fSReza Sabdar strerror(err)); 12252654012fSReza Sabdar return (-1); 12262654012fSReza Sabdar } 12272654012fSReza Sabdar 12282654012fSReza Sabdar /* Act as the writer thread. */ 12292654012fSReza Sabdar err = ndmp_tar_writer(session, mod_params, cmds); 12302654012fSReza Sabdar 12312654012fSReza Sabdar nlp->nlp_jstat->js_stop_time = time(NULL); 12322654012fSReza Sabdar 12332654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 12342654012fSReza Sabdar "Runtime [%s] %llu bytes (%llu): %d seconds", 12352654012fSReza Sabdar nlp->nlp_backup_path, session->ns_mover.md_data_written, 12362654012fSReza Sabdar session->ns_mover.md_data_written, 12372654012fSReza Sabdar nlp->nlp_jstat->js_stop_time - 12382654012fSReza Sabdar nlp->nlp_jstat->js_start_ltime); 12392654012fSReza Sabdar MOD_LOG(mod_params, 12402654012fSReza Sabdar "Runtime [%s] %llu bytes (%llu): %d seconds", 12412654012fSReza Sabdar nlp->nlp_backup_path, session->ns_mover.md_data_written, 12422654012fSReza Sabdar session->ns_mover.md_data_written, 12432654012fSReza Sabdar nlp->nlp_jstat->js_stop_time - 12442654012fSReza Sabdar nlp->nlp_jstat->js_start_ltime); 12452654012fSReza Sabdar 12462654012fSReza Sabdar if (session->ns_data.dd_abort) 12472654012fSReza Sabdar err = -1; 12482654012fSReza Sabdar 12492654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Backing up \"%s\" finished. (%d)", 12502654012fSReza Sabdar nlp->nlp_backup_path, err); 12512654012fSReza Sabdar } else { 12522654012fSReza Sabdar nlp->nlp_jstat->js_stop_time = time(NULL); 12532654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Backing up \"%s\" aborted.", 12542654012fSReza Sabdar nlp->nlp_backup_path); 12552654012fSReza Sabdar err = 0; 12562654012fSReza Sabdar } 12572654012fSReza Sabdar 12582654012fSReza Sabdar backup_release_structs(session); 12592654012fSReza Sabdar return (err); 12602654012fSReza Sabdar } 12612654012fSReza Sabdar 12622654012fSReza Sabdar 12632654012fSReza Sabdar /* 12642654012fSReza Sabdar * ndmpd_tar_restore 12652654012fSReza Sabdar * 12662654012fSReza Sabdar * Restore function that launches TAR reader thread to read from the 12672654012fSReza Sabdar * tape and writes the extracted files/dirs to the filesystem 12682654012fSReza Sabdar */ 12692654012fSReza Sabdar static int 12702654012fSReza Sabdar ndmpd_tar_restore(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, 12712654012fSReza Sabdar ndmp_lbr_params_t *nlp) 12722654012fSReza Sabdar { 12732654012fSReza Sabdar char jname[TLM_MAX_BACKUP_JOB_NAME]; 12742654012fSReza Sabdar char *rspath; 12752654012fSReza Sabdar int err; 12762654012fSReza Sabdar tlm_commands_t *cmds; 12772654012fSReza Sabdar ndmp_tar_reader_arg_t arg; 12782654012fSReza Sabdar tlm_backup_restore_arg_t tlm_arg; 12792654012fSReza Sabdar ndmp_name *ent; 12802654012fSReza Sabdar pthread_t rdtp, wrtp; 12812654012fSReza Sabdar int i; 12822654012fSReza Sabdar 12832654012fSReza Sabdar if (mod_params->mp_operation != NDMP_DATA_OP_RECOVER) { 12842654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 12852654012fSReza Sabdar "mod_params->mp_operation != NDMP_DATA_OP_RECOVER"); 12862654012fSReza Sabdar return (-1); 12872654012fSReza Sabdar } 12882654012fSReza Sabdar 12892654012fSReza Sabdar if (nlp->nlp_restore_path[0] != '\0') 12902654012fSReza Sabdar rspath = nlp->nlp_restore_path; 12912654012fSReza Sabdar else if (nlp->nlp_restore_bk_path[0] != '\0') 12922654012fSReza Sabdar rspath = nlp->nlp_restore_bk_path; 12932654012fSReza Sabdar else 12942654012fSReza Sabdar rspath = ""; 12952654012fSReza Sabdar 12962654012fSReza Sabdar (void) ndmp_new_job_name(jname); 12972654012fSReza Sabdar if (restore_create_structs(session, jname) < 0) 12982654012fSReza Sabdar return (-1); 12992654012fSReza Sabdar 13002654012fSReza Sabdar nlp->nlp_jstat->js_start_ltime = time(NULL); 13012654012fSReza Sabdar nlp->nlp_jstat->js_start_time = time(NULL); 13022654012fSReza Sabdar 13032654012fSReza Sabdar if (!session->ns_data.dd_abort) { 13042654012fSReza Sabdar cmds = &nlp->nlp_cmds; 13052654012fSReza Sabdar cmds->tcs_reader = cmds->tcs_writer = TLM_RESTORE_RUN; 13062654012fSReza Sabdar cmds->tcs_command->tc_reader = TLM_RESTORE_RUN; 13072654012fSReza Sabdar cmds->tcs_command->tc_writer = TLM_RESTORE_RUN; 13082654012fSReza Sabdar 13092654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" started.", rspath); 13102654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Restoring from %s tape(s).", 13112654012fSReza Sabdar ndmp_data_get_mover_mode(session)); 13122654012fSReza Sabdar 13132654012fSReza Sabdar arg.tr_session = session; 13142654012fSReza Sabdar arg.tr_mod_params = mod_params; 13152654012fSReza Sabdar arg.tr_cmds = cmds; 13162654012fSReza Sabdar 13172654012fSReza Sabdar err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader, 13182654012fSReza Sabdar (void *)&arg); 13192654012fSReza Sabdar if (err == 0) { 13202654012fSReza Sabdar tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER); 13212654012fSReza Sabdar } else { 13222654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Launch ndmp_tar_reader: %m"); 13232654012fSReza Sabdar return (-1); 13242654012fSReza Sabdar } 13252654012fSReza Sabdar 13262654012fSReza Sabdar if (!ndmp_check_utf8magic(cmds->tcs_command)) { 13272654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "UTF8Magic not found!"); 13282654012fSReza Sabdar } else { 13292654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "UTF8Magic found"); 13302654012fSReza Sabdar } 13312654012fSReza Sabdar 13322654012fSReza Sabdar (void) memset(&tlm_arg, 0, sizeof (tlm_backup_restore_arg_t)); 13332654012fSReza Sabdar (void) pthread_barrier_init(&tlm_arg.ba_barrier, 0, 2); 13342654012fSReza Sabdar 13352654012fSReza Sabdar /* 13362654012fSReza Sabdar * Set up restore parameters 13372654012fSReza Sabdar */ 13382654012fSReza Sabdar tlm_arg.ba_commands = cmds; 13392654012fSReza Sabdar tlm_arg.ba_cmd = cmds->tcs_command; 13402654012fSReza Sabdar tlm_arg.ba_job = nlp->nlp_jstat->js_job_name; 13412654012fSReza Sabdar tlm_arg.ba_dir = nlp->nlp_restore_path; 13422654012fSReza Sabdar for (i = 0; i < nlp->nlp_nfiles; i++) { 13432654012fSReza Sabdar ent = (ndmp_name *)MOD_GETNAME(mod_params, i); 13442654012fSReza Sabdar tlm_arg.ba_sels[i] = ent->name; 13452654012fSReza Sabdar } 13462654012fSReza Sabdar 13472654012fSReza Sabdar 13482654012fSReza Sabdar if (tm_tar_ops.tm_getfile != NULL) { 13492654012fSReza Sabdar err = pthread_create(&wrtp, NULL, 13502654012fSReza Sabdar (funct_t)tm_tar_ops.tm_getfile, (void *)&tlm_arg); 13512654012fSReza Sabdar } else { 13522654012fSReza Sabdar (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); 13532654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 13542654012fSReza Sabdar "Thread create tm_getfile: ops NULL"); 13552654012fSReza Sabdar return (-1); 13562654012fSReza Sabdar } 13572654012fSReza Sabdar if (err == 0) { 13582654012fSReza Sabdar (void) pthread_barrier_wait(&tlm_arg.ba_barrier); 13592654012fSReza Sabdar } else { 13602654012fSReza Sabdar (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); 13612654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "thread create tm_getfile: %m"); 13622654012fSReza Sabdar return (-1); 13632654012fSReza Sabdar } 13642654012fSReza Sabdar 13652654012fSReza Sabdar (void) pthread_join(rdtp, NULL); 13662654012fSReza Sabdar (void) pthread_join(wrtp, NULL); 13672654012fSReza Sabdar (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); 13682654012fSReza Sabdar 13692654012fSReza Sabdar nlp->nlp_jstat->js_stop_time = time(NULL); 13702654012fSReza Sabdar 13712654012fSReza Sabdar /* Send the list of un-recovered files/dirs to the client. */ 13722654012fSReza Sabdar (void) send_unrecovered_list(mod_params, nlp); 13732654012fSReza Sabdar 13742654012fSReza Sabdar ndmp_stop_local_reader(session, cmds); 13752654012fSReza Sabdar ndmp_wait_for_reader(cmds); 13762654012fSReza Sabdar ndmp_stop_remote_reader(session); 13772654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" finished. (%d)", 13782654012fSReza Sabdar rspath, err); 13792654012fSReza Sabdar } else { 13802654012fSReza Sabdar nlp->nlp_jstat->js_stop_time = time(NULL); 13812654012fSReza Sabdar 13822654012fSReza Sabdar /* nothing restored. */ 13832654012fSReza Sabdar (void) send_unrecovered_list(mod_params, nlp); 13842654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" aborted.", 13852654012fSReza Sabdar rspath); 13862654012fSReza Sabdar err = -1; 13872654012fSReza Sabdar } 13882654012fSReza Sabdar 13892654012fSReza Sabdar NDMP_FREE(nlp->nlp_restore_path); 13902654012fSReza Sabdar backup_release_structs(session); 13912654012fSReza Sabdar 13922654012fSReza Sabdar return (err); 13932654012fSReza Sabdar } 13942654012fSReza Sabdar 13952654012fSReza Sabdar 13962654012fSReza Sabdar /* 13972654012fSReza Sabdar * prefixdir 13982654012fSReza Sabdar * 13992654012fSReza Sabdar * Extract the path for a given full path entry 14002654012fSReza Sabdar */ 14012654012fSReza Sabdar static char * 14022654012fSReza Sabdar prefixdir(char *dir, char *suffix) 14032654012fSReza Sabdar { 14042654012fSReza Sabdar static char tmp[TLM_MAX_PATH_NAME]; 14052654012fSReza Sabdar char *tend, *send; /* tmp and suffix end */ 14062654012fSReza Sabdar 14072654012fSReza Sabdar if (dir == NULL || suffix == NULL) 14082654012fSReza Sabdar return (NULL); 14092654012fSReza Sabdar 14102654012fSReza Sabdar if (*suffix == '\0') 14112654012fSReza Sabdar return (dir); 14122654012fSReza Sabdar 14132654012fSReza Sabdar if (*dir == '\0') 14142654012fSReza Sabdar return (NULL); 14152654012fSReza Sabdar 14162654012fSReza Sabdar (void) strlcpy(tmp, dir, TLM_MAX_PATH_NAME); 14172654012fSReza Sabdar tend = &tmp[strlen(tmp)]; 14182654012fSReza Sabdar send = &suffix[strlen(suffix)]; 14192654012fSReza Sabdar 14202654012fSReza Sabdar /* 14212654012fSReza Sabdar * Move backward as far as the last part of the dir and 14222654012fSReza Sabdar * the suffix match. 14232654012fSReza Sabdar */ 14242654012fSReza Sabdar while (tend >= tmp && send >= suffix) 14252654012fSReza Sabdar if (*tend == *send) 14262654012fSReza Sabdar tend--, send--; 14272654012fSReza Sabdar else 14282654012fSReza Sabdar break; 14292654012fSReza Sabdar 14302654012fSReza Sabdar *++tend = '\0'; 14312654012fSReza Sabdar return (tmp); 14322654012fSReza Sabdar } 14332654012fSReza Sabdar 14342654012fSReza Sabdar 14352654012fSReza Sabdar /* 14362654012fSReza Sabdar * get_nfiles 14372654012fSReza Sabdar * 14382654012fSReza Sabdar * Get the count of files to be restored 14392654012fSReza Sabdar */ 14402654012fSReza Sabdar static int 14412654012fSReza Sabdar get_nfiles(ndmpd_session_t *session, ndmpd_module_params_t *params) 14422654012fSReza Sabdar { 14432654012fSReza Sabdar if (session->ns_data.dd_nlist_len == 0) { 14442654012fSReza Sabdar MOD_LOG(params, "Error: nothing specified to be restored.\n"); 14452654012fSReza Sabdar return (-1); 14462654012fSReza Sabdar } 14472654012fSReza Sabdar 14482654012fSReza Sabdar return (session->ns_data.dd_nlist_len); 14492654012fSReza Sabdar } 14502654012fSReza Sabdar 14512654012fSReza Sabdar 14522654012fSReza Sabdar /* 14532654012fSReza Sabdar * get_restore_dest 14542654012fSReza Sabdar * 14552654012fSReza Sabdar * Get the full pathname of where the entries should be restored to. 14562654012fSReza Sabdar */ 14572654012fSReza Sabdar static char * 14582654012fSReza Sabdar get_restore_dest(ndmpd_module_params_t *params) 14592654012fSReza Sabdar { 14602654012fSReza Sabdar ndmp_name *ent; 14612654012fSReza Sabdar char *cp; 14622654012fSReza Sabdar 14632654012fSReza Sabdar /* 14642654012fSReza Sabdar * Destination of restore: 14652654012fSReza Sabdar * NetBackup of Veritas(C) sends the entries like this: 14662654012fSReza Sabdar * 14672654012fSReza Sabdar * ent[i].name: is the relative pathname of what is selected in 14682654012fSReza Sabdar * the GUI. 14692654012fSReza Sabdar * ent[i].dest: is the full pathname of where the dir/file must 14702654012fSReza Sabdar * be restored to. 14712654012fSReza Sabdar * ent[i].ssi: 0 14722654012fSReza Sabdar * ent[i].fh_info: 0 14732654012fSReza Sabdar * 14742654012fSReza Sabdar */ 14752654012fSReza Sabdar ent = (ndmp_name *)MOD_GETNAME(params, 0); 14762654012fSReza Sabdar cp = prefixdir(ent->dest, ent->name); 14772654012fSReza Sabdar if (cp == NULL) { 14782654012fSReza Sabdar MOD_LOG(params, "Error: empty restore path.\n"); 14792654012fSReza Sabdar return (NULL); 14802654012fSReza Sabdar } 14812654012fSReza Sabdar 14822654012fSReza Sabdar return (cp); 14832654012fSReza Sabdar } 14842654012fSReza Sabdar 14852654012fSReza Sabdar 14862654012fSReza Sabdar /* 14872654012fSReza Sabdar * correct_ents 14882654012fSReza Sabdar * 14892654012fSReza Sabdar * Correct the entries in the restore list by appending the appropriate 14902654012fSReza Sabdar * path to them 14912654012fSReza Sabdar */ 14922654012fSReza Sabdar static int 14932654012fSReza Sabdar correct_ents(ndmpd_module_params_t *params, int n, char *bkpath) 14942654012fSReza Sabdar { 14952654012fSReza Sabdar char *cp, *pathname; 14962654012fSReza Sabdar int i, len, rv; 14972654012fSReza Sabdar ndmp_name *ent; 14982654012fSReza Sabdar 14992654012fSReza Sabdar if ((pathname = ndmp_malloc(TLM_MAX_PATH_NAME)) == NULL) { 15002654012fSReza Sabdar MOD_LOG(params, "Error: insufficient memory.\n"); 15012654012fSReza Sabdar return (-1); 15022654012fSReza Sabdar } 15032654012fSReza Sabdar 15042654012fSReza Sabdar rv = 0; 15052654012fSReza Sabdar /* Append the backup path to all the "ent[].name"s. */ 15062654012fSReza Sabdar for (i = 0; i < n; i++) { 15072654012fSReza Sabdar ent = (ndmp_name *)MOD_GETNAME(params, i); 15082654012fSReza Sabdar 15092654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 15102654012fSReza Sabdar "Old: ent[%d].name: \"%s\"", i, ent->name); 15112654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 15122654012fSReza Sabdar "Old: ent[%d].dest: \"%s\"", i, ent->dest); 15132654012fSReza Sabdar 15142654012fSReza Sabdar /* remove trailing slash */ 15152654012fSReza Sabdar len = strlen(ent->name); 15162654012fSReza Sabdar if (ent->name[len - 1] == '/') 15172654012fSReza Sabdar ent->name[len - 1] = '\0'; 15182654012fSReza Sabdar 15192654012fSReza Sabdar if (!tlm_cat_path(pathname, bkpath, ent->name)) { 15202654012fSReza Sabdar MOD_LOG(params, "Error: path too long.\n"); 15212654012fSReza Sabdar rv = -1; 15222654012fSReza Sabdar break; 15232654012fSReza Sabdar } 15242654012fSReza Sabdar 15252654012fSReza Sabdar /* Make a copy of the new string and save it in ent->name. */ 15262654012fSReza Sabdar cp = strdup(pathname); 15272654012fSReza Sabdar if (cp == NULL) { 15282654012fSReza Sabdar MOD_LOG(params, "Error: insufficient memory.\n"); 15292654012fSReza Sabdar rv = -1; 15302654012fSReza Sabdar break; 15312654012fSReza Sabdar } 15322654012fSReza Sabdar free(ent->name); 15332654012fSReza Sabdar ent->name = cp; 15342654012fSReza Sabdar 15352654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 15362654012fSReza Sabdar "New: ent[%d].name: \"%s\"", i, ent->name); 15372654012fSReza Sabdar } 15382654012fSReza Sabdar 15392654012fSReza Sabdar free(pathname); 15402654012fSReza Sabdar return (rv); 15412654012fSReza Sabdar } 15422654012fSReza Sabdar 15432654012fSReza Sabdar 15442654012fSReza Sabdar /* 15452654012fSReza Sabdar * check_restore_paths 15462654012fSReza Sabdar * 15472654012fSReza Sabdar * Go through the restore list and check the validity of the 15482654012fSReza Sabdar * restore path. 15492654012fSReza Sabdar */ 15502654012fSReza Sabdar static int 15512654012fSReza Sabdar check_restore_paths(ndmpd_module_params_t *params, int n, char *rspath) 15522654012fSReza Sabdar { 15532654012fSReza Sabdar int i, rv; 15542654012fSReza Sabdar ndmp_name *ent; 15552654012fSReza Sabdar 15562654012fSReza Sabdar rv = 0; 15572654012fSReza Sabdar if (rspath != NULL && *rspath != '\0') { 15582654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "rspath: \"%s\"", rspath); 15592654012fSReza Sabdar if (!fs_volexist(rspath)) { 15602654012fSReza Sabdar MOD_LOG(params, 15612654012fSReza Sabdar "Error: Invalid volume name for restore."); 15622654012fSReza Sabdar rv = -1; 15632654012fSReza Sabdar } 15642654012fSReza Sabdar } else { 15652654012fSReza Sabdar for (i = 0; i < n; i++) { 15662654012fSReza Sabdar ent = (ndmp_name *)MOD_GETNAME(params, i); 15672654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 15682654012fSReza Sabdar "ent[%d].name: \"%s\"", i, ent->name); 15692654012fSReza Sabdar 15702654012fSReza Sabdar if (!fs_volexist(ent->name)) { 15712654012fSReza Sabdar MOD_LOG(params, 15722654012fSReza Sabdar "Error: Invalid volume name for restore.", 15732654012fSReza Sabdar ent->name); 15742654012fSReza Sabdar rv = -1; 15752654012fSReza Sabdar break; 15762654012fSReza Sabdar } 15772654012fSReza Sabdar } 15782654012fSReza Sabdar } 15792654012fSReza Sabdar 15802654012fSReza Sabdar return (rv); 15812654012fSReza Sabdar } 15822654012fSReza Sabdar 15832654012fSReza Sabdar 15842654012fSReza Sabdar /* 15852654012fSReza Sabdar * check_backup_dir_validity 15862654012fSReza Sabdar * 15872654012fSReza Sabdar * Check if the backup directory is valid. Make sure it exists and 15882654012fSReza Sabdar * is writable. Check for snapshot and readonly cases. 15892654012fSReza Sabdar */ 15902654012fSReza Sabdar static int 15912654012fSReza Sabdar check_backup_dir_validity(ndmpd_module_params_t *params, char *bkpath) 15922654012fSReza Sabdar { 15932654012fSReza Sabdar char *msg; 15942654012fSReza Sabdar int rv; 15952654012fSReza Sabdar struct stat64 st; 15962654012fSReza Sabdar 15972654012fSReza Sabdar rv = NDMP_NO_ERR; 15982654012fSReza Sabdar if (stat64(bkpath, &st) < 0) { 15992654012fSReza Sabdar msg = strerror(errno); 16002654012fSReza Sabdar MOD_LOG(params, "Error: stat(%s): %s.\n", bkpath, msg); 16012654012fSReza Sabdar rv = NDMP_ILLEGAL_ARGS_ERR; 16022654012fSReza Sabdar } else if (!S_ISDIR(st.st_mode)) { 16032654012fSReza Sabdar MOD_LOG(params, "Error: %s is not a directory.\n", bkpath); 16042654012fSReza Sabdar rv = NDMP_ILLEGAL_ARGS_ERR; 16052654012fSReza Sabdar } else if (fs_is_rdonly(bkpath) && !fs_is_chkpntvol(bkpath) && 16062654012fSReza Sabdar fs_is_chkpnt_enabled(bkpath)) { 16072654012fSReza Sabdar MOD_LOG(params, "Error: %s is not a checkpointed path.\n", 16082654012fSReza Sabdar bkpath); 16092654012fSReza Sabdar rv = NDMP_BAD_FILE_ERR; 16102654012fSReza Sabdar } 16112654012fSReza Sabdar 16122654012fSReza Sabdar return (rv); 16132654012fSReza Sabdar } 16142654012fSReza Sabdar 16152654012fSReza Sabdar 16162654012fSReza Sabdar /* 16172654012fSReza Sabdar * ndmp_backup_extract_params 16182654012fSReza Sabdar * 16192654012fSReza Sabdar * Go through the backup parameters and check the validity 16202654012fSReza Sabdar * for each one. Then set the NLP flags according to the parameters. 16212654012fSReza Sabdar */ 16222654012fSReza Sabdar int 16232654012fSReza Sabdar ndmp_backup_extract_params(ndmpd_session_t *session, 16242654012fSReza Sabdar ndmpd_module_params_t *params) 16252654012fSReza Sabdar { 16262654012fSReza Sabdar char *cp; 16272654012fSReza Sabdar int rv; 16282654012fSReza Sabdar ndmp_lbr_params_t *nlp; 16292654012fSReza Sabdar 16302654012fSReza Sabdar /* Extract directory to be backed up from env variables */ 16312654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 16322654012fSReza Sabdar MOD_LOG(params, "Error: Internal error: nlp == NULL.\n"); 16332654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 16342654012fSReza Sabdar } 16358c4f9701SJanice Chang if ((nlp->nlp_backup_path = get_backup_path_v2(params)) == NULL) 16362654012fSReza Sabdar return (NDMP_FILE_NOT_FOUND_ERR); 16372654012fSReza Sabdar 16382654012fSReza Sabdar if ((rv = check_backup_dir_validity(params, 16392654012fSReza Sabdar nlp->nlp_backup_path)) != NDMP_NO_ERR) 16402654012fSReza Sabdar return (rv); 16412654012fSReza Sabdar 16422654012fSReza Sabdar /* Should the st_ctime be ignored when backing up? */ 16432654012fSReza Sabdar if (ndmp_ignore_ctime) { 16442654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ignoring st_ctime"); 16452654012fSReza Sabdar NLP_SET(nlp, NLPF_IGNCTIME); 16462654012fSReza Sabdar } else 16472654012fSReza Sabdar NLP_UNSET(nlp, NLPF_IGNCTIME); 16482654012fSReza Sabdar 16492654012fSReza Sabdar /* Should the st_lmtime be ignored when backing up? */ 16502654012fSReza Sabdar if (ndmp_include_lmtime) { 16512654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "including st_lmtime"); 16522654012fSReza Sabdar NLP_SET(nlp, NLPF_INCLMTIME); 16532654012fSReza Sabdar } else 16542654012fSReza Sabdar NLP_UNSET(nlp, NLPF_INCLMTIME); 16552654012fSReza Sabdar 16562654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "flags %x", nlp->nlp_flags); 16572654012fSReza Sabdar 16582654012fSReza Sabdar /* Is backup history requested? */ 16592654012fSReza Sabdar cp = MOD_GETENV(params, "HIST"); 16602654012fSReza Sabdar if (cp == NULL) { 16612654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "env(HIST) not specified"); 16622654012fSReza Sabdar NLP_UNSET(nlp, NLPF_FH); 16632654012fSReza Sabdar } else { 16642654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "env(HIST): \"%s\"", cp); 16652654012fSReza Sabdar 16662654012fSReza Sabdar if (strchr("t_ty_y", *cp)) 16672654012fSReza Sabdar NLP_SET(nlp, NLPF_FH); 16682654012fSReza Sabdar else 16692654012fSReza Sabdar NLP_UNSET(nlp, NLPF_FH); 16702654012fSReza Sabdar } 16712654012fSReza Sabdar 16722654012fSReza Sabdar nlp->nlp_clevel = 0; 16732654012fSReza Sabdar /* Is it an incremental backup? */ 16742654012fSReza Sabdar cp = MOD_GETENV(params, "LEVEL"); 16752654012fSReza Sabdar if (cp == NULL) { 16762654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 16772654012fSReza Sabdar "env(LEVEL) not specified, default to 0"); 16782654012fSReza Sabdar } else if (*cp < '0' || *cp > '9' || *(cp+1) != '\0') { 16792654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid backup level '%s'", cp); 16802654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 16812654012fSReza Sabdar } else 16822654012fSReza Sabdar nlp->nlp_clevel = *cp - '0'; 16832654012fSReza Sabdar 16842654012fSReza Sabdar /* Extract last backup time from the dumpdates file */ 16852654012fSReza Sabdar nlp->nlp_llevel = nlp->nlp_clevel; 16862654012fSReza Sabdar nlp->nlp_ldate = 0; 16872654012fSReza Sabdar if (ndmpd_get_dumptime(nlp->nlp_backup_path, &nlp->nlp_llevel, 16882654012fSReza Sabdar &nlp->nlp_ldate) < 0) { 16892654012fSReza Sabdar MOD_LOG(params, "Error: getting dumpdate for %s level %d\n", 16902654012fSReza Sabdar nlp->nlp_backup_path, nlp->nlp_clevel); 16912654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 16922654012fSReza Sabdar } 16932654012fSReza Sabdar 16942654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 16952654012fSReza Sabdar "Date of this level %d on \"%s\": %s", 16962654012fSReza Sabdar nlp->nlp_clevel, nlp->nlp_backup_path, cctime(&nlp->nlp_cdate)); 16972654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 16982654012fSReza Sabdar "Date of last level %d on \"%s\": %s", 16992654012fSReza Sabdar nlp->nlp_llevel, nlp->nlp_backup_path, cctime(&nlp->nlp_ldate)); 17002654012fSReza Sabdar 17012654012fSReza Sabdar /* Should the dumpdate file be updated? */ 17022654012fSReza Sabdar cp = MOD_GETENV(params, "UPDATE"); 17032654012fSReza Sabdar if (cp == NULL) { 17042654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 17052654012fSReza Sabdar "env(UPDATE) not specified, default to TRUE"); 17062654012fSReza Sabdar NLP_SET(nlp, NLPF_UPDATE); 17072654012fSReza Sabdar } else { 17082654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "env(UPDATE): \"%s\"", cp); 17092654012fSReza Sabdar if (strchr("t_ty_y", *cp) != NULL) 17102654012fSReza Sabdar NLP_SET(nlp, NLPF_UPDATE); 17112654012fSReza Sabdar else 17122654012fSReza Sabdar NLP_UNSET(nlp, NLPF_UPDATE); 17132654012fSReza Sabdar } 17142654012fSReza Sabdar 17152654012fSReza Sabdar return (NDMP_NO_ERR); 17162654012fSReza Sabdar } 17172654012fSReza Sabdar 17182654012fSReza Sabdar 17192654012fSReza Sabdar 17202654012fSReza Sabdar /* 17212654012fSReza Sabdar * log_bk_params_v2 17222654012fSReza Sabdar * 17232654012fSReza Sabdar * Dump the value of the parameters in the log file for debugging. 17242654012fSReza Sabdar */ 17252654012fSReza Sabdar void 17262654012fSReza Sabdar log_bk_params_v2(ndmpd_session_t *session, ndmpd_module_params_t *params, 17272654012fSReza Sabdar ndmp_lbr_params_t *nlp) 17282654012fSReza Sabdar { 17292654012fSReza Sabdar MOD_LOG(params, "Date of this level %d on \"%s\": %s\n", 17302654012fSReza Sabdar nlp->nlp_clevel, nlp->nlp_backup_path, cctime(&nlp->nlp_cdate)); 17312654012fSReza Sabdar MOD_LOG(params, "Date of last level %d on \"%s\": %s\n", 17322654012fSReza Sabdar nlp->nlp_llevel, nlp->nlp_backup_path, cctime(&nlp->nlp_ldate)); 17332654012fSReza Sabdar 17342654012fSReza Sabdar MOD_LOG(params, "Backing up: \"%s\".\n", nlp->nlp_backup_path); 17352654012fSReza Sabdar MOD_LOG(params, "Record size: %d\n", session->ns_mover.md_record_size); 17362654012fSReza Sabdar MOD_LOG(params, "File history: %c.\n", 17372654012fSReza Sabdar NDMP_YORN(NLP_ISSET(nlp, NLPF_FH))); 17382654012fSReza Sabdar MOD_LOG(params, "Update: %s\n", 17392654012fSReza Sabdar NLP_ISSET(nlp, NLPF_UPDATE) ? "TRUE" : "FALSE"); 17402654012fSReza Sabdar 17412654012fSReza Sabdar } 17422654012fSReza Sabdar 17432654012fSReza Sabdar 17442654012fSReza Sabdar /* 17452654012fSReza Sabdar * same_path 17462654012fSReza Sabdar * 17472654012fSReza Sabdar * Find out if the paths are the same regardless of the ending slash 17482654012fSReza Sabdar * 17492654012fSReza Sabdar * Examples : 17502654012fSReza Sabdar * /a/b/c == /a/b/c 17512654012fSReza Sabdar * /a/b/c/ == /a/b/c 17522654012fSReza Sabdar * /a/b/c == /a/b/c/ 17532654012fSReza Sabdar */ 17542654012fSReza Sabdar static boolean_t 17552654012fSReza Sabdar same_path(char *s, char *t) 17562654012fSReza Sabdar { 17572654012fSReza Sabdar boolean_t rv; 17582654012fSReza Sabdar int slen, tlen; 17592654012fSReza Sabdar 17602654012fSReza Sabdar rv = FALSE; 17612654012fSReza Sabdar slen = strlen(s); 17622654012fSReza Sabdar tlen = strlen(t); 17632654012fSReza Sabdar if (slen == tlen && strcmp(s, t) == 0) { 17642654012fSReza Sabdar rv = TRUE; 17652654012fSReza Sabdar } else { 17662654012fSReza Sabdar if (slen == tlen - 1) { 17672654012fSReza Sabdar if (strncmp(s, t, slen) == 0 && t[tlen - 1] == '/') 17682654012fSReza Sabdar rv = TRUE; 17692654012fSReza Sabdar } else if (tlen == slen -1) { 17702654012fSReza Sabdar if (strncmp(s, t, tlen) == 0 && s[slen - 1] == '/') 17712654012fSReza Sabdar rv = TRUE; 17722654012fSReza Sabdar } 17732654012fSReza Sabdar } 17742654012fSReza Sabdar 17752654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "rv: %d", rv); 17762654012fSReza Sabdar return (rv); 17772654012fSReza Sabdar } 17782654012fSReza Sabdar 17792654012fSReza Sabdar 17802654012fSReza Sabdar /* 17812654012fSReza Sabdar * ndmp_restore_extract_params 17822654012fSReza Sabdar * 17832654012fSReza Sabdar * Go through the restore parameters and check them and extract them 17842654012fSReza Sabdar * by setting NLP flags and other values. 17852654012fSReza Sabdar * 17862654012fSReza Sabdar * Parameters: 17872654012fSReza Sabdar * 17882654012fSReza Sabdar * Returns: 17892654012fSReza Sabdar * 0: on success 17902654012fSReza Sabdar * -1: otherwise 17912654012fSReza Sabdar */ 17922654012fSReza Sabdar int 17932654012fSReza Sabdar ndmp_restore_extract_params(ndmpd_session_t *session, 17942654012fSReza Sabdar ndmpd_module_params_t *params) 17952654012fSReza Sabdar { 17962654012fSReza Sabdar char *bkpath, *rspath; 17972654012fSReza Sabdar ndmp_lbr_params_t *nlp; 17982654012fSReza Sabdar 17992654012fSReza Sabdar if ((nlp = ndmp_get_nlp(session)) == NULL) { 18002654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nlp == NULL"); 18012654012fSReza Sabdar return (-1); 18022654012fSReza Sabdar } 18032654012fSReza Sabdar 18042654012fSReza Sabdar /* Extract directory from where the backup was made. */ 18058c4f9701SJanice Chang if ((bkpath = get_backup_path_v2(params)) == NULL) 18062654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 18072654012fSReza Sabdar 18082654012fSReza Sabdar nlp->nlp_restore_bk_path = bkpath; 18092654012fSReza Sabdar 18102654012fSReza Sabdar /* The number of the selections. */ 18112654012fSReza Sabdar if ((nlp->nlp_nfiles = get_nfiles(session, params)) == 0) 18122654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 18132654012fSReza Sabdar 18142654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "nfiles: %d", nlp->nlp_nfiles); 18152654012fSReza Sabdar 18162654012fSReza Sabdar if ((rspath = get_restore_dest(params)) == NULL) 18172654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 18182654012fSReza Sabdar 18192654012fSReza Sabdar if (fs_is_rdonly(rspath)) { 18202654012fSReza Sabdar MOD_LOG(params, 18212654012fSReza Sabdar "Error: Can't restore to a read-only volume: \"%s\"\n", 18222654012fSReza Sabdar rspath); 18232654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 18242654012fSReza Sabdar } 18252654012fSReza Sabdar if (fs_is_chkpntvol(rspath)) { 18262654012fSReza Sabdar MOD_LOG(params, 18272654012fSReza Sabdar "Error: Can't restore to a checkpoint: \"%s\"\n", rspath); 18282654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 18292654012fSReza Sabdar } 18302654012fSReza Sabdar 18312654012fSReza Sabdar if (same_path(bkpath, rspath)) 18322654012fSReza Sabdar rspath = ""; 18332654012fSReza Sabdar 18342654012fSReza Sabdar if ((nlp->nlp_restore_path = strdup(rspath)) == NULL) 18352654012fSReza Sabdar return (NDMP_NO_MEM_ERR); 18362654012fSReza Sabdar 18372654012fSReza Sabdar bkpath = trim_name(bkpath); 18382654012fSReza Sabdar if (correct_ents(params, nlp->nlp_nfiles, bkpath) < 0) { 18392654012fSReza Sabdar free(nlp->nlp_restore_path); 18402654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 18412654012fSReza Sabdar } 18422654012fSReza Sabdar 18432654012fSReza Sabdar if (check_restore_paths(params, nlp->nlp_nfiles, rspath) < 0) { 18442654012fSReza Sabdar free(nlp->nlp_restore_path); 18452654012fSReza Sabdar return (NDMP_ILLEGAL_ARGS_ERR); 18462654012fSReza Sabdar } 18472654012fSReza Sabdar 18482654012fSReza Sabdar MOD_LOG(params, "Restoring %d files.\n", nlp->nlp_nfiles); 18492654012fSReza Sabdar MOD_LOG(params, "Restoring to: \"%s\".\n", nlp->nlp_restore_path); 18502654012fSReza Sabdar MOD_LOG(params, "Record size: %d\n", session->ns_mover.md_record_size); 18512654012fSReza Sabdar 18522654012fSReza Sabdar return (NDMP_NO_ERR); 18532654012fSReza Sabdar } 18542654012fSReza Sabdar 18552654012fSReza Sabdar /* 18562654012fSReza Sabdar * ndmpd_tar_backup_starter (V2 only) 18572654012fSReza Sabdar * 18582654012fSReza Sabdar * The main backup starter function. It creates a snapshot if necessary 18592654012fSReza Sabdar * and calls ndmp_tar_backup to perform the actual backup. It does the cleanup 18602654012fSReza Sabdar * and release the snapshot at the end. 18612654012fSReza Sabdar */ 18622654012fSReza Sabdar int 18638c4f9701SJanice Chang ndmpd_tar_backup_starter(void *arg) 18642654012fSReza Sabdar { 18658c4f9701SJanice Chang ndmpd_module_params_t *mod_params = arg; 18662654012fSReza Sabdar int err; 18672654012fSReza Sabdar ndmpd_session_t *session; 18682654012fSReza Sabdar ndmp_lbr_params_t *nlp; 18692654012fSReza Sabdar 18702654012fSReza Sabdar session = (ndmpd_session_t *)(mod_params->mp_daemon_cookie); 18712654012fSReza Sabdar *(mod_params->mp_module_cookie) = nlp = ndmp_get_nlp(session); 18722654012fSReza Sabdar ndmp_session_ref(session); 18732654012fSReza Sabdar 18742654012fSReza Sabdar err = 0; 18752654012fSReza Sabdar if (fs_is_chkpntvol(nlp->nlp_backup_path) || 18762654012fSReza Sabdar fs_is_rdonly(nlp->nlp_backup_path) || 18772654012fSReza Sabdar !fs_is_chkpnt_enabled(nlp->nlp_backup_path)) 18782654012fSReza Sabdar NLP_SET(nlp, NLPF_CHKPNTED_PATH); 18792654012fSReza Sabdar else { 18802654012fSReza Sabdar NLP_UNSET(nlp, NLPF_CHKPNTED_PATH); 1881876b86efSReza Sabdar if (ndmp_create_snapshot(nlp->nlp_backup_path, 18822654012fSReza Sabdar nlp->nlp_jstat->js_job_name) < 0) { 18832654012fSReza Sabdar MOD_LOG(mod_params, 18842654012fSReza Sabdar "Error: creating checkpoint on %s\n", 18852654012fSReza Sabdar nlp->nlp_backup_path); 18862654012fSReza Sabdar /* -1 causes halt reason to become internal error. */ 18872654012fSReza Sabdar err = -1; 18882654012fSReza Sabdar } 18892654012fSReza Sabdar } 18902654012fSReza Sabdar 18912654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "NLPF_CHKPNTED_PATH: %c", 18922654012fSReza Sabdar NDMP_YORN(NLP_ISCHKPNTED(nlp))); 18932654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "err: %d, update %c", 18942654012fSReza Sabdar err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp))); 18952654012fSReza Sabdar 18962654012fSReza Sabdar if (err == 0) { 18972654012fSReza Sabdar err = ndmp_get_cur_bk_time(nlp, &nlp->nlp_cdate, 18982654012fSReza Sabdar nlp->nlp_jstat->js_job_name); 18992654012fSReza Sabdar if (err != 0) { 19002654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "err %d", err); 19012654012fSReza Sabdar } else { 19022654012fSReza Sabdar log_bk_params_v2(session, mod_params, nlp); 19032654012fSReza Sabdar err = ndmpd_tar_backup(session, mod_params, nlp); 19042654012fSReza Sabdar } 19052654012fSReza Sabdar } 19062654012fSReza Sabdar 19072654012fSReza Sabdar if (nlp->nlp_bkmap >= 0) { 19082654012fSReza Sabdar (void) dbm_free(nlp->nlp_bkmap); 19092654012fSReza Sabdar nlp->nlp_bkmap = -1; 19102654012fSReza Sabdar } 19112654012fSReza Sabdar 19122654012fSReza Sabdar if (!NLP_ISCHKPNTED(nlp)) 1913876b86efSReza Sabdar (void) ndmp_remove_snapshot(nlp->nlp_backup_path, 19142654012fSReza Sabdar nlp->nlp_jstat->js_job_name); 19152654012fSReza Sabdar 19162654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "err %d, update %c", 19172654012fSReza Sabdar err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp))); 19182654012fSReza Sabdar 19192654012fSReza Sabdar if (err == 0 && NLP_SHOULD_UPDATE(nlp)) { 19202654012fSReza Sabdar if (ndmpd_put_dumptime(nlp->nlp_backup_path, nlp->nlp_clevel, 19212654012fSReza Sabdar nlp->nlp_cdate) < 0) { 19222654012fSReza Sabdar err = EPERM; 19232654012fSReza Sabdar MOD_LOG(mod_params, 19242654012fSReza Sabdar "Error: updating the dumpdates file on %s\n", 19252654012fSReza Sabdar nlp->nlp_backup_path); 19262654012fSReza Sabdar } 19272654012fSReza Sabdar } 19282654012fSReza Sabdar 19292654012fSReza Sabdar MOD_DONE(mod_params, err); 19302654012fSReza Sabdar 19312654012fSReza Sabdar /* nlp_params is allocated in start_backup() */ 19322654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 19332654012fSReza Sabdar 19342654012fSReza Sabdar NS_DEC(nbk); 19352654012fSReza Sabdar ndmp_session_unref(session); 19362654012fSReza Sabdar return (err); 19372654012fSReza Sabdar } 19382654012fSReza Sabdar 19392654012fSReza Sabdar 19402654012fSReza Sabdar /* 19412654012fSReza Sabdar * ndmpd_tar_backup_abort 19422654012fSReza Sabdar * 19432654012fSReza Sabdar * Abort the running backup by stopping the reader thread (V2 only) 19442654012fSReza Sabdar */ 19452654012fSReza Sabdar int 19462654012fSReza Sabdar ndmpd_tar_backup_abort(void *module_cookie) 19472654012fSReza Sabdar { 19482654012fSReza Sabdar ndmp_lbr_params_t *nlp; 19492654012fSReza Sabdar 19502654012fSReza Sabdar nlp = (ndmp_lbr_params_t *)module_cookie; 19512654012fSReza Sabdar if (nlp != NULL && nlp->nlp_session != NULL) { 19522654012fSReza Sabdar if (nlp->nlp_session->ns_data.dd_mover.addr_type == 19532654012fSReza Sabdar NDMP_ADDR_TCP && nlp->nlp_session->ns_data.dd_sock != -1) { 19542654012fSReza Sabdar (void) close(nlp->nlp_session->ns_data.dd_sock); 19552654012fSReza Sabdar nlp->nlp_session->ns_data.dd_sock = -1; 19562654012fSReza Sabdar } 19572654012fSReza Sabdar ndmp_stop_reader_thread(nlp->nlp_session); 19582654012fSReza Sabdar } 19592654012fSReza Sabdar 19602654012fSReza Sabdar return (0); 19612654012fSReza Sabdar } 19622654012fSReza Sabdar 19632654012fSReza Sabdar /* 19642654012fSReza Sabdar * ndmpd_tar_restore_starter 19652654012fSReza Sabdar * 19662654012fSReza Sabdar * Starts the restore by running ndmpd_tar_restore function (V2 only) 19672654012fSReza Sabdar */ 19682654012fSReza Sabdar 19692654012fSReza Sabdar int 19708c4f9701SJanice Chang ndmpd_tar_restore_starter(void *arg) 19712654012fSReza Sabdar { 19728c4f9701SJanice Chang ndmpd_module_params_t *mod_params = arg; 19732654012fSReza Sabdar int err; 19742654012fSReza Sabdar ndmpd_session_t *session; 19752654012fSReza Sabdar ndmp_lbr_params_t *nlp; 19762654012fSReza Sabdar 19772654012fSReza Sabdar session = (ndmpd_session_t *)(mod_params->mp_daemon_cookie); 19782654012fSReza Sabdar *(mod_params->mp_module_cookie) = nlp = ndmp_get_nlp(session); 19792654012fSReza Sabdar ndmp_session_ref(session); 19802654012fSReza Sabdar 19812654012fSReza Sabdar err = ndmpd_tar_restore(session, mod_params, nlp); 19822654012fSReza Sabdar MOD_DONE(mod_params, err); 19832654012fSReza Sabdar 19842654012fSReza Sabdar /* nlp_params is allocated in start_recover() */ 19852654012fSReza Sabdar NDMP_FREE(nlp->nlp_params); 19862654012fSReza Sabdar 19872654012fSReza Sabdar NS_DEC(nrs); 19882654012fSReza Sabdar ndmp_session_unref(session); 19892654012fSReza Sabdar return (err); 19902654012fSReza Sabdar } 19912654012fSReza Sabdar 19922654012fSReza Sabdar 19932654012fSReza Sabdar /* 19942654012fSReza Sabdar * ndmpd_tar_restore_abort 19952654012fSReza Sabdar * 19962654012fSReza Sabdar * Aborts the restore operation by stopping the writer thread (V2 only) 19972654012fSReza Sabdar */ 19982654012fSReza Sabdar int 19992654012fSReza Sabdar ndmpd_tar_restore_abort(void *module_cookie) 20002654012fSReza Sabdar { 20012654012fSReza Sabdar ndmp_lbr_params_t *nlp; 20022654012fSReza Sabdar 20032654012fSReza Sabdar nlp = (ndmp_lbr_params_t *)module_cookie; 20042654012fSReza Sabdar if (nlp != NULL && nlp->nlp_session != NULL) { 2005*a23888a3SJan Kryl (void) mutex_lock(&nlp->nlp_mtx); 20062654012fSReza Sabdar if (nlp->nlp_session->ns_data.dd_mover.addr_type == 20072654012fSReza Sabdar NDMP_ADDR_TCP && nlp->nlp_session->ns_data.dd_sock != -1) { 20082654012fSReza Sabdar (void) close(nlp->nlp_session->ns_data.dd_sock); 20092654012fSReza Sabdar nlp->nlp_session->ns_data.dd_sock = -1; 20102654012fSReza Sabdar } 2011*a23888a3SJan Kryl (void) cond_broadcast(&nlp->nlp_cv); 2012*a23888a3SJan Kryl (void) mutex_unlock(&nlp->nlp_mtx); 20132654012fSReza Sabdar ndmp_stop_writer_thread(nlp->nlp_session); 20142654012fSReza Sabdar } 20152654012fSReza Sabdar 20162654012fSReza Sabdar return (0); 20172654012fSReza Sabdar } 2018