/*
Bacula® - The Network Backup Solution
- Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2002-2010 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*
* Kern Sibbald, July MMII
*
- * Version $Id$
*/
#include "bacula.h"
if (bsr->VolParams) {
free(bsr->VolParams);
}
+ if (bsr->fileregex) {
+ free(bsr->fileregex);
+ }
next = bsr->next;
free(bsr);
}
}
bsr->VolSessionId = jr.VolSessionId;
bsr->VolSessionTime = jr.VolSessionTime;
+ if (jr.JobFiles == 0) { /* zero files is OK, not an error, but */
+ bsr->VolCount = 0; /* there are no volumes */
+ continue;
+ }
if ((bsr->VolCount=db_get_job_volume_parameters(ua->jcr, ua->db, bsr->JobId,
&(bsr->VolParams))) == 0) {
ua->error_msg(_("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db));
return count;
}
-void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
+static void display_vol_info(UAContext *ua, RESTORE_CTX &rx, JobId_t JobId)
{
- char *p;
POOL_MEM volmsg(PM_MESSAGE);
- JobId_t JobId;
char Device[MAX_NAME_LENGTH];
+ char online;
RBSR *bsr;
+ for (bsr=rx.bsr; bsr; bsr=bsr->next) {
+ if (JobId && JobId != bsr->JobId) {
+ continue;
+ }
+
+ for (int i=0; i < bsr->VolCount; i++) {
+ if (bsr->VolParams[i].VolumeName[0]) {
+ if (!get_storage_device(Device, bsr->VolParams[i].Storage)) {
+ Device[0] = 0;
+ }
+ if (bsr->VolParams[i].InChanger && bsr->VolParams[i].Slot) {
+ online = '*';
+ } else {
+ online = ' ';
+ }
+ Mmsg(volmsg, "%c%-25s %-25s %-25s",
+ online, bsr->VolParams[i].VolumeName,
+ bsr->VolParams[i].Storage, Device);
+ add_prompt(ua, volmsg.c_str());
+ }
+ }
+ }
+}
+
+void display_bsr_info(UAContext *ua, RESTORE_CTX &rx)
+{
+ char *p;
+ JobId_t JobId;
+
/* Tell the user what he will need to mount */
ua->send_msg("\n");
ua->send_msg(_("The job will require the following\n"
start_prompt(ua, "");
if (*rx.JobIds == 0) {
/* Print Volumes in any order */
- for (bsr=rx.bsr; bsr; bsr=bsr->next) {
- for (int i=0; i < bsr->VolCount; i++) {
- if (bsr->VolParams[i].VolumeName[0]) {
- if (!get_storage_device(Device, bsr->VolParams[i].Storage)) {
- Device[0] = 0;
- }
- Mmsg(volmsg, "%-25.25s %-25.25s %-25.25s",
- bsr->VolParams[i].VolumeName,
- bsr->VolParams[i].Storage, Device);
- add_prompt(ua, volmsg.c_str());
- }
- }
- }
+ display_vol_info(ua, rx, 0);
} else {
/* Ensure that the volumes are printed in JobId order */
for (p=rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) {
- for (bsr=rx.bsr; bsr; bsr=bsr->next) {
- if (JobId != bsr->JobId) {
- continue;
- }
- for (int i=0; i < bsr->VolCount; i++) {
- if (bsr->VolParams[i].VolumeName[0]) {
- if (!get_storage_device(Device, bsr->VolParams[i].Storage)) {
- Device[0] = 0;
- }
- Mmsg(volmsg, "%-25.25s %-25.25s %-25.25s",
- bsr->VolParams[i].VolumeName,
- bsr->VolParams[i].Storage, Device);
- add_prompt(ua, volmsg.c_str());
- }
- }
- }
+ display_vol_info(ua, rx, JobId);
}
}
for (int i=0; i < ua->num_prompts; i++) {
}
if (ua->num_prompts == 0) {
ua->send_msg(_("No Volumes found to restore.\n"));
+ } else {
+ ua->send_msg(_("\nVolumes marked with \"*\" are online.\n"));
}
ua->num_prompts = 0;
ua->send_msg("\n");
return;
}
+/*
+ * Write bsr data for a single bsr record
+ */
+static uint32_t write_bsr_item(RBSR *bsr, UAContext *ua,
+ RESTORE_CTX &rx, FILE *fd, bool &first, uint32_t &LastIndex)
+{
+ char ed1[50], ed2[50];
+ uint32_t count = 0;
+ uint32_t total_count = 0;
+ char device[MAX_NAME_LENGTH];
+
+ /*
+ * For a given volume, loop over all the JobMedia records.
+ * VolCount is the number of JobMedia records.
+ */
+ for (int i=0; i < bsr->VolCount; i++) {
+ if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
+ bsr->VolParams[i].LastIndex)) {
+ bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */
+ continue;
+ }
+ if (!rx.store) {
+ find_storage_resource(ua, rx, bsr->VolParams[i].Storage,
+ bsr->VolParams[i].MediaType);
+ }
+ fprintf(fd, "Storage=\"%s\"\n", bsr->VolParams[i].Storage);
+ fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+ fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
+ if (bsr->fileregex) {
+ fprintf(fd, "FileRegex=%s\n", bsr->fileregex);
+ }
+ if (get_storage_device(device, bsr->VolParams[i].Storage)) {
+ fprintf(fd, "Device=\"%s\"\n", device);
+ }
+ if (bsr->VolParams[i].Slot > 0) {
+ fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
+ }
+ fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
+ fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
+ fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
+ edit_uint64(bsr->VolParams[i].EndAddr, ed2));
+// Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
+// bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
+
+ count = write_findex(bsr->fi, bsr->VolParams[i].FirstIndex,
+ bsr->VolParams[i].LastIndex, fd);
+ if (count) {
+ fprintf(fd, "Count=%u\n", count);
+ }
+ total_count += count;
+ /* If the same file is present on two tapes or in two files
+ * on a tape, it is a continuation, and should not be treated
+ * twice in the totals.
+ */
+ if (!first && LastIndex == bsr->VolParams[i].FirstIndex) {
+ total_count--;
+ }
+ first = false;
+ LastIndex = bsr->VolParams[i].LastIndex;
+ }
+ return total_count;
+}
+
+
/*
* Here we actually write out the details of the bsr file.
* Note, there is one bsr for each JobId, but the bsr may
*/
static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd)
{
- char ed1[50], ed2[50];
- uint32_t count = 0;
- uint32_t total_count = 0;
- uint32_t LastIndex = 0;
bool first = true;
+ uint32_t LastIndex = 0;
+ uint32_t total_count = 0;
char *p;
JobId_t JobId;
- char device[MAX_NAME_LENGTH];
RBSR *bsr;
if (*rx.JobIds == 0) {
for (bsr=rx.bsr; bsr; bsr=bsr->next) {
- /*
- * For a given volume, loop over all the JobMedia records.
- * VolCount is the number of JobMedia records.
- */
- for (int i=0; i < bsr->VolCount; i++) {
- if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
- bsr->VolParams[i].LastIndex)) {
- bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */
- continue;
- }
- if (!rx.store) {
- find_storage_resource(ua, rx, bsr->VolParams[i].Storage,
- bsr->VolParams[i].MediaType);
- }
- fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
- fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
- if (bsr->fileregex) {
- fprintf(fd, "FileRegex=%s\n", bsr->fileregex);
- }
- if (get_storage_device(device, bsr->VolParams[i].Storage)) {
- fprintf(fd, "Device=\"%s\"\n", device);
- }
- if (bsr->VolParams[i].Slot > 0) {
- fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
- }
- fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
- fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-// if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-// fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-// } else {
-// fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-// bsr->VolParams[i].EndFile);
-// }
-// if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-// fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-// } else {
-// fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-// bsr->VolParams[i].EndBlock);
-// }
- fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
- edit_uint64(bsr->VolParams[i].EndAddr, ed2));
- // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
- // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
-
- count = write_findex(bsr->fi, bsr->VolParams[i].FirstIndex,
- bsr->VolParams[i].LastIndex, fd);
- if (count) {
- fprintf(fd, "Count=%u\n", count);
- }
- total_count += count;
- /* If the same file is present on two tapes or in two files
- * on a tape, it is a continuation, and should not be treated
- * twice in the totals.
- */
- if (!first && LastIndex == bsr->VolParams[i].FirstIndex) {
- total_count--;
- }
- first = false;
- LastIndex = bsr->VolParams[i].LastIndex;
- }
+ total_count += write_bsr_item(bsr, ua, rx, fd, first, LastIndex);
}
return total_count;
}
for (p=rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) {
for (bsr=rx.bsr; bsr; bsr=bsr->next) {
- if (JobId != bsr->JobId) {
- continue;
- }
- /*
- * For a given volume, loop over all the JobMedia records.
- * VolCount is the number of JobMedia records.
- */
- for (int i=0; i < bsr->VolCount; i++) {
- if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
- bsr->VolParams[i].LastIndex)) {
- bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */
- continue;
- }
- if (!rx.store) {
- find_storage_resource(ua, rx, bsr->VolParams[i].Storage,
- bsr->VolParams[i].MediaType);
- }
- fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
- fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
- if (bsr->fileregex) {
- fprintf(fd, "FileRegex=%s\n", bsr->fileregex);
- }
- if (get_storage_device(device, bsr->VolParams[i].Storage)) {
- fprintf(fd, "Device=\"%s\"\n", device);
- }
- if (bsr->VolParams[i].Slot > 0) {
- fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
- }
- fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
- fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-// if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-// fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-// } else {
-// fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-// bsr->VolParams[i].EndFile);
-// }
-// if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-// fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-// } else {
-// fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-// bsr->VolParams[i].EndBlock);
-// }
- fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
- edit_uint64(bsr->VolParams[i].EndAddr, ed2));
- // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
- // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
-
- count = write_findex(bsr->fi, bsr->VolParams[i].FirstIndex,
- bsr->VolParams[i].LastIndex, fd);
- if (count) {
- fprintf(fd, "Count=%u\n", count);
- }
- total_count += count;
- /* If the same file is present on two tapes or in two files
- * on a tape, it is a continuation, and should not be treated
- * twice in the totals.
- */
- if (!first && LastIndex == bsr->VolParams[i].FirstIndex) {
- total_count--;
- }
- first = false;
- LastIndex = bsr->VolParams[i].LastIndex;
+ if (JobId == bsr->JobId) {
+ total_count += write_bsr_item(bsr, ua, rx, fd, first, LastIndex);
}
}
}
/* Add new JobId at end of chain */
for (nbsr=bsr; nbsr->next; nbsr=nbsr->next)
{ }
+
nbsr->next = new_bsr();
nbsr->next->JobId = JobId;
+
+ /* If we use regexp to restore, set it for each jobid */
+ if (bsr->fileregex) {
+ nbsr->next->fileregex = bstrdup(bsr->fileregex);
+ }
+
nbsr->next->fi = new_findex();
nbsr->next->fi->findex = 1;
nbsr->next->fi->findex2 = INT32_MAX;