- Release Notes for Bacula 1.37.35
+ Release Notes for Bacula 1.37.36
- Bacula code: Total files = 420 Total lines = 137,098 (*.h *.c *.in)
+ Bacula code: Total files = 420 Total lines = 137,650 (*.h *.c *.in)
Major Changes:
- There is a new database format that is not compatible
General:
Changes to 1.37.36:
+18Aug05
+- Implement search for exact Volume in reservation before
+ other searches.
+- Fix picking up drive in Dir so that it is not done in
+ the status command.
+- Eliminate double check on "loaded" for autochanger.
17Aug05
- Start coding better reservation algorithm
- Always look for slot for label command.
/* fd_cmds.c */
extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern bool send_include_list(JCR *jcr);
extern bool send_exclude_list(JCR *jcr);
extern bool send_bootstrap_file(JCR *jcr);
extern int get_attributes_and_put_in_catalog(JCR *jcr);
extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
- char *link, char *attr, int stream);
+ char *link, char *attr, int stream);
extern void get_level_since_time(JCR *jcr, char *since, int since_len);
extern int send_run_before_and_after_commands(JCR *jcr);
/* msgchan.c */
extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int start_storage_daemon_job(JCR *jcr, alist *store, int append);
extern int start_storage_daemon_message_thread(JCR *jcr);
extern int bget_dirmsg(BSOCK *bs);
void free_ua_context(UAContext *ua);
/* ua_select.c */
-STORE *select_storage_resource(UAContext *ua);
-JOB *select_job_resource(UAContext *ua);
-JOB *select_restore_job_resource(UAContext *ua);
-CLIENT *select_client_resource(UAContext *ua);
+STORE *select_storage_resource(UAContext *ua);
+JOB *select_job_resource(UAContext *ua);
+JOB *select_restore_job_resource(UAContext *ua);
+CLIENT *select_client_resource(UAContext *ua);
FILESET *select_fileset_resource(UAContext *ua);
-int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-
-void start_prompt(UAContext *ua, const char *msg);
-void add_prompt(UAContext *ua, const char *prompt);
-int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
+bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+
+void start_prompt(UAContext *ua, const char *msg);
+void add_prompt(UAContext *ua, const char *prompt);
+int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
CAT *get_catalog_resource(UAContext *ua);
STORE *get_storage_resource(UAContext *ua, bool use_default);
-int get_media_type(UAContext *ua, char *MediaType, int max_media);
-bool get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+int get_storage_drive(UAContext *ua, STORE *store);
+int get_media_type(UAContext *ua, char *MediaType, int max_media);
+bool 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 get_job_dbr(UAContext *ua, JOB_DBR *jr);
int find_arg_keyword(UAContext *ua, const char **list);
int find_arg(UAContext *ua, const char *keyword);
extern int r_last;
extern struct s_res resources[];
extern char my_name[];
-extern jobq_t job_queue; /* job queue */
+extern jobq_t job_queue; /* job queue */
/* Imported functions */
{ N_("var"), var_cmd, _("does variable expansion")},
{ N_("version"), version_cmd, _("print Director version")},
{ N_("wait"), wait_cmd, _("wait until no jobs are running")},
- };
+ };
#define comsize (sizeof(commands)/sizeof(struct cmdstruct))
/*
}
len = strlen(ua->argk[0]);
- for (i=0; i<comsize; i++) { /* search for command */
+ for (i=0; i<comsize; i++) { /* search for command */
if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) {
- if (!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
- break;
- }
- stat = (*commands[i].func)(ua, cmd); /* go execute command */
- found = true;
- break;
+ if (!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
+ break;
+ }
+ stat = (*commands[i].func)(ua, cmd); /* go execute command */
+ found = true;
+ break;
}
}
if (!found) {
bsendmsg(ua, _("Pool already has maximum volumes = %d\n"), pr.MaxVols);
for (;;) {
if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
- return 1;
- }
- pr.MaxVols = ua->pint32_val;
+ return 1;
+ }
+ pr.MaxVols = ua->pint32_val;
}
}
char buf[100];
bsnprintf(buf, sizeof(buf), _("Enter number of Volumes to create. 0=>fixed name. Max=%d: "), max);
if (!get_pint(ua, buf)) {
- return 1;
+ return 1;
}
num = ua->pint32_val;
if (num < 0 || num > max) {
bsendmsg(ua, _("The number must be between 0 and %d\n"), max);
- continue;
+ continue;
}
break;
}
getVolName:
if (num == 0) {
if (!get_cmd(ua, _("Enter Volume name: "))) {
- return 1;
+ return 1;
}
} else {
if (!get_cmd(ua, _("Enter base volume name: "))) {
- return 1;
+ return 1;
}
}
/* Don't allow | in Volume name because it is the volume separator character */
for (;;) {
if (!get_pint(ua, _("Enter the starting number: "))) {
- return 1;
- }
- startnum = ua->pint32_val;
- if (startnum < 1) {
+ return 1;
+ }
+ startnum = ua->pint32_val;
+ if (startnum < 1) {
bsendmsg(ua, _("Start number must be greater than zero.\n"));
- continue;
- }
- break;
+ continue;
+ }
+ break;
}
} else {
startnum = 1;
if (store && store->autochanger) {
if (!get_pint(ua, _("Enter slot (0 for none): "))) {
- return 1;
+ return 1;
}
Slot = ua->pint32_val;
if (!get_yesno(ua, _("InChanger? yes/no: "))) {
- return 1;
+ return 1;
}
InChanger = ua->pint32_val;
}
Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
if (!db_create_media_record(ua->jcr, ua->db, &mr)) {
bsendmsg(ua, "%s", db_strerror(ua->db));
- return 1;
+ return 1;
}
if (i == startnum) {
- first_id = mr.PoolId;
+ first_id = mr.PoolId;
}
}
pr.NumVols += num;
if (ua->argc != 2) {
if (!get_cmd(ua, _("Turn on or off? "))) {
- return 1;
+ return 1;
}
onoff = ua->cmd;
} else {
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], _("jobid")) == 0) {
- uint32_t JobId;
- if (!ua->argv[i]) {
- break;
- }
- JobId = str_to_int64(ua->argv[i]);
- if (!(jcr=get_jcr_by_id(JobId))) {
+ uint32_t JobId;
+ if (!ua->argv[i]) {
+ break;
+ }
+ JobId = str_to_int64(ua->argv[i]);
+ if (!(jcr=get_jcr_by_id(JobId))) {
bsendmsg(ua, _("JobId %s is not running. Use Job name to cancel inactive jobs.\n"), ua->argv[i]);
- return 1;
- }
- break;
+ return 1;
+ }
+ break;
} else if (strcasecmp(ua->argk[i], _("job")) == 0) {
- if (!ua->argv[i]) {
- break;
- }
- if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) {
+ if (!ua->argv[i]) {
+ break;
+ }
+ if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) {
bsendmsg(ua, _("Warning Job %s is not running. Continuing anyway ...\n"), ua->argv[i]);
- jcr = new_jcr(sizeof(JCR), dird_free_jcr);
- bstrncpy(jcr->Job, ua->argv[i], sizeof(jcr->Job));
- }
- break;
+ jcr = new_jcr(sizeof(JCR), dird_free_jcr);
+ bstrncpy(jcr->Job, ua->argv[i], sizeof(jcr->Job));
+ }
+ break;
}
}
/* If we still do not have a jcr,
- * throw up a list and ask the user to select one.
+ * throw up a list and ask the user to select one.
*/
if (!jcr) {
char buf[1000];
/* Count Jobs running */
foreach_jcr(jcr) {
- if (jcr->JobId == 0) { /* this is us */
- free_jcr(jcr);
- continue;
- }
- free_jcr(jcr);
- njobs++;
+ if (jcr->JobId == 0) { /* this is us */
+ free_jcr(jcr);
+ continue;
+ }
+ free_jcr(jcr);
+ njobs++;
}
if (njobs == 0) {
bsendmsg(ua, _("No Jobs running.\n"));
- return 1;
+ return 1;
}
start_prompt(ua, _("Select Job:\n"));
foreach_jcr(jcr) {
- char ed1[50];
- if (jcr->JobId == 0) { /* this is us */
- free_jcr(jcr);
- continue;
- }
+ char ed1[50];
+ if (jcr->JobId == 0) { /* this is us */
+ free_jcr(jcr);
+ continue;
+ }
bsnprintf(buf, sizeof(buf), _("JobId=%s Job=%s"), edit_int64(jcr->JobId, ed1), jcr->Job);
- add_prompt(ua, buf);
- free_jcr(jcr);
+ add_prompt(ua, buf);
+ free_jcr(jcr);
}
if (do_prompt(ua, _("Job"), _("Choose Job to cancel"), buf, sizeof(buf)) < 0) {
- return 1;
+ return 1;
}
if (njobs == 1) {
if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
- return 1;
- }
+ return 1;
+ }
}
/* NOTE! This increments the ref_count */
sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName);
jcr = get_jcr_by_full_name(JobName);
if (!jcr) {
bsendmsg(ua, _("Job %s not found.\n"), JobName);
- return 1;
+ return 1;
}
}
if (op == POOL_OP_CREATE) {
pr->MaxVols = pool->max_volumes;
pr->NumVols = 0;
- } else { /* update pool */
+ } else { /* update pool */
if (pr->MaxVols != pool->max_volumes) {
- pr->MaxVols = pool->max_volumes;
+ pr->MaxVols = pool->max_volumes;
}
if (pr->MaxVols != 0 && pr->MaxVols < pr->NumVols) {
- pr->MaxVols = pr->NumVols;
+ pr->MaxVols = pr->NumVols;
}
}
pr->LabelType = pool->LabelType;
/*
* Create a pool record from a given Pool resource
* Also called from backup.c
- * Returns: -1 on error
- * 0 record already exists
- * 1 record created
+ * Returns: -1 on error
+ * 0 record already exists
+ * 1 record created
*/
int create_pool(JCR *jcr, B_DB *db, POOL *pool, e_pool_op op)
if (db_get_pool_record(jcr, db, &pr)) {
/* Pool Exists */
if (op == POOL_OP_UPDATE) { /* update request */
- set_pooldbr_from_poolres(&pr, pool, op);
- db_update_pool_record(jcr, db, &pr);
+ set_pooldbr_from_poolres(&pr, pool, op);
+ db_update_pool_record(jcr, db, &pr);
}
- return 0; /* exists */
+ return 0; /* exists */
}
set_pooldbr_from_poolres(&pr, pool, op);
if (!db_create_pool_record(jcr, db, &pr)) {
- return -1; /* error */
+ return -1; /* error */
}
return 1;
}
sockaddr_to_ascii(&(ua->UA_sock->client_addr), buf, sizeof(buf));
client->address = bstrdup(buf);
bsendmsg(ua, _("Client \"%s\" address set to %s\n"),
- client->hdr.name, client->address);
+ client->hdr.name, client->address);
get_out:
UnlockRes();
return 1;
while ((store = (STORE *)GetNextRes(R_STORAGE, (RES *)store))) {
found = 0;
for (j=0; j<i; j++) {
- if (strcmp(unique_store[j]->address, store->address) == 0 &&
- unique_store[j]->SDport == store->SDport) {
- found = 1;
- break;
- }
+ if (strcmp(unique_store[j]->address, store->address) == 0 &&
+ unique_store[j]->SDport == store->SDport) {
+ found = 1;
+ break;
+ }
}
if (!found) {
- unique_store[i++] = store;
+ unique_store[i++] = store;
Dmsg2(140, "Stuffing: %s:%d\n", store->address, store->SDport);
}
}
while ((client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client))) {
found = 0;
for (j=0; j<i; j++) {
- if (strcmp(unique_client[j]->address, client->address) == 0 &&
- unique_client[j]->FDport == client->FDport) {
- found = 1;
- break;
- }
+ if (strcmp(unique_client[j]->address, client->address) == 0 &&
+ unique_client[j]->FDport == client->FDport) {
+ found = 1;
+ break;
+ }
}
if (!found) {
- unique_client[i++] = client;
+ unique_client[i++] = client;
Dmsg2(140, "Stuffing: %s:%d\n", client->address, client->FDport);
}
}
}
if (level < 0) {
if (!get_pint(ua, _("Enter new debug level: "))) {
- return 1;
+ return 1;
}
level = ua->pint32_val;
}
if (i >= 0) {
trace_flag = atoi(ua->argv[i]);
if (trace_flag > 0) {
- trace_flag = 1;
+ trace_flag = 1;
}
}
/* General debug? */
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], "all") == 0) {
- do_all_setdebug(ua, level, trace_flag);
- return 1;
+ do_all_setdebug(ua, level, trace_flag);
+ return 1;
}
if (strcasecmp(ua->argk[i], "dir") == 0 ||
strcasecmp(ua->argk[i], "director") == 0) {
- debug_level = level;
- set_trace(trace_flag);
- return 1;
+ debug_level = level;
+ set_trace(trace_flag);
+ return 1;
}
if (strcasecmp(ua->argk[i], "client") == 0 ||
strcasecmp(ua->argk[i], "fd") == 0) {
- client = NULL;
- if (ua->argv[i]) {
- client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
- if (client) {
- do_client_setdebug(ua, client, level, trace_flag);
- return 1;
- }
- }
- client = select_client_resource(ua);
- if (client) {
- do_client_setdebug(ua, client, level, trace_flag);
- return 1;
- }
+ client = NULL;
+ if (ua->argv[i]) {
+ client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+ if (client) {
+ do_client_setdebug(ua, client, level, trace_flag);
+ return 1;
+ }
+ }
+ client = select_client_resource(ua);
+ if (client) {
+ do_client_setdebug(ua, client, level, trace_flag);
+ return 1;
+ }
}
if (strcasecmp(ua->argk[i], "store") == 0 ||
strcasecmp(ua->argk[i], "storage") == 0 ||
strcasecmp(ua->argk[i], "sd") == 0) {
- store = NULL;
- if (ua->argv[i]) {
- store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
- if (store) {
- do_storage_setdebug(ua, store, level, trace_flag);
- return 1;
- }
- }
- store = get_storage_resource(ua, false/*no default*/);
- if (store) {
- do_storage_setdebug(ua, store, level, trace_flag);
- return 1;
- }
+ store = NULL;
+ if (ua->argv[i]) {
+ store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
+ if (store) {
+ do_storage_setdebug(ua, store, level, trace_flag);
+ return 1;
+ }
+ }
+ store = get_storage_resource(ua, false/*no default*/);
+ if (store) {
+ do_storage_setdebug(ua, store, level, trace_flag);
+ return 1;
+ }
}
}
/*
add_prompt(ua, "Client");
add_prompt(ua, "All");
switch(do_prompt(ua, "", _("Select daemon type to set debug level"), NULL, 0)) {
- case 0: /* Director */
+ case 0: /* Director */
debug_level = level;
set_trace(trace_flag);
break;
case 1:
store = get_storage_resource(ua, false/*no default*/);
if (store) {
- do_storage_setdebug(ua, store, level, trace_flag);
+ do_storage_setdebug(ua, store, level, trace_flag);
}
break;
case 2:
client = select_client_resource(ua);
if (client) {
- do_client_setdebug(ua, client, level, trace_flag);
+ do_client_setdebug(ua, client, level, trace_flag);
}
break;
case 3:
if (ua->argc != 2) {
if (!get_cmd(ua, _("Turn on or off? "))) {
- return 1;
+ return 1;
}
onoff = ua->cmd;
} else {
for (int i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], "client") == 0 ||
strcasecmp(ua->argk[i], "fd") == 0) {
- if (ua->argv[i]) {
- client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
- continue;
- }
+ if (ua->argv[i]) {
+ client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+ continue;
+ }
}
if (strcasecmp(ua->argk[i], "job") == 0) {
- if (ua->argv[i]) {
- job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
- continue;
- }
+ if (ua->argv[i]) {
+ job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
+ continue;
+ }
}
if (strcasecmp(ua->argk[i], "fileset") == 0) {
- if (ua->argv[i]) {
- fileset = (FILESET *)GetResWithName(R_FILESET, ua->argv[i]);
- continue;
- }
+ if (ua->argv[i]) {
+ fileset = (FILESET *)GetResWithName(R_FILESET, ua->argv[i]);
+ continue;
+ }
}
if (strcasecmp(ua->argk[i], "listing") == 0) {
- listing = 1;
- continue;
+ listing = 1;
+ continue;
}
if (strcasecmp(ua->argk[i], "level") == 0) {
- if (!get_level_from_name(ua->jcr, ua->argv[i])) {
+ if (!get_level_from_name(ua->jcr, ua->argv[i])) {
bsendmsg(ua, _("Level %s not valid.\n"), ua->argv[i]);
- }
- continue;
+ }
+ continue;
}
}
if (!job && !(client && fileset)) {
if (!(job = select_job_resource(ua))) {
- return 1;
+ return 1;
}
}
if (!job) {
job = (JOB *)GetResWithName(R_JOB, ua->argk[1]);
if (!job) {
bsendmsg(ua, _("No job specified.\n"));
- return 1;
+ return 1;
}
}
if (!client) {
case 2:
int i;
while ((i=find_arg(ua, "jobid")) > 0) {
- delete_job(ua);
- *ua->argk[i] = 0; /* zap keyword already visited */
+ delete_job(ua);
+ *ua->argk[i] = 0; /* zap keyword already visited */
}
return 1;
default:
int i = find_arg_with_value(ua, N_("jobid"));
if (i >= 0) {
if (strchr(ua->argv[i], ',') != NULL || strchr(ua->argv[i], '-') != NULL) {
- s = bstrdup(ua->argv[i]);
- tok = s;
- /*
+ s = bstrdup(ua->argv[i]);
+ tok = s;
+ /*
* We could use strtok() here. But we're not going to, because:
- * (a) strtok() is deprecated, having been replaced by strsep();
- * (b) strtok() is broken in significant ways.
+ * (a) strtok() is deprecated, having been replaced by strsep();
+ * (b) strtok() is broken in significant ways.
* we could use strsep() instead, but it's not universally available.
- * so we grow our own using strchr().
- */
+ * so we grow our own using strchr().
+ */
sep = strchr(tok, ',');
- while (sep != NULL) {
+ while (sep != NULL) {
*sep = '\0';
if (strchr(tok, '-')) {
- delete_job_id_range(ua, tok);
- } else {
- JobId = str_to_int64(tok);
- do_job_delete(ua, JobId);
- }
- tok = ++sep;
+ delete_job_id_range(ua, tok);
+ } else {
+ JobId = str_to_int64(tok);
+ do_job_delete(ua, JobId);
+ }
+ tok = ++sep;
sep = strchr(tok, ',');
- }
- /* pick up the last token */
+ }
+ /* pick up the last token */
if (strchr(tok, '-')) {
- delete_job_id_range(ua, tok);
- } else {
- JobId = str_to_int64(tok);
- do_job_delete(ua, JobId);
- }
+ delete_job_id_range(ua, tok);
+ } else {
+ JobId = str_to_int64(tok);
+ do_job_delete(ua, JobId);
+ }
- free(s);
+ free(s);
} else {
- JobId = str_to_int64(ua->argv[i]);
- do_job_delete(ua, JobId);
+ JobId = str_to_int64(ua->argv[i]);
+ do_job_delete(ua, JobId);
}
} else if (!get_pint(ua, _("Enter JobId to delete: "))) {
return;
if (!store) {
return;
}
- drive = ua->int32_val;
+ drive = get_storage_drive(ua, store);
Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n",
store->media_type, store->dev_name(), drive);
CAT *oldcatalog, *catalog;
- close_db(ua); /* close any previously open db */
+ close_db(ua); /* close any previously open db */
oldcatalog = ua->catalog;
if (!(catalog = get_catalog_resource(ua))) {
}
if (open_db(ua)) {
bsendmsg(ua, _("Using Catalog name=%s DB=%s\n"),
- ua->catalog->hdr.name, ua->catalog->db_name);
+ ua->catalog->hdr.name, ua->catalog->db_name);
}
return 1;
}
int wait_cmd(UAContext *ua, const char *cmd)
{
JCR *jcr;
- bmicrosleep(0, 200000); /* let job actually start */
+ bmicrosleep(0, 200000); /* let job actually start */
for (bool running=true; running; ) {
running = false;
foreach_jcr(jcr) {
- if (jcr->JobId != 0) {
- running = true;
- free_jcr(jcr);
- break;
- }
- free_jcr(jcr);
+ if (jcr->JobId != 0) {
+ running = true;
+ free_jcr(jcr);
+ break;
+ }
+ free_jcr(jcr);
}
if (running) {
- bmicrosleep(1, 0);
+ bmicrosleep(1, 0);
}
}
return 1;
UnlockRes();
if (!ua->catalog) {
bsendmsg(ua, _("Could not find a Catalog resource\n"));
- return 0;
+ return 0;
} else {
bsendmsg(ua, _("Using default Catalog name=%s DB=%s\n"),
- ua->catalog->hdr.name, ua->catalog->db_name);
+ ua->catalog->hdr.name, ua->catalog->db_name);
}
}
Dmsg0(150, "Open database\n");
ua->db = db_init_database(ua->jcr, ua->catalog->db_name, ua->catalog->db_user,
- ua->catalog->db_password, ua->catalog->db_address,
- ua->catalog->db_port, ua->catalog->db_socket,
- ua->catalog->mult_db_connections);
+ ua->catalog->db_password, ua->catalog->db_address,
+ ua->catalog->db_port, ua->catalog->db_socket,
+ ua->catalog->mult_db_connections);
if (!ua->db || !db_open_database(ua->jcr, ua->db)) {
bsendmsg(ua, _("Could not open database \"%s\".\n"),
- ua->catalog->db_name);
+ ua->catalog->db_name);
if (ua->db) {
bsendmsg(ua, "%s", db_strerror(ua->db));
}
db_close_database(ua->jcr, ua->db);
ua->db = NULL;
if (ua->jcr) {
- ua->jcr->db = NULL;
+ ua->jcr->db = NULL;
}
}
}
char *slot_list;
bool scan;
int max_slots;
- int drive = -1;
+ int drive;
if (!open_db(ua)) {
if (!store) {
return 1;
}
+ drive = get_storage_drive(ua, store);
set_storage(ua->jcr, store);
scan = find_arg(ua, N_("scan")) >= 0;
if (!store) {
return 1;
}
- drive = ua->int32_val;
+ drive = get_storage_drive(ua, store);
set_storage(ua->jcr, store);
if (!relabel && find_arg_keyword(ua, barcode_keyword) >= 0) {
/*
*
* Bacula Director -- User Agent Database restore Command
- * Creates a bootstrap file for restoring files and
- * starts the restore job.
+ * Creates a bootstrap file for restoring files and
+ * starts the restore job.
*
- * Tree handling routines split into ua_tree.c July MMIII.
- * BSR (bootstrap record) handling routines split into
- * bsr.c July MMIII
+ * Tree handling routines split into ua_tree.c July MMIII.
+ * BSR (bootstrap record) handling routines split into
+ * bsr.c July MMIII
*
* Kern Sibbald, July MMII
*
extern void print_bsr(UAContext *ua, RBSR *bsr);
/* Imported variables */
-extern char *uar_list_jobs, *uar_file, *uar_sel_files;
-extern char *uar_del_temp, *uar_del_temp1, *uar_create_temp;
-extern char *uar_create_temp1, *uar_last_full, *uar_full;
-extern char *uar_inc, *uar_list_temp, *uar_sel_jobid_temp;
+extern char *uar_list_jobs, *uar_file, *uar_sel_files;
+extern char *uar_del_temp, *uar_del_temp1, *uar_create_temp;
+extern char *uar_create_temp1, *uar_last_full, *uar_full;
+extern char *uar_inc, *uar_list_temp, *uar_sel_jobid_temp;
extern char *uar_sel_all_temp1, *uar_sel_fileset, *uar_mediatype;
-extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp;
-extern char *uar_count_files, *uar_jobids_fileindex;
+extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp;
+extern char *uar_count_files, *uar_jobids_fileindex;
extern char *uar_jobid_fileindex_from_dir;
struct NAME_LIST {
- char **name; /* list of names */
- int num_ids; /* ids stored */
- int max_ids; /* size of array */
- int num_del; /* number deleted */
- int tot_ids; /* total to process */
+ char **name; /* list of names */
+ int num_ids; /* ids stored */
+ int max_ids; /* size of array */
+ int num_del; /* number deleted */
+ int tot_ids; /* total to process */
};
uint32_t JobId;
char ClientName[MAX_NAME_LENGTH];
char last_jobid[20];
- POOLMEM *JobIds; /* User entered string of JobIds */
+ POOLMEM *JobIds; /* User entered string of JobIds */
STORE *store;
JOB *restore_job;
POOL *pool;
uint32_t selected_files;
char *where;
RBSR *bsr;
- POOLMEM *fname; /* filename only */
- POOLMEM *path; /* path only */
+ POOLMEM *fname; /* filename only */
+ POOLMEM *path; /* path only */
POOLMEM *query;
- int fnl; /* filename length */
- int pnl; /* path length */
+ int fnl; /* filename length */
+ int pnl; /* path length */
bool found;
- bool all; /* mark all as default */
+ bool all; /* mark all as default */
NAME_LIST name_list;
};
static void split_path_and_filename(RESTORE_CTX *rx, char *fname);
static int jobid_fileindex_handler(void *ctx, int num_fields, char **row);
static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file,
- char *date);
+ char *date);
static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir,
- char *date);
+ char *date);
static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, bool dir);
static int get_client_name(UAContext *ua, RESTORE_CTX *rx);
static int get_date(UAContext *ua, char *date, int date_len);
*/
int restore_cmd(UAContext *ua, const char *cmd)
{
- RESTORE_CTX rx; /* restore context */
+ RESTORE_CTX rx; /* restore context */
JOB *job;
int i;
POOLMEM *fname;
LockRes();
foreach_res(job, R_JOB) {
if (job->JobType == JT_RESTORE) {
- if (!rx.restore_job) {
- rx.restore_job = job;
- }
- rx.restore_jobs++;
+ if (!rx.restore_job) {
+ rx.restore_job = job;
+ }
+ rx.restore_jobs++;
}
}
UnlockRes();
* add_findex()
*/
switch (user_select_jobids_or_files(ua, &rx)) {
- case 0: /* error */
+ case 0: /* error */
goto bail_out;
- case 1: /* selected by jobid */
+ case 1: /* selected by jobid */
if (!build_directory_tree(ua, &rx)) {
bsendmsg(ua, _("Restore not done.\n"));
- goto bail_out;
+ goto bail_out;
}
break;
- case 2: /* selected by filename, no tree needed */
+ case 2: /* selected by filename, no tree needed */
break;
}
if (rx.bsr->JobId) {
uint32_t selected_files;
- if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */
+ if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */
bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n"));
- goto bail_out;
+ goto bail_out;
}
if (!(selected_files = write_bsr_file(ua, rx.bsr))) {
bsendmsg(ua, _("No files selected to be restored.\n"));
- goto bail_out;
+ goto bail_out;
}
/* If no count of files, use bsr generated value (often wrong) */
if (rx.selected_files == 0) {
- rx.selected_files = selected_files;
+ rx.selected_files = selected_files;
}
if (rx.selected_files==1) {
bsendmsg(ua, _("\n1 file selected to be restored.\n\n"));
"run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
" where=\"%s\" files=%d catalog=\"%s\"",
job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
- fname, rx.where, rx.selected_files, ua->catalog->hdr.name);
+ fname, rx.where, rx.selected_files, ua->catalog->hdr.name);
} else {
Mmsg(ua->cmd,
"run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
" files=%d catalog=\"%s\"",
job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
- fname, rx.selected_files, ua->catalog->hdr.name);
+ fname, rx.selected_files, ua->catalog->hdr.name);
}
free_pool_memory(fname);
if (find_arg(ua, N_("yes")) > 0) {
/* try command line argument */
int i = find_arg_with_value(ua, N_("client"));
if (i >= 0) {
- bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName));
- return 1;
+ bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName));
+ return 1;
}
memset(&cr, 0, sizeof(cr));
if (!get_client_dbr(ua, &cr)) {
- return 0;
+ return 0;
}
bstrncpy(rx->ClientName, cr.Name, sizeof(rx->ClientName));
}
* select which files are to be restored.
*
* Returns: 2 if filename list made
- * 1 if jobid list made
- * 0 on error
+ * 1 if jobid list made
+ * 0 on error
*/
static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
{
for (i=1; i<ua->argc; i++) { /* loop through arguments */
bool found_kw = false;
- for (j=0; kw[j]; j++) { /* loop through keywords */
- if (strcasecmp(kw[j], ua->argk[i]) == 0) {
- found_kw = true;
- break;
- }
+ for (j=0; kw[j]; j++) { /* loop through keywords */
+ if (strcasecmp(kw[j], ua->argk[i]) == 0) {
+ found_kw = true;
+ break;
+ }
}
if (!found_kw) {
bsendmsg(ua, _("Unknown keyword: %s\n"), ua->argk[i]);
- return 0;
+ return 0;
}
/* Found keyword in kw[] list, process it */
switch (j) {
- case 0: /* jobid */
- if (*rx->JobIds != 0) {
+ case 0: /* jobid */
+ if (*rx->JobIds != 0) {
pm_strcat(rx->JobIds, ",");
- }
- pm_strcat(rx->JobIds, ua->argv[i]);
- done = true;
- break;
- case 1: /* current */
- bstrutime(date, sizeof(date), time(NULL));
- have_date = true;
- break;
- case 2: /* before */
- if (str_to_utime(ua->argv[i]) == 0) {
+ }
+ pm_strcat(rx->JobIds, ua->argv[i]);
+ done = true;
+ break;
+ case 1: /* current */
+ bstrutime(date, sizeof(date), time(NULL));
+ have_date = true;
+ break;
+ case 2: /* before */
+ if (str_to_utime(ua->argv[i]) == 0) {
bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]);
- return 0;
- }
- bstrncpy(date, ua->argv[i], sizeof(date));
- have_date = true;
- break;
- case 3: /* file */
- case 4: /* dir */
- if (!have_date) {
- bstrutime(date, sizeof(date), time(NULL));
- }
- if (!get_client_name(ua, rx)) {
- return 0;
- }
- pm_strcpy(ua->cmd, ua->argv[i]);
- insert_one_file_or_dir(ua, rx, date, j==4);
- if (rx->name_list.num_ids) {
- /* Check MediaType and select storage that corresponds */
- get_storage_from_mediatype(ua, &rx->name_list, rx);
- done = true;
- }
- break;
- case 5: /* select */
- if (!have_date) {
- bstrutime(date, sizeof(date), time(NULL));
- }
- if (!select_backups_before_date(ua, rx, date)) {
- return 0;
- }
- done = true;
- break;
- case 6: /* pool specified */
- rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
- if (!rx->pool) {
+ return 0;
+ }
+ bstrncpy(date, ua->argv[i], sizeof(date));
+ have_date = true;
+ break;
+ case 3: /* file */
+ case 4: /* dir */
+ if (!have_date) {
+ bstrutime(date, sizeof(date), time(NULL));
+ }
+ if (!get_client_name(ua, rx)) {
+ return 0;
+ }
+ pm_strcpy(ua->cmd, ua->argv[i]);
+ insert_one_file_or_dir(ua, rx, date, j==4);
+ if (rx->name_list.num_ids) {
+ /* Check MediaType and select storage that corresponds */
+ get_storage_from_mediatype(ua, &rx->name_list, rx);
+ done = true;
+ }
+ break;
+ case 5: /* select */
+ if (!have_date) {
+ bstrutime(date, sizeof(date), time(NULL));
+ }
+ if (!select_backups_before_date(ua, rx, date)) {
+ return 0;
+ }
+ done = true;
+ break;
+ case 6: /* pool specified */
+ rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
+ if (!rx->pool) {
bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]);
- return 0;
- }
- if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
- rx->pool = NULL;
+ return 0;
+ }
+ if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
+ rx->pool = NULL;
bsendmsg(ua, _("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]);
- return 0;
- }
- break;
- case 7: /* all specified */
- rx->all = true;
- break;
+ return 0;
+ }
+ break;
+ case 7: /* all specified */
+ rx->all = true;
+ break;
/*
* All keywords 7 or greater are ignored or handled by a select prompt
*/
default:
- break;
+ break;
}
}
if (rx->name_list.num_ids) {
- return 2; /* filename list made */
+ return 2; /* filename list made */
}
if (!done) {
start_prompt(ua, _("To select the JobIds, you have the following choices:\n"));
for (int i=0; list[i]; i++) {
- add_prompt(ua, list[i]);
+ add_prompt(ua, list[i]);
}
done = true;
switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
- case -1: /* error */
- return 0;
- case 0: /* list last 20 Jobs run */
- gui_save = ua->jcr->gui;
- ua->jcr->gui = true;
- db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST);
- ua->jcr->gui = gui_save;
- done = false;
- break;
- case 1: /* list where a file is saved */
- if (!get_client_name(ua, rx)) {
- return 0;
- }
+ case -1: /* error */
+ return 0;
+ case 0: /* list last 20 Jobs run */
+ gui_save = ua->jcr->gui;
+ ua->jcr->gui = true;
+ db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST);
+ ua->jcr->gui = gui_save;
+ done = false;
+ break;
+ case 1: /* list where a file is saved */
+ if (!get_client_name(ua, rx)) {
+ return 0;
+ }
if (!get_cmd(ua, _("Enter Filename (no path):"))) {
- return 0;
- }
- len = strlen(ua->cmd);
- fname = (char *)malloc(len * 2 + 1);
- db_escape_string(fname, ua->cmd, len);
- Mmsg(rx->query, uar_file, rx->ClientName, fname);
- free(fname);
- gui_save = ua->jcr->gui;
- ua->jcr->gui = true;
- db_list_sql_query(ua->jcr, ua->db, rx->query, prtit, ua, 1, HORZ_LIST);
- ua->jcr->gui = gui_save;
- done = false;
- break;
- case 2: /* enter a list of JobIds */
+ return 0;
+ }
+ len = strlen(ua->cmd);
+ fname = (char *)malloc(len * 2 + 1);
+ db_escape_string(fname, ua->cmd, len);
+ Mmsg(rx->query, uar_file, rx->ClientName, fname);
+ free(fname);
+ gui_save = ua->jcr->gui;
+ ua->jcr->gui = true;
+ db_list_sql_query(ua->jcr, ua->db, rx->query, prtit, ua, 1, HORZ_LIST);
+ ua->jcr->gui = gui_save;
+ done = false;
+ break;
+ case 2: /* enter a list of JobIds */
if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
- return 0;
- }
- pm_strcpy(rx->JobIds, ua->cmd);
- break;
- case 3: /* Enter an SQL list command */
+ return 0;
+ }
+ pm_strcpy(rx->JobIds, ua->cmd);
+ break;
+ case 3: /* Enter an SQL list command */
if (!get_cmd(ua, _("Enter SQL list command: "))) {
- return 0;
- }
- gui_save = ua->jcr->gui;
- ua->jcr->gui = true;
- db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST);
- ua->jcr->gui = gui_save;
- done = false;
- break;
- case 4: /* Select the most recent backups */
- bstrutime(date, sizeof(date), time(NULL));
- if (!select_backups_before_date(ua, rx, date)) {
- return 0;
- }
- break;
- case 5: /* select backup at specified time */
- if (!get_date(ua, date, sizeof(date))) {
- return 0;
- }
- if (!select_backups_before_date(ua, rx, date)) {
- return 0;
- }
- break;
- case 6: /* Enter files */
- bstrutime(date, sizeof(date), time(NULL));
- if (!get_client_name(ua, rx)) {
- return 0;
- }
+ return 0;
+ }
+ gui_save = ua->jcr->gui;
+ ua->jcr->gui = true;
+ db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST);
+ ua->jcr->gui = gui_save;
+ done = false;
+ break;
+ case 4: /* Select the most recent backups */
+ bstrutime(date, sizeof(date), time(NULL));
+ if (!select_backups_before_date(ua, rx, date)) {
+ return 0;
+ }
+ break;
+ case 5: /* select backup at specified time */
+ if (!get_date(ua, date, sizeof(date))) {
+ return 0;
+ }
+ if (!select_backups_before_date(ua, rx, date)) {
+ return 0;
+ }
+ break;
+ case 6: /* Enter files */
+ bstrutime(date, sizeof(date), time(NULL));
+ if (!get_client_name(ua, rx)) {
+ return 0;
+ }
bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
"containg a list of file names with paths, and terminate\n"
"them with a blank line.\n"));
- for ( ;; ) {
+ for ( ;; ) {
if (!get_cmd(ua, _("Enter full filename: "))) {
- return 0;
- }
- len = strlen(ua->cmd);
- if (len == 0) {
- break;
- }
- insert_one_file_or_dir(ua, rx, date, false);
- }
- /* Check MediaType and select storage that corresponds */
- if (rx->name_list.num_ids) {
- get_storage_from_mediatype(ua, &rx->name_list, rx);
- }
- return 2;
- case 7: /* enter files backed up before specified time */
- if (!get_date(ua, date, sizeof(date))) {
- return 0;
- }
- if (!get_client_name(ua, rx)) {
- return 0;
- }
+ return 0;
+ }
+ len = strlen(ua->cmd);
+ if (len == 0) {
+ break;
+ }
+ insert_one_file_or_dir(ua, rx, date, false);
+ }
+ /* Check MediaType and select storage that corresponds */
+ if (rx->name_list.num_ids) {
+ get_storage_from_mediatype(ua, &rx->name_list, rx);
+ }
+ return 2;
+ case 7: /* enter files backed up before specified time */
+ if (!get_date(ua, date, sizeof(date))) {
+ return 0;
+ }
+ if (!get_client_name(ua, rx)) {
+ return 0;
+ }
bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
"containg a list of file names with paths, and terminate\n"
"them with a blank line.\n"));
- for ( ;; ) {
+ for ( ;; ) {
if (!get_cmd(ua, _("Enter full filename: "))) {
- return 0;
- }
- len = strlen(ua->cmd);
- if (len == 0) {
- break;
- }
- insert_one_file_or_dir(ua, rx, date, false);
- }
- /* Check MediaType and select storage that corresponds */
- if (rx->name_list.num_ids) {
- get_storage_from_mediatype(ua, &rx->name_list, rx);
- }
- return 2;
-
- case 8: /* Find JobIds for current backup */
- bstrutime(date, sizeof(date), time(NULL));
- if (!select_backups_before_date(ua, rx, date)) {
- return 0;
- }
- done = false;
- break;
-
- case 9: /* Find JobIds for give date */
- if (!get_date(ua, date, sizeof(date))) {
- return 0;
- }
- if (!select_backups_before_date(ua, rx, date)) {
- return 0;
- }
- done = false;
- break;
-
- case 10: /* Enter directories */
- if (*rx->JobIds != 0) {
+ return 0;
+ }
+ len = strlen(ua->cmd);
+ if (len == 0) {
+ break;
+ }
+ insert_one_file_or_dir(ua, rx, date, false);
+ }
+ /* Check MediaType and select storage that corresponds */
+ if (rx->name_list.num_ids) {
+ get_storage_from_mediatype(ua, &rx->name_list, rx);
+ }
+ return 2;
+
+ case 8: /* Find JobIds for current backup */
+ bstrutime(date, sizeof(date), time(NULL));
+ if (!select_backups_before_date(ua, rx, date)) {
+ return 0;
+ }
+ done = false;
+ break;
+
+ case 9: /* Find JobIds for give date */
+ if (!get_date(ua, date, sizeof(date))) {
+ return 0;
+ }
+ if (!select_backups_before_date(ua, rx, date)) {
+ return 0;
+ }
+ done = false;
+ break;
+
+ case 10: /* Enter directories */
+ if (*rx->JobIds != 0) {
bsendmsg(ua, _("You have already seleted the following JobIds: %s\n"),
- rx->JobIds);
+ rx->JobIds);
} else if (get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
- if (*rx->JobIds != 0 && *ua->cmd) {
+ if (*rx->JobIds != 0 && *ua->cmd) {
pm_strcat(rx->JobIds, ",");
- }
- pm_strcat(rx->JobIds, ua->cmd);
- }
+ }
+ pm_strcat(rx->JobIds, ua->cmd);
+ }
if (*rx->JobIds == 0 || *rx->JobIds == '.') {
- return 0; /* nothing entered, return */
- }
- bstrutime(date, sizeof(date), time(NULL));
- if (!get_client_name(ua, rx)) {
- return 0;
- }
+ return 0; /* nothing entered, return */
+ }
+ bstrutime(date, sizeof(date), time(NULL));
+ if (!get_client_name(ua, rx)) {
+ return 0;
+ }
bsendmsg(ua, _("Enter full directory names or start the name\n"
"with a < to indicate it is a filename containg a list\n"
"of directories and terminate them with a blank line.\n"));
- for ( ;; ) {
+ for ( ;; ) {
if (!get_cmd(ua, _("Enter directory name: "))) {
- return 0;
- }
- len = strlen(ua->cmd);
- if (len == 0) {
- break;
- }
- /* Add trailing slash to end of directory names */
+ return 0;
+ }
+ len = strlen(ua->cmd);
+ if (len == 0) {
+ break;
+ }
+ /* Add trailing slash to end of directory names */
if (ua->cmd[0] != '<' && ua->cmd[len-1] != '/') {
strcat(ua->cmd, "/");
- }
- insert_one_file_or_dir(ua, rx, date, true);
- }
- /* Check MediaType and select storage that corresponds */
- if (rx->name_list.num_ids) {
- get_storage_from_mediatype(ua, &rx->name_list, rx);
- }
- return 2;
-
- case 11: /* Cancel or quit */
- return 0;
+ }
+ insert_one_file_or_dir(ua, rx, date, true);
+ }
+ /* Check MediaType and select storage that corresponds */
+ if (rx->name_list.num_ids) {
+ get_storage_from_mediatype(ua, &rx->name_list, rx);
+ }
+ return 2;
+
+ case 11: /* Cancel or quit */
+ return 0;
}
}
int stat = get_next_jobid_from_list(&p, &JobId);
if (stat < 0) {
bsendmsg(ua, _("Invalid JobId in list.\n"));
- return 0;
+ return 0;
}
if (stat == 0) {
- break;
+ break;
}
if (jr.JobId == JobId) {
- continue; /* duplicate of last JobId */
+ continue; /* duplicate of last JobId */
}
jr.JobId = JobId;
if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
- char ed1[50];
+ char ed1[50];
bsendmsg(ua, _("Unable to get Job record for JobId=%s: ERR=%s\n"),
- edit_int64(JobId, ed1), db_strerror(ua->db));
- return 0;
+ edit_int64(JobId, ed1), db_strerror(ua->db));
+ return 0;
}
if (!acl_access_ok(ua, Job_ACL, jr.Name)) {
bsendmsg(ua, _("No authorization. Job \"%s\" not selected.\n"),
- jr.Name);
- continue;
+ jr.Name);
+ continue;
}
rx->TotalFiles += jr.JobFiles;
}
"BEFORE the date you specify below.\n\n"));
for ( ;; ) {
if (!get_cmd(ua, _("Enter date as YYYY-MM-DD HH:MM:SS :"))) {
- return 0;
+ return 0;
}
if (str_to_utime(ua->cmd) != 0) {
- break;
+ break;
}
bsendmsg(ua, _("Improper date format.\n"));
}
case '<':
p++;
if ((ffd = fopen(p, "r")) == NULL) {
- berrno be;
+ berrno be;
bsendmsg(ua, _("Cannot open file %s: ERR=%s\n"),
- p, be.strerror());
- break;
+ p, be.strerror());
+ break;
}
while (fgets(file, sizeof(file), ffd)) {
- line++;
- if (dir) {
- if (!insert_dir_into_findex_list(ua, rx, file, date)) {
+ line++;
+ if (dir) {
+ if (!insert_dir_into_findex_list(ua, rx, file, date)) {
bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p);
- }
- } else {
- if (!insert_file_into_findex_list(ua, rx, file, date)) {
+ }
+ } else {
+ if (!insert_file_into_findex_list(ua, rx, file, date)) {
bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p);
- }
- }
+ }
+ }
}
fclose(ffd);
break;
default:
if (dir) {
- insert_dir_into_findex_list(ua, rx, ua->cmd, date);
+ insert_dir_into_findex_list(ua, rx, ua->cmd, date);
} else {
- insert_file_into_findex_list(ua, rx, ua->cmd, date);
+ insert_file_into_findex_list(ua, rx, ua->cmd, date);
}
break;
}
* and FileIndex, then insert them into the findex list.
*/
static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file,
- char *date)
+ char *date)
{
char ed1[50];
split_path_and_filename(rx, file);
if (*rx->JobIds == 0) {
Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname,
- rx->ClientName);
+ rx->ClientName);
} else {
Mmsg(rx->query, uar_jobids_fileindex, rx->JobIds, date,
- rx->path, rx->fname, rx->ClientName);
+ rx->path, rx->fname, rx->ClientName);
}
rx->found = false;
/* Find and insert jobid and File Index */
if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) {
bsendmsg(ua, _("Query failed: %s. ERR=%s\n"),
- rx->query, db_strerror(ua->db));
+ rx->query, db_strerror(ua->db));
}
if (!rx->found) {
bsendmsg(ua, _("No database record found for: %s\n"), file);
* to get the JobId and FileIndexes of all files in that directory.
*/
static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir,
- char *date)
+ char *date)
{
char ed1[50];
return false;
} else {
Mmsg(rx->query, uar_jobid_fileindex_from_dir, rx->JobIds,
- dir, rx->ClientName);
+ dir, rx->ClientName);
}
rx->found = false;
/* Find and insert jobid and File Index */
if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) {
bsendmsg(ua, _("Query failed: %s. ERR=%s\n"),
- rx->query, db_strerror(ua->db));
+ rx->query, db_strerror(ua->db));
}
if (!rx->found) {
bsendmsg(ua, _("No database record found for: %s\n"), dir);
*/
for (p=f=name; *p; p++) {
if (*p == '/') {
- f = p; /* set pos of last slash */
+ f = p; /* set pos of last slash */
}
}
if (*f == '/') { /* did we find a slash? */
- f++; /* yes, point to filename */
- } else { /* no, whole thing must be path name */
+ f++; /* yes, point to filename */
+ } else { /* no, whole thing must be path name */
f = p;
}
rx->fnl = p - f;
if (rx->fnl > 0) {
rx->fname = check_pool_memory_size(rx->fname, rx->fnl+1);
- memcpy(rx->fname, f, rx->fnl); /* copy filename */
+ memcpy(rx->fname, f, rx->fnl); /* copy filename */
rx->fname[rx->fnl] = 0;
} else {
rx->fname[0] = 0;
bsendmsg(ua, "%s\n", db_strerror(ua->db));
}
if (rx->found) {
- /* Add about 25% more than this job for over estimate */
- tree.FileEstimate = rx->JobId + (rx->JobId >> 2);
- tree.DeltaCount = rx->JobId/50; /* print 50 ticks */
+ /* Add about 25% more than this job for over estimate */
+ tree.FileEstimate = rx->JobId + (rx->JobId >> 2);
+ tree.DeltaCount = rx->JobId/50; /* print 50 ticks */
}
}
for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) {
char ed1[50];
if (JobId == last_JobId) {
- continue; /* eliminate duplicate JobIds */
+ continue; /* eliminate duplicate JobIds */
}
last_JobId = JobId;
bsendmsg(ua, _("\nBuilding directory tree for JobId %s ... "),
- edit_int64(JobId, ed1));
+ edit_int64(JobId, ed1));
items++;
/*
* Find files for this JobId and insert them in the tree
bsendmsg(ua, _("\nThere were no files inserted into the tree, so file selection\n"
"is not possible.Most likely your retention policy pruned the files\n"));
if (!get_yesno(ua, _("\nDo you want to restore all the files? (yes|no): "))) {
- OK = false;
+ OK = false;
} else {
- last_JobId = 0;
- for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) {
- if (JobId == last_JobId) {
- continue; /* eliminate duplicate JobIds */
- }
- add_findex_all(rx->bsr, JobId);
- }
- OK = true;
+ last_JobId = 0;
+ for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) {
+ if (JobId == last_JobId) {
+ continue; /* eliminate duplicate JobIds */
+ }
+ add_findex_all(rx->bsr, JobId);
+ }
+ OK = true;
}
} else {
char ec1[50];
if (items==1) {
- if (tree.all) {
+ if (tree.all) {
bsendmsg(ua, _("\n1 Job, %s files inserted into the tree and marked for extraction.\n"),
- edit_uint64_with_commas(tree.FileCount, ec1));
- }
- else {
+ edit_uint64_with_commas(tree.FileCount, ec1));
+ }
+ else {
bsendmsg(ua, _("\n1 Job, %s files inserted into the tree.\n"),
- edit_uint64_with_commas(tree.FileCount, ec1));
- }
+ edit_uint64_with_commas(tree.FileCount, ec1));
+ }
}
else {
- if (tree.all) {
+ if (tree.all) {
bsendmsg(ua, _("\n%d Jobs, %s files inserted into the tree and marked for extraction.\n"),
- items, edit_uint64_with_commas(tree.FileCount, ec1));
- }
- else {
+ items, edit_uint64_with_commas(tree.FileCount, ec1));
+ }
+ else {
bsendmsg(ua, _("\n%d Jobs, %s files inserted into the tree.\n"),
- items, edit_uint64_with_commas(tree.FileCount, ec1));
- }
+ items, edit_uint64_with_commas(tree.FileCount, ec1));
+ }
}
/* Check MediaType and select storage that corresponds */
get_storage_from_mediatype(ua, &rx->name_list, rx);
if (find_arg(ua, N_("done")) < 0) {
- /* Let the user interact in selecting which files to restore */
- OK = user_select_files_from_tree(&tree);
+ /* Let the user interact in selecting which files to restore */
+ OK = user_select_files_from_tree(&tree);
}
/*
* extracted making a bootstrap file.
*/
if (OK) {
- for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) {
+ for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) {
Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node);
- if (node->extract || node->extract_dir) {
+ if (node->extract || node->extract_dir) {
Dmsg2(400, "type=%d FI=%d\n", node->type, node->FileIndex);
- add_findex(rx->bsr, node->JobId, node->FileIndex);
- if (node->extract && node->type != TN_NEWDIR) {
- rx->selected_files++; /* count only saved files */
- }
- }
- }
+ add_findex(rx->bsr, node->JobId, node->FileIndex);
+ if (node->extract && node->type != TN_NEWDIR) {
+ rx->selected_files++; /* count only saved files */
+ }
+ }
+ }
}
}
- free_tree(tree.root); /* free the directory tree */
+ free_tree(tree.root); /* free the directory tree */
return OK;
}
bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet));
if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) {
bsendmsg(ua, _("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet,
- db_strerror(ua->db));
- i = -1;
+ db_strerror(ua->db));
+ i = -1;
}
}
- if (i < 0) { /* fileset not found */
+ if (i < 0) { /* fileset not found */
edit_int64(cr.ClientId, ed1);
Mmsg(rx->query, uar_sel_fileset, ed1, ed1);
start_prompt(ua, _("The defined FileSet resources are:\n"));
bsendmsg(ua, "%s\n", db_strerror(ua->db));
}
if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"),
- fileset_name, sizeof(fileset_name)) < 0) {
- goto bail_out;
+ fileset_name, sizeof(fileset_name)) < 0) {
+ goto bail_out;
}
bstrncpy(fsr.FileSet, fileset_name, sizeof(fsr.FileSet));
bstrncpy(pr.Name, rx->pool->hdr.name, sizeof(pr.Name));
if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ",
- edit_int64(pr.PoolId, ed1));
+ edit_int64(pr.PoolId, ed1));
} else {
bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name);
}
/* Find JobId of last Full backup for this client, fileset */
edit_int64(cr.ClientId, ed1);
Mmsg(rx->query, uar_last_full, ed1, ed1, date, fsr.FileSet,
- pool_select);
+ pool_select);
if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
bsendmsg(ua, "%s\n", db_strerror(ua->db));
goto bail_out;
/* Now find most recent Differental Job after Full save, if any */
Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date,
- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
+ edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
bsendmsg(ua, "%s\n", db_strerror(ua->db));
}
/* Now find all Incremental Jobs after Full/dif save */
Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date,
- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
+ edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
bsendmsg(ua, "%s\n", db_strerror(ua->db));
}
jobid[0] = 0;
for (int i=0; i<(int)sizeof(jobid); i++) {
if (*q == 0) {
- break;
+ break;
} else if (*q == ',') {
- q++;
- break;
+ q++;
+ break;
}
jobid[i] = *q++;
jobid[i+1] = 0;
if (jobid[0] == 0) {
return 0;
} else if (!is_a_number(jobid)) {
- return -1; /* error */
+ return -1; /* error */
}
*p = q;
*JobId = str_to_int64(jobid);
RESTORE_CTX *rx = (RESTORE_CTX *)ctx;
if (strcmp(rx->last_jobid, row[0]) == 0) {
- return 0; /* duplicate id */
+ return 0; /* duplicate id */
}
bstrncpy(rx->last_jobid, row[0], sizeof(rx->last_jobid));
if (rx->JobIds[0] != 0) {
}
if (name->num_ids == name->max_ids) {
if (name->max_ids == 0) {
- name->max_ids = 1000;
- name->name = (char **)bmalloc(sizeof(char *) * name->max_ids);
+ name->max_ids = 1000;
+ name->name = (char **)bmalloc(sizeof(char *) * name->max_ids);
} else {
- name->max_ids = (name->max_ids * 3) / 2;
- name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids);
+ name->max_ids = (name->max_ids * 3) / 2;
+ name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids);
}
}
for (int i=0; i<name->num_ids; i++) {
if (strcmp(name->name[i], row[0]) == 0) {
- return 0; /* already in list, return */
+ return 0; /* already in list, return */
}
}
/* Add new name to list */
LockRes();
foreach_res(store, R_STORAGE) {
if (strcmp(name_list->name[0], store->media_type) == 0) {
- if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- rx->store = store;
- }
- break;
+ if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+ rx->store = store;
+ }
+ break;
}
}
UnlockRes();
store = NULL;
int i = find_arg_with_value(ua, "storage");
if (i > 0) {
- store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
- if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- store = NULL;
- }
+ store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
+ if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+ store = NULL;
+ }
}
if (store && (store != rx->store)) {
bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"),
- store->hdr.name);
- rx->store = store;
+ store->hdr.name);
+ rx->store = store;
}
return;
}
bsendmsg(ua, _("\nWarning. Unable to find Storage resource for\n"
"MediaType \"%s\", needed by the Jobs you selected.\n"
"You will be allowed to select a Storage device later.\n"),
- name_list->name[0]);
+ name_list->name[0]);
}
}
for ( ;; ) {
bsendmsg(ua, _("The current %s retention period is: %s\n"),
- msg, edit_utime(*ret, ed1, sizeof(ed1)));
+ msg, edit_utime(*ret, ed1, sizeof(ed1)));
if (!get_cmd(ua, _("Continue? (yes/mod/no): "))) {
- return 0;
+ return 0;
}
if (strcasecmp(ua->cmd, _("mod")) == 0) {
if (!get_cmd(ua, _("Enter new retention period: "))) {
- return 0;
- }
- if (!duration_to_utime(ua->cmd, ret)) {
+ return 0;
+ }
+ if (!duration_to_utime(ua->cmd, ret)) {
bsendmsg(ua, _("Invalid period.\n"));
- continue;
- }
- continue;
+ continue;
+ }
+ continue;
}
if (strcasecmp(ua->cmd, _("yes")) == 0) {
- return 1;
+ return 1;
}
if (strcasecmp(ua->cmd, _("no")) == 0) {
- return 0;
+ return 0;
}
}
return 1;
* Given a list of keywords, find the first one
* that is in the argument list.
* Returns: -1 if not found
- * index into list (base 0) on success
+ * index into list (base 0) on success
*/
int find_arg_keyword(UAContext *ua, const char **list)
{
for (int i=1; i<ua->argc; i++) {
for(int j=0; list[j]; j++) {
- if (strcasecmp(_(list[j]), ua->argk[i]) == 0) {
- return j;
- }
+ if (strcasecmp(_(list[j]), ua->argk[i]) == 0) {
+ return j;
+ }
}
}
return -1;
* Given one keyword, find the first one that
* is in the argument list.
* Returns: argk index (always gt 0)
- * -1 if not found
+ * -1 if not found
*/
int find_arg(UAContext *ua, const char *keyword)
{
for (int i=1; i<ua->argc; i++) {
if (strcasecmp(keyword, ua->argk[i]) == 0) {
- return i;
+ return i;
}
}
return -1;
* Given a single keyword, find it in the argument list, but
* it must have a value
* Returns: -1 if not found or no value
- * list index (base 0) on success
+ * list index (base 0) on success
*/
int find_arg_with_value(UAContext *ua, const char *keyword)
{
for (int i=1; i<ua->argc; i++) {
if (strcasecmp(keyword, ua->argk[i]) == 0) {
- if (ua->argv[i]) {
- return i;
- } else {
- return -1;
- }
+ if (ua->argv[i]) {
+ return i;
+ } else {
+ return -1;
+ }
}
}
return -1;
* to choose one.
*
* Returns: -1 on failure
- * index into list (base 0) on success
+ * index into list (base 0) on success
*/
int do_keyword_prompt(UAContext *ua, const char *msg, const char **list)
{
LockRes();
foreach_res(store, R_STORAGE) {
if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- add_prompt(ua, store->hdr.name);
+ add_prompt(ua, store->hdr.name);
}
}
UnlockRes();
LockRes();
foreach_res(fs, R_FILESET) {
if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) {
- add_prompt(ua, fs->hdr.name);
+ add_prompt(ua, fs->hdr.name);
}
}
UnlockRes();
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], _("catalog")) == 0 && ua->argv[i]) {
- if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) {
- catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]);
- break;
- }
+ if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) {
+ catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]);
+ break;
+ }
}
}
if (!catalog) {
start_prompt(ua, _("The defined Catalog resources are:\n"));
LockRes();
foreach_res(catalog, R_CATALOG) {
- if (acl_access_ok(ua, Catalog_ACL, catalog->hdr.name)) {
- add_prompt(ua, catalog->hdr.name);
- }
+ if (acl_access_ok(ua, Catalog_ACL, catalog->hdr.name)) {
+ add_prompt(ua, catalog->hdr.name);
+ }
}
UnlockRes();
do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
LockRes();
foreach_res(job, R_JOB) {
if (acl_access_ok(ua, Job_ACL, job->hdr.name)) {
- add_prompt(ua, job->hdr.name);
+ add_prompt(ua, job->hdr.name);
}
}
UnlockRes();
LockRes();
foreach_res(job, R_JOB) {
if (job->JobType == JT_RESTORE && acl_access_ok(ua, Job_ACL, job->hdr.name)) {
- add_prompt(ua, job->hdr.name);
+ add_prompt(ua, job->hdr.name);
}
}
UnlockRes();
LockRes();
foreach_res(client, R_CLIENT) {
if (acl_access_ok(ua, Client_ACL, client->hdr.name)) {
- add_prompt(ua, client->hdr.name);
+ add_prompt(ua, client->hdr.name);
}
}
UnlockRes();
for (i=1; i<ua->argc; i++) {
if ((strcasecmp(ua->argk[i], N_("client")) == 0 ||
strcasecmp(ua->argk[i], N_("fd")) == 0) && ua->argv[i]) {
- if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
- break;
- }
- client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
- if (client) {
- return client;
- }
+ if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
+ break;
+ }
+ client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+ if (client) {
+ return client;
+ }
bsendmsg(ua, _("Error: Client resource %s does not exist.\n"), ua->argv[i]);
- break;
+ break;
}
}
return select_client_resource(ua);
* to choose from.
*
* returns: 0 on error
- * 1 on success and fills in CLIENT_DBR
+ * 1 on success and fills in CLIENT_DBR
*/
int get_client_dbr(UAContext *ua, CLIENT_DBR *cr)
{
int i;
- if (cr->Name[0]) { /* If name already supplied */
+ if (cr->Name[0]) { /* If name already supplied */
if (db_get_client_record(ua->jcr, ua->db, cr)) {
- return 1;
+ return 1;
}
bsendmsg(ua, _("Could not find Client %s: ERR=%s"), cr->Name, db_strerror(ua->db));
}
for (i=1; i<ua->argc; i++) {
if ((strcasecmp(ua->argk[i], _("client")) == 0 ||
strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) {
- if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
- break;
- }
- bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name));
- if (!db_get_client_record(ua->jcr, ua->db, cr)) {
+ if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
+ break;
+ }
+ bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name));
+ if (!db_get_client_record(ua->jcr, ua->db, cr)) {
bsendmsg(ua, _("Could not find Client \"%s\": ERR=%s"), ua->argv[i],
- db_strerror(ua->db));
- cr->ClientId = 0;
- break;
- }
- return 1;
+ db_strerror(ua->db));
+ cr->ClientId = 0;
+ break;
+ }
+ return 1;
}
}
if (!select_client_dbr(ua, cr)) { /* try once more by proposing a list */
/*
* Select a Client record from the catalog
* Returns 1 on success
- * 0 on failure
+ * 0 on failure
*/
int select_client_dbr(UAContext *ua, CLIENT_DBR *cr)
{
for (i=0; i < num_clients; i++) {
ocr.ClientId = ids[i];
if (!db_get_client_record(ua->jcr, ua->db, &ocr) ||
- !acl_access_ok(ua, Client_ACL, ocr.Name)) {
- continue;
+ !acl_access_ok(ua, Client_ACL, ocr.Name)) {
+ continue;
}
add_prompt(ua, ocr.Name);
}
* to choose from.
*
* returns: false on error
- * true on success and fills in POOL_DBR
+ * true on success and fills in POOL_DBR
*/
bool get_pool_dbr(UAContext *ua, POOL_DBR *pr)
{
- if (pr->Name[0]) { /* If name already supplied */
+ if (pr->Name[0]) { /* If name already supplied */
if (db_get_pool_record(ua->jcr, ua->db, pr) &&
- acl_access_ok(ua, Pool_ACL, pr->Name)) {
- return true;
+ acl_access_ok(ua, Pool_ACL, pr->Name)) {
+ return true;
}
bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), pr->Name, db_strerror(ua->db));
}
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], N_("pool")) == 0 && ua->argv[i] &&
- acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
- bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name));
- if (!db_get_pool_record(ua->jcr, ua->db, pr)) {
+ acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
+ bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name));
+ if (!db_get_pool_record(ua->jcr, ua->db, pr)) {
bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), ua->argv[i],
- db_strerror(ua->db));
- pr->PoolId = 0;
- break;
- }
- return true;
+ db_strerror(ua->db));
+ pr->PoolId = 0;
+ break;
+ }
+ return true;
}
}
for (i=0; i < num_pools; i++) {
opr.PoolId = ids[i];
if (!db_get_pool_record(ua->jcr, ua->db, &opr) ||
- !acl_access_ok(ua, Pool_ACL, opr.Name)) {
- continue;
+ !acl_access_ok(ua, Pool_ACL, opr.Name)) {
+ continue;
}
add_prompt(ua, opr.Name);
}
memset(&pr, 0, sizeof(pr));
/* Get the pool from pool=<pool-name> */
if (!get_pool_dbr(ua, &pr)) {
- return 0;
+ return 0;
}
mr->PoolId = pr.PoolId;
db_list_media_records(ua->jcr, ua->db, mr, prtit, ua, HORZ_LIST);
if (!get_cmd(ua, _("Enter MediaId or Volume name: "))) {
- return 0;
+ return 0;
}
if (is_a_number(ua->cmd)) {
- mr->MediaId = str_to_int64(ua->cmd);
+ mr->MediaId = str_to_int64(ua->cmd);
} else {
- bstrncpy(mr->VolumeName, ua->cmd, sizeof(mr->VolumeName));
+ bstrncpy(mr->VolumeName, ua->cmd, sizeof(mr->VolumeName));
}
}
LockRes();
foreach_res(pool, R_POOL) {
if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
- add_prompt(ua, pool->hdr.name);
+ add_prompt(ua, pool->hdr.name);
}
}
UnlockRes();
if (i >= 0 && acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
if (pool) {
- return pool;
+ return pool;
}
bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]);
}
* to choose from.
*
* returns: 0 on error
- * JobId on success and fills in JOB_DBR
+ * JobId on success and fills in JOB_DBR
*/
int get_job_dbr(UAContext *ua, JOB_DBR *jr)
{
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], N_("job")) == 0 && ua->argv[i]) {
- jr->JobId = 0;
- bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job));
+ jr->JobId = 0;
+ bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job));
} else if (strcasecmp(ua->argk[i], N_("jobid")) == 0 && ua->argv[i]) {
- jr->JobId = str_to_int64(ua->argv[i]);
+ jr->JobId = str_to_int64(ua->argv[i]);
} else {
- continue;
+ continue;
}
if (!db_get_job_record(ua->jcr, ua->db, jr)) {
bsendmsg(ua, _("Could not find Job \"%s\": ERR=%s"), ua->argv[i],
- db_strerror(ua->db));
- jr->JobId = 0;
- break;
+ db_strerror(ua->db));
+ jr->JobId = 0;
+ break;
}
return jr->JobId;
}
if (ua->num_prompts == ua->max_prompts) {
ua->max_prompts *= 2;
ua->prompt = (char **)brealloc(ua->prompt, sizeof(char *) *
- ua->max_prompts);
+ ua->max_prompts);
}
for (i=1; i < ua->num_prompts; i++) {
if (strcmp(ua->prompt[i], prompt) == 0) {
- return;
+ return;
}
}
ua->prompt[ua->num_prompts++] = bstrdup(prompt);
* Display prompts and get user's choice
*
* Returns: -1 on error
- * index base 0 on success, and choice
- * is copied to prompt if not NULL
+ * index base 0 on success, and choice
+ * is copied to prompt if not NULL
*/
int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
{
if (ua->num_prompts == 2) {
item = 1;
if (prompt) {
- bstrncpy(prompt, ua->prompt[1], max_prompt);
+ bstrncpy(prompt, ua->prompt[1], max_prompt);
}
bsendmsg(ua, _("Automatically selected %s: %s\n"), automsg, ua->prompt[1]);
goto done;
/* First item is the prompt string, not the items */
if (ua->num_prompts == 1) {
bsendmsg(ua, _("Selection is empty!\n"));
- item = 0; /* list is empty ! */
- break;
+ item = 0; /* list is empty ! */
+ break;
}
if (ua->num_prompts == 2) {
- item = 1;
+ item = 1;
bsendmsg(ua, _("Item 1 selected automatically.\n"));
- if (prompt) {
- bstrncpy(prompt, ua->prompt[1], max_prompt);
- }
- break;
+ if (prompt) {
+ bstrncpy(prompt, ua->prompt[1], max_prompt);
+ }
+ break;
} else {
sprintf(pmsg, "%s (1-%d): ", msg, ua->num_prompts-1);
}
/* Either a . or an @ will get you out of the loop */
if (!get_pint(ua, pmsg)) {
- item = -1; /* error */
+ item = -1; /* error */
bsendmsg(ua, _("Selection aborted, nothing done.\n"));
- break;
+ break;
}
item = ua->pint32_val;
if (item < 1 || item >= ua->num_prompts) {
bsendmsg(ua, _("Please enter a number between 1 and %d\n"), ua->num_prompts-1);
- continue;
+ continue;
}
if (prompt) {
- bstrncpy(prompt, ua->prompt[item], max_prompt);
+ bstrncpy(prompt, ua->prompt[item], max_prompt);
}
break;
}
* storage=<storage-resource>
* job=<job_name>
* jobid=<jobid>
- * ? (prompt him with storage list)
+ * ? (prompt him with storage list)
* <some-error> (prompt him with storage list)
*
* If use_default is set, we assume that any keyword without a value
STORE *store = NULL;
int jobid;
JCR *jcr;
- int i, drive;
+ int i;
char ed1[50];
for (i=1; i<ua->argc; i++) {
if (use_default && !ua->argv[i]) {
- /* Ignore slots, scan and barcode(s) keywords */
+ /* Ignore slots, scan and barcode(s) keywords */
if (strcasecmp("scan", ua->argk[i]) == 0 ||
strcasecmp("barcode", ua->argk[i]) == 0 ||
strcasecmp("slots", ua->argk[i]) == 0) {
- continue;
- }
- /* Default argument is storage */
- if (store_name) {
+ continue;
+ }
+ /* Default argument is storage */
+ if (store_name) {
bsendmsg(ua, _("Storage name given twice.\n"));
- return NULL;
- }
- store_name = ua->argk[i];
+ return NULL;
+ }
+ store_name = ua->argk[i];
if (*store_name == '?') {
- *store_name = 0;
- break;
- }
+ *store_name = 0;
+ break;
+ }
} else {
if (strcasecmp(ua->argk[i], N_("storage")) == 0 ||
strcasecmp(ua->argk[i], N_("sd")) == 0) {
- store_name = ua->argv[i];
- break;
+ store_name = ua->argv[i];
+ break;
} else if (strcasecmp(ua->argk[i], N_("jobid")) == 0) {
- jobid = str_to_int64(ua->argv[i]);
- if (jobid <= 0) {
+ jobid = str_to_int64(ua->argv[i]);
+ if (jobid <= 0) {
bsendmsg(ua, _("Expecting jobid=nn command, got: %s\n"), ua->argk[i]);
- return NULL;
- }
- if (!(jcr=get_jcr_by_id(jobid))) {
+ return NULL;
+ }
+ if (!(jcr=get_jcr_by_id(jobid))) {
bsendmsg(ua, _("JobId %s is not running.\n"), edit_int64(jobid, ed1));
- return NULL;
- }
- store = jcr->store;
- free_jcr(jcr);
- break;
+ return NULL;
+ }
+ store = jcr->store;
+ free_jcr(jcr);
+ break;
} else if (strcasecmp(ua->argk[i], N_("job")) == 0) {
- if (!ua->argv[i]) {
+ if (!ua->argv[i]) {
bsendmsg(ua, _("Expecting job=xxx, got: %s.\n"), ua->argk[i]);
- return NULL;
- }
- if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) {
+ return NULL;
+ }
+ if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) {
bsendmsg(ua, _("Job \"%s\" is not running.\n"), ua->argv[i]);
- return NULL;
- }
- store = jcr->store;
- free_jcr(jcr);
- break;
- }
+ return NULL;
+ }
+ store = jcr->store;
+ free_jcr(jcr);
+ break;
+ }
}
}
if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
if (!store) {
store = select_storage_resource(ua);
}
+ return store;
+}
+
+int get_storage_drive(UAContext *ua, STORE *store)
+{
+ int i, drive;
/* Get drive for autochanger if possible */
- drive = -2; /* dummy */
- if (store && store->autochanger) {
- i = find_arg_with_value(ua, "drive");
- if (i >=0) {
- drive = atoi(ua->argv[i]);
+ i = find_arg_with_value(ua, "drive");
+ if (i >=0) {
+ drive = atoi(ua->argv[i]);
+ } else if (store && store->autochanger) {
+ ua->cmd[0] = 0;
+ if (!get_cmd(ua, _("Enter autochanger drive[0]: "))) {
+ drive = -1; /* None */
} else {
- ua->cmd[0] = 0;
- if (!get_cmd(ua, _("Enter autochanger drive[0]: "))) {
- drive = -1; /* None */
- } else {
- drive = atoi(ua->cmd);
- }
+ drive = atoi(ua->cmd);
}
}
- ua->int32_val = drive;
- return store;
+ return drive;
}
* if not found or error, put up selection list
*
* Returns: 0 on error
- * 1 on success, MediaType is set
+ * 1 on success, MediaType is set
*/
int get_media_type(UAContext *ua, char *MediaType, int max_media)
{
bool found = false;
for (int i=0; joblevels[i].level_name; i++) {
if (strcasecmp(level_name, joblevels[i].level_name) == 0) {
- jcr->JobLevel = joblevels[i].level;
- found = true;
- break;
+ jcr->JobLevel = joblevels[i].level;
+ found = true;
+ break;
}
}
return found;
if (strcasecmp(ua->argk[2], "current") == 0) {
bsendmsg(ua, OKqstatus, ua->argk[2]);
foreach_jcr(njcr) {
- if (njcr->JobId != 0) {
- bsendmsg(ua, DotStatusJob, edit_int64(njcr->JobId, ed1),
- njcr->JobStatus, njcr->JobErrors);
- }
- free_jcr(njcr);
+ if (njcr->JobId != 0) {
+ bsendmsg(ua, DotStatusJob, edit_int64(njcr->JobId, ed1),
+ njcr->JobStatus, njcr->JobErrors);
+ }
+ free_jcr(njcr);
}
} else if (strcasecmp(ua->argk[2], "last") == 0) {
bsendmsg(ua, OKqstatus, ua->argk[2]);
if ((last_jobs) && (last_jobs->size() > 0)) {
- job = (s_last_job*)last_jobs->last();
- bsendmsg(ua, DotStatusJob, edit_int64(njcr->JobId, ed1),
- njcr->JobStatus, njcr->JobErrors);
+ job = (s_last_job*)last_jobs->last();
+ bsendmsg(ua, DotStatusJob, edit_int64(njcr->JobId, ed1),
+ njcr->JobStatus, njcr->JobErrors);
}
} else {
bsendmsg(ua, "1900 Bad .status command, wrong argument.\n");
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], N_("all")) == 0) {
- do_all_status(ua);
- return 1;
+ do_all_status(ua);
+ return 1;
} else if (strcasecmp(ua->argk[i], N_("dir")) == 0 ||
strcasecmp(ua->argk[i], N_("director")) == 0) {
- do_director_status(ua);
- return 1;
+ do_director_status(ua);
+ return 1;
} else if (strcasecmp(ua->argk[i], N_("client")) == 0) {
- client = get_client_resource(ua);
- if (client) {
- do_client_status(ua, client);
- }
- return 1;
+ client = get_client_resource(ua);
+ if (client) {
+ do_client_status(ua, client);
+ }
+ return 1;
} else {
- store = get_storage_resource(ua, 0);
- if (store) {
- do_storage_status(ua, store);
- }
- return 1;
+ store = get_storage_resource(ua, false/*no default*/);
+ if (store) {
+ do_storage_status(ua, store);
+ }
+ return 1;
}
}
/* If no args, ask for status type */
add_prompt(ua, N_("All"));
Dmsg0(20, "do_prompt: select daemon\n");
if ((item=do_prompt(ua, "", _("Select daemon type for status"), prmt, sizeof(prmt))) < 0) {
- return 1;
+ return 1;
}
Dmsg1(20, "item=%d\n", item);
switch (item) {
- case 0: /* Director */
- do_director_status(ua);
- break;
+ case 0: /* Director */
+ do_director_status(ua);
+ break;
case 1:
- store = select_storage_resource(ua);
- if (store) {
- do_storage_status(ua, store);
- }
- break;
+ store = select_storage_resource(ua);
+ if (store) {
+ do_storage_status(ua, store);
+ }
+ break;
case 2:
- client = select_client_resource(ua);
- if (client) {
- do_client_status(ua, client);
- }
- break;
+ client = select_client_resource(ua);
+ if (client) {
+ do_client_status(ua, client);
+ }
+ break;
case 3:
- do_all_status(ua);
- break;
+ do_all_status(ua);
+ break;
default:
- break;
+ break;
}
}
return 1;
foreach_res(store, R_STORAGE) {
found = false;
if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- continue;
+ continue;
}
for (j=0; j<i; j++) {
- if (strcmp(unique_store[j]->address, store->address) == 0 &&
- unique_store[j]->SDport == store->SDport) {
- found = true;
- break;
- }
+ if (strcmp(unique_store[j]->address, store->address) == 0 &&
+ unique_store[j]->SDport == store->SDport) {
+ found = true;
+ break;
+ }
}
if (!found) {
- unique_store[i++] = store;
+ unique_store[i++] = store;
Dmsg2(40, "Stuffing: %s:%d\n", store->address, store->SDport);
}
}
foreach_res(client, R_CLIENT) {
found = false;
if (!acl_access_ok(ua, Client_ACL, client->hdr.name)) {
- continue;
+ continue;
}
for (j=0; j<i; j++) {
- if (strcmp(unique_client[j]->address, client->address) == 0 &&
- unique_client[j]->FDport == client->FDport) {
- found = true;
- break;
- }
+ if (strcmp(unique_client[j]->address, client->address) == 0 &&
+ unique_client[j]->FDport == client->FDport) {
+ found = true;
+ break;
+ }
}
if (!found) {
- unique_client[i++] = client;
+ unique_client[i++] = client;
Dmsg2(40, "Stuffing: %s:%d\n", client->address, client->FDport);
}
}
char dt[MAX_TIME_LENGTH];
bsendmsg(ua, _("%s Version: %s (%s) %s %s %s\n"), my_name, VERSION, BDATE,
- HOST_OS, DISTNAME, DISTVER);
+ HOST_OS, DISTNAME, DISTVER);
bstrftime_nc(dt, sizeof(dt), daemon_start_time);
if (num_jobs_run == 1) {
bsendmsg(ua, _("Daemon started %s, 1 Job run since started.\n"), dt);
}
else {
bsendmsg(ua, _("Daemon started %s, %d Jobs run since started.\n"),
- dt, num_jobs_run);
+ dt, num_jobs_run);
}
if (debug_level > 0) {
char b1[35], b2[35], b3[35], b4[35];
bsendmsg(ua, _(" Heap: bytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
- edit_uint64_with_commas(sm_bytes, b1),
- edit_uint64_with_commas(sm_max_bytes, b2),
- edit_uint64_with_commas(sm_buffers, b3),
- edit_uint64_with_commas(sm_max_buffers, b4));
+ edit_uint64_with_commas(sm_bytes, b1),
+ edit_uint64_with_commas(sm_max_bytes, b2),
+ edit_uint64_with_commas(sm_buffers, b3),
+ edit_uint64_with_commas(sm_max_buffers, b4));
}
/*
* List scheduled Jobs
store->hdr.name, store->address, store->SDport);
if (!connect_to_storage_daemon(ua->jcr, 1, 15, 0)) {
bsendmsg(ua, _("\nFailed to connect to Storage daemon %s.\n====\n"),
- store->hdr.name);
+ store->hdr.name);
if (ua->jcr->store_bsock) {
- bnet_close(ua->jcr->store_bsock);
- ua->jcr->store_bsock = NULL;
+ bnet_close(ua->jcr->store_bsock);
+ ua->jcr->store_bsock = NULL;
}
return;
}
client->hdr.name, client->address, client->FDport);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
bsendmsg(ua, _("Failed to connect to Client %s.\n====\n"),
- client->hdr.name);
+ client->hdr.name);
if (ua->jcr->file_bsock) {
- bnet_close(ua->jcr->file_bsock);
- ua->jcr->file_bsock = NULL;
+ bnet_close(ua->jcr->file_bsock);
+ ua->jcr->file_bsock = NULL;
}
return;
}
/* Scheduling packet */
struct sched_pkt {
- dlink link; /* keep this as first item!!! */
+ dlink link; /* keep this as first item!!! */
JOB *job;
int level;
int priority;
jcr->db = NULL;
ok = complete_jcr_for_job(jcr, sp->job, sp->pool);
if (jcr->db) {
- close_db = true; /* new db opened, remember to close it */
+ close_db = true; /* new db opened, remember to close it */
}
if (ok) {
- mr.PoolId = jcr->PoolId;
- ok = find_next_volume_for_append(jcr, &mr, 0);
+ mr.PoolId = jcr->PoolId;
+ ok = find_next_volume_for_append(jcr, &mr, 0);
}
if (!ok) {
bstrncpy(mr.VolumeName, "*unknown*", sizeof(mr.VolumeName));
if (close_db) {
db_close_database(jcr, jcr->db);
}
- jcr->db = ua->db; /* restore ua db to jcr */
+ jcr->db = ua->db; /* restore ua db to jcr */
}
LockRes();
foreach_res(job, R_JOB) {
if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) {
- continue;
+ continue;
}
for (run=NULL; (run = find_next_run(run, job, runtime)); ) {
- level = job->JobLevel;
- if (run->level) {
- level = run->level;
- }
- priority = job->Priority;
- if (run->Priority) {
- priority = run->Priority;
- }
- if (!hdr_printed) {
- prt_runhdr(ua);
- hdr_printed = true;
- }
- sp = (sched_pkt *)malloc(sizeof(sched_pkt));
- sp->job = job;
- sp->level = level;
- sp->priority = priority;
- sp->runtime = runtime;
- sp->pool = run->pool;
- sched.binary_insert_multiple(sp, my_compare);
- num_jobs++;
+ level = job->JobLevel;
+ if (run->level) {
+ level = run->level;
+ }
+ priority = job->Priority;
+ if (run->Priority) {
+ priority = run->Priority;
+ }
+ if (!hdr_printed) {
+ prt_runhdr(ua);
+ hdr_printed = true;
+ }
+ sp = (sched_pkt *)malloc(sizeof(sched_pkt));
+ sp->job = job;
+ sp->level = level;
+ sp->priority = priority;
+ sp->runtime = runtime;
+ sp->pool = run->pool;
+ sched.binary_insert_multiple(sp, my_compare);
+ num_jobs++;
}
} /* end for loop over resources */
UnlockRes();
JCR *jcr;
int njobs = 0;
const char *msg;
- char *emsg; /* edited message */
+ char *emsg; /* edited message */
char dt[MAX_TIME_LENGTH];
char level[10];
bool pool_mem = false;
bsendmsg(ua, _("\nRunning Jobs:\n"));
foreach_jcr(jcr) {
njobs++;
- if (jcr->JobId == 0) { /* this is us */
- /* this is a console or other control job. We only show console
- * jobs in the status output.
- */
- if (jcr->JobType == JT_CONSOLE) {
- bstrftime_nc(dt, sizeof(dt), jcr->start_time);
+ if (jcr->JobId == 0) { /* this is us */
+ /* this is a console or other control job. We only show console
+ * jobs in the status output.
+ */
+ if (jcr->JobType == JT_CONSOLE) {
+ bstrftime_nc(dt, sizeof(dt), jcr->start_time);
bsendmsg(ua, _("Console connected at %s\n"), dt);
- }
- njobs--;
+ }
+ njobs--;
}
free_jcr(jcr);
}
bsendmsg(ua, _("======================================================================\n"));
foreach_jcr(jcr) {
if (jcr->JobId == 0 || !acl_access_ok(ua, Job_ACL, jcr->job->hdr.name)) {
- free_jcr(jcr);
- continue;
+ free_jcr(jcr);
+ continue;
}
njobs++;
switch (jcr->JobStatus) {
case JS_Created:
msg = _("is waiting execution");
- break;
+ break;
case JS_Running:
msg = _("is running");
- break;
+ break;
case JS_Blocked:
msg = _("is blocked");
- break;
+ break;
case JS_Terminated:
msg = _("has terminated");
- break;
+ break;
case JS_ErrorTerminated:
msg = _("has erred");
- break;
+ break;
case JS_Error:
msg = _("has errors");
- break;
+ break;
case JS_FatalError:
msg = _("has a fatal error");
- break;
+ break;
case JS_Differences:
msg = _("has verify differences");
- break;
+ break;
case JS_Canceled:
msg = _("has been canceled");
- break;
+ break;
case JS_WaitFD:
- emsg = (char *) get_pool_memory(PM_FNAME);
+ emsg = (char *) get_pool_memory(PM_FNAME);
Mmsg(emsg, _("is waiting on Client %s"), jcr->client->hdr.name);
- pool_mem = true;
- msg = emsg;
- break;
+ pool_mem = true;
+ msg = emsg;
+ break;
case JS_WaitSD:
- emsg = (char *) get_pool_memory(PM_FNAME);
+ emsg = (char *) get_pool_memory(PM_FNAME);
Mmsg(emsg, _("is waiting on Storage %s"), jcr->store->hdr.name);
- pool_mem = true;
- msg = emsg;
- break;
+ pool_mem = true;
+ msg = emsg;
+ break;
case JS_WaitStoreRes:
msg = _("is waiting on max Storage jobs");
- break;
+ break;
case JS_WaitClientRes:
msg = _("is waiting on max Client jobs");
- break;
+ break;
case JS_WaitJobRes:
msg = _("is waiting on max Job jobs");
- break;
+ break;
case JS_WaitMaxJobs:
msg = _("is waiting on max total jobs");
- break;
+ break;
case JS_WaitStartTime:
msg = _("is waiting for its start time");
- break;
+ break;
case JS_WaitPriority:
msg = _("is waiting for higher priority jobs to finish");
- break;
+ break;
default:
- emsg = (char *) get_pool_memory(PM_FNAME);
+ emsg = (char *) get_pool_memory(PM_FNAME);
Mmsg(emsg, _("is in unknown state %c"), jcr->JobStatus);
- pool_mem = true;
- msg = emsg;
- break;
+ pool_mem = true;
+ msg = emsg;
+ break;
}
/*
* Now report Storage daemon status code
*/
switch (jcr->SDJobStatus) {
case JS_WaitMount:
- if (pool_mem) {
- free_pool_memory(emsg);
- pool_mem = false;
- }
+ if (pool_mem) {
+ free_pool_memory(emsg);
+ pool_mem = false;
+ }
msg = _("is waiting for a mount request");
- break;
+ break;
case JS_WaitMedia:
- if (pool_mem) {
- free_pool_memory(emsg);
- pool_mem = false;
- }
+ if (pool_mem) {
+ free_pool_memory(emsg);
+ pool_mem = false;
+ }
msg = _("is waiting for an appendable Volume");
- break;
+ break;
case JS_WaitFD:
- if (!pool_mem) {
- emsg = (char *) get_pool_memory(PM_FNAME);
- pool_mem = true;
- }
+ if (!pool_mem) {
+ emsg = (char *) get_pool_memory(PM_FNAME);
+ pool_mem = true;
+ }
Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"),
- jcr->client->hdr.name, jcr->store->hdr.name);
- msg = emsg;
- break;
+ jcr->client->hdr.name, jcr->store->hdr.name);
+ msg = emsg;
+ break;
}
switch (jcr->JobType) {
case JT_ADMIN:
case JT_RESTORE:
bstrncpy(level, " ", sizeof(level));
- break;
+ break;
default:
- bstrncpy(level, level_to_str(jcr->JobLevel), sizeof(level));
- level[7] = 0;
- break;
+ bstrncpy(level, level_to_str(jcr->JobLevel), sizeof(level));
+ level[7] = 0;
+ break;
}
bsendmsg(ua, _("%6d %-6s %-20s %s\n"),
- jcr->JobId,
- level,
- jcr->Job,
- msg);
+ jcr->JobId,
+ level,
+ jcr->Job,
+ msg);
if (pool_mem) {
- free_pool_memory(emsg);
- pool_mem = false;
+ free_pool_memory(emsg);
+ pool_mem = false;
}
free_jcr(jcr);
}
char *p;
for (int i=0; i<3; i++) {
if ((p=strrchr(JobName, '.')) != NULL) {
- *p = 0;
- }
+ *p = 0;
+ }
}
if (!acl_access_ok(ua, Job_ACL, JobName)) {
- continue;
+ continue;
}
bstrftime_nc(dt, sizeof(dt), je->end_time);
case JT_ADMIN:
case JT_RESTORE:
bstrncpy(level, " ", sizeof(level));
- break;
+ break;
default:
- bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
- level[4] = 0;
- break;
+ bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
+ level[4] = 0;
+ break;
}
switch (je->JobStatus) {
case JS_Created:
termstat = _("Created");
- break;
+ break;
case JS_FatalError:
case JS_ErrorTerminated:
termstat = _("Error");
- break;
+ break;
case JS_Differences:
termstat = _("Diffs");
- break;
+ break;
case JS_Canceled:
termstat = _("Cancel");
- break;
+ break;
case JS_Terminated:
termstat = _("OK");
- break;
+ break;
default:
termstat = _("Other");
- break;
+ break;
}
bsendmsg(ua, _("%6d %-6s %8s %14s %-7s %-8s %s\n"),
- je->JobId,
- level,
- edit_uint64_with_commas(je->JobFiles, b1),
- edit_uint64_with_commas(je->JobBytes, b2),
- termstat,
- dt, JobName);
+ je->JobId,
+ level,
+ edit_uint64_with_commas(je->JobFiles, b1),
+ edit_uint64_with_commas(je->JobBytes, b2),
+ termstat,
+ dt, JobName);
}
bsendmsg(ua, _("\n"));
unlock_last_jobs_list();
/* This is mostly to indicate that we are here */
ok = bnet_fsend(dir, Device_update,
jcr->Job,
- dev_name.c_str(), /* Changer name */
- 0, 0, 0, /* append, read, num_writers */
- 0, 0, 0, /* is_open, is_labeled, offline */
- 0, 0, /* reserved, max_writers */
- 0, /* Autoselect */
- changer->device->size(), /* Number of devices */
+ dev_name.c_str(), /* Changer name */
+ 0, 0, 0, /* append, read, num_writers */
+ 0, 0, 0, /* is_open, is_labeled, offline */
+ 0, 0, /* reserved, max_writers */
+ 0, /* Autoselect */
+ changer->device->size(), /* Number of devices */
"0", /* PoolId */
"*", /* ChangerName */
- MediaType.c_str(), /* MediaType */
+ MediaType.c_str(), /* MediaType */
"*"); /* VolName */
Dmsg1(100, ">dird: %s\n", dir->msg);
return ok;
* dir_find_next_appendable_volume()
*
* Returns: true on success and vol info in dcr->VolCatInfo
- * false on failure
+ * false on failure
*/
static bool do_get_volume_info(DCR *dcr)
{
int n;
int InChanger;
- dcr->VolumeName[0] = 0; /* No volume */
+ dcr->VolumeName[0] = 0; /* No volume */
if (bnet_recv(dir) <= 0) {
Dmsg0(200, "getvolname error bnet_recv\n");
Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n"));
memset(&vol, 0, sizeof(vol));
Dmsg1(100, "<dird %s", dir->msg);
n = sscanf(dir->msg, OK_media, vol.VolCatName,
- &vol.VolCatJobs, &vol.VolCatFiles,
- &vol.VolCatBlocks, &vol.VolCatBytes,
- &vol.VolCatMounts, &vol.VolCatErrors,
- &vol.VolCatWrites, &vol.VolCatMaxBytes,
- &vol.VolCatCapacityBytes, vol.VolCatStatus,
- &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles,
- &InChanger, &vol.VolReadTime, &vol.VolWriteTime,
- &vol.EndFile, &vol.EndBlock, &vol.VolCatParts,
- &vol.LabelType);
+ &vol.VolCatJobs, &vol.VolCatFiles,
+ &vol.VolCatBlocks, &vol.VolCatBytes,
+ &vol.VolCatMounts, &vol.VolCatErrors,
+ &vol.VolCatWrites, &vol.VolCatMaxBytes,
+ &vol.VolCatCapacityBytes, vol.VolCatStatus,
+ &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles,
+ &InChanger, &vol.VolReadTime, &vol.VolWriteTime,
+ &vol.EndFile, &vol.EndBlock, &vol.VolCatParts,
+ &vol.LabelType);
if (n != 21) {
Dmsg2(100, "Bad response from Dir fields=%d: %s\n", n, dir->msg);
Mmsg(jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg);
return false;
}
- vol.InChanger = InChanger; /* bool in structure */
+ vol.InChanger = InChanger; /* bool in structure */
unbash_spaces(vol.VolCatName);
bstrncpy(dcr->VolumeName, vol.VolCatName, sizeof(dcr->VolumeName));
memcpy(&dcr->VolCatInfo, &vol, sizeof(dcr->VolCatInfo));
Dmsg2(300, "do_reqest_vol_info return true slot=%d Volume=%s\n",
- vol.Slot, vol.VolCatName);
+ vol.Slot, vol.VolCatName);
return true;
}
* Get Volume info for a specific volume from the Director's Database
*
* Returns: true on success (Director guarantees that Pool and MediaType
- * are correct and VolStatus==Append or
- * VolStatus==Recycle)
- * false on failure
+ * are correct and VolStatus==Append or
+ * VolStatus==Recycle)
+ * false on failure
*
- * Volume information returned in dcr->VolCatInfo
+ * Volume information returned in dcr->VolCatInfo
*/
bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
{
/*
* Get info on the next appendable volume in the Director's database
* Returns: true on success
- * false on failure
+ * false on failure
*
- * Volume information returned in dcr
+ * Volume information returned in dcr
*
*/
bool dir_find_next_appendable_volume(DCR *dcr)
Dmsg0(200, "dir_find_next_appendable_volume\n");
/*
* Try the twenty oldest or most available volumes. Note,
- * the most available could already be mounted on another
- * drive, so we continue looking for a not in use Volume.
+ * the most available could already be mounted on another
+ * drive, so we continue looking for a not in use Volume.
*/
for (int vol_index=1; vol_index < 20; vol_index++) {
bash_spaces(dcr->media_type);
Dmsg1(100, ">dird: %s", dir->msg);
bool OK = do_get_volume_info(dcr);
if (OK) {
- if (is_volume_in_use(dcr)) {
+ if (dcr->any_volume || !is_volume_in_use(dcr)) {
+ found = true;
+ break;
+ } else {
Dmsg1(100, "Volume %s is in use.\n", dcr->VolumeName);
- continue;
- } else {
- found = true;
- break;
- }
+ continue;
+ }
} else {
Dmsg0(200, "No volume info, return false\n");
- return false;
+ return false;
}
}
if (found) {
/* Just labeled or relabeled the tape */
if (label) {
bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
- vol->VolCatBytes = 1; /* indicates tape labeled */
+ vol->VolCatBytes = 1; /* indicates tape labeled */
}
pm_strcpy(VolumeName, vol->VolCatName);
bash_spaces(VolumeName);
vol->VolCatMounts, vol->VolCatErrors,
vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2),
LastWritten, vol->VolCatStatus, vol->Slot, label,
- InChanger, /* bool in structure */
+ InChanger, /* bool in structure */
edit_uint64(vol->VolReadTime, ed3),
edit_uint64(vol->VolWriteTime, ed4),
vol->VolCatParts);
if (!do_get_volume_info(dcr)) {
Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
Pmsg2(000, _("Didn't get vol info vol=%s: ERR=%s"),
- vol->VolCatName, jcr->errmsg);
+ vol->VolCatName, jcr->errmsg);
return false;
}
Dmsg1(420, "get_volume_info(): %s", dir->msg);
BSOCK *dir = jcr->dir_bsock;
if (!dcr->WroteVol) {
- return true; /* nothing written to tape */
+ return true; /* nothing written to tape */
}
dcr->WroteVol = false;
if (bnet_recv(dir) <= 0) {
Dmsg0(190, "create_jobmedia error bnet_recv\n");
Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"),
- bnet_strerror(dir));
+ bnet_strerror(dir));
return false;
}
Dmsg1(100, "<dir: %s", dir->msg);
dir->msglen = sprintf(dir->msg, FileAttributes, jcr->Job);
dir->msg = check_pool_memory_size(dir->msg, dir->msglen +
- sizeof(DEV_RECORD) + rec->data_len);
+ sizeof(DEV_RECORD) + rec->data_len);
ser_begin(dir->msg + dir->msglen, 0);
ser_uint32(rec->VolSessionId);
ser_uint32(rec->VolSessionTime);
* Leaves with device blocked.
*
* Returns: true on success (operator issues a mount command)
- * false on failure
- * Note, must create dev->errmsg on error return.
+ * false on failure
+ * Note, must create dev->errmsg on error return.
*
* On success, dcr->VolumeName and dcr->VolCatInfo contain
- * information on suggested volume, but this may not be the
- * same as what is actually mounted.
+ * information on suggested volume, but this may not be the
+ * same as what is actually mounted.
*
* When we return with success, the correct tape may or may not
- * actually be mounted. The calling routine must read it and
- * verify the label.
+ * actually be mounted. The calling routine must read it and
+ * verify the label.
*/
bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
{
ASSERT(dev->dev_blocked);
for ( ;; ) {
if (job_canceled(jcr)) {
- Mmsg(dev->errmsg,
+ Mmsg(dev->errmsg,
_("Job %s canceled while waiting for mount on Storage Device \"%s\".\n"),
- jcr->Job, dev->print_name());
+ jcr->Job, dev->print_name());
Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
- return false;
+ return false;
}
/* First pass, we *know* there are no appendable volumes, so no need to call */
if (!first) {
- P(dev->mutex);
- OK = dir_find_next_appendable_volume(dcr); /* get suggested volume */
- V(dev->mutex);
+ P(dev->mutex);
+ OK = dir_find_next_appendable_volume(dcr); /* get suggested volume */
+ V(dev->mutex);
}
if (!first && OK) {
- unmounted = is_device_unmounted(dev);
- /*
- * If we have a valid volume name and we are not
- * removable media, return now, or if we have a
- * Slot for an autochanger, otherwise wait
- * for the operator to mount the media.
- */
- if (!unmounted && ((dcr->VolumeName[0] && !dev_cap(dev, CAP_REM) &&
- dev_cap(dev, CAP_LABEL)) ||
- (dcr->VolumeName[0] && dcr->VolCatInfo.Slot))) {
+ unmounted = is_device_unmounted(dev);
+ /*
+ * If we have a valid volume name and we are not
+ * removable media, return now, or if we have a
+ * Slot for an autochanger, otherwise wait
+ * for the operator to mount the media.
+ */
+ if (!unmounted && ((dcr->VolumeName[0] && !dev_cap(dev, CAP_REM) &&
+ dev_cap(dev, CAP_LABEL)) ||
+ (dcr->VolumeName[0] && dcr->VolCatInfo.Slot))) {
Dmsg0(400, "Return 1 from mount without wait.\n");
- return true;
- }
- jstat = JS_WaitMount;
- if (!dev->poll) {
- Jmsg(jcr, M_MOUNT, 0, _(
+ return true;
+ }
+ jstat = JS_WaitMount;
+ if (!dev->poll) {
+ Jmsg(jcr, M_MOUNT, 0, _(
"Please mount Volume \"%s\" on Storage Device %s for Job %s\n"
"Use \"mount\" command to release Job.\n"),
- dcr->VolumeName, dev->print_name(), jcr->Job);
+ dcr->VolumeName, dev->print_name(), jcr->Job);
Dmsg3(400, "Mount %s on %s for Job %s\n",
- dcr->VolumeName, dcr->dev_name, jcr->Job);
- }
+ dcr->VolumeName, dcr->dev_name, jcr->Job);
+ }
} else {
- jstat = JS_WaitMedia;
- if (!dev->poll) {
- Jmsg(jcr, M_MOUNT, 0, _(
+ jstat = JS_WaitMedia;
+ if (!dev->poll) {
+ Jmsg(jcr, M_MOUNT, 0, _(
"Job %s waiting. Cannot find any appendable volumes.\n"
"Please use the \"label\" command to create a new Volume for:\n"
" Storage: %s\n"
" Media type: %s\n"
" Pool: %s\n"),
- jcr->Job,
- dev->print_name(),
- dcr->media_type,
- dcr->pool_name);
- }
+ jcr->Job,
+ dev->print_name(),
+ dcr->media_type,
+ dcr->pool_name);
+ }
}
first = false;
stat = wait_for_sysop(dcr);
if (dev->poll) {
Dmsg1(400, "Poll timeout in create append vol on device %s\n", dev->print_name());
- continue;
+ continue;
}
if (stat == ETIMEDOUT) {
- if (!double_dev_wait_time(dev)) {
+ if (!double_dev_wait_time(dev)) {
Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"),
- dev->print_name(), jcr->Job);
+ dev->print_name(), jcr->Job);
Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
Dmsg1(400, "Gave up waiting on device %s\n", dev->print_name());
- return false; /* exceeded maximum waits */
- }
- continue;
+ return false; /* exceeded maximum waits */
+ }
+ continue;
}
if (stat == EINVAL) {
- berrno be;
+ berrno be;
Mmsg2(dev->errmsg, _("pthread error in mount_next_volume stat=%d ERR=%s\n"),
- stat, be.strerror(stat));
+ stat, be.strerror(stat));
Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
- return false;
+ return false;
}
if (stat != 0) {
- berrno be;
+ berrno be;
Jmsg(jcr, M_WARNING, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat,
- be.strerror(stat));
+ be.strerror(stat));
}
Dmsg1(400, "Someone woke me for device %s\n", dev->print_name());
/* If no VolumeName, and cannot get one, try again */
P(dev->mutex);
if (dcr->VolumeName[0] == 0 && !job_canceled(jcr) &&
- !dir_find_next_appendable_volume(dcr)) {
- V(dev->mutex);
- Jmsg(jcr, M_MOUNT, 0, _(
+ !dir_find_next_appendable_volume(dcr)) {
+ V(dev->mutex);
+ Jmsg(jcr, M_MOUNT, 0, _(
"Someone woke me up, but I cannot find any appendable\n"
"volumes for Job=%s.\n"), jcr->Job);
- /* Restart wait counters after user interaction */
- init_device_wait_timers(dcr);
- continue;
+ /* Restart wait counters after user interaction */
+ init_device_wait_timers(dcr);
+ continue;
}
V(dev->mutex);
unmounted = is_device_unmounted(dev);
if (unmounted) {
Dmsg0(400, "Device is unmounted. Must wait.\n");
- continue; /* continue to wait */
+ continue; /* continue to wait */
}
/*
* Request to mount specific Volume
*
* Entered with device blocked and dcr->VolumeName is desired
- * volume.
+ * volume.
* Leaves with device blocked.
*
* Returns: true on success (operator issues a mount command)
- * false on failure
- * Note, must create dev->errmsg on error return.
+ * false on failure
+ * Note, must create dev->errmsg on error return.
*
*/
bool dir_ask_sysop_to_mount_volume(DCR *dcr)
for ( ;; ) {
if (job_canceled(jcr)) {
Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device %s.\n"),
- jcr->Job, dev->print_name());
- return false;
+ jcr->Job, dev->print_name());
+ return false;
}
if (!dev->poll) {
Jmsg(jcr, M_MOUNT, 0, _("Please mount Volume \"%s\" on Storage Device %s for Job %s\n"),
- dcr->VolumeName, dev->print_name(), jcr->Job);
+ dcr->VolumeName, dev->print_name(), jcr->Job);
Dmsg3(400, "Mount \"%s\" on device \"%s\" for Job %s\n",
- dcr->VolumeName, dev->print_name(), jcr->Job);
+ dcr->VolumeName, dev->print_name(), jcr->Job);
}
jcr->JobStatus = JS_WaitMount;
dir_send_job_status(jcr);
- stat = wait_for_sysop(dcr); ; /* wait on device */
+ stat = wait_for_sysop(dcr); ; /* wait on device */
if (dev->poll) {
Dmsg1(400, "Poll timeout in mount vol on device %s\n", dev->print_name());
Dmsg1(400, "Blocked=%s\n", dev->print_blocked());
- return true;
+ return true;
}
if (stat == ETIMEDOUT) {
- if (!double_dev_wait_time(dev)) {
+ if (!double_dev_wait_time(dev)) {
Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"),
- dev->print_name(), jcr->Job);
+ dev->print_name(), jcr->Job);
Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
Dmsg1(400, "Gave up waiting on device %s\n", dev->print_name());
- return false; /* exceeded maximum waits */
- }
- continue;
+ return false; /* exceeded maximum waits */
+ }
+ continue;
}
if (stat == EINVAL) {
- berrno be;
+ berrno be;
Mmsg2(dev->errmsg, _("pthread error in mount_volume stat=%d ERR=%s\n"),
- stat, be.strerror(stat));
+ stat, be.strerror(stat));
Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
- return false;
+ return false;
}
if (stat != 0) {
- berrno be;
+ berrno be;
Jmsg(jcr, M_FATAL, 0, _("pthread error in mount_next_volume stat=%d: ERR=%s\n"), stat,
- be.strerror(stat));
+ be.strerror(stat));
}
Dmsg1(400, "Someone woke me for device %s\n", dev->print_name());
break;
* Routines for handling the autochanger.
*
* Kern Sibbald, August MMII
- *
+ *
* Version $Id$
*/
/*
* dir bsock.
*
* Returns: 1 on success
- * 0 on failure (no changer available)
- * -1 on error on autochanger
+ * 0 on failure (no changer available)
+ * -1 on error on autochanger
*/
int autoload_device(DCR *dcr, int writing, BSOCK *dir)
{
DEVICE *dev = dcr->dev;
int slot;
int drive = dev->drive_index;
- int rtn_stat = -1; /* error status */
+ int rtn_stat = -1; /* error status */
POOLMEM *changer;
slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
/*
- * Handle autoloaders here. If we cannot autoload it, we
+ * Handle autoloaders here. If we cannot autoload it, we
* will return 0 so that the sysop will be asked to load it.
*/
if (writing && dev->is_autochanger() && slot <= 0) {
if (dir) {
- return 0; /* For user, bail out right now */
+ return 0; /* For user, bail out right now */
}
if (dir_find_next_appendable_volume(dcr)) {
- slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
+ slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
} else {
- slot = 0;
+ slot = 0;
}
}
Dmsg1(400, "Want changer slot=%d\n", slot);
/* If tape we want is not loaded, load it. */
if (loaded != slot) {
- if (!unload_autochanger(dcr, loaded)) {
- goto bail_out;
- }
- /*
- * Load the desired cassette
- */
+ if (!unload_autochanger(dcr, loaded)) {
+ goto bail_out;
+ }
+ /*
+ * Load the desired cassette
+ */
Dmsg1(400, "Doing changer load slot %d\n", slot);
- Jmsg(jcr, M_INFO, 0,
+ Jmsg(jcr, M_INFO, 0,
_("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"),
- slot, drive);
- dcr->VolCatInfo.Slot = slot; /* slot to be loaded */
- changer = edit_device_codes(dcr, changer,
+ slot, drive);
+ dcr->VolCatInfo.Slot = slot; /* slot to be loaded */
+ changer = edit_device_codes(dcr, changer,
dcr->device->changer_command, "load");
- status = run_program(changer, timeout, NULL);
- if (status == 0) {
+ status = run_program(changer, timeout, NULL);
+ if (status == 0) {
Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"),
- slot, drive);
- dev->Slot = slot; /* set currently loaded slot */
- } else {
- berrno be;
- be.set_errno(status);
+ slot, drive);
+ dev->Slot = slot; /* set currently loaded slot */
+ } else {
+ berrno be;
+ be.set_errno(status);
Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"),
- slot, drive, be.strerror());
- goto bail_out;
- }
- unlock_changer(dcr);
+ slot, drive, be.strerror());
+ goto bail_out;
+ }
+ unlock_changer(dcr);
Dmsg2(400, "load slot %d status=%d\n", slot, status);
} else {
- status = 0; /* we got what we want */
- dev->Slot = slot; /* set currently loaded slot */
+ status = 0; /* we got what we want */
+ dev->Slot = slot; /* set currently loaded slot */
}
Dmsg1(400, "After changer, status=%d\n", status);
- if (status == 0) { /* did we succeed? */
- rtn_stat = 1; /* tape loaded by changer */
+ if (status == 0) { /* did we succeed? */
+ rtn_stat = 1; /* tape loaded by changer */
}
} else {
- rtn_stat = 0; /* no changer found */
+ rtn_stat = 0; /* no changer found */
}
free_pool_memory(changer);
return rtn_stat;
/*
* Returns: -1 if error from changer command
- * slot otherwise
+ * slot otherwise
*/
int get_autochanger_loaded_slot(DCR *dcr)
{
/* Find out what is loaded, zero means device is unloaded */
Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded drive %d\" command.\n"),
- drive);
+ drive);
changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "loaded");
*results = 0;
status = run_program(changer, timeout, results);
loaded = atoi(results);
if (loaded > 0) {
Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result is Slot %d.\n"),
- drive, loaded);
- dcr->dev->Slot = loaded;
+ drive, loaded);
+ dcr->dev->Slot = loaded;
} else {
Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result: nothing loaded.\n"),
- drive);
- dcr->dev->Slot = 0;
+ drive);
+ dcr->dev->Slot = 0;
}
} else {
berrno be;
be.set_errno(status);
Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"loaded drive %d\" command: ERR=%s.\n"),
- drive, be.strerror());
- loaded = -1; /* force unload */
+ drive, be.strerror());
+ loaded = -1; /* force unload */
}
unlock_changer(dcr);
free_pool_memory(changer);
/*
* Unload the volume, if any, in this drive
+ * On entry: loaded == 0 -- nothing to do
+ * loaded < 0 -- check if anything to do
+ * loaded > 0 -- load slot == loaded
*/
bool unload_autochanger(DCR *dcr, int loaded)
{
JCR *jcr = dcr->jcr;
int slot;
uint32_t timeout = dcr->device->max_changer_wait;
+ bool ok = true;
+
+ if (loaded == 0) {
+ return true;
+ }
if (!dev->is_autochanger() || !dcr->device->changer_name ||
!dcr->device->changer_command) {
/* We are going to load a new tape, so close the device */
force_close_device(dev);
- if (loaded <= 0) {
+ if (loaded < 0) {
loaded = get_autochanger_loaded_slot(dcr);
}
if (loaded > 0) {
POOLMEM *changer = get_pool_memory(PM_FNAME);
Jmsg(jcr, M_INFO, 0,
_("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
- loaded, dev->drive_index);
+ loaded, dev->drive_index);
slot = dcr->VolCatInfo.Slot;
dcr->VolCatInfo.Slot = loaded;
changer = edit_device_codes(dcr, changer,
unlock_changer(dcr);
dcr->VolCatInfo.Slot = slot;
if (stat != 0) {
- berrno be;
- be.set_errno(stat);
+ berrno be;
+ be.set_errno(stat);
Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
- slot, dev->drive_index, be.strerror());
- free_pool_memory(changer);
- return false;
+ slot, dev->drive_index, be.strerror());
+ ok = false;
} else {
- dev->Slot = 0; /* nothing loaded */
+ dev->Slot = 0; /* nothing loaded */
}
free_pool_memory(changer);
}
- return true;
+ return ok;
}
if (!dev->is_autochanger() || !dcr->device->changer_name ||
!dcr->device->changer_command) {
bnet_fsend(dir, _("3993 Device %s not an autochanger device.\n"),
- dev->print_name());
+ dev->print_name());
return false;
}
changer = get_pool_memory(PM_FNAME);
/* List command? */
if (strcmp(cmd, "list") == 0) {
- unload_autochanger(dcr, 0);
+ unload_autochanger(dcr, -1);
}
/* Now issue the command */
changer = edit_device_codes(dcr, changer,
- dcr->device->changer_command, cmd);
+ dcr->device->changer_command, cmd);
bnet_fsend(dir, _("3306 Issuing autochanger \"%s\" command.\n"), cmd);
lock_changer(dcr);
bpipe = open_bpipe(changer, timeout, "r");
if (strcmp(cmd, "list") == 0) {
/* Get output from changer */
while (fgets(dir->msg, len, bpipe->rfd)) {
- dir->msglen = strlen(dir->msg);
+ dir->msglen = strlen(dir->msg);
Dmsg1(100, "<stored: %s\n", dir->msg);
- bnet_send(dir);
+ bnet_send(dir);
}
} else {
/* For slots command, read a single line */
Dmsg1(100, "<stored: %s", dir->msg);
bnet_send(dir);
}
-
+
stat = close_bpipe(bpipe);
unlock_changer(dcr);
if (stat != 0) {
Dmsg1(1800, "edit_device_codes: %s\n", imsg);
for (p=imsg; *p; p++) {
if (*p == '%') {
- switch (*++p) {
+ switch (*++p) {
case '%':
str = "%";
- break;
+ break;
case 'a':
- str = dcr->dev->archive_name();
- break;
+ str = dcr->dev->archive_name();
+ break;
case 'c':
- str = NPRT(dcr->device->changer_name);
- break;
+ str = NPRT(dcr->device->changer_name);
+ break;
case 'd':
sprintf(add, "%d", dcr->dev->drive_index);
- str = add;
- break;
+ str = add;
+ break;
case 'o':
- str = NPRT(cmd);
- break;
+ str = NPRT(cmd);
+ break;
case 's':
sprintf(add, "%d", dcr->VolCatInfo.Slot - 1);
- str = add;
- break;
+ str = add;
+ break;
case 'S':
sprintf(add, "%d", dcr->VolCatInfo.Slot);
- str = add;
- break;
+ str = add;
+ break;
case 'j': /* Job name */
- str = dcr->jcr->Job;
- break;
+ str = dcr->jcr->Job;
+ break;
case 'v':
- str = NPRT(dcr->VolumeName);
- break;
+ str = NPRT(dcr->VolumeName);
+ break;
case 'f':
- str = NPRT(dcr->jcr->client_name);
- break;
+ str = NPRT(dcr->jcr->client_name);
+ break;
- default:
+ default:
add[0] = '%';
- add[1] = *p;
- add[2] = 0;
- str = add;
- break;
- }
+ add[1] = *p;
+ add[2] = 0;
+ str = add;
+ break;
+ }
} else {
- add[0] = *p;
- add[1] = 0;
- str = add;
+ add[0] = *p;
+ add[1] = 0;
+ str = add;
}
Dmsg1(1900, "add_str %s\n", str);
pm_strcat(&omsg, (char *)str);
bool WroteVol; /* set if Volume written */
bool NewFile; /* set when EOF written */
bool reserved_device; /* set if reserve done */
+ bool any_volume; /* Any OK for dir_find_next... */
uint32_t VolFirstIndex; /* First file index this Volume */
uint32_t VolLastIndex; /* Last file index this Volume */
uint32_t FileIndex; /* Current File Index */
DIRSTORE *store;
DEVRES *device;
bool PreferMountedVols;
+ bool exact_match;
+ bool have_volume;
char VolumeName[MAX_NAME_LENGTH];
};
static pthread_mutex_t search_lock = PTHREAD_MUTEX_INITIALIZER;
/* Forward referenced functions */
-static int can_reserve_drive(DCR *dcr, bool PerferMountedVols);
+static int can_reserve_drive(DCR *dcr, RCTX &rctx);
static int search_res_for_device(RCTX &rctx);
static int reserve_device(RCTX &rctx);
static bool reserve_device_for_read(DCR *dcr);
-static bool reserve_device_for_append(DCR *dcr, bool PreferMountedVols);
+static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
static bool use_storage_cmd(JCR *jcr);
bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx);
* drive with something mounted. If that fails, then we
* do a second pass with PerferMountedVols set false.
*/
+ rctx.exact_match = true;
+ if ((ok = find_suitable_device_for_job(jcr, rctx))) {
+ goto done;
+ }
+ rctx.exact_match = false;
rctx.PreferMountedVols = jcr->PreferMountedVols;
ok = find_suitable_device_for_job(jcr, rctx);
if (ok) {
bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
bstrncpy(dcr->dev_name, rctx.device_name, name_len);
if (rctx.store->append == SD_APPEND) {
-#ifdef implemented
- if (dir_find_next_appendable_volume(dcr)) {
- Dmsg1(000, "Looking for Volume=%s\n", dcr->VolumeName);
- } else {
- Dmsg0(000, "No next volume found\n");
- dcr->VolumeName[0] = 0;
+ if (rctx.exact_match && !rctx.have_volume) {
+ dcr->any_volume = true;
+ if (dir_find_next_appendable_volume(dcr)) {
+ Dmsg1(000, "Looking for Volume=%s\n", dcr->VolumeName);
+ bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
+ rctx.have_volume = true;
+ } else {
+ Dmsg0(000, "No next volume found\n");
+ rctx.VolumeName[0] = 0;
+ }
}
-#endif
- ok = reserve_device_for_append(dcr, rctx.PreferMountedVols);
+ ok = reserve_device_for_append(dcr, rctx);
Dmsg3(200, "dev_name=%s mediatype=%s ok=%d\n", dcr->dev_name, dcr->media_type, ok);
} else {
ok = reserve_device_for_read(dcr);
* the first tor reserve the device, we put the pool
* name and pool type in the device record.
*/
-static bool reserve_device_for_append(DCR *dcr, bool PreferMountedVols)
+static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
{
JCR *jcr = dcr->jcr;
DEVICE *dev = dcr->dev;
Dmsg1(190, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
- if (can_reserve_drive(dcr, PreferMountedVols) != 1) {
+ if (can_reserve_drive(dcr, rctx) != 1) {
Mmsg1(jcr->errmsg, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
Dmsg1(100, "%s", jcr->errmsg);
goto bail_out;
* 0 if we should wait
* -1 on error
*/
-static int can_reserve_drive(DCR *dcr, bool PreferMountedVols)
+static int can_reserve_drive(DCR *dcr, RCTX &rctx)
{
DEVICE *dev = dcr->dev;
JCR *jcr = dcr->jcr;
- if (PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
+ /* Check for prefer mounted volumes */
+ if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
+ Dmsg0(200, "want mounted -- no vol\n");
return 0; /* No volume mounted */
}
+ /* Check for exact Volume name match */
+ if (rctx.exact_match && rctx.have_volume &&
+ strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
+ Dmsg2(200, "Not exact match have=%s want=%s\n",
+ dev->VolHdr.VolumeName, rctx.VolumeName);
+ return 0;
+ }
+
/*
* Handle the case that there are no writers
*/
if (dev->num_writers == 0) {
/* Now check if there are any reservations on the drive */
if (dev->reserved_device) {
- /* Yes, now check if we want the same Pool and pool type */
+ /* Now check if we want the same Pool and pool type */
if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
strcmp(dev->pool_type, dcr->pool_type) == 0) {
/* OK, compatible device */
Dmsg0(200, "got dev: num_writers=0, reserved, pool matches\n");
+ return 1;
} else {
/* Drive not suitable for us */
Dmsg2(200, "busy: num_writers=0, reserved, pool=%s wanted=%s\n",
strcmp(dev->pool_type, dcr->pool_type) == 0) {
Dmsg0(200, "got dev: num_writers=0, can_append, pool matches\n");
/* OK, compatible device */
+ return 1;
} else {
/* Changing pool, unload old tape if any in drive */
Dmsg0(200, "got dev: num_writers=0, reserved, pool change\n");
/* */
#undef VERSION
#define VERSION "1.37.36"
-#define BDATE "16 August 2005"
-#define LSMDATE "16Aug05"
+#define BDATE "18 August 2005"
+#define LSMDATE "18Aug05"
/* Debug flags */
#undef DEBUG