- multiple simultaneous Volumes
For 1.30 release:
-- Change stat1= fgets()!=NULL to stat1=fgest()==NULL; in
- run_program -- bpipe.c
+- Add chflags() code for FreeBSD file flags
- Add RunBeforeJob and RunAfterJob to the Client program.
- Have SD compute MD5 or SHA1 and compare to what FD computes.
- Make VolumeToCatalog calculate an MD5 or SHA1 from the
- Implement multiple simultaneous file Volumes on a single device.
- Cleanup db_update_media and db_update_pool
- Flush all the daemon messages at the end of every job.
+- Change stat1= fgets()!=NULL to stat1=fgest()==NULL; in
+ run_program -- bpipe.c
+
int get_pool_dbr(UAContext *ua, POOL_DBR *pr);
int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
POOL *get_pool_resource(UAContext *ua);
+POOL *select_pool_resource(UAContext *ua);
CLIENT *get_client_resource(UAContext *ua);
int get_job_dbr(UAContext *ua, JOB_DBR *jr);
int runcmd(UAContext *ua, char *cmd)
{
JCR *jcr;
- char *job_name, *level_name, *jid, *store_name;
+ char *job_name, *level_name, *jid, *store_name, *pool_name;
char *where, *fileset_name, *client_name, *bootstrap, *replace;
int i, j, found, opt;
JOB *job = NULL;
STORE *store = NULL;
CLIENT *client = NULL;
FILESET *fileset = NULL;
+ POOL *pool = NULL;
static char *kw[] = {
N_("job"),
N_("jobid"),
N_("fileset"),
N_("level"),
N_("storage"),
+ N_("pool"),
N_("where"),
N_("bootstrap"),
N_("replace"),
level_name = NULL;
jid = NULL;
store_name = NULL;
+ pool_name = NULL;
where = NULL;
client_name = NULL;
fileset_name = NULL;
store_name = ua->argv[i];
found = True;
break;
- case 6: /* where */
+ case 6: /* pool */
+ if (pool_name) {
+ bsendmsg(ua, _("Pool specified twice.\n"));
+ return 1;
+ }
+ pool_name = ua->argv[i];
+ found = True;
+ break;
+ case 7: /* where */
if (where) {
bsendmsg(ua, _("Where specified twice.\n"));
return 1;
where = ua->argv[i];
found = True;
break;
- case 7: /* bootstrap */
+ case 8: /* bootstrap */
if (bootstrap) {
bsendmsg(ua, _("Bootstrap specified twice.\n"));
return 1;
bootstrap = ua->argv[i];
found = True;
break;
- case 8: /* replace */
+ case 9: /* replace */
if (replace) {
bsendmsg(ua, _("Replace specified twice.\n"));
return 1;
return 1;
}
+
+ if (pool_name) {
+ pool = (POOL *)GetResWithName(R_POOL, pool_name);
+ if (!pool) {
+ bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name);
+ pool = get_pool_resource(ua);
+ }
+ } else {
+ pool = job->pool; /* use default */
+ }
+
if (client_name) {
client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
if (!client) {
jcr->store = store;
jcr->client = client;
jcr->fileset = fileset;
+ jcr->pool = pool;
if (where) {
if (jcr->RestoreWhere) {
free(jcr->RestoreWhere);
FileSet: %s\n\
Level: %s\n\
Client: %s\n\
-Storage: %s\n"),
+Storage: %s\n\
+Pool: %s\n"),
jcr->JobType==JT_BACKUP?_("Backup"):_("Verify"),
job->hdr.name,
jcr->fileset->hdr.name,
level_to_str(jcr->JobLevel),
jcr->client->hdr.name,
- jcr->store->hdr.name);
+ jcr->store->hdr.name,
+ NPRT(jcr->pool->hdr.name));
break;
case JT_RESTORE:
if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
add_prompt(ua, _("Job")); /* 2 */
add_prompt(ua, _("FileSet")); /* 3 */
add_prompt(ua, _("Client")); /* 4 */
- if (jcr->JobType == JT_RESTORE) {
+ if (jcr->JobType == JT_BACKUP ||
+ jcr->JobType == JT_VERIFY) {
+ add_prompt(ua, _("Pool")); /* 5 */
+ } else if (jcr->JobType == JT_RESTORE) {
add_prompt(ua, _("Bootstrap")); /* 5 */
add_prompt(ua, _("Where")); /* 6 */
add_prompt(ua, _("Replace")); /* 7 */
}
break;
case 5:
+ if (jcr->JobType == JT_BACKUP ||
+ jcr->JobType == JT_VERIFY) { /* Pool */
+ pool = select_pool_resource(ua);
+ if (pool) {
+ jcr->pool = pool;
+ goto try_again;
+ }
+ break;
+ }
+
/* Bootstrap */
if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
break;
}
+/*
+ * Select a pool resource from prompt list
+ */
+POOL *select_pool_resource(UAContext *ua)
+{
+ char name[MAX_NAME_LENGTH];
+ POOL *pool = NULL;
+
+ start_prompt(ua, _("The defined Pool resources are:\n"));
+ LockRes();
+ while ((pool = (POOL *)GetNextRes(R_POOL, (RES *)pool))) {
+ add_prompt(ua, pool->hdr.name);
+ }
+ UnlockRes();
+ do_prompt(ua, _("Select Pool resource"), name, sizeof(name));
+ pool = (POOL *)GetResWithName(R_POOL, name);
+}
+
+
/*
- * This routine is ONLY used in the create command.
* If you are thinking about using it, you
* probably want to use select_pool_dbr()
* or get_pool_dbr() above.
break;
}
}
- start_prompt(ua, _("The defined Pool resources are:\n"));
- LockRes();
- while ((pool = (POOL *)GetNextRes(R_POOL, (RES *)pool))) {
- add_prompt(ua, pool->hdr.name);
- }
- UnlockRes();
- do_prompt(ua, _("Select Pool resource"), name, sizeof(name));
- pool = (POOL *)GetResWithName(R_POOL, name);
- return pool;
+ return select_pool_resource(ua);
}
/*
LockRes();
for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
- dev = device->dev;
- if (dev) {
+ for (dev=device->dev; dev; dev=dev->next) {
if (dev->state & ST_OPENED) {
if (dev->state & ST_LABEL) {
bnet_fsend(user, _("Device %s is mounted with Volume %s\n"),
job_type_to_str(jcr->JobType), jcr->Job);
}
if (jcr->device) {
- bnet_fsend(user, _("%s %s job %s is using device %s\n"),
+ bnet_fsend(user, _("%s %s job %s is using device %s volume %s\n"),
job_level_to_str(jcr->JobLevel),
job_type_to_str(jcr->JobType),
- jcr->Job, jcr->device->device_name);
+ jcr->Job, jcr->device->device_name,
+ jcr->VolumeName);
sec = time(NULL) - jcr->run_time;
if (sec <= 0) {
sec = 1;
exit(1);
}
printf("Found %d duplicate Filename records.\n", name_list.num_ids);
- if (verbose && yes_no("Print the list? (yes/no): ")) {
+ if (name_list.num_ids && verbose && yes_no("Print the list? (yes/no): ")) {
print_name_list(&name_list);
}
if (fix) {