Skip to content

Commit

Permalink
Fix some logic errors in NDMP backup and restore.
Browse files Browse the repository at this point in the history
We still have a problem when you restore two NDMP streams
part of one backup. The solution for now is to first restore
the first full backup and then the second one.
  • Loading branch information
Marco van Wieringen committed Feb 17, 2015
1 parent f040d5c commit c816eb6
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
34 changes: 29 additions & 5 deletions src/dird/ndmp_dma.c
Expand Up @@ -691,11 +691,15 @@ static inline bool fill_restore_environment(JCR *jcr,
return false;
}

Mmsg(destination_path, "%s/%s", restore_prefix, restore_pathname + 7);

/*
* Tell the data engine where to restore.
*/
if (strlen(restore_prefix) == 1 && *restore_prefix == '/') {
pm_strcpy(destination_path, restore_pathname + 6);
} else {
pm_strcpy(destination_path, restore_prefix);
pm_strcat(destination_path, restore_pathname + 6);
}
pv.name = ndmp_env_keywords[NDMP_ENV_KW_PREFIX];
pv.value = destination_path.c_str();
ndma_store_env_list(&job->env_tab, &pv);
Expand Down Expand Up @@ -1264,10 +1268,10 @@ bool do_ndmp_backup(JCR *jcr)
/*
* See if this is the first Backup run or not. For NDMP we can have multiple Backup
* runs as part of the same Job. When we are saving data to a Native Storage Daemon
* we let it know to expect a new backup session. It will generate a new authentication
* id so we wait for the nextrun_ready conditional variable to be raised by the msg_thread.
* we let it know to expect a new backup session. It will generate a new authorization
* key so we wait for the nextrun_ready conditional variable to be raised by the msg_thread.
*/
if (jcr->store_bsock && j > 0) {
if (jcr->store_bsock && cnt > 0) {
jcr->store_bsock->fsend("nextrun");
P(mutex);
pthread_cond_wait(&jcr->nextrun_ready, &mutex);
Expand Down Expand Up @@ -1616,6 +1620,7 @@ static inline int ndmp_wait_for_job_termination(JCR *jcr)
*/
static inline bool do_ndmp_restore_bootstrap(JCR *jcr)
{
int cnt;
BSOCK *sd;
BSR *bsr;
BSR_FINDEX *fileindex;
Expand Down Expand Up @@ -1715,8 +1720,22 @@ static inline bool do_ndmp_restore_bootstrap(JCR *jcr)
* Walk each fileindex of the current BSR record. Each different fileindex is
* a seperate NDMP stream.
*/
cnt = 0;
for (fileindex = bsr->FileIndex; fileindex; fileindex = fileindex->next) {
for (current_fi = fileindex->findex; current_fi <= fileindex->findex2; current_fi++) {
/*
* See if this is the first Restore NDMP stream or not. For NDMP we can have multiple Backup
* runs as part of the same Job. When we are restoring data from a Native Storage Daemon
* we let it know to expect a next restore session. It will generate a new authorization
* key so we wait for the nextrun_ready conditional variable to be raised by the msg_thread.
*/
if (jcr->store_bsock && cnt > 0) {
jcr->store_bsock->fsend("nextrun");
P(mutex);
pthread_cond_wait(&jcr->nextrun_ready, &mutex);
V(mutex);
}

/*
* Perform the actual NDMP job.
* Initialize a new NDMP session
Expand Down Expand Up @@ -1824,6 +1843,11 @@ static inline bool do_ndmp_restore_bootstrap(JCR *jcr)
* Reset the initialized state so we don't try to cleanup again.
*/
session_initialized = false;

/*
* Keep track that we finished this part of the restore.
*/
cnt++;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/stored/dir_cmd.c
Expand Up @@ -163,7 +163,7 @@ static struct s_cmds cmds[] = {
{ "label", label_cmd, false }, /* Label a tape */
{ "listen", listen_cmd, false }, /* Listen for an incoming Storage Job */
{ "mount", mount_cmd, false },
{ "nextrun", nextrun_cmd, false }, /* Prepare for next backup part of same Job */
{ "nextrun", nextrun_cmd, false }, /* Prepare for next backup/restore part of same Job */
{ "passive", passive_cmd, false },
// { "query", query_cmd, false },
{ "readlabel", readlabel_cmd, false },
Expand Down

0 comments on commit c816eb6

Please sign in to comment.