Kern's ToDo List
- 06 July 2004
+ 14 July 2004
1.35 Items to do:
-- Require resource names to be unique.
+- Make sure that all errors from libacl are printed.
- Add new DCR calling sequences everywhere in SD.
This will permit simultaneous use of multiple
devices by a single job.
- Document a get out of jail procedure if everything breaks if
you lost/broke the Catalog -- do the same for "I know my
file is there how do I get it back?".
-- Look at Win32 inc problem when new directory added files not saved???
- Make FD run on Win95 if possible:
The error I when I installed 1.34.2 clients:
The BACULA-FD file is
- Look at adding Client run command that will use the
port opened by the client.
- Fix find_device in stored/dircmd.c:462
+- Make entering multiple Storage names in Dir illegal.
Documentation to do: (any release a little bit at a time)
- Document query file format.
- Test new despooling error recovery code when partition fills.
- Sort Scheduled jobs status listing by start time.
- Add priority to Scheduled jobs status listing.
+- Look at Win32 inc problem when new directory added files not saved???
+- Require resource names to be unique.
msg_type = M_INFO; /* by default INFO message */
switch (jcr->JobStatus) {
- case JS_Terminated:
- term_msg = _("Admin OK");
- break;
- case JS_FatalError:
- case JS_ErrorTerminated:
- term_msg = _("*** Admin Error ***");
- msg_type = M_ERROR; /* Generate error message */
- break;
- case JS_Canceled:
- term_msg = _("Admin Canceled");
- break;
- default:
- term_msg = term_code;
- sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
- break;
+ case JS_Terminated:
+ term_msg = _("Admin OK");
+ break;
+ case JS_FatalError:
+ case JS_ErrorTerminated:
+ term_msg = _("*** Admin Error ***");
+ msg_type = M_ERROR; /* Generate error message */
+ break;
+ case JS_Canceled:
+ term_msg = _("Admin Canceled");
+ break;
+ default:
+ term_msg = term_code;
+ sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
+ break;
}
bstrftime(sdt, sizeof(sdt), jcr->jr.StartTime);
bstrftime(edt, sizeof(edt), jcr->jr.EndTime);
{"no", INC_KW_KEEPATIME, "0"},
{"yes", INC_KW_EXCLUDE, "e"},
{"no", INC_KW_EXCLUDE, "0"},
- {"yes", INC_KW_ACL, "A"},
- {"no", INC_KW_ACL, "0"},
- {NULL, 0, 0}
+ {"yes", INC_KW_ACL, "A"},
+ {"no", INC_KW_ACL, "0"},
+ {NULL, 0, 0}
};
sm_check(__FILE__, __LINE__, true);
for ( ;; ) {
-
Dmsg0(200, "=====Start Job=========\n");
jcr->start_time = time(NULL); /* set the real start time */
set_jcr_job_status(jcr, JS_Running);
*/
void update_job_end_record(JCR *jcr)
{
- if (jcr->jr.EndTime == 0) {
- jcr->jr.EndTime = time(NULL);
- }
+ jcr->jr.EndTime = time(NULL);
jcr->end_time = jcr->jr.EndTime;
jcr->jr.JobId = jcr->JobId;
jcr->jr.JobStatus = jcr->JobStatus;
jcr->JobStatus != JS_Canceled &&
jcr->job->RescheduleTimes > 0 &&
jcr->reschedule_count < jcr->job->RescheduleTimes) {
+ char dt[50];
/*
* Reschedule this job by cleaning it up, but
jcr->sched_time = time(NULL) + jcr->job->RescheduleInterval;
Dmsg2(300, "Rescheduled Job %s to re-run in %d seconds.\n", jcr->Job,
(int)jcr->job->RescheduleInterval);
+ bstrftime(dt, sizeof(dt), time(NULL));
+ Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds.\n"),
+ jcr->Job, dt, (int)jcr->job->RescheduleInterval);
jcr->JobStatus = JS_Created; /* force new status */
dird_free_jcr(jcr); /* partial cleanup old stuff */
if (jcr->JobBytes == 0) {
"AND Path.Path='%s' "
"AND Filename.Name='%s' "
"AND Client.Name='%s' "
+ "AND Job.ClientId=Client.ClientId "
"AND Path.PathId=File.PathId "
"AND Filename.FilenameId=File.FilenameId "
"ORDER BY Job.StartTime DESC LIMIT 1";
mr.InChanger = InChanger;
Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
if (!db_create_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
return 1;
}
if (i == startnum) {
pr.NumVols += num;
Dmsg0(200, "Update pool record.\n");
if (db_update_pool_record(ua->jcr, ua->db, &pr) != 1) {
- bsendmsg(ua, db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
return 1;
}
bsendmsg(ua, _("%d Volumes created in pool %s\n"), num, pr.Name);
break;
case -1:
- bsendmsg(ua, db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
break;
default:
}
/* Modify the Pool in which this Volume is located */
-static void update_volpool(UAContext *ua, char *val, MEDIA_DBR *mr)
+static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
{
POOL_DBR pr;
POOLMEM *query;
bsendmsg(ua, "%s", db_strerror(ua->db));
} else {
bsendmsg(ua, _("New Pool is: %s\n"), pr.Name);
+ opr->NumVols--;
+ if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ pr.NumVols++;
+ if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
+ db_make_inchanger_unique(ua->jcr, ua->db, mr);
}
- db_make_inchanger_unique(ua->jcr, ua->db, mr);
db_unlock(ua->db);
free_pool_memory(query);
}
+/*
+ * Refresh the Volume information from the Pool record
+ */
static void update_volfrompool(UAContext *ua, MEDIA_DBR *mr)
{
POOL_DBR pr;
for (int i=0; kw[i]; i++) {
int j;
+ POOL_DBR pr;
if ((j=find_arg_with_value(ua, kw[i])) > 0) {
if (!select_media_dbr(ua, &mr)) {
return 0;
update_volrecycle(ua, ua->argv[j], &mr);
break;
case 7:
- update_volpool(ua, ua->argv[j], &mr);
+ memset(&pr, 0, sizeof(POOL_DBR));
+ pr.PoolId = mr.PoolId;
+ if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ break;
+ }
+ update_vol_pool(ua, ua->argv[j], &mr, &pr);
break;
case 8:
update_volfrompool(ua, &mr);
if (!get_cmd(ua, _("Enter new Pool name: "))) {
return 0;
}
- update_volpool(ua, ua->cmd, &mr);
+ update_vol_pool(ua, ua->cmd, &mr, &pr);
return 1;
default: /* Done or error */
/* Forward referenced functions */
static int do_label(UAContext *ua, const char *cmd, int relabel);
static void label_from_barcodes(UAContext *ua);
-static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
+static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
POOL_DBR *pr, int relabel, bool media_record_exits);
static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan);
static void free_vol_list(vol_list_t *vol_list);
mr.Slot = vl->Slot;
mr.InChanger = 1;
if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, _("%s\n"), db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
} else {
bsendmsg(ua, _(
"Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
if (ok) {
sd = ua->jcr->store_bsock;
if (relabel) {
+ /* Delete the old media record */
if (!db_delete_media_record(ua->jcr, ua->db, &omr)) {
bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
omr.VolumeName, db_strerror(ua->db));
} else {
bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"),
omr.VolumeName);
+ /* Update the number of Volumes in the pool */
+ pr.NumVols--;
+ if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
}
}
if (ua->automount) {
if (db_create_media_record(ua->jcr, ua->db, &mr)) {
bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
mr.VolumeName);
+ pr.NumVols++; /* this is a bit suspect */
+ if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
} else {
bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
}
/*
* NOTE! This routine opens the SD socket but leaves it open
*/
-static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
- POOL_DBR *pr, int relabel, bool media_record_exists)
+static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
+ POOL_DBR *pr, int relabel, bool media_record_exists)
{
BSOCK *sd;
char dev_name[MAX_NAME_LENGTH];
- int ok = FALSE;
+ bool ok = false;
if (!(sd=open_sd_bsock(ua))) {
- return 0;
+ return false;
}
bstrncpy(dev_name, ua->jcr->store->dev_name, sizeof(dev_name));
bash_spaces(dev_name);
while (bnet_recv(sd) >= 0) {
bsendmsg(ua, "%s", sd->msg);
if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
- ok = TRUE;
+ ok = true;
}
}
unbash_spaces(mr->VolumeName);
mr->InChanger = 1;
if (!db_update_media_record(ua->jcr, ua->db, mr)) {
bsendmsg(ua, "%s", db_strerror(ua->db));
- ok = FALSE;
+ ok = false;
}
} else { /* create the media record */
set_pool_dbr_defaults_in_media_dbr(mr, pr);
if (db_create_media_record(ua->jcr, ua->db, mr)) {
bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d successfully created.\n"),
mr->VolumeName, mr->Slot);
+ /* Update number of volumes in pool */
+ pr->NumVols++;
+ if (!db_update_pool_record(ua->jcr, ua->db, pr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ }
} else {
bsendmsg(ua, "%s", db_strerror(ua->db));
- ok = FALSE;
+ ok = false;
}
}
} else {
int priority;
bool hdr_printed = false;
dlist sched;
- sched_pkt *sp, *ip;
+ sched_pkt *sp;
Dmsg0(200, "enter list_sched_jobs()\n");
sp->priority = priority;
sp->runtime = runtime;
sp->pool = run->pool;
- ip = (sched_pkt *)sched.binary_insert(sp, my_compare);
- if (ip != sp) {
- /* Identical entry already, we must explictly insert it */
- sched.insert_after(sp, ip);
- }
+ sched.binary_insert(sp, my_compare);
num_jobs++;
}
} /* end for loop over resources */
}
/*
+ * Insert an item in the list, but only if it is unique
+ * otherwise, the item is returned non inserted
+ *
* Returns: item if item inserted
* other_item if same value already exists (item not inserted)
*/
-void *dlist::binary_insert(void *item, int compare(void *item1, void *item2))
+void *dlist::unique_binary_insert(void *item, int compare(void *item1, void *item2))
{
int comp;
int low, high, cur;
}
+/*
+ * Insert an item in the list, regardless if it is unique
+ * or not.
+ */
+void dlist::binary_insert(void *item, int compare(void *item1, void *item2))
+{
+ void *ins_item = unique_binary_insert(item, compare);
+ /* If identical, insert after the one found */
+ if (ins_item != item) {
+ insert_after(item, ins_item);
+ }
+}
+
+
void dlist::remove(void *item)
{
void *xitem;
void append(void *item);
void insert_before(void *item, void *where);
void insert_after(void *item, void *where);
- void *dlist::binary_insert(void *item, int compare(void *item1, void *item2));
+ void *unique_binary_insert(void *item, int compare(void *item1, void *item2));
+ void binary_insert(void *item, int compare(void *item1, void *item2));
void remove(void *item);
bool empty();
int size();
scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
lc->str, lc->line_no, lc->line);
}
+ if (*(item->value)) {
+ scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
+ lc->str, lc->line_no, lc->line);
+ }
*(item->value) = (char *)res;
}
scan_to_eol(lc);
TREE_NODE *node, *found_node;
node = new_tree_node(root);
node->fname = fname;
- found_node = (TREE_NODE *)parent->child.binary_insert(node, node_compare);
+ found_node = (TREE_NODE *)parent->child.unique_binary_insert(node, node_compare);
if (found_node != node) { /* already in list */
free_tree_node(root); /* free node allocated above */
found_node->inserted = false;
break;
}
pm_strcpy(&jcr->VolumeName, newname);
- bnet_fsend(dir, _("3000 OK label. Volume=%s Device=%s\n"),
+ /* The following 3000 OK label. string is scanned in ua_label.c */
+ bnet_fsend(dir, "3000 OK label. Volume=%s Device=%s\n",
newname, dev_name(dev));
break;
case VOL_NO_MEDIA:
bail_out:
free_block(block);
give_back_device_lock(dev, &hold);
-
return;
}
{
DEV_RECORD rec;
DEV_BLOCK *block;
- bool stat = true;
+ bool ok = false;
Dmsg0(99, "write_volume_label()\n");
if (!write_record_to_block(block, &rec)) {
Dmsg2(30, "Bad Label write on %s. ERR=%s\n", dev_name(dev), strerror_dev(dev));
memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
- free_block(block);
- free_pool_memory(rec.data);
- return false;
+ goto bail_out;
} else {
Dmsg2(30, "Wrote label of %d bytes to %s\n", rec.data_len, dev_name(dev));
}
- free_pool_memory(rec.data);
Dmsg0(99, "Call write_block_to_dev()\n");
if (!write_block_to_dev(jcr->dcr, block)) {
memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
Dmsg2(30, "Bad Label write on %s. ERR=%s\n", dev_name(dev), strerror_dev(dev));
- stat = false;
+ goto bail_out;
}
Dmsg0(99, " Wrote block to device\n");
- flush_dev(dev);
weof_dev(dev, 1);
dev->state |= ST_LABEL;
+ ok = true;
if (debug_level >= 20) {
dump_volume_label(dev);
}
+
+bail_out:
free_block(block);
- return stat;
+ free_pool_memory(rec.data);
+ return ok;
}
#undef VERSION
#define VERSION "1.35.1"
#define VSTRING "1"
-#define BDATE "09 July 2004"
-#define LSMDATE "09Jul04"
+#define BDATE "16 July 2004"
+#define LSMDATE "16Jul04"
/* Debug flags */
#undef DEBUG