Kern's ToDo List
- 15 September 2003
+ 16 September 2003
Documentation to do: (any release a little bit at a time)
- Document running a test version.
- Test not zeroing Autochanger slot when it is wrong.
- Figure out how to use ssh or stunnel to protect Bacula communications.
-For 1.32:
+For 1.32 Testing/Documentation:
- Document list nextvol and new format status dir.
- Document new records in Director. SDAddress SDDeviceName, SDPassword.
FDPassword, FDAddress, DBAddress, DBPort, DBPassword.
-- It is generally safe to use the drive when the lights stop flashing.
+- Document that it is safe to use the drive when the lights stop flashing.
- Document new Include/Exclude ...
- Document all the status codes JobLevel, JobType, JobStatus.
- Add test of exclusion, test multiple Include {} statements.
+
+For 1.32:
- Enhance "update slots" to include a "scan" feature
scan 1; scan 1-5; scan 1,2,4 ... to update the catalog
- Allow a slot or range of slots on the label barcodes command.
- when the magazine is changed.
- Don't print "Warning: Wrong Volume mounted ..." if mounting second volume.
-- LabelFormat on tape volume apparently creates the db record but
- never actually labels the volume.
-- Copy static programs into install directory.
+
+
+
For 1.33
-- Think about changing Storage resource Device record to be
- SDDeviceName.
+- Write a mini-readline with history and editing.
- Look at how fuser works and /proc/PID/fd that is how Nic found the
file descriptor leak in Bacula.
- Implement WrapCounters in Counters.
- Figure out some way to estimate output size and to avoid splitting
a backup across two Volumes -- this could be useful for writing CDROMs
where you really prefer not to have it split -- not serious.
-- Add RunBeforeJob and RunAfterJob to the Client program.
- Have SD compute MD5 or SHA1 and compare to what FD computes.
- Make VolumeToCatalog calculate an MD5 or SHA1 from the
actual data on the Volume and compare it.
- Check if we can increase Bacula FD priorty in Win2000
- Make sure the MaxVolFiles is fully implemented in SD
- Check if both CatalogFiles and UseCatalog are set to SD.
-- Need return status on read_cb() from read_records(). Need multiple
- records -- one per Job, maybe a JCR or some other structure with
- a block and a record.
- Figure out how to do a bare metal Windows restore
- Possibly add email to Watchdog if drive is unmounted too
long and a job is waiting on the drive.
- Document restore by files.
- Make variable expansion work correctly.
- Implement List Volume Job=xxx or List scheduled volumes or Status Director
+- Copy static programs into install directory.
+- Think about changing Storage resource Device record to be
+ SDDeviceName.
+- Add RunBeforeJob and RunAfterJob to the Client program.
+- Need return status on read_cb() from read_records(). Need multiple
+ records -- one per Job, maybe a JCR or some other structure with
+ a block and a record.
+- LabelFormat on tape volume apparently creates the db record but
+ never actually labels the volume.
+
#define mp_chr(x) ((char*)(x))
class POOLMEM {
public:
- POOLMEM() { }
+ POOLMEM();
operator char * const() { return this; }
};
#endif
db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
{
int stat;
- char ed1[30], ed2[30], ed3[30], ed4[30];
+ char ed1[30], ed2[30], ed3[30], ed4[30], ed5[30];
char dt[MAX_TIME_LENGTH];
struct tm tm;
localtime_r(&mr->LabelDate, &tm);
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
} else {
- strcpy(dt, "0000-00-00 00:00:00");
+ bstrncpy(dt, "0000-00-00 00:00:00", sizeof(dt));
}
Mmsg(&mdb->cmd,
"INSERT INTO Media (VolumeName,MediaType,PoolId,MaxVolBytes,VolCapacityBytes,"
"Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
-"VolStatus,LabelDate,Slot) "
-"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s','%s',%d)",
+"VolStatus,LabelDate,Slot,VolBytes) "
+"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s','%s',%d,%s)",
mr->VolumeName,
mr->MediaType, mr->PoolId,
edit_uint64(mr->MaxVolBytes,ed1),
mr->MaxVolJobs,
mr->MaxVolFiles,
mr->VolStatus, dt,
- mr->Slot);
+ mr->Slot,
+ edit_uint64(mr->VolBytes, ed5));
Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
Dmsg1(400, "Firstwritten stat=%d\n", stat);
}
+ /* Label just done? */
+ if (mr->VolBytes == 1) {
+ ttime = mr->LabelDate;
+ if (ttime == 0) {
+ ttime = time(NULL);
+ }
+ localtime_r(&ttime, &tm);
+ strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
+ Mmsg(&mdb->cmd, "UPDATE Media SET LabelDate='%s'\
+ WHERE VolumeName='%s'", dt, mr->VolumeName);
+ stat = UPDATE_DB(jcr, mdb, mdb->cmd);
+ }
+
ttime = mr->LastWritten;
localtime_r(&ttime, &tm);
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
$(MV) -f ${DESTDIR}${scriptdir}/query.sql ${DESTDIR}${scriptdir}/query.sql.save; \
fi
${INSTALL_DATA} query.sql ${DESTDIR}${scriptdir}/query.sql
+ @if test -f static-bacula-dir; then \
+ $(INSTALL_PROGRAM) static-bacula-dir $(DESTDIR)$(sbindir)/static-bacula-dir; \
+ fi
uninstall:
MEDIA_DBR mr, sdmr;
JOBMEDIA_DBR jm;
char Job[MAX_NAME_LENGTH];
- int index, ok, relabel, writing;
+ int index, ok, label, writing;
POOLMEM *omsg;
memset(&mr, 0, sizeof(mr));
} else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName, &sdmr.VolJobs,
&sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes, &sdmr.VolMounts, &sdmr.VolErrors,
&sdmr.VolWrites, &sdmr.MaxVolBytes, &sdmr.LastWritten, &sdmr.VolStatus,
- &sdmr.Slot, &relabel) == 14) {
+ &sdmr.Slot, &label) == 14) {
db_lock(jcr->db);
Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName,
if (mr.VolJobs == 0 || sdmr.VolJobs == 1) {
mr.FirstWritten = jcr->start_time; /* use Job start time as first write */
}
+ /* If we just labeled the tape set time */
+ Dmsg2(400, "label=%d labeldate=%d\n", label, mr.LabelDate);
+ if (label || mr.LabelDate == 0) {
+ mr.LabelDate = time(NULL);
+ }
Dmsg2(200, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
/* Copy updated values to original media record */
mr.VolJobs = sdmr.VolJobs;
* Update Media Record
*/
- /* Check limits and expirations if "Append" and not a relable request */
- if (strcmp(mr.VolStatus, "Append") == 0 && !relabel) {
+ /* Check limits and expirations if "Append" and not a lable request */
+ if (strcmp(mr.VolStatus, "Append") == 0 && !label) {
/* First handle Max Volume Bytes */
if ((mr.MaxVolBytes > 0 && mr.VolBytes >= mr.MaxVolBytes)) {
Jmsg(jcr, M_INFO, 0, _("Max Volume bytes exceeded. "
/*
- * Automatic Volume name creation using
- * LabelFormat. We assume that if this routine is being
- * called the Volume will be labeled, so we set the LabelDate.
+ * Automatic Volume name creation using the LabelFormat
*/
int newVolume(JCR *jcr, MEDIA_DBR *mr)
{
if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
memset(mr, 0, sizeof(MEDIA_DBR));
set_pool_dbr_defaults_in_media_dbr(mr, &pr);
- mr->LabelDate = time(NULL);
bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType));
/* Check for special characters */
if (is_volume_name_legal(NULL, pr.LabelFormat)) {
void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr)
{
mr->PoolId = pr->PoolId;
- strcpy(mr->VolStatus, "Append");
+ bstrncpy(mr->VolStatus, "Append", sizeof(mr->VolStatus));
mr->Recycle = pr->Recycle;
mr->VolRetention = pr->VolRetention;
mr->VolUseDuration = pr->VolUseDuration;
}
}
if (ua->automount) {
- strcpy(dev_name, store->dev_name);
+ bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
bsendmsg(ua, _("Requesting mount %s ...\n"), dev_name);
bash_spaces(dev_name);
bnet_fsend(sd, "mount %s", dev_name);
bash_spaces(pr->Name);
if (relabel) {
bash_spaces(omr->VolumeName);
- bnet_fsend(sd, _("relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d"),
+ bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d",
dev_name, omr->VolumeName, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
bsendmsg(ua, _("Sending relabel command from \"%s\" to \"%s\" ...\n"),
omr->VolumeName, mr->VolumeName);
} else {
- bnet_fsend(sd, _("label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d"),
+ bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d",
dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
bsendmsg(ua, _("Sending label command for Volume \"%s\" Slot %d ...\n"),
mr->VolumeName, mr->Slot);
mr->LabelDate = time(NULL);
if (ok) {
set_pool_dbr_defaults_in_media_dbr(mr, pr);
+ mr->VolBytes = 1; /* flag indicating Volume labeled */
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);
fi; \
echo "${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf"; \
${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf
+ @if test -f static-bacula-fd; then \
+ $(INSTALL_PROGRAM) static-bacula-fd $(DESTDIR)$(sbindir)/static-bacula-fd; \
+ fi
+
+
uninstall:
(cd $(DESTDIR)$(sbindir); $(RMF) bacula-fd)
fi; \
echo "${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf"; \
${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf
+ @if test -f static-bacula-sd; then \
+ $(INSTALL_PROGRAM) static-bacula-sd $(DESTDIR)$(sbindir)/static-bacula-sd; \
+ fi
uninstall:
(cd $(DESTDIR)$(sbindir); $(RMF) bacula-sd)
* After writing a Volume, send the updated statistics
* back to the director.
*/
-int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel)
+int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int label)
{
BSOCK *dir = jcr->dir_bsock;
time_t EndTime = time(NULL);
Jmsg0(jcr, M_ERROR, 0, _("NULL Volume name. This shouldn't happen!!!\n"));
return 0;
}
+ /* Just labeled or relabeled the tape */
+ if (label) {
+ bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
+ vol->VolCatBytes = 1; /* indicates tape labeled */
+ }
bash_spaces(vol->VolCatName);
bnet_fsend(dir, Update_media, jcr->Job,
vol->VolCatName, vol->VolCatJobs, vol->VolCatFiles,
vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1),
vol->VolCatMounts, vol->VolCatErrors,
vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2),
- EndTime, vol->VolCatStatus, vol->Slot, relabel);
+ EndTime, vol->VolCatStatus, vol->Slot, label);
Dmsg1(120, "update_volume_data(): %s", dir->msg);
unbash_spaces(vol->VolCatName);
if (bnet_recv(dir) <= 0) {
return dev->fd;
}
+#ifdef debug_tracing
+#undef rewind_dev
+int _rewind_dev(char *file, int line, DEVICE *dev)
+{
+ Dmsg2(000, "rewind_dev called from %s:%d\n", file, line);
+ return rewind_dev(dev);
+}
+#endif
+
+
/*
* Rewind the device.
* Returns: 1 on success
struct mtop mt_com;
unsigned int i;
- Dmsg0(29, "rewind_dev\n");
+ Dmsg1(29, "rewind_dev %s\n", dev->dev_name);
if (dev->fd < 0) {
dev->dev_errno = EBADF;
Mmsg1(&dev->errmsg, _("Bad call to rewind_dev. Device %s not open\n"),
/* ***FIXME*** we really need to get the volume name,
* pool name, and pool type from the database.
*/
- strcpy(dev->VolHdr.Id, BaculaId);
+ bstrncpy(dev->VolHdr.Id, BaculaId, sizeof(dev->VolHdr.Id));
dev->VolHdr.VerNum = BaculaTapeVersion;
dev->VolHdr.LabelType = PRE_LABEL; /* Mark tape as unused */
bstrncpy(dev->VolHdr.VolName, VolName, sizeof(dev->VolHdr.VolName));
bstrncpy(dev->VolHdr.PoolName, PoolName, sizeof(dev->VolHdr.PoolName));
bstrncpy(dev->VolHdr.MediaType, device->media_type, sizeof(dev->VolHdr.MediaType));
- strcpy(dev->VolHdr.PoolType, "Backup");
+ bstrncpy(dev->VolHdr.PoolType, "Backup", sizeof(dev->VolHdr.PoolType));
/* Put label time/date in header */
if (BaculaTapeVersion >= 11) {
for ( ;; ) {
int vol_label_status;
autochanger = autoload_device(jcr, dev, 1, NULL);
+ Dmsg1(100, "autoload_dev returns %d\n", autochanger);
/*
* If we autochanged to correct Volume or (we have not just
goto mount_error;
}
Dmsg1(100, "want new name=%s\n", jcr->VolumeName);
- memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo));
+ memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(dev->VolCatInfo));
if (strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0) {
recycle = 1;
}
*/
case VOL_NO_LABEL:
case VOL_IO_ERROR:
- Dmsg1(500, "Vol NO_LABEL or IO_ERROR name=%s\n", jcr->VolumeName);
- /* If permitted, create a label */
- if (dev_cap(dev, CAP_LABEL)) {
+ /*
+ * If permitted, we label the device, make sure we can do
+ * it by checking that the VolCatBytes is zero => not labeled.
+ */
+ if (dev_cap(dev, CAP_LABEL) && dev->VolCatInfo.VolCatBytes == 0) {
Dmsg0(100, "Create volume label\n");
- /* ***FIXME*** ask for label name */
if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName,
jcr->pool_name)) {
Dmsg0(100, "!write_vol_label\n");
goto mount_next_vol;
}
+ Dmsg0(200, "dir_update_vol_info. Set Append\n");
+ memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(dev->VolCatInfo));
+ dir_update_volume_info(jcr, &dev->VolCatInfo, 1); /* indicate tape labeled */
Jmsg(jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
jcr->VolumeName, dev_name(dev));
goto read_volume; /* read label we just wrote */
* It is better to find out now rather than later.
*/
if (!dev_cap(dev, CAP_STREAM)) {
- dev->VolCatInfo.VolCatBytes = 0;
if (!rewind_dev(dev)) {
Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"),
dev_name(dev), strerror_dev(dev));
/* Set or reset Volume statistics */
dev->VolCatInfo.VolCatJobs = 0;
dev->VolCatInfo.VolCatFiles = 0;
+ dev->VolCatInfo.VolCatBytes = 0;
dev->VolCatInfo.VolCatErrors = 0;
dev->VolCatInfo.VolCatBlocks = 0;
dev->VolCatInfo.VolCatRBytes = 0;
dev->VolCatInfo.VolCatWrites = 1;
dev->VolCatInfo.VolCatReads = 1;
}
- bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus));
Dmsg0(200, "dir_update_vol_info. Set Append\n");
dir_update_volume_info(jcr, &dev->VolCatInfo, 1); /* indicate doing relabel */
if (recycle) {
};
int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw);
int dir_find_next_appendable_volume(JCR *jcr);
-int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
+int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int label);
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);
extern STORES *me; /* "Global" daemon resource */
+#ifdef debug_tracing
+extern int _rewind_dev(char *file, int line, DEVICE *dev);
+#define rewind_dev(d) _rewind_dev(__FILE__, __LINE__, (d))
+#endif
+
#endif /* __STORED_H_ */