#endif
/* #define ASSERT(x) if (!(x)) Emsg1(M_ABORT, 0, "Failed ASSERT: %s\n", __STRING(x)) */
-#define ASSERT(x) if (!(x)) Emsg1(M_ABORT, 0, "Failed ASSERT: %s\n", #x)
+#define ASSERT(x) if (!(x)) { \
+ char *jcr = NULL; \
+ Emsg1(M_ERROR, 0, "Failed ASSERT: %s\n", #x); \
+ jcr[0] = 0; }
+
#ifdef ENABLE_NLS
db_unlock(mdb);
return 0;
}
- sql_free_result(mdb);
cr->ClientId = atoi(row[0]);
+ sql_free_result(mdb);
db_unlock(mdb);
return 1;
}
db_unlock(mdb);
return 0;
}
- sql_free_result(mdb);
fsr->FileSetId = atoi(row[0]);
+ sql_free_result(mdb);
db_unlock(mdb);
return 1;
}
if (*path == 0) {
Mmsg0(&mdb->errmsg, _("Null path given to db_create_path_record\n"));
ar->PathId = 0;
+ ASSERT(ar->PathId);
return 0;
}
if (mdb->cached_path_id != 0 && strcmp(mdb->cached_path, path) == 0) {
ar->PathId = mdb->cached_path_id;
+ ASSERT(ar->PathId);
db_unlock(mdb);
return 1;
}
Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
sql_free_result(mdb);
ar->PathId = 0;
+ ASSERT(ar->PathId);
return 0;
}
- sql_free_result(mdb);
ar->PathId = atoi(row[0]);
+ sql_free_result(mdb);
/* Cache path */
if (ar->PathId != mdb->cached_path_id) {
mdb->cached_path_id = ar->PathId;
strlen(path)+1);
strcpy(mdb->cached_path, path);
}
+ ASSERT(ar->PathId);
db_unlock(mdb);
return 1;
}
strlen(path)+1);
strcpy(mdb->cached_path, path);
}
+ ASSERT(ar->PathId);
db_unlock(mdb);
return stat;
}
</widget>
</widget>
-<widget>
- <class>GnomeDialog</class>
- <name>SelectDirectorDialog</name>
- <title>Select Director</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>True</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox2</name>
- <homogeneous>False</homogeneous>
- <spacing>1</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area2</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button11</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_select_director_clicked</handler>
- <last_modification_time>Sun, 17 Mar 2002 21:07:26 GMT</last_modification_time>
- </signal>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button13</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox4</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label20</name>
- <label>Select Director</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>3</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox10</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo1</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items></items>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>combo-entry9</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
<widget>
<class>GnomeDialog</class>
<name>RunDialog</name>
<handler>on_app1_delete_event</handler>
<last_modification_time>Mon, 01 Apr 2002 07:29:22 GMT</last_modification_time>
</signal>
- <signal>
- <name>show</name>
- <handler>on_app1_show</handler>
- <last_modification_time>Mon, 01 Apr 2002 07:29:16 GMT</last_modification_time>
- </signal>
<title>Bacula Console</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
</widget>
</widget>
+<widget>
+ <class>GtkDialog</class>
+ <name>SelectDirectorDialog</name>
+ <title>Select Director</title>
+ <type>GTK_WINDOW_TOPLEVEL</type>
+ <position>GTK_WIN_POS_CENTER</position>
+ <modal>True</modal>
+ <allow_shrink>False</allow_shrink>
+ <allow_grow>False</allow_grow>
+ <auto_shrink>False</auto_shrink>
+
+ <widget>
+ <class>GtkVBox</class>
+ <child_name>Dialog:vbox</child_name>
+ <name>dialog-vbox6</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+
+ <widget>
+ <class>GtkHBox</class>
+ <child_name>Dialog:action_area</child_name>
+ <name>dialog-action_area2</name>
+ <border_width>10</border_width>
+ <homogeneous>True</homogeneous>
+ <spacing>5</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>True</fill>
+ <pack>GTK_PACK_END</pack>
+ </child>
+
+ <widget>
+ <class>GtkHBox</class>
+ <name>hbox21</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkButton</class>
+ <name>button11</name>
+ <width>85</width>
+ <can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_select_director_OK_clicked</handler>
+ <last_modification_time>Wed, 22 May 2002 19:42:41 GMT</last_modification_time>
+ </signal>
+ <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
+ <relief>GTK_RELIEF_NORMAL</relief>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label46</name>
+ <label> </label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0.5</xalign>
+ <yalign>0.5</yalign>
+ <xpad>2</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkButton</class>
+ <name>button13</name>
+ <can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_select_director_cancel_clicked</handler>
+ <last_modification_time>Wed, 22 May 2002 19:43:08 GMT</last_modification_time>
+ </signal>
+ <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
+ <relief>GTK_RELIEF_NORMAL</relief>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+ </widget>
+ </widget>
+
+ <widget>
+ <class>GtkVBox</class>
+ <name>vbox10</name>
+ <homogeneous>False</homogeneous>
+ <spacing>0</spacing>
+ <child>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
+ </child>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label48</name>
+ <height>12</height>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0.48</xalign>
+ <yalign>0.46</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label47</name>
+ <label>Select Director</label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0.5</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkCombo</class>
+ <name>combo1</name>
+ <border_width>6</border_width>
+ <value_in_list>False</value_in_list>
+ <ok_if_empty>True</ok_if_empty>
+ <case_sensitive>False</case_sensitive>
+ <use_arrows>True</use_arrows>
+ <use_arrows_always>False</use_arrows_always>
+ <items></items>
+ <child>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
+ </child>
+
+ <widget>
+ <class>GtkEntry</class>
+ <child_name>GtkCombo:entry</child_name>
+ <name>dirselect</name>
+ <can_focus>True</can_focus>
+ <editable>True</editable>
+ <text_visible>True</text_visible>
+ <text_max_length>0</text_max_length>
+ <text></text>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+</widget>
+
</GTK-Interface>
return;
}
+ /* The following code is only executed during pass 1 */
switch (type) {
case R_CONSOLE:
size = sizeof(CONSRES);
UAContext ua;
if (!jcr->job->PruneVolumes && !jcr->pool->AutoPrune) {
- Dmsg0(200, "AutoPrune not set in Pool.\n");
- return stat;
+ Dmsg0(100, "AutoPrune not set in Pool.\n");
+ return 0;
}
memset(&mr, 0, sizeof(mr));
memset(&pr, 0, sizeof(pr));
VolJobs=%d VolFiles=%d VolBlocks=%d VolBytes=%" lld " VolMounts=%d\
VolErrors=%d VolWrites=%d VolMaxBytes=%" lld " EndTime=%d VolStatus=%10s\
FirstIndex=%d LastIndex=%d StartFile=%d EndFile=%d \
- StartBlock=%d EndBlock=%d\n";
+ StartBlock=%d EndBlock=%d relabel=%d\n";
/* Responses sent to Storage daemon */
static char OK_media[] = "1000 OK VolName=%s VolJobs=%d VolFiles=%d\
MEDIA_DBR mr;
JOBMEDIA_DBR jm;
char Job[MAX_NAME_LENGTH];
- int index, ok;
+ int index, ok, relabel;
char *omsg;
memset(&mr, 0, sizeof(mr));
/*
* Find the Volume
*/
- ok = FALSE;
- if (db_find_next_volume(jcr->db, index, &mr)) {
- jcr->MediaId = mr.MediaId;
- Dmsg1(20, "Find_next_vol MediaId=%d\n", jcr->MediaId);
- strcpy(jcr->VolumeName, mr.VolumeName);
- ok = TRUE;
- } else {
+ ok = db_find_next_volume(jcr->db, index, &mr);
+ if (!ok) {
/* Well, try finding recycled tapes */
ok = find_recycled_volume(jcr, &mr);
+ Dmsg1(100, "find_recycled_volume1 %d\n", ok);
if (!ok) {
- if (prune_volumes(jcr)) {
- ok = recycle_a_volume(jcr, &mr);
- }
+ prune_volumes(jcr);
+ ok = recycle_a_volume(jcr, &mr);
+ Dmsg1(100, "find_recycled_volume2 %d\n", ok);
if (!ok) {
/* See if we can create a new Volume */
- ok = newVolume(jcr);
+ ok = newVolume(jcr, &mr);
}
}
}
* Send Find Media response to Storage daemon
*/
if (ok) {
+ jcr->MediaId = mr.MediaId;
+ strcpy(jcr->VolumeName, mr.VolumeName);
bash_spaces(mr.VolumeName);
bnet_fsend(bs, OK_media, mr.VolumeName, mr.VolJobs,
mr.VolFiles, mr.VolBlocks, mr.VolBytes, mr.VolMounts, mr.VolErrors,
mr.VolWrites, mr.VolMaxBytes, mr.VolCapacityBytes,
mr.VolStatus);
} else {
- Dmsg4(000, "get_media_record PoolId=%d wanted %d, Status=%s, \
+ Dmsg4(100, "get_media_record PoolId=%d wanted %d, Status=%s, \
MediaType=%s\n", mr.PoolId, jcr->PoolId, mr.VolStatus, mr.MediaType);
/* Not suitable volume */
bnet_fsend(bs, "1998 Volume not appropriate.\n");
&mr.VolFiles, &mr.VolBlocks, &mr.VolBytes, &mr.VolMounts, &mr.VolErrors,
&mr.VolWrites, &mr.VolMaxBytes, &mr.LastWritten, &mr.VolStatus,
&jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile,
- &jm.StartBlock, &jm.EndBlock) == 18) {
+ &jm.StartBlock, &jm.EndBlock, &relabel) == 19) {
/*
* Update Media Record
*/
jm.JobId = jcr->JobId;
jm.MediaId = jcr->MediaId;
/*
- * A single write means we just labeled the tape,
+ * If relabel is set, it means we just labeled the tape,
* so no need to create a jobmedia record.
* Otherwise, record the fact that this job used this Volume
*/
- if (mr.VolWrites > 1) {
- Dmsg4(20, "create_jobmedia JobId=%d MediaId=%d FI=%d LI=%d\n",
+ if (!relabel) {
+ Dmsg4(100, "create_jobmedia JobId=%d MediaId=%d FI=%d LI=%d\n",
jm.JobId, jm.MediaId, jm.FirstIndex, jm.LastIndex);
if(!db_create_jobmedia_record(jcr->db, &jm)) {
Jmsg(jcr, M_ERROR, 0, _("Catalog error creating JobMedia record. %s"),
/* Create pid must come after we are a daemon -- so we have our final pid */
create_pid_file(director->pid_directory, "bacula-dir", director->DIRport);
- signal(SIGHUP, reload_config);
+/* signal(SIGHUP, reload_config); */
init_console_msg(working_directory);
sendit(sock, " Exc: %s\n", res->res_fs.exclude_array[i]);
break;
case R_SCHEDULE:
- if (res->res_sch.run)
- sendit(sock, "Schedule: name=%s Level=%s\n", res->res_sch.hdr.name,
- level_to_str(res->res_sch.run->level));
- else
+ if (res->res_sch.run) {
+ int i;
+ RUN *run = res->res_sch.run;
+ char buf[1000], num[10];
sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
+ if (!run) {
+ break;
+ }
+next_run:
+ sendit(sock, " --> Run Level=%s\n", level_to_str(run->level));
+ strcpy(buf, " hour=");
+ for (i=0; i<24; i++) {
+ if (bit_is_set(i, run->hour)) {
+ sprintf(num, "%d ", i+1);
+ strcat(buf, num);
+ }
+ }
+ strcat(buf, "\n");
+ sendit(sock, buf);
+ strcpy(buf, " mday=");
+ for (i=0; i<31; i++) {
+ if (bit_is_set(i, run->mday)) {
+ sprintf(num, "%d ", i+1);
+ strcat(buf, num);
+ }
+ }
+ strcat(buf, "\n");
+ sendit(sock, buf);
+ strcpy(buf, " month=");
+ for (i=0; i<12; i++) {
+ if (bit_is_set(i, run->month)) {
+ sprintf(num, "%d ", i+1);
+ strcat(buf, num);
+ }
+ }
+ strcat(buf, "\n");
+ sendit(sock, buf);
+ strcpy(buf, " wday=");
+ for (i=0; i<7; i++) {
+ if (bit_is_set(i, run->wday)) {
+ sprintf(num, "%d ", i+1);
+ strcat(buf, num);
+ }
+ }
+ strcat(buf, "\n");
+ sendit(sock, buf);
+ sendit(sock, " mins=%d\n", run->minute);
+ if (run->pool) {
+ sendit(sock, " --> ");
+ dump_resource(-R_POOL, (RES *)run->pool, sendit, sock);
+ }
+ if (run->storage) {
+ sendit(sock, " --> ");
+ dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock);
+ }
+ if (run->msgs) {
+ sendit(sock, " --> ");
+ dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock);
+ }
+ /* If another Run record is chained in, go print it */
+ if (run->next) {
+ run = run->next;
+ goto next_run;
+ }
+ } else {
+ sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
+ }
break;
case R_GROUP:
sendit(sock, "Group: name=%s\n", res->res_group.hdr.name);
sendit(sock, " max_vols=%d auto_prune=%d VolRetention=%" lld "\n",
res->res_pool.max_volumes, res->res_pool.AutoPrune,
res->res_pool.VolRetention);
- sendit(sock, " recycle=%d\n", res->res_pool.Recycle);
-
-
- sendit(sock, " LabelFormat=%s\n", res->res_pool.label_format?
- res->res_pool.label_format:"NONE");
+ sendit(sock, " recycle=%d LabelFormat=%s\n", res->res_pool.Recycle,
+ res->res_pool.label_format?res->res_pool.label_format:"*None*");
break;
case R_MSGS:
sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
/*
* Save the new resource by chaining it into the head list for
* the resource. If this is pass 2, we update any resource
- * pointers (currently only in the Job resource).
+ * pointers because they may not have been defined until
+ * later in pass 1.
*/
void save_resource(int type, struct res_items *items, int pass)
{
}
}
- /* During pass 2, we looked up pointers to all the resources
- * referrenced in the current resource, , now we
- * must copy their address from the static record to the allocated
+ /* During pass 2 in each "store" routine, we looked up pointers
+ * to all the resources referrenced in the current resource, now we
+ * must copy their addresses from the static record to the allocated
* record.
*/
if (pass == 2) {
case R_CATALOG:
case R_STORAGE:
case R_FILESET:
- case R_SCHEDULE:
case R_GROUP:
case R_POOL:
case R_MSGS:
}
res->res_client.catalog = res_all.res_client.catalog;
break;
+ case R_SCHEDULE:
+ /* Schedule is a bit different in that it contains a RUN record
+ * chain which isn't a "named" resource. This chain was linked
+ * in by run_conf.c during pass 2, so here we jam the pointer
+ * into the Schedule resource.
+ */
+ if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) {
+ Emsg1(M_ABORT, 0, "Cannot find Schedule resource %s\n", res_all.res_client.hdr.name);
+ }
+ res->res_sch.run = res_all.res_sch.run;
+ break;
default:
Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type);
error = 1;
return;
}
+ /* The following code is only executed for pass 1 */
switch (type) {
case R_DIRECTOR:
size = sizeof(DIRRES);
}
/* Common */
if (!error) {
- res = (URES *) malloc(size);
+ res = (URES *)malloc(size);
memcpy(res, &res_all, size);
res->res_dir.hdr.next = resources[rindex].res_head;
resources[rindex].res_head = (RES *)res;
switch (jcr->JobType) {
case JT_BACKUP:
do_backup(jcr);
- do_autoprune(jcr);
+ if (jcr->JobStatus == JS_Terminated) {
+ do_autoprune(jcr);
+ }
break;
case JT_VERIFY:
do_verify(jcr);
* Really crude automatic Volume name creation using
* LabelFormat
*/
-int newVolume(JCR *jcr)
+int newVolume(JCR *jcr, MEDIA_DBR *mr)
{
- MEDIA_DBR mr;
POOL_DBR pr;
char name[MAXSTRING];
- memset(&mr, 0, sizeof(mr));
memset(&pr, 0, sizeof(pr));
/* See if we can create a new Volume */
if (db_get_pool_record(jcr->db, &pr) && pr.LabelFormat[0] &&
pr.LabelFormat[0] != '*') {
if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
- memset(&mr, 0, sizeof(mr));
- mr.PoolId = jcr->PoolId;
- strcpy(mr.MediaType, jcr->store->media_type);
+ mr->PoolId = jcr->PoolId;
+ strcpy(mr->MediaType, jcr->store->media_type);
strcpy(name, pr.LabelFormat);
strcat(name, "%04d");
- sprintf(mr.VolumeName, name, ++pr.NumVols);
- strcpy(mr.VolStatus, "Append");
- mr.Recycle = pr.Recycle;
- mr.VolRetention = pr.VolRetention;
- if (db_create_media_record(jcr->db, &mr) &&
+ sprintf(mr->VolumeName, name, ++pr.NumVols);
+ strcpy(mr->VolStatus, "Append");
+ mr->Recycle = pr.Recycle;
+ mr->VolRetention = pr.VolRetention;
+ if (db_create_media_record(jcr->db, mr) &&
db_update_pool_record(jcr->db, &pr) == 1) {
- Dmsg1(90, "Created new Volume=%s\n", mr.VolumeName);
+ Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
return 1;
} else {
Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
extern int response(BSOCK *fd, char *resp, char *cmd);
/* newvol.c */
-extern int newVolume(JCR *jcr);
+extern int newVolume(JCR *jcr, MEDIA_DBR *mr);
/* ua_cmd.c */
extern int create_pool(B_DB *db, POOL *pool);
*
* Parse Run statement:
*
- * Run <full|incremental|...> [on] 2 january at 23:45
+ * Run <keyword=value ...> [on] 2 january at 23:45
*
* Default Run time is daily at 0:0
*
} /* end switch */
} /* end if strcasecmp */
} /* end for RunFields */
+
+ /* At this point, it is not a keyword. Check for old syle
+ * Job Levels without keyword. This form is depreciated!!!
+ */
+ for (j=0; joblevels[j].level_name; j++) {
+ if (strcasecmp(lc->str, joblevels[j].level_name) == 0) {
+ lrun.level = joblevels[j].level;
+ lrun.job_type = joblevels[j].job_type;
+ found = TRUE;
+ break;
+ }
+ }
} /* end for found */
state = s_none;
set_defaults();
- while ((token = lex_get_token(lc)) != T_EOL) {
+ for ( ; token != T_EOL; (token = lex_get_token(lc))) {
int len, pm;
switch (token) {
case T_NUMBER:
}
if (!have_hour) {
clear_bit(0, lrun.hour);
- have_hour = TRUE;
}
p = strchr(lc->str, ':');
if (!p) {
}
set_bit(code, lrun.hour);
lrun.minute = code2;
+ have_hour = TRUE;
break;
case s_at:
have_at = TRUE;
break;
case s_monthly:
clear_defaults();
- set_bit(0, lrun.mday);
set_bits(0, 11, lrun.month);
break;
default:
* and link it into the list of run records
* in the schedule resource.
*/
- if (pass == 1) {
- trun = (RUN *) malloc(sizeof(RUN));
+ if (pass == 2) {
+ trun = (RUN *)malloc(sizeof(RUN));
memcpy(trun, &lrun, sizeof(RUN));
if (*run) {
trun->next = *run;
int id;
POOL *pool;
+
+ pool = get_pool_resource(ua);
+ if (!pool) {
+ return 0;
+ }
+
memset(&pr, 0, sizeof(pr));
+ strcpy(pr.Name, pool->hdr.name);
if (!get_pool_dbr(ua, &pr)) {
- return 1;
+ return 0;
}
-
strcpy(pr.PoolType, pool->pool_type);
if (pr.MaxVols != (uint32_t) (pool->max_volumes)) {
pr.MaxVols = pool->max_volumes;
*/
int listcmd(UAContext *ua, char *cmd)
{
- char *VolumeName;
+ POOLMEM *VolumeName;
int jobid, n;
int i, j;
JOB_DBR jr;
} else if (strcasecmp(ua->argk[i], _("pools")) == 0) {
db_list_pool_records(ua->db, prtit, ua);
- /* List MEDIA */
- } else if (strcasecmp(ua->argk[i], _("media")) == 0) {
+ /* List MEDIA or VOLUMES */
+ } else if (strcasecmp(ua->argk[i], _("media")) == 0 ||
+ strcasecmp(ua->argk[i], _("volumes")) == 0) {
int done = FALSE;
for (j=i+1; j<ua->argc; j++) {
if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
} else {
continue;
}
- VolumeName = (char *) get_pool_memory(PM_FNAME);
+ VolumeName = get_pool_memory(PM_FNAME);
n = db_get_job_volume_names(ua->db, jobid, VolumeName);
bsendmsg(ua, _("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName);
free_memory(VolumeName);
rewind(con_fd);
while (fgets(msg, sizeof(msg), con_fd)) {
mlen = strlen(msg);
- ua->UA_sock->msg = (char *) check_pool_memory_size(
- ua->UA_sock->msg, mlen+1);
+ ua->UA_sock->msg = check_pool_memory_size(ua->UA_sock->msg, mlen+1);
strcpy(ua->UA_sock->msg, msg);
ua->UA_sock->msglen = mlen;
bnet_send(ua->UA_sock);
UAContext *ua = (UAContext *)ctx;
BSOCK *bs = ua->UA_sock;
int maxlen, len;
- char *msg;
+ POOLMEM *msg;
if (bs) {
msg = bs->msg;
} else {
- msg = (char *)get_pool_memory(PM_EMSG);
+ msg = get_pool_memory(PM_EMSG);
}
again:
len = bvsnprintf(msg, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
if (len < 0 || len >= maxlen) {
- msg = (char *) realloc_pool_memory(msg, maxlen + 200);
+ msg = realloc_pool_memory(msg, maxlen + 200);
goto again;
}
bnet_send(bs);
} else { /* No UA, send to Job */
Jmsg(ua->jcr, M_INFO, 0, msg);
- free_memory(msg);
+ free_pool_memory(msg);
}
}
db_sql_query(ua->db, query, NULL, (void *)NULL);
Dmsg1(050, "Del sql=%s\n", query);
}
- bsendmsg(ua, _("Pruned %d Jobs for client %s from %s catalog.\n"), del.num_ids,
- client->hdr.name, client->catalog->hdr.name);
+ bsendmsg(ua, _("Pruned %d %s for client %s from %s catalog.\n"), del.num_ids,
+ del.num_ids==1?_("Job"):_("Jobs"), client->hdr.name, client->catalog->hdr.name);
bail_out:
drop_temp_tables(ua);
if (del.JobId) {
free(del.JobId);
}
- if (ua->verbose) {
+ if (ua->verbose && del.num_del != 0) {
bsendmsg(ua, _("Pruned %d Jobs on Volume %s from catalog.\n"), del.num_del,
mr->VolumeName);
}
{
int i;
+ if (pr->Name[0]) { /* If name already supplied */
+ if (db_get_pool_record(ua->db, pr)) {
+ return pr->PoolId;
+ }
+ 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], _("pool")) == 0 && ua->argv[i]) {
strcpy(pr->Name, ua->argv[i]);
return;
}
+ /* The following code is only executed on pass 1 */
switch (type) {
case R_DIRECTOR:
size = sizeof(DIRRES);
long CurVolume; /* current volume number */
int mode; /* manual/auto run */
int label_status; /* device volume label status */
+ int label_errors; /* count of label errors */
int session_opened;
DEV_RECORD rec; /* Read/Write record */
long Ticket; /* ticket for this job */
* for the current Job.
*/
for (d=msg->dest_chain; d; d=d->next) {
- dnew = (DEST *) malloc(sizeof(DEST));
+ dnew = (DEST *)malloc(sizeof(DEST));
memcpy(dnew, d, sizeof(DEST));
dnew->next = temp_chain;
dnew->fd = NULL;
Dmsg1(200, "Enter Jmsg type=%d\n", type);
msgs = NULL;
+ job = NULL;
if (jcr) {
msgs = jcr->msgs;
job = jcr->Job;
}
- if (msgs == NULL) {
+ if (!msgs) {
msgs = daemon_msgs;
+ }
+ if (!job) {
job = "*None*";
}
/*
* Edit a message into a Pool memory buffer, with file:lineno
*/
-int m_msg(char *file, int line, char **pool_buf, char *fmt, ...)
+int m_msg(char *file, int line, POOLMEM **pool_buf, char *fmt, ...)
{
va_list arg_ptr;
int i, len, maxlen;
len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
if (len < 0 || len >= maxlen) {
- *pool_buf = (char *) realloc_pool_memory(*pool_buf, maxlen + i + 200);
+ *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + 200);
goto again;
}
return len;
* Edit a message into a Pool Memory buffer NO file:lineno
* Returns: string length of what was edited.
*/
-int Mmsg(char **pool_buf, char *fmt, ...)
+int Mmsg(POOLMEM **pool_buf, char *fmt, ...)
{
va_list arg_ptr;
int len, maxlen;
* definitions as well as any specific store routines
* for the resource records.
*
+ * N.B. This is a two pass parser, so if you malloc() a string
+ * in a "store" routine, you must ensure to do it during
+ * only one of the two passes, or to free it between.
+ * Also, note that the resource record is malloced and
+ * saved in save_resource() during pass 1. Anything that
+ * you want saved after pass two (e.g. resource pointers)
+ * must explicitly be done in save_resource. Take a look
+ * at the Job resource in src/dird/dird_conf.c to see how
+ * it is done.
+ *
* Kern Sibbald, January MM
*
* Version $Id$
* and the second picks up the items.
*/
Dmsg0(200, "Enter parse_config()\n");
- for (pass=1; pass<= 2; pass++) {
+ for (pass=1; pass <= 2; pass++) {
Dmsg1(200, "parse_config pass %d\n", pass);
lc = lex_open_file(lc, cf);
while ((token=lex_get_token(lc)) != T_EOF) {
*/
/* base64.c */
-void base64_init __PROTO((void));
-int to_base64 __PROTO((intmax_t value, char *where));
-int from_base64 __PROTO((intmax_t *value, char *where));
-void encode_stat __PROTO((char *buf, struct stat *statp));
-void decode_stat __PROTO((char *buf, struct stat *statp));
-int bin_to_base64 __PROTO((char *buf, char *bin, int len));
+void base64_init (void);
+int to_base64 (intmax_t value, char *where);
+int from_base64 (intmax_t *value, char *where);
+void encode_stat (char *buf, struct stat *statp);
+void decode_stat (char *buf, struct stat *statp);
+int bin_to_base64 (char *buf, char *bin, int len);
/* bmisc.c */
-void *b_malloc (char *file, int line, size_t size);
+void *b_malloc (char *file, int line, size_t size);
#ifndef DEBUG
-void *bmalloc (size_t size);
+void *bmalloc (size_t size);
#endif
-void *brealloc (void *buf, size_t size);
-void *bcalloc (size_t size1, size_t size2);
-int bsnprintf (char *str, size_t size, const char *format, ...);
-int bvsnprintf (char *str, size_t size, const char *format, va_list ap);
-int pool_sprintf (char *pool_buf, char *fmt, ...);
-void create_pid_file (char *dir, char *progname, int port);
-int delete_pid_file (char *dir, char *progname, int port);
+void *brealloc (void *buf, size_t size);
+void *bcalloc (size_t size1, size_t size2);
+int bsnprintf (char *str, size_t size, const char *format, ...);
+int bvsnprintf (char *str, size_t size, const char *format, va_list ap);
+int pool_sprintf (char *pool_buf, char *fmt, ...);
+void create_pid_file (char *dir, char *progname, int port);
+int delete_pid_file (char *dir, char *progname, int port);
/* bnet.c */
-int32_t bnet_recv __PROTO((BSOCK *bsock));
-int bnet_send __PROTO((BSOCK *bsock));
-int bnet_fsend (BSOCK *bs, char *fmt, ...);
-int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
-int bnet_sig (BSOCK *bs, int sig);
-BSOCK * bnet_connect (void *jcr, int retry_interval,
- int max_retry_time, char *name, char *host, char *service,
- int port, int verbose);
-int bnet_wait_data (BSOCK *bsock, int sec);
-void bnet_close __PROTO((BSOCK *bsock));
-BSOCK * init_bsock __PROTO((int sockfd, char *who, char *ip, int port));
-BSOCK * dup_bsock __PROTO((BSOCK *bsock));
-void term_bsock __PROTO((BSOCK *bsock));
-char * bnet_strerror __PROTO((BSOCK *bsock));
-char * bnet_sig_to_ascii __PROTO((BSOCK *bsock));
-int bnet_wait_data __PROTO((BSOCK *bsock, int sec));
+int32_t bnet_recv (BSOCK *bsock);
+int bnet_send (BSOCK *bsock);
+int bnet_fsend (BSOCK *bs, char *fmt, ...);
+int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
+int bnet_sig (BSOCK *bs, int sig);
+BSOCK * bnet_connect (void *jcr, int retry_interval,
+ int max_retry_time, char *name, char *host, char *service,
+ int port, int verbose);
+int bnet_wait_data (BSOCK *bsock, int sec);
+void bnet_close (BSOCK *bsock);
+BSOCK * init_bsock (int sockfd, char *who, char *ip, int port);
+BSOCK * dup_bsock (BSOCK *bsock);
+void term_bsock (BSOCK *bsock);
+char * bnet_strerror (BSOCK *bsock);
+char * bnet_sig_to_ascii (BSOCK *bsock);
+int bnet_wait_data (BSOCK *bsock, int sec);
/* cram-md5.c */
int cram_md5_get_auth(BSOCK *bs, char *password);
int cram_md5_auth(BSOCK *bs, char *password);
void hmac_md5(uint8_t* text, int text_len, uint8_t* key,
- int key_len, uint8_t *hmac);
+ int key_len, uint8_t *hmac);
/* create_file.c */
int create_file(void *jcr, char *fname, char *ofile, char *lname,
- int type, struct stat *statp, int *ofd);
+ int type, struct stat *statp, int *ofd);
int set_statp(void *jcr, char *fname, char *ofile, char *lname, int type,
- struct stat *statp);
+ struct stat *statp);
/* crc32.c */
uint32_t bcrc32(uint8_t *buf, int len);
/* daemon.c */
-void daemon_start __PROTO(());
+void daemon_start ();
/* lex.c */
-LEX * lex_close_file __PROTO((LEX *lf));
-LEX * lex_open_file __PROTO((LEX *lf, char *fname));
-int lex_get_char __PROTO((LEX *lf));
-void lex_unget_char __PROTO((LEX *lf));
-char * lex_tok_to_str __PROTO((int token));
-int lex_get_token __PROTO((LEX *lf));
+LEX * lex_close_file (LEX *lf);
+LEX * lex_open_file (LEX *lf, char *fname);
+int lex_get_char (LEX *lf);
+void lex_unget_char (LEX *lf);
+char * lex_tok_to_str (int token);
+int lex_get_token (LEX *lf);
/* makepath.c */
int make_path(
- void *jcr,
- const char *argpath,
- int mode,
- int parent_mode,
- uid_t owner,
- gid_t group,
- int preserve_existing,
- char *verbose_fmt_string);
+ void *jcr,
+ const char *argpath,
+ int mode,
+ int parent_mode,
+ uid_t owner,
+ gid_t group,
+ int preserve_existing,
+ char *verbose_fmt_string);
/* message.c */
-void my_name_is __PROTO((int argc, char *argv[], char *name));
-void init_msg __PROTO((void *jcr, MSGS *msg));
-void term_msg __PROTO((void));
-void close_msg __PROTO((void *jcr));
-void add_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where, char *dest_code));
-void rem_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where));
-void Jmsg (void *jcr, int type, int level, char *fmt, ...);
-void dispatch_message __PROTO((void *jcr, int type, int level, char *buf));
-void init_console_msg __PROTO((char *wd));
-void free_msgs_res(MSGS *msgs);
+void my_name_is (int argc, char *argv[], char *name);
+void init_msg (void *jcr, MSGS *msg);
+void term_msg (void);
+void close_msg (void *jcr);
+void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code);
+void rem_msg_dest (MSGS *msg, int dest, int type, char *where);
+void Jmsg (void *jcr, int type, int level, char *fmt, ...);
+void dispatch_message (void *jcr, int type, int level, char *buf);
+void init_console_msg (char *wd);
+void free_msgs_res (MSGS *msgs);
/* bnet_server.c */
-void bnet_thread_server(int port, int max_clients, workq_t *client_wq,
- void handle_client_request(void *bsock));
-void bnet_server __PROTO((int port, void handle_client_request(BSOCK *bsock)));
-int net_connect __PROTO((int port));
-BSOCK * bnet_bind __PROTO((int port));
-BSOCK * bnet_accept __PROTO((BSOCK *bsock, char *who));
+void bnet_thread_server(int port, int max_clients, workq_t *client_wq,
+ void handle_client_request(void *bsock));
+void bnet_server (int port, void handle_client_request(BSOCK *bsock));
+int net_connect (int port);
+BSOCK * bnet_bind (int port);
+BSOCK * bnet_accept (BSOCK *bsock, char *who);
/* signal.c */
-void init_signals __PROTO((void terminate(int sig)));
-void init_stack_dump (void);
+void init_signals (void terminate(int sig));
+void init_stack_dump (void);
/* util.c */
-void lcase __PROTO((char *str));
-void bash_spaces __PROTO((char *str));
-void unbash_spaces __PROTO((char *str));
-void strip_trailing_junk __PROTO((char *str));
-void strip_trailing_slashes __PROTO((char *dir));
-int skip_spaces __PROTO((char **msg));
-int skip_nonspaces __PROTO((char **msg));
-int fstrsch __PROTO((char *a, char *b));
-char * encode_time __PROTO((time_t time, char *buf));
-char * encode_mode __PROTO((mode_t mode, char *buf));
-char * edit_uint64_with_commas __PROTO((uint64_t val, char *buf));
-char * add_commas __PROTO((char *val, char *buf));
-char * edit_uint64 (uint64_t val, char *buf);
-int do_shell_expansion (char *name);
-int is_a_number (const char *num);
-int string_to_btime(char *str, btime_t *value);
-char *edit_btime(btime_t val, char *buf);
+void lcase (char *str);
+void bash_spaces (char *str);
+void unbash_spaces (char *str);
+void strip_trailing_junk (char *str);
+void strip_trailing_slashes (char *dir);
+int skip_spaces (char **msg);
+int skip_nonspaces (char **msg);
+int fstrsch (char *a, char *b);
+char * encode_time (time_t time, char *buf);
+char * encode_mode (mode_t mode, char *buf);
+char * edit_uint64_with_commas (uint64_t val, char *buf);
+char * add_commas (char *val, char *buf);
+char * edit_uint64 (uint64_t val, char *buf);
+int do_shell_expansion (char *name);
+int is_a_number (const char *num);
+int string_to_btime (char *str, btime_t *value);
+char *edit_btime (btime_t val, char *buf);
/*
- *void print_ls_output __PROTO((char *fname, char *lname, int type, struct stat *statp));
+ *void print_ls_output (char *fname, char *lname, int type, struct stat *statp);
*/
/* watchdog.c */
VolJobs=%d VolFiles=%d VolBlocks=%d VolBytes=%" lld " VolMounts=%d\
VolErrors=%d VolWrites=%d VolMaxBytes=%" lld " EndTime=%d VolStatus=%s\
FirstIndex=%d LastIndex=%d StartFile=%d EndFile=%d \
- StartBlock=%d EndBlock=%d\n";
+ StartBlock=%d EndBlock=%d relabel=%d\n";
static char FileAttributes[] = "UpdCat Job=%s FileAttributes ";
* After writing a Volume, send the updated statistics
* back to the director.
*/
-int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol)
+int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel)
{
BSOCK *dir = jcr->dir_bsock;
time_t EndTime = time(NULL);
if (vol->VolCatName[0] == 0) {
- Emsg0(M_ERROR, 0, "NULL Volume name. This shouldn't happen!!!\n");
+ Jmsg0(jcr, M_ERROR, 0, _("NULL Volume name. This shouldn't happen!!!\n"));
}
bnet_fsend(dir, Update_media, jcr->Job,
vol->VolCatName, vol->VolCatJobs, vol->VolCatFiles,
vol->VolCatStatus,
jcr->VolFirstFile, jcr->JobFiles,
jcr->start_file, jcr->end_file,
- jcr->start_block, jcr->end_block);
+ jcr->start_block, jcr->end_block,
+ relabel);
Dmsg1(20, "update_volume_data(): %s", dir->msg);
if (bnet_recv(dir) <= 0) {
Dmsg0(90, "updateVolCatInfo error bnet_recv\n");
Dmsg1(20, "Updatevol: %s", dir->msg);
if (strcmp(dir->msg, OK_update) != 0) {
Dmsg1(30, "Bad response from Dir: %s\n", dir->msg);
- Jmsg(jcr, M_ERROR, 0, "Error updating Volume Info: %s\n",
- dir->msg);
+ Jmsg(jcr, M_ERROR, 0, _("Error updating Volume Info: %s\n"), dir->msg);
return 0;
}
return 1;
wait_sec = min_wait;
for ( ;; ) {
if (job_cancelled(jcr)) {
- Mmsg(&dev->errmsg, "Job %s cancelled while waiting for mount on Storage Device \"%s\".\n",
+ Mmsg(&dev->errmsg, _("Job %s cancelled while waiting for mount on Storage Device \"%s\".\n"),
jcr->Job, jcr->dev_name);
return 0;
}
} else {
msg = "Please mount";
}
- Jmsg(jcr, M_MOUNT, 0, "%s Volume \"%s\" on Storage Device \"%s\" for Job %s\n",
+ Jmsg(jcr, M_MOUNT, 0, _("%s Volume \"%s\" on Storage Device \"%s\" for Job %s\n"),
msg, jcr->VolumeName, jcr->dev_name, jcr->Job);
Dmsg3(90, "Mount %s on %s for Job %s\n",
jcr->VolumeName, jcr->dev_name, jcr->Job);
} else {
jstat = JS_WaitMedia;
- Jmsg(jcr, M_MOUNT, 0, "Job %s waiting. Cannot find any appendable volumes.\n\
+ Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting. Cannot find any appendable volumes.\n\
Please use the \"unmount\" and \"label\" commands to create new Volumes for:\n\
Storage Device \"%s\" with Pool \"%s\" and Media type \"%s\".\n\
-Use \"mount\" to resume the job.\n",
+Use \"mount\" to resume the job.\n"),
jcr->Job, jcr->dev_name, jcr->pool_name, jcr->media_type);
}
/*
}
num_wait++;
if (num_wait >= max_num_wait) {
- Mmsg(&dev->errmsg, "Gave up waiting to mount Storage Device \"%s\" for Job %s\n",
+ Mmsg(&dev->errmsg, _("Gave up waiting to mount Storage Device \"%s\" for Job %s\n"),
jcr->dev_name, jcr->Job);
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
Dmsg1(90, "Gave up waiting on device %s\n", dev->dev_name);
continue;
}
if (stat == EINVAL) {
- Mmsg2(&dev->errmsg, "pthread error in mount_next_volume stat=%d ERR=%s\n",
+ Mmsg2(&dev->errmsg, _("pthread error in mount_next_volume stat=%d ERR=%s\n"),
stat, strerror(stat));
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
return 0;
}
if (stat != 0) {
- Jmsg(jcr, M_ERROR, 0, "pthread error in mount_next_volume stat=%d ERR=%s\n", stat,
+ Jmsg(jcr, M_ERROR, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat,
strerror(stat));
}
Dmsg1(90, "Someone woke me for device %s\n", dev->dev_name);
/* If no VolumeName, and cannot get one, try again */
if (jcr->VolumeName[0] == 0 &&
!dir_find_next_appendable_volume(jcr)) {
- Jmsg(jcr, M_MOUNT, 0,
+ Jmsg(jcr, M_MOUNT, 0, _(
"You woke me up, but I cannot find any appendable\n\
-volumes for Job=%s.\n", jcr->Job);
+volumes for Job=%s.\n"), jcr->Job);
continue;
}
break;
Dmsg0(30, "enter dir_ask_sysop_to_mount_next_volume\n");
if (!jcr->VolumeName[0]) {
- Mmsg0(&dev->errmsg, "Cannot request another volume: no volume name given.\n");
+ Mmsg0(&dev->errmsg, _("Cannot request another volume: no volume name given.\n"));
return 0;
}
ASSERT(dev->dev_blocked);
wait_sec = min_wait;
for ( ;; ) {
if (job_cancelled(jcr)) {
- Mmsg(&dev->errmsg, "Job %s cancelled while waiting for mount on Storage Device \"%s\".\n",
+ Mmsg(&dev->errmsg, _("Job %s cancelled while waiting for mount on Storage Device \"%s\".\n"),
jcr->Job, jcr->dev_name);
return 0;
}
- msg = "Please mount";
- Jmsg(jcr, M_MOUNT, 0, "%s Volume \"%s\" on Storage Device \"%s\" for Job %s\n",
+ msg = _("Please mount");
+ Jmsg(jcr, M_MOUNT, 0, _("%s Volume \"%s\" on Storage Device \"%s\" for Job %s\n"),
msg, jcr->VolumeName, jcr->dev_name, jcr->Job);
Dmsg3(90, "Mount %s on %s for Job %s\n",
jcr->VolumeName, jcr->dev_name, jcr->Job);
}
num_wait++;
if (num_wait >= max_num_wait) {
- Mmsg(&dev->errmsg, "Gave up waiting to mount Storage Device \"%s\" for Job %s\n",
+ Mmsg(&dev->errmsg, _("Gave up waiting to mount Storage Device \"%s\" for Job %s\n"),
jcr->dev_name, jcr->Job);
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
Dmsg1(90, "Gave up waiting on device %s\n", dev->dev_name);
continue;
}
if (stat == EINVAL) {
- Mmsg2(&dev->errmsg, "pthread error in mount_volume stat=%d ERR=%s\n",
+ Mmsg2(&dev->errmsg, _("pthread error in mount_volume stat=%d ERR=%s\n"),
stat, strerror(stat));
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
return 0;
}
if (stat != 0) {
- Jmsg(jcr, M_ERROR, 0, "pthread error in mount_next_volume stat=%d ERR=%s\n", stat,
+ Jmsg(jcr, M_ERROR, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat,
strerror(stat));
}
Dmsg1(90, "Someone woke me for device %s\n", dev->dev_name);
long total = 0;
DEV_RECORD rec;
DEV_BLOCK *block;
- char *fname; /* original file name */
- char *ofile; /* output name with prefix */
- char *lname; /* link name */
+ POOLMEM *fname; /* original file name */
+ POOLMEM *ofile; /* output name with prefix */
+ POOLMEM *lname; /* link name */
int wherelen; /* prefix length */
if (strncmp(devname, "/dev/", 5) != 0) {
}
wherelen = strlen(where);
- fname = (char *)get_pool_memory(PM_FNAME);
- ofile = (char *)get_pool_memory(PM_FNAME);
- lname = (char *)get_pool_memory(PM_FNAME);
+ fname = get_pool_memory(PM_FNAME);
+ ofile = get_pool_memory(PM_FNAME);
+ lname = get_pool_memory(PM_FNAME);
block = new_block(dev);
}
memset(&rec, 0, sizeof(rec));
- rec.data = (char *) get_memory(70000);
+ rec.data = get_memory(70000);
for ( ;; ) {
}
if (sizeof_pool_memory(fname) < rec.data_len) {
- fname = (char *) realloc_pool_memory(fname, rec.data_len + 1);
+ fname = realloc_pool_memory(fname, rec.data_len + 1);
}
if (sizeof_pool_memory(ofile) < sizeof_pool_memory(fname) + wherelen + 1) {
- ofile = (char *)realloc_pool_memory(ofile, sizeof_pool_memory(fname) + wherelen + 1);
+ ofile = realloc_pool_memory(ofile, sizeof_pool_memory(fname) + wherelen + 1);
}
if (sizeof_pool_memory(lname) < rec.data_len) {
- ofile = (char *)realloc_pool_memory(ofile, rec.data_len + 1);
+ ofile = realloc_pool_memory(ofile, rec.data_len + 1);
}
*fname = 0;
*lname = 0;
*/
DEV_BLOCK *new_block(DEVICE *dev)
{
- DEV_BLOCK *block = (DEV_BLOCK *) get_memory(sizeof(DEV_BLOCK));
+ DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
memset(block, 0, sizeof(DEV_BLOCK));
block->buf_len = ((block->buf_len + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
}
block->block_len = block->buf_len; /* default block size */
- block->buf = (char *) get_memory(block->buf_len);
+ block->buf = get_memory(block->buf_len);
if (block->buf == NULL) {
Mmsg0(&dev->errmsg, _("Unable to malloc block buffer.\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
#ifndef __BLOCK_H
#define __BLOCK_H 1
-#define MAX_BLOCK_LENGTH 500001 /* this is a sort of sanity check */
-#define DEFAULT_BLOCK_SIZE (512 * 126) /* 64,512 N.B. do not use 65,636 here */
+#define MAX_BLOCK_LENGTH 500001 /* this is a sort of sanity check */
+#define DEFAULT_BLOCK_SIZE (512 * 126) /* 64,512 N.B. do not use 65,636 here */
/* Block Header definitions. */
#define BLKHDR_ID "BB01"
#define BLKHDR_ID_LENGTH 4
-#define BLKHDR_CS_LENGTH 4 /* checksum length */
-#define BLKHDR_LENGTH 16 /* Total length */
+#define BLKHDR_CS_LENGTH 4 /* checksum length */
+#define BLKHDR_LENGTH 16 /* Total length */
/*
* This is the Media structure for a block header
* This is the memory structure for a device block.
*/
typedef struct s_dev_block {
- struct s_dev_block *next; /* pointer to next one */
+ struct s_dev_block *next; /* pointer to next one */
/* binbuf is the number of bytes remaining
* in the buffer. For writes, it is bytes not yet written.
* For reads, it is remaining bytes not yet read.
*/
- uint32_t binbuf; /* bytes in buffer */
- uint32_t block_len; /* length of current block read */
- uint32_t buf_len; /* max/default block length */
- uint32_t BlockNumber; /* sequential block number */
- uint32_t read_len; /* bytes read into buffer */
- int failed_write; /* set if write failed */
- char *bufp; /* pointer into buffer */
- char *buf; /* actual data buffer. This is a
- * Pool buffer!
- */
+ uint32_t binbuf; /* bytes in buffer */
+ uint32_t block_len; /* length of current block read */
+ uint32_t buf_len; /* max/default block length */
+ uint32_t BlockNumber; /* sequential block number */
+ uint32_t read_len; /* bytes read into buffer */
+ int failed_write; /* set if write failed */
+ char *bufp; /* pointer into buffer */
+ POOLMEM *buf; /* actual data buffer. This is a
+ * Pool buffer!
+ */
} DEV_BLOCK;
#endif
if ((errstat = pthread_mutex_init(&dev->mutex, NULL)) != 0) {
dev->dev_errno = errstat;
- Mmsg1(&dev->errmsg, "Unable to init mutex: ERR=%s\n", strerror(errstat));
+ Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
Emsg0(M_FATAL, 0, dev->errmsg);
}
if ((errstat = pthread_cond_init(&dev->wait, NULL)) != 0) {
dev->dev_errno = errstat;
- Mmsg1(&dev->errmsg, "Unable to init cond variable: ERR=%s\n", strerror(errstat));
+ Mmsg1(&dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), strerror(errstat));
Emsg0(M_FATAL, 0, dev->errmsg);
}
if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
dev->dev_errno = errstat;
- Mmsg1(&dev->errmsg, "Unable to init cond variable: ERR=%s\n", strerror(errstat));
+ Mmsg1(&dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), strerror(errstat));
Emsg0(M_FATAL, 0, dev->errmsg);
}
dev->fd = -1;
return -1;
}
dev->use_count++;
- Mmsg2(&dev->errmsg, "WARNING!!!! device %s opened %d times!!!\n",
+ Mmsg2(&dev->errmsg, _("WARNING!!!! device %s opened %d times!!!\n"),
dev->dev_name, dev->use_count);
Emsg0(M_WARNING, 0, dev->errmsg);
return dev->fd;
}
if ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) {
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "stored: unable to open device %s: ERR=%s\n",
+ Mmsg2(&dev->errmsg, _("stored: unable to open device %s: ERR=%s\n"),
dev->dev_name, strerror(dev->dev_errno));
Emsg0(M_FATAL, 0, dev->errmsg);
} else {
}
if ((dev->fd = open(archive_name, dev->mode, MODE_RW)) < 0) {
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "Could not open: %s, ERR=%s\n", archive_name, strerror(dev->dev_errno));
+ Mmsg2(&dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name, strerror(dev->dev_errno));
Emsg0(M_FATAL, 0, dev->errmsg);
} else {
dev->dev_errno = 0;
Dmsg0(29, "rewind_dev\n");
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg1(&dev->errmsg, "Bad call to rewind_dev. Device %s not open\n",
+ Mmsg1(&dev->errmsg, _("Bad call to rewind_dev. Device %s not open\n"),
dev->dev_name);
Emsg0(M_ABORT, 0, dev->errmsg);
return 0;
sleep(5);
continue;
}
- Mmsg2(&dev->errmsg, "Rewind error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("Rewind error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
return 0;
}
} else {
if (lseek(dev->fd, 0, SEEK_SET) < 0) {
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "lseek error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
return 0;
}
Dmsg1(50, "ioctl error: %s\n", strerror(dev->dev_errno));
clrerror_dev(dev, mt_com.mt_op);
update_pos_dev(dev);
- Mmsg2(&dev->errmsg, "ioctl MTEOM error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
return 0;
}
if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "ioctl MTIOCGET error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
return 0;
}
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad device call. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad device call. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return 0;
}
Dmsg1(200, "Seek error: ERR=%s\n", strerror(dev->dev_errno));
pos = 0;
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "lseek error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
} else {
stat = 1;
if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
Dmsg1(50, "MTIOCGET error: %s\n", strerror(dev->dev_errno));
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "ioctl MTIOCGET error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
} else {
stat = 1;
Dmsg2(-20," file=%d block=%d\n", dev->file, dev->block_num);
if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "ioctl MTIOCGET error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
return 0;
}
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to load_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to load_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return 0;
}
#ifndef MTLOAD
Dmsg0(200, "stored: MTLOAD command not available\n");
dev->dev_errno = ENOTTY; /* function not available */
- Mmsg2(&dev->errmsg, "ioctl MTLOAD error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno)); return 0;
return 0;
#else
mt_com.mt_count = 1;
if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "ioctl MTLOAD error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno)); return 0;
}
return 1;
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to load_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to load_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return 0;
}
mt_com.mt_count = 1;
if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, "ioctl MTOFFL error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTOFFL error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
return 0;
}
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return -1;
}
}
if (dev->state & ST_EOT) {
dev->dev_errno = 0;
- Mmsg1(&dev->errmsg, "Device %s at End of Tape.\n", dev->dev_name);
+ Mmsg1(&dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
return -1;
}
if (dev->state & ST_EOF)
dev->state |= ST_EOT;
clrerror_dev(dev, -1);
Dmsg1(200, "Set ST_EOT read error %d\n", dev->dev_errno);
- Mmsg2(&dev->errmsg, "read error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("read error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
Dmsg1(200, "%s", dev->errmsg);
break;
dev->state |= ST_EOT;
Dmsg0(200, "Set ST_EOT\n");
clrerror_dev(dev, MTFSF);
- Mmsg2(&dev->errmsg, "ioctl MTFSF error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
Dmsg0(200, "Got < 0 for MT_FSF\n");
Dmsg1(200, "%s", dev->errmsg);
}
if (dev->state & ST_EOT) {
dev->dev_errno = 0;
- Mmsg1(&dev->errmsg, "Device %s at End of Tape.\n", dev->dev_name);
+ Mmsg1(&dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
stat = -1;
} else {
stat = 0;
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return -1;
}
stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
if (stat < 0) {
clrerror_dev(dev, MTBSF);
- Mmsg2(&dev->errmsg, "ioctl MTBSF error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTBSF error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
}
update_pos_dev(dev);
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return -1;
}
dev->file++;
}
clrerror_dev(dev, MTFSR);
- Mmsg2(&dev->errmsg, "ioctl MTFSR error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTFSR error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
}
update_pos_dev(dev);
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return -1;
}
stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
if (stat < 0) {
clrerror_dev(dev, MTBSR);
- Mmsg2(&dev->errmsg, "ioctl MTBSR error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
}
update_pos_dev(dev);
if (dev->fd < 0) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return -1;
}
dev->file++;
} else {
clrerror_dev(dev, MTWEOF);
- Mmsg2(&dev->errmsg, "ioctl MTWEOF error on %s. ERR=%s.\n",
+ Mmsg2(&dev->errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
}
return stat;
}
if (msg != NULL) {
dev->dev_errno = ENOSYS;
- Mmsg1(&dev->errmsg, "This device does not support %s.\n", msg);
+ Mmsg1(&dev->errmsg, _("This device does not support %s.\n"), msg);
Emsg0(M_ERROR, 0, dev->errmsg);
}
}
close_dev(DEVICE *dev)
{
if (!dev) {
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return;
}
void force_close_dev(DEVICE *dev)
{
if (!dev) {
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return;
}
dev->use_count--;
}
+int truncate_dev(DEVICE *dev)
+{
+ if (dev->state & ST_TAPE) {
+ return 1;
+ }
+ if (ftruncate(dev->fd, 0) != 0) {
+ Mmsg1(&dev->errmsg, _("Unable to truncate device. ERR=%s\n"), strerror(errno));
+ return 0;
+ }
+ return 1;
+}
+
int
dev_is_tape(DEVICE *dev)
{
{
if (!dev) {
dev->dev_errno = EBADF;
- Mmsg0(&dev->errmsg, "Bad call to fsf_dev. Archive not open\n");
+ Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
Emsg0(M_FATAL, 0, dev->errmsg);
return;
}
weof_dev(dev, 1);
dev->VolCatInfo.VolCatFiles++; /* increment number of files */
/* Note! do volume update before close, which zaps VolCatInfo */
- dir_update_volume_info(jcr, &dev->VolCatInfo); /* send Volume info to Director */
+ dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */
if (!dev_is_tape(dev)) {
close_dev(dev);
} else {
Dmsg0(90, "Device is tape leave open in release_device\n");
}
} else {
- dir_update_volume_info(jcr, &dev->VolCatInfo); /* send Volume info to Director */
+ dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */
}
} else {
- Emsg1(M_ERROR, 0, _("BAD ERROR: release_device %s not in use.\n"), dev_name(dev));
+ Jmsg1(jcr, M_ERROR, 0, _("BAD ERROR: release_device %s not in use.\n"), dev_name(dev));
}
V(dev->mutex);
return 1;
Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"),
dev_name(dev), strerror_dev(dev));
}
+ if (recycle) {
+ if (!truncate_dev(dev)) {
+ Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device %s. ERR=%s\n"),
+ dev_name(dev), strerror_dev(dev));
+ }
+ }
if (!write_block_to_dev(dev, block)) {
Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s. ERR=%s\n"),
dev_name(dev), strerror_dev(dev));
dev->VolCatInfo.VolCatReads = 1;
}
strcpy(dev->VolCatInfo.VolCatStatus, "Append");
- dir_update_volume_info(jcr, &dev->VolCatInfo);
+ dir_update_volume_info(jcr, &dev->VolCatInfo, 1); /* indicate doing relabel */
if (recycle) {
Jmsg(jcr, M_INFO, 0, _("Recycled volume %s on device %s, all previous data lost.\n"),
jcr->VolumeName, dev_name(dev));
Jmsg(jcr, M_INFO, 0, _("Marking Volume %s in Error in Catalog.\n"),
jcr->VolumeName);
strcpy(dev->VolCatInfo.VolCatStatus, "Error");
- dir_update_volume_info(jcr, &dev->VolCatInfo);
+ dir_update_volume_info(jcr, &dev->VolCatInfo, 0);
return 0;
}
/* *****FIXME**** we might do some checking for files too */
strcpy(dev->VolCatInfo.VolCatStatus, "Full");
Dmsg0(90, "Call update_vol_info\n");
- if (!dir_update_volume_info(jcr, &dev->VolCatInfo)) { /* send Volume info to Director */
+ if (!dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) { /* send Volume info to Director */
Jmsg(jcr, M_ERROR, 0, _("Could not update Volume info Volume=%s Job=%s\n"),
dev->VolCatInfo.VolCatName, jcr->Job);
return 0; /* device locked */
* Authenticate the Director
*/
if (!authenticate_director(jcr)) {
- Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
+ Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n"));
free_jcr(jcr);
return;
}
if (VolName && *VolName && strcmp(dev->VolHdr.VolName, VolName) != 0) {
Mmsg(&jcr->errmsg, _("Volume name mismatch on device %s: Wanted %s got %s\n"),
dev_name(dev), VolName, dev->VolHdr.VolName);
-
+ /*
+ * Cancel Job if too many label errors
+ * => we are in a loop
+ */
+ if (jcr->label_errors > 100) {
+ jcr->JobStatus = JS_Cancelled;
+ Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
+ }
return jcr->label_status = VOL_NAME_ERROR;
}
Dmsg0(30, "Leave read_volume_label() VOL_OK\n");
if (VolName && *VolName && strcmp(dev->VolHdr.VolName, VolName) != 0) {
Mmsg(&jcr->errmsg, _("Volume name mismatch. Wanted %s got %s\n"),
VolName, dev->VolHdr.VolName);
+ /*
+ * Cancel Job if too many label errors
+ * => we are in a loop
+ */
+ if (jcr->label_errors > 100) {
+ jcr->JobStatus = JS_Cancelled;
+ Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
+ }
return jcr->label_status = VOL_NAME_ERROR;
}
Dmsg1(30, "Copy vol_name=%s\n", dev->VolHdr.VolName);
Dmsg0(20, "write Label in write_volume_label_to_block()\n");
memset(&rec, 0, sizeof(rec));
- rec.data = (char *) get_memory(SER_LENGTH_Volume_Label);
+ rec.data = get_memory(SER_LENGTH_Volume_Label);
create_volume_label_record(jcr, dev, &rec);
/* From askdir.c */
int dir_get_volume_info(JCR *jcr);
int dir_find_next_appendable_volume(JCR *jcr);
-int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol);
+int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
int open_dev(DEVICE *dev, char *VolName, int mode);
void close_dev(DEVICE *dev);
void force_close_dev(DEVICE *dev);
+int truncate_dev(DEVICE *dev);
void term_dev(DEVICE *dev);
char * strerror_dev(DEVICE *dev);
void clrerror_dev(DEVICE *dev, int func);
rec = (DEV_RECORD *) get_memory(sizeof(DEV_RECORD));
memset(rec, 0, sizeof(DEV_RECORD));
- rec->data = (char *) get_pool_memory(PM_MESSAGE);
+ rec->data = get_pool_memory(PM_MESSAGE);
return rec;
}
ASSERT(data_bytes < MAX_BLOCK_LENGTH); /* temp sanity check */
- rec->data = (char *) check_pool_memory_size(rec->data, rec->data_len+data_bytes);
+ rec->data = check_pool_memory_size(rec->data, rec->data_len+data_bytes);
/*
* At this point, we have read the header, now we
#define __RECORD_H 1
/* Return codes from read_device_volume_label() */
-#define VOL_NOT_READ 0 /* Volume label not read */
-#define VOL_OK 1 /* volume name OK */
-#define VOL_NO_LABEL 2 /* volume not labeled */
-#define VOL_IO_ERROR 3 /* volume I/O error */
-#define VOL_NAME_ERROR 4 /* Volume name mismatch */
-#define VOL_CREATE_ERROR 5 /* Error creating label */
-#define VOL_VERSION_ERROR 6 /* Bacula version error */
-#define VOL_LABEL_ERROR 7 /* Bad label type */
+#define VOL_NOT_READ 0 /* Volume label not read */
+#define VOL_OK 1 /* volume name OK */
+#define VOL_NO_LABEL 2 /* volume not labeled */
+#define VOL_IO_ERROR 3 /* volume I/O error */
+#define VOL_NAME_ERROR 4 /* Volume name mismatch */
+#define VOL_CREATE_ERROR 5 /* Error creating label */
+#define VOL_VERSION_ERROR 6 /* Bacula version error */
+#define VOL_LABEL_ERROR 7 /* Bad label type */
/* Length of Record Header (5 * 4 bytes) */
* This is the memory structure for the record header.
*/
typedef struct s_dev_rec {
- int sync; /* synchronous */
- uint32_t File; /* File number, returned if sync set */
- uint32_t Block; /* Block number, returned if sync set */
- uint32_t VolSessionId; /* sequential id within this session */
- uint32_t VolSessionTime; /* session start time */
- int32_t FileIndex; /* sequential file number */
- int32_t Stream; /* stream number */
- uint32_t data_len; /* current record length */
- uint32_t remainder; /* remaining bytes to read/write */
+ int sync; /* synchronous */
+ uint32_t File; /* File number, returned if sync set */
+ uint32_t Block; /* Block number, returned if sync set */
+ uint32_t VolSessionId; /* sequential id within this session */
+ uint32_t VolSessionTime; /* session start time */
+ int32_t FileIndex; /* sequential file number */
+ int32_t Stream; /* stream number */
+ uint32_t data_len; /* current record length */
+ uint32_t remainder; /* remaining bytes to read/write */
uint8_t ser_buf[RECHDR_LENGTH]; /* serialized record header goes here */
- char *data; /* Record data. This MUST be a memory pool item */
+ POOLMEM *data; /* Record data. This MUST be a memory pool item */
} DEV_RECORD;
* Note, these values are negative to distinguish them
* from user records where the FileIndex is forced positive.
*/
-#define PRE_LABEL -1 /* Vol label on unwritten tape */
-#define VOL_LABEL -2 /* Volume label first file */
-#define EOM_LABEL -3 /* Writen at end of tape */
-#define SOS_LABEL -4 /* Start of Session */
-#define EOS_LABEL -5 /* End of Session */
+#define PRE_LABEL -1 /* Vol label on unwritten tape */
+#define VOL_LABEL -2 /* Volume label first file */
+#define EOM_LABEL -3 /* Writen at end of tape */
+#define SOS_LABEL -4 /* Start of Session */
+#define EOS_LABEL -5 /* End of Session */
/*
* in the DEVICE buffer, but are not actually written
* to the tape.
*/
- int32_t LabelType; /* This is written in header only */
- uint32_t LabelSize; /* length of serialized label */
+ int32_t LabelType; /* This is written in header only */
+ uint32_t LabelSize; /* length of serialized label */
/*
* The items below this line are stored on
* the tape
*/
- char Id[32]; /* Bacula Immortal ... */
+ char Id[32]; /* Bacula Immortal ... */
- uint32_t VerNum; /* Label version number */
+ uint32_t VerNum; /* Label version number */
- float64_t label_date; /* Date tape labeled */
- float64_t label_time; /* Time tape labeled */
- float64_t write_date; /* Date this label written */
- float64_t write_time; /* Time this label written */
+ float64_t label_date; /* Date tape labeled */
+ float64_t label_time; /* Time tape labeled */
+ float64_t write_date; /* Date this label written */
+ float64_t write_time; /* Time this label written */
char VolName[MAX_NAME_LENGTH]; /* Volume name */
char PrevVolName[MAX_NAME_LENGTH]; /* Previous Volume Name */
char MediaType[MAX_NAME_LENGTH]; /* Type of this media */
char HostName[MAX_NAME_LENGTH]; /* Host name of writing computer */
- char LabelProg[32]; /* Label program name */
- char ProgVersion[32]; /* Program version */
- char ProgDate[32]; /* Program build date/time */
+ char LabelProg[32]; /* Label program name */
+ char ProgVersion[32]; /* Program version */
+ char ProgDate[32]; /* Program build date/time */
};
#define SER_LENGTH_Volume_Label 1024 /* max serialised length of volume label */
* This record is at the beginning and end of each session
*/
struct Session_Label {
- char Id[32]; /* Bacula Immortal ... */
+ char Id[32]; /* Bacula Immortal ... */
- uint32_t VerNum; /* Label version number */
+ uint32_t VerNum; /* Label version number */
- uint32_t JobId; /* Job id */
- uint32_t VolumeIndex; /* Sequence no of volume for this job */
+ uint32_t JobId; /* Job id */
+ uint32_t VolumeIndex; /* Sequence no of volume for this job */
- float64_t write_date; /* Date this label written */
- float64_t write_time; /* Time this label written */
+ float64_t write_date; /* Date this label written */
+ float64_t write_time; /* Time this label written */
char PoolName[MAX_NAME_LENGTH]; /* Pool name */
char PoolType[MAX_NAME_LENGTH]; /* Pool type */
};
typedef struct Session_Label SESSION_LABEL;
-#define SERIAL_BUFSIZE 1024 /* volume serialisation buffer size */
+#define SERIAL_BUFSIZE 1024 /* volume serialisation buffer size */
#endif
return;
}
+ /* The following code is only executed on pass 1 */
switch (type) {
case R_DIRECTOR:
size = sizeof(DIRRES);
/* */
#define VERSION "1.20"
#define VSTRING "1"
-#define DATE "22 May 2002"
-#define LSMDATE "22May02"
+#define DATE "25 May 2002"
+#define LSMDATE "25May02"
/* Debug flags */
#define DEBUG 1