int jndex_merge_environment (void) { struct ndm_env_entry * entry; for (entry = ji_environment.head; entry; entry = entry->next) { ndma_store_env_list (&E_environment, &entry->pval); } return 0; }
int jndex_fetch_post_backup_data_env (FILE *fp) { int rc; char buf[512]; char * p; char * q; ndmp9_pval pv; rc = ndmbstf_first (fp, "DE ", buf, sizeof buf); if (rc <= 0) { return rc; /* error or not found */ } /* DE HIST=Yes */ while (buf[0] == 'D' && buf[1] == 'E' && buf[2] == ' ') { if (ji_environment.n_env >= NDM_MAX_ENV) { goto overflow; } p = &buf[2]; while (*p == ' ') p++; if (!strchr (p, '=')) { goto malformed; } q = strchr (p, '='); if (!q) { goto malformed; } *q++ = 0; pv.name = p; pv.value = q; ndma_store_env_list (&ji_environment, &pv); rc = ndmbstf_getline (fp, buf, sizeof buf); if (rc <= 0) { break; } continue; malformed: ndmjob_log (1, "Malformed in -J%s: %s", J_index_file, buf); continue; overflow: ndmjob_log (1, "Overflow in -J%s: %s", J_index_file, buf); } return 0; }
/* * Database handler that handles the returned environment data for a given JobId. */ static int ndmp_env_handler(void *ctx, int num_fields, char **row) { struct ndm_env_table *envtab; ndmp9_pval pv; if (row[0] && row[1]) { envtab = (struct ndm_env_table *)ctx; pv.name = row[0]; pv.value = row[1]; ndma_store_env_list(envtab, &pv); } return 0; }
/* * Update an entry in an environment list table. * If it doesn't exist add a new entry. * Return entry if caller want to modify it. */ struct ndm_env_entry * ndma_update_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv) { struct ndm_env_entry * entry; for (entry = envtab->head; entry; entry = entry->next) { if (strcmp(entry->pval.name, pv->name) == 0) { NDMOS_API_FREE (entry->pval.value); entry->pval.value = NDMOS_API_STRDUP (pv->value); return entry; } } return ndma_store_env_list (envtab, pv); }
int ndmda_copy_environment (struct ndm_session *sess, ndmp9_pval *env, unsigned n_env) { struct ndm_data_agent * da = sess->data_acb; unsigned int i; for (i = 0; i < n_env; i++) { if (!ndma_store_env_list (&da->env_tab, &env[i])) goto fail; } return 0; fail: ndma_destroy_env_list (&da->env_tab); return -1; }
int args_to_job_backup_env (void) { ndmp9_pval pv; int i; if (C_chdir) { pv.name = "FILESYSTEM"; pv.value = C_chdir; ndma_store_env_list (&E_environment, &pv); } pv.name = "HIST"; pv.value = I_index_file ? "y" : "n"; ndma_store_env_list (&E_environment, &pv); pv.name = "TYPE"; pv.value = B_bu_type; ndma_store_env_list (&E_environment, &pv); if (U_user) { pv.name = "USER"; pv.value = U_user; ndma_store_env_list (&E_environment, &pv); } for (i = 0; (i < n_e_exclude_pattern); i++) { pv.name = "EXCLUDE"; pv.value = e_exclude_pattern[i]; ndma_store_env_list (&E_environment, &pv); } for (i = 0; (i < n_file_arg); i++) { pv.name = "FILES"; pv.value = file_arg[i]; ndma_store_env_list (&E_environment, &pv); } if (o_rules) { pv.name = "RULES"; pv.value = o_rules; ndma_store_env_list (&E_environment, &pv); } return E_environment.n_env; }
int args_to_job_recover_env (void) { ndmp9_pval pv; int i; if (C_chdir) { pv.name = "PREFIX"; pv.value = C_chdir; ndma_store_env_list (&E_environment, &pv); } pv.name = "HIST"; pv.value = I_index_file ? "y" : "n"; ndma_store_env_list (&E_environment, &pv); pv.name = "TYPE"; pv.value = B_bu_type; ndma_store_env_list (&E_environment, &pv); if (U_user) { pv.name = "USER"; pv.value = U_user; ndma_store_env_list (&E_environment, &pv); } for (i = 0; i < n_e_exclude_pattern; i++) { pv.name = "EXCLUDE"; pv.value = e_exclude_pattern[i]; ndma_store_env_list (&E_environment, &pv); } if (o_rules) { pv.name = "RULES"; pv.value = o_rules; ndma_store_env_list (&E_environment, &pv); } /* file_arg[]s are done in nlist[] */ jndex_merge_environment (); return E_environment.n_env; }
/* * Fill the NDMP restore environment table with the data for the data agent to act on. */ static inline bool fill_restore_environment(JCR *jcr, int32_t current_fi, struct ndm_job_param *job) { int i; char *bp; ndmp9_pval pv; FILESETRES *fileset; char *restore_pathname, *ndmp_filesystem, *restore_prefix, *level; POOL_MEM tape_device; POOL_MEM destination_path; ndmp_backup_format_option *nbf_options; /* * See if we know this backup format and get it options. */ nbf_options = ndmp_lookup_backup_format_options(job->bu_type); /* * Lookup the current fileindex and map it to an actual pathname. */ restore_pathname = lookup_fileindex(jcr, current_fi); if (!restore_pathname) { return false; } else { /* * Skip over the /@NDMP prefix. */ ndmp_filesystem = restore_pathname + 6; } /* * See if there is a level embedded in the pathname. */ bp = strrchr(ndmp_filesystem, '%'); if (bp) { *bp++ = '\0'; level = bp; } else { level = NULL; } /* * Lookup the environment stack saved during the backup so we can restore it. */ if (!db_get_ndmp_environment_string(jcr, jcr->db, &jcr->jr, ndmp_env_handler, &job->env_tab)) { /* * Fallback code try to build a environment stack that is good enough to * restore this NDMP backup. This is used when the data is not available in * the database when its either expired or when an old NDMP backup is restored * where the whole environment was not saved. */ if (!nbf_options || nbf_options->uses_file_history) { /* * We asked during the NDMP backup to receive file history info. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_HIST]; pv.value = ndmp_env_values[NDMP_ENV_VALUE_YES]; ndma_store_env_list(&job->env_tab, &pv); } /* * Tell the data agent what type of restore stream to expect. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_TYPE]; pv.value = job->bu_type; ndma_store_env_list(&job->env_tab, &pv); /* * Tell the data agent that this is a NDMP backup which uses a level indicator. */ if (level) { pv.name = ndmp_env_keywords[NDMP_ENV_KW_LEVEL]; pv.value = level; ndma_store_env_list(&job->env_tab, &pv); } /* * Tell the data engine what was backuped. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_FILESYSTEM]; pv.value = ndmp_filesystem; ndma_store_env_list(&job->env_tab, &pv); } /* * Lookup any meta tags that need to be added. */ fileset = jcr->res.fileset; for (i = 0; i < fileset->num_includes; i++) { int j; char *item; INCEXE *ie = fileset->include_items[i]; /* * Loop over each file = entry of the fileset. */ for (j = 0; j < ie->name_list.size(); j++) { item = (char *)ie->name_list.get(j); /* * See if the original path matches. */ if (bstrcasecmp(item, ndmp_filesystem)) { int k, l; FOPTS *fo; for (k = 0; k < ie->num_opts; k++) { fo = ie->opts_list[i]; /* * Parse all specific META tags for this option block. */ for (l = 0; l < fo->meta.size(); l++) { ndmp_parse_meta_tag(&job->env_tab, (char *)fo->meta.get(l)); } } } } } /* * See where to restore the data. */ restore_prefix = NULL; if (jcr->where) { restore_prefix = jcr->where; } else { restore_prefix = jcr->res.job->RestoreWhere; } if (!restore_prefix) { return false; } /* * Tell the data engine where to restore. */ if (nbf_options && nbf_options->restore_prefix_relative) { switch (*restore_prefix) { case '^': /* * Use the restore_prefix as an absolute restore prefix. * We skip the leading ^ that is the trigger for absolute restores. */ pm_strcpy(destination_path, restore_prefix + 1); break; default: /* * Use the restore_prefix as an relative restore prefix. */ if (strlen(restore_prefix) == 1 && *restore_prefix == '/') { pm_strcpy(destination_path, ndmp_filesystem); } else { pm_strcpy(destination_path, ndmp_filesystem); pm_strcat(destination_path, restore_prefix); } } } else { if (strlen(restore_prefix) == 1 && *restore_prefix == '/') { /* * Use the original pathname as restore prefix. */ pm_strcpy(destination_path, ndmp_filesystem); } else { /* * Use the restore_prefix as an absolute restore prefix. */ pm_strcpy(destination_path, restore_prefix); } } pv.name = ndmp_env_keywords[NDMP_ENV_KW_PREFIX]; pv.value = ndmp_filesystem; ndma_store_env_list(&job->env_tab, &pv); if (!nbf_options || nbf_options->needs_namelist) { if (set_files_to_restore(jcr, job, current_fi, destination_path.c_str(), ndmp_filesystem) == 0) { /* * There is no specific filename selected so restore everything. */ add_to_namelist(job, (char *)"", destination_path.c_str(), (char *)"", (char *)"", NDMP_INVALID_U_QUAD); } } /* * If we have a paired storage definition we put the storage daemon * auth key and the filesystem into the tape device name of the * NDMP session. This way the storage daemon can link the NDMP * data and the normal save session together. */ if (jcr->store_bsock) { Mmsg(tape_device, "%s@%s", jcr->sd_auth_key, restore_pathname + 6); job->tape_device = bstrdup(tape_device.c_str()); } free(restore_pathname); return true; }