/* * check_restore_paths * * Go through the restore list and check the validity of the * restore path. */ static int check_restore_paths(ndmpd_module_params_t *params, int n, char *rspath) { int i, rv; ndmp_name *ent; rv = 0; if (rspath != NULL && *rspath != '\0') { NDMP_LOG(LOG_DEBUG, "rspath: \"%s\"", rspath); if (!fs_volexist(rspath)) { MOD_LOG(params, "Error: Invalid volume name for restore."); rv = -1; } } else { for (i = 0; i < n; i++) { ent = (ndmp_name *)MOD_GETNAME(params, i); NDMP_LOG(LOG_DEBUG, "ent[%d].name: \"%s\"", i, ent->name); if (!fs_volexist(ent->name)) { MOD_LOG(params, "Error: Invalid volume name for restore.", ent->name); rv = -1; break; } } } return (rv); }
/* * ndmp_send_recovery_stat_v3 * * Send the recovery status to the DMA */ int ndmp_send_recovery_stat_v3(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp, int idx, int stat) { int rv; mem_ndmp_name_v3_t *ep; rv = -1; if (!params) { syslog(LOG_DEBUG, "params == NULL"); } else if (!params->mp_file_recovered_func) { syslog(LOG_DEBUG, "paramsfile_recovered_func == NULL"); } else if (!nlp) { syslog(LOG_DEBUG, "nlp == NULL"); } else if (idx < 0) { syslog(LOG_DEBUG, "idx(%d) < 0", idx); } else if (!(ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, idx))) { syslog(LOG_DEBUG, "nlist[%d] == NULL", idx); } else if (!ep->nm3_opath) { syslog(LOG_DEBUG, "nlist[%d].nm3_opath == NULL", idx); } else { syslog(LOG_DEBUG, "ep[%d].nm3_opath \"%s\"", idx, ep->nm3_opath); rv = MOD_FILERECOVERD(params, ep->nm3_opath, stat); } return (rv); }
/* * get_restore_dest * * Get the full pathname of where the entries should be restored to. */ static char * get_restore_dest(ndmpd_module_params_t *params) { ndmp_name *ent; char *cp; /* * Destination of restore: * NetBackup of Veritas(C) sends the entries like this: * * ent[i].name: is the relative pathname of what is selected in * the GUI. * ent[i].dest: is the full pathname of where the dir/file must * be restored to. * ent[i].ssi: 0 * ent[i].fh_info: 0 * */ ent = (ndmp_name *)MOD_GETNAME(params, 0); cp = prefixdir(ent->dest, ent->name); if (cp == NULL) { MOD_LOG(params, "Error: empty restore path.\n"); return (NULL); } return (cp); }
/* * correct_ents * * Correct the entries in the restore list by appending the appropriate * path to them */ static int correct_ents(ndmpd_module_params_t *params, int n, char *bkpath) { char *cp, *pathname; int i, len, rv; ndmp_name *ent; if ((pathname = ndmp_malloc(TLM_MAX_PATH_NAME)) == NULL) { MOD_LOG(params, "Error: insufficient memory.\n"); return (-1); } rv = 0; /* Append the backup path to all the "ent[].name"s. */ for (i = 0; i < n; i++) { ent = (ndmp_name *)MOD_GETNAME(params, i); NDMP_LOG(LOG_DEBUG, "Old: ent[%d].name: \"%s\"", i, ent->name); NDMP_LOG(LOG_DEBUG, "Old: ent[%d].dest: \"%s\"", i, ent->dest); /* remove trailing slash */ len = strlen(ent->name); if (ent->name[len - 1] == '/') ent->name[len - 1] = '\0'; if (!tlm_cat_path(pathname, bkpath, ent->name)) { MOD_LOG(params, "Error: path too long.\n"); rv = -1; break; } /* Make a copy of the new string and save it in ent->name. */ cp = strdup(pathname); if (cp == NULL) { MOD_LOG(params, "Error: insufficient memory.\n"); rv = -1; break; } free(ent->name); ent->name = cp; NDMP_LOG(LOG_DEBUG, "New: ent[%d].name: \"%s\"", i, ent->name); } free(pathname); return (rv); }
/*ARGSUSED*/ int ndmpd_path_restored(lbr_fhlog_call_backs_t *cbp, char *name, struct stat64 *stp, u_longlong_t ll_pos) { int rv; ndmp_name *entp; ndmp_lbr_params_t *nlp; ndmpd_module_params_t *params; int pos = (int)ll_pos; if (cbp == NULL) { syslog(LOG_DEBUG, "cbp is NULL"); return (-1); } if (name == NULL) { syslog(LOG_DEBUG, "name is NULL"); return (-1); } if ((nlp = ndmp_get_nlp(cbp->fh_cookie)) == NULL) { syslog(LOG_DEBUG, "nlp is NULL"); return (-1); } if (pos < 0 || pos >= nlp->nlp_nfiles) { syslog(LOG_DEBUG, "Invalid pos: %d", pos); return (-1); } params = get_params(cbp->fh_cookie); if (params == NULL || params->mp_file_recovered_func == NULL) return (-1); rv = 0; if (!nlp->nlp_restored[pos]) { entp = (ndmp_name *)MOD_GETNAME(params, pos); if (entp && entp->name) name = entp->name; if ((rv = MOD_FILERECOVERD(params, name, 0)) >= 0) nlp->nlp_restored[pos] = TRUE; } return (rv); }
/* * send_unrecovered_list * * Creates a list of restored files * * Parameters: * params (input) - NDMP parameters * nlp (input) - NDMP/LBR parameters * * Returns: * 0: on success * -1: otherwise */ static int send_unrecovered_list(ndmpd_module_params_t *params, ndmp_lbr_params_t *nlp) { int i, rv; ndmp_name *ent; if (params == NULL) { NDMP_LOG(LOG_DEBUG, "params == NULL"); return (-1); } if (nlp == NULL) { NDMP_LOG(LOG_DEBUG, "nlp == NULL"); return (-1); } rv = 0; for (i = 0; i < (int)nlp->nlp_nfiles; i++) { NDMP_LOG(LOG_DEBUG, "nlp->nlp_restored[%d]: %s", i, nlp->nlp_restored[i] ? "TRUE" : "FALSE"); if (!nlp->nlp_restored[i]) { ent = (ndmp_name *)MOD_GETNAME(params, i); if (ent == NULL) { NDMP_LOG(LOG_DEBUG, "ent == NULL"); rv = -1; break; } if (ent->name == NULL) { NDMP_LOG(LOG_DEBUG, "ent->name == NULL"); rv = -1; break; } NDMP_LOG(LOG_DEBUG, "ent.name: \"%s\"", ent->name); rv = MOD_FILERECOVERD(params, ent->name, ENOENT); if (rv < 0) break; } } return (rv); }
/* * ndmpd_tar_restore * * Restore function that launches TAR reader thread to read from the * tape and writes the extracted files/dirs to the filesystem */ static int ndmpd_tar_restore(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, ndmp_lbr_params_t *nlp) { char jname[TLM_MAX_BACKUP_JOB_NAME]; char *rspath; int err; tlm_commands_t *cmds; ndmp_tar_reader_arg_t arg; tlm_backup_restore_arg_t tlm_arg; ndmp_name *ent; pthread_t rdtp, wrtp; int i; if (mod_params->mp_operation != NDMP_DATA_OP_RECOVER) { NDMP_LOG(LOG_DEBUG, "mod_params->mp_operation != NDMP_DATA_OP_RECOVER"); return (-1); } if (nlp->nlp_restore_path[0] != '\0') rspath = nlp->nlp_restore_path; else if (nlp->nlp_restore_bk_path[0] != '\0') rspath = nlp->nlp_restore_bk_path; else rspath = ""; (void) ndmp_new_job_name(jname); if (restore_create_structs(session, jname) < 0) return (-1); nlp->nlp_jstat->js_start_ltime = time(NULL); nlp->nlp_jstat->js_start_time = time(NULL); if (!session->ns_data.dd_abort) { cmds = &nlp->nlp_cmds; cmds->tcs_reader = cmds->tcs_writer = TLM_RESTORE_RUN; cmds->tcs_command->tc_reader = TLM_RESTORE_RUN; cmds->tcs_command->tc_writer = TLM_RESTORE_RUN; NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" started.", rspath); NDMP_LOG(LOG_DEBUG, "Restoring from %s tape(s).", ndmp_data_get_mover_mode(session)); arg.tr_session = session; arg.tr_mod_params = mod_params; arg.tr_cmds = cmds; err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader, (void *)&arg); if (err == 0) { tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER); } else { NDMP_LOG(LOG_DEBUG, "Launch ndmp_tar_reader: %m"); return (-1); } if (!ndmp_check_utf8magic(cmds->tcs_command)) { NDMP_LOG(LOG_DEBUG, "UTF8Magic not found!"); } else { NDMP_LOG(LOG_DEBUG, "UTF8Magic found"); } (void) memset(&tlm_arg, 0, sizeof (tlm_backup_restore_arg_t)); (void) pthread_barrier_init(&tlm_arg.ba_barrier, 0, 2); /* * Set up restore parameters */ tlm_arg.ba_commands = cmds; tlm_arg.ba_cmd = cmds->tcs_command; tlm_arg.ba_job = nlp->nlp_jstat->js_job_name; tlm_arg.ba_dir = nlp->nlp_restore_path; for (i = 0; i < nlp->nlp_nfiles; i++) { ent = (ndmp_name *)MOD_GETNAME(mod_params, i); tlm_arg.ba_sels[i] = ent->name; } if (tm_tar_ops.tm_getfile != NULL) { err = pthread_create(&wrtp, NULL, (funct_t)tm_tar_ops.tm_getfile, (void *)&tlm_arg); } else { (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); NDMP_LOG(LOG_DEBUG, "Thread create tm_getfile: ops NULL"); return (-1); } if (err == 0) { (void) pthread_barrier_wait(&tlm_arg.ba_barrier); } else { (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); NDMP_LOG(LOG_DEBUG, "thread create tm_getfile: %m"); return (-1); } (void) pthread_join(rdtp, NULL); (void) pthread_join(wrtp, NULL); (void) pthread_barrier_destroy(&tlm_arg.ba_barrier); nlp->nlp_jstat->js_stop_time = time(NULL); /* Send the list of un-recovered files/dirs to the client. */ (void) send_unrecovered_list(mod_params, nlp); ndmp_stop_local_reader(session, cmds); ndmp_wait_for_reader(cmds); ndmp_stop_remote_reader(session); NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" finished. (%d)", rspath, err); } else { nlp->nlp_jstat->js_stop_time = time(NULL); /* nothing restored. */ (void) send_unrecovered_list(mod_params, nlp); NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" aborted.", rspath); err = -1; } NDMP_FREE(nlp->nlp_restore_path); backup_release_structs(session); return (err); }