return false;
}
if (strcmp(info->plugin_license, "Bacula AGPLv3") != 0 &&
- strcmp(info->plugin_license, "AGPLv3") != 0 &&
+ strcmp(info->plugin_license, "AGPLv3") != 0) {
Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"),
plugin->file, info->plugin_license);
Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n",
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
return false;
}
- jcr->setJobStatus(JS_Running);
- dir_send_job_status(jcr);
+ jcr->sendJobStatus(JS_Running);
if (dev->VolCatInfo.VolCatName[0] == 0) {
Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n"));
stream_to_ascii(buf1, rec.Stream,rec.FileIndex),
rec.data_len);
- while (!write_record_to_block(dcr, &rec)) {
- Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
- rec.remainder);
- if (!dcr->write_block_to_device()) {
- Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
- dev->print_name(), dev->bstrerror());
- ok = false;
- break;
- }
- }
+ ok = dcr->write_record(&rec);
if (!ok) {
- Dmsg0(400, "Not OK\n");
+ Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+ dcr->dev->print_name(), dcr->dev->bstrerror());
break;
}
jcr->JobBytes += rec.data_len; /* increment bytes this job */
fd->fsend("3999 Failed append\n");
}
- /*
- * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits,
- * and the subsequent Jmsg() editing will break
- */
- int32_t job_elapsed = time(NULL) - jcr->run_time;
-
- if (job_elapsed <= 0) {
- job_elapsed = 1;
- }
-
- Jmsg(dcr->jcr, M_INFO, 0, _("Job write elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n"),
- job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60,
- edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec));
-
-
Dmsg1(200, "Write EOS label JobStatus=%c\n", jcr->JobStatus);
/*
}
}
-
if (!ok && !jcr->is_JobStatus(JS_Incomplete)) {
discard_data_spool(dcr);
} else {
if (ok) {
ok = dvd_close_job(dcr); /* do DVD cleanup if any */
}
+
+ /*
+ * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits,
+ * and the subsequent Jmsg() editing will break
+ */
+ int32_t job_elapsed = time(NULL) - jcr->run_time;
+
+ if (job_elapsed <= 0) {
+ job_elapsed = 1;
+ }
+
+ Jmsg(dcr->jcr, M_INFO, 0, _("Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n"),
+ job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60,
+ edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec));
/*
* Release the device -- and send final Vol info to DIR
commit_attribute_spool(jcr);
}
- dir_send_job_status(jcr); /* update director */
+ jcr->sendJobStatus(); /* update director */
Dmsg1(100, "return from do_append_data() ok=%d\n", ok);
return ok;
" FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u"
" StartBlock=%u EndBlock=%u Copy=%d Strip=%d MediaId=%s\n";
static char FileAttributes[] = "UpdCat Job=%s FileAttributes ";
-static char Job_status[] = "Status Job=%s JobStatus=%d\n";
/* Responses received from the Director */
static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%lu"
*/
bool dir_send_job_status(JCR *jcr)
{
- return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus);
+ return jcr->sendJobStatus();
}
/**
Dmsg1(100, ">dird %s", dir->msg);
/* Do not lock device here because it may be locked from label */
- if (!do_get_volume_info(dcr)) {
- Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
- Dmsg2(100, _("Didn't get vol info vol=%s: ERR=%s"),
- vol->VolCatName, jcr->errmsg);
- goto bail_out;
+ if (!jcr->is_canceled()) {
+ if (!do_get_volume_info(dcr)) {
+ Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
+ Dmsg2(100, _("Didn't get vol info vol=%s: ERR=%s"),
+ vol->VolCatName, jcr->errmsg);
+ goto bail_out;
+ }
+ Dmsg1(420, "get_volume_info() %s", dir->msg);
+ /* Update dev Volume info in case something changed (e.g. expired) */
+ dev->VolCatInfo = dcr->VolCatInfo;
+ ok = true;
}
- Dmsg1(420, "get_volume_info() %s", dir->msg);
- /* Update dev Volume info in case something changed (e.g. expired) */
- dev->VolCatInfo = dcr->VolCatInfo;
- ok = true;
bail_out:
V(vol_info_mutex);
}
}
- jcr->setJobStatus(JS_WaitMedia);
- dir_send_job_status(jcr);
+ jcr->sendJobStatus(JS_WaitMedia);
stat = wait_for_sysop(dcr);
Dmsg1(100, "Back from wait_for_sysop stat=%d\n", stat);
}
get_out:
- jcr->setJobStatus(JS_Running);
- dir_send_job_status(jcr);
+ jcr->sendJobStatus(JS_Running);
Dmsg0(100, "leave dir_ask_sysop_to_mount_create_appendable_volume\n");
return true;
}
dcr->VolumeName, dev->print_name(), jcr->Job);
}
- jcr->setJobStatus(JS_WaitMount);
- dir_send_job_status(jcr);
+ jcr->sendJobStatus(JS_WaitMount);
stat = wait_for_sysop(dcr); /* wait on device */
Dmsg1(100, "Back from wait_for_sysop stat=%d\n", stat);
}
get_out:
- jcr->setJobStatus(JS_Running);
- dir_send_job_status(jcr);
+ jcr->sendJobStatus(JS_Running);
Dmsg0(400, "leave dir_ask_sysop_to_mount_volume\n");
return true;
}
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2002-2011 Free Software Foundation Europe e.V.
+ Copyright (C) 2002-2012 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
device->hdr.name);
OK = false;
}
-
-#ifdef xxx_needed
- if (media_type == NULL) {
- media_type = device->media_type; /* get Media Type of first device */
- continue;
- }
- /* Ensure that other devices Media Types are the same */
- if (strcmp(media_type, device->media_type) != 0) {
- Jmsg(NULL, M_ERROR, 0,
- _("Media Type not the same for all devices in changer %s. Cannot continue.\n"),
- changer->hdr.name);
- OK = false;
- continue;
- }
-#endif
}
}
return OK;
return -1;
}
if (!dcr->device->changer_command) {
-// Jmsg(jcr, M_FATAL, 0, _("3992 Missing Changer command.\n"));
return -1;
}
if (dev->get_slot() > 0) {
changer = get_pool_memory(PM_FNAME);
lock_changer(dcr);
/* Suppress info when polling */
- if (!dev->poll) {
+ if (!dev->poll && debug_level >= 1) {
Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded? drive %d\" command.\n"),
drive);
}
loaded = str_to_int32(results.c_str());
if (loaded > 0) {
/* Suppress info when polling */
- if (!dev->poll) {
+ if (!dev->poll && debug_level >= 1) {
Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n"),
drive, loaded);
}
dev->set_slot(loaded);
} else {
/* Suppress info when polling */
- if (!dev->poll) {
+ if (!dev->poll && debug_level >= 1) {
Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n"),
drive);
}
continue;
}
dev_save = dcr->dev;
- dcr->dev = dev;
+ dcr->set_dev(dev);
if (dev->get_slot() <= 0 && get_autochanger_loaded_slot(dcr) <= 0) {
- dcr->dev = dev_save;
+ dcr->set_dev(dev_save);
continue;
}
- dcr->dev = dev_save;
+ dcr->set_dev(dev_save);
if (dev->get_slot() == slot) {
found = true;
break;
}
save_dev = dcr->dev; /* save dcr device */
- dcr->dev = dev; /* temporarily point dcr at other device */
+ dcr->set_dev(dev); /* temporarily point dcr at other device */
/* Update slot if not set or not always_open */
if (dev->get_slot() <= 0 || !dev->has_cap(CAP_ALWAYSOPEN)) {
/* Fail if we have no slot to unload */
if (dev->get_slot() <= 0) {
- dcr->dev = save_dev;
+ dcr->set_dev(save_dev);
return false;
}
Dmsg1(100, "Run program=%s\n", changer_cmd);
int stat = run_program_full_output(changer_cmd, timeout, results.addr());
dcr->VolCatInfo.Slot = save_slot;
- dcr->dev = save_dev;
+ dcr->set_dev(save_dev);
if (stat != 0) {
berrno be;
be.set_errno(stat);
return true;
}
+ /* If listing, reprobe changer */
+ if (bstrcmp(cmd, "list") || bstrcmp(cmd, "listall")) {
+ dcr->dev->set_slot(0);
+ get_autochanger_loaded_slot(dcr);
+ }
+
changer = get_pool_memory(PM_FNAME);
lock_changer(dcr);
/* Now issue the command */
*/
void free_block(DEV_BLOCK *block)
{
- Dmsg1(999, "free_block buffer %x\n", block->buf);
- free_memory(block->buf);
- Dmsg1(999, "free_block block %x\n", block);
- free_memory((POOLMEM *)block);
+ if (block) {
+ Dmsg1(999, "free_block buffer %x\n", block->buf);
+ free_memory(block->buf);
+ Dmsg1(999, "free_block block %x\n", block);
+ free_memory((POOLMEM *)block);
+ }
}
/* Empty the block -- for writing */
VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */
/* Methods */
+ void set_dev(DEVICE *ndev) { dev = ndev; };
bool found_in_use() const { return m_found_in_use; };
void set_found_in_use() { m_found_in_use = true; };
void clear_found_in_use() { m_found_in_use = false; };
bool is_reserved() const { return m_reserved; };
bool is_dev_locked() { return m_dev_locked; }
-#ifdef SD_DEBUG_LOCK
- void _dlock(const char *, int); /* in lock.c */
- void _dunlock(const char *, int); /* in lock.c */
-#else
- void dlock() { dev->dlock(); m_dev_locked = true; }
- void dunlock() { m_dev_locked = false; dev->dunlock(); }
-#endif
- void dblock(int why) { dev->dblock(why); }
void setVolCatInfo(bool valid) { VolCatInfo.is_valid = valid; };
bool haveVolCatInfo() const { return VolCatInfo.is_valid; };
void setVolCatName(const char *name) {
};
char *getVolCatName() { return VolCatInfo.VolCatName; };
+ /* Methods in lock.c */
+ void dblock(int why) { dev->dblock(why); }
+#ifdef SD_DEBUG_LOCK
+ void _dlock(const char *, int); /* in lock.c */
+ void _dunlock(const char *, int); /* in lock.c */
+#else
+ void dlock() { dev->dlock(); m_dev_locked = true; }
+ void dunlock() { m_dev_locked = false; dev->dunlock(); }
+#endif
+
+ /* Methods in record.c */
+ bool write_record(DEV_RECORD *rec);
/* Methods in reserve.c */
void clear_reserved();
}
bail_out:
generate_daemon_event(jcr, "JobEnd");
+ generate_plugin_event(jcr, bsdEventJobEnd);
dequeue_messages(jcr); /* send any queued messages */
bs->signal(BNET_TERMINATE);
+ free_plugins(jcr); /* release instantiated plugins */
free_jcr(jcr);
return NULL;
}
{
#ifdef DEVELOPER
JCR *djcr = NULL;
- int a, b;
+ int a;
BSOCK *dir = jcr->dir_bsock;
pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
Pmsg1(000, "I have been requested to die ... (%s)\n", dir->msg);
a = djcr->JobId; /* ref NULL pointer */
- b = a; /* Keep compiler quiet */
- a = b;
+ djcr->JobId = a;
#endif
return 0;
}
int oldStatus;
char Job[MAX_NAME_LENGTH];
JCR *jcr;
+ int status;
+ const char *reason;
if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
- if (!(jcr=get_jcr_by_full_name(Job))) {
- dir->fsend(_("3904 Job %s not found.\n"), Job);
- } else {
- oldStatus = jcr->JobStatus;
- jcr->setJobStatus(JS_Canceled);
- Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr);
- if (!jcr->authenticated && oldStatus == JS_WaitFD) {
- pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
- }
- if (jcr->file_bsock) {
- jcr->file_bsock->set_terminated();
- jcr->file_bsock->set_timed_out();
- Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr);
- } else {
- /* Still waiting for FD to connect, release it */
- pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
- Dmsg2(800, "Signal FD connect jid=%d %p\n", jcr->JobId, jcr);
- }
- /* If thread waiting on mount, wake him */
- if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
- pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
- Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
- pthread_cond_broadcast(&wait_device_release);
- }
- if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
- pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
- Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
- pthread_cond_broadcast(&wait_device_release);
- }
- dir->fsend(_("3000 JobId=%ld Job=\"%s\" marked to be canceled.\n"), jcr->JobId, jcr->Job);
- free_jcr(jcr);
- }
+ status = JS_Canceled;
+ reason = "canceled";
} else {
dir->fsend(_("3903 Error scanning cancel command.\n"));
+ goto bail_out;
+ }
+ if (!(jcr=get_jcr_by_full_name(Job))) {
+ dir->fsend(_("3904 Job %s not found.\n"), Job);
+ } else {
+ oldStatus = jcr->JobStatus;
+ jcr->setJobStatus(status);
+ Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr);
+ if (!jcr->authenticated && oldStatus == JS_WaitFD) {
+ pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
+ }
+ if (jcr->file_bsock) {
+ jcr->file_bsock->set_terminated();
+ jcr->file_bsock->set_timed_out();
+ Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr);
+ } else {
+ /* Still waiting for FD to connect, release it */
+ pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
+ Dmsg2(800, "Signal FD connect jid=%d %p\n", jcr->JobId, jcr);
+ }
+ /* If thread waiting on mount, wake him */
+ if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
+ pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
+ Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
+ pthread_cond_broadcast(&wait_device_release);
+ }
+ if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
+ pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
+ Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
+ pthread_cond_broadcast(&wait_device_release);
+ }
+ dir->fsend(_("3000 JobId=%ld Job=\"%s\" marked to be %s.\n"),
+ jcr->JobId, jcr->Job, reason);
+ free_jcr(jcr);
}
+
+bail_out:
dir->signal(BNET_EOD);
return 1;
}
}
bail_out:
+ if (dev->is_open() && !dev->has_cap(CAP_ALWAYSOPEN)) {
+ dev->close();
+ }
if (!dev->is_open()) {
dev->clear_volhdr();
}
"If this is not a blank tape, try unmounting and remounting the Volume.\n"),
dev->print_name());
}
+ if (dev->is_open() && !dev->has_cap(CAP_ALWAYSOPEN)) {
+ dev->close();
+ }
} else if (dev->is_unmountable()) {
if (dev->mount(1)) {
dir->fsend(_("3002 Device \"%s\" is mounted.\n"), dev->print_name());
BSOCK *dir = jcr->dir_bsock;
bsteal_lock_t hold;
- dcr->dev = dev;
+ dcr->set_dev(dev);
steal_device_lock(dev, &hold, BST_WRITING_LABEL);
if (!try_autoload_device(jcr, dcr, Slot, "")) {
}
return true;
}
+
+/*
+ * Write a Record to the block
+ *
+ * Returns: false means the block could not be written to tape/disk.
+ * true on success (all bytes written to the block).
+ */
+bool DCR::write_record(DEV_RECORD *rec)
+{
+ while (!write_record_to_block(this, rec)) {
+ Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
+ rec->remainder);
+ if (!write_block_to_device()) {
+ Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+ dev->print_name(), dev->bstrerror());
+ return false;
+ }
+ }
+ return true;
+}
+
/*
* Write a Record to the block
*
/* Responses sent to Director daemon */
static char OK_device[] = "3000 OK use device device=%s\n";
-static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
+static char NO_device[] = "3924 Device \"%s\" not in SD Device"
+ " resources or no matching Media Type.\n";
static char BAD_use[] = "3913 Bad use command: %s\n";
bool use_cmd(JCR *jcr)
dev->num_writers = 0;
}
if (dev->num_reserved() == 0 && dev->num_writers == 0) {
+ generate_plugin_event(jcr, bsdEventDeviceClose, this);
volume_unused(this);
}
}
unlock_volumes();
- generate_plugin_event(jcr, bsdEventDeviceClose, this);
dev->dunlock();
}
#include "stored.h"
#include "sd_plugins.h"
-const int dbglvl = 150;
+const int dbglvl = 250;
const char *plugin_type = "-sd.so";
free_pool_memory(rdev->errmsg);
/* Be careful to NULL the jcr and free rdev after free_dcr() */
rdcr->jcr = NULL;
- rdcr->dev = NULL;
+ rdcr->set_dev(NULL);
free_dcr(rdcr);
free(rdev);
dcr->spooling = true; /* turn on spooling again */
free_volume(dev); /* free any volume attached to our drive */
Dmsg1(50, "set_unload dev=%s\n", dev->print_name());
dev->set_unload(); /* Unload any volume that is on our drive */
- dcr->dev = vol->dev; /* temp point to other dev */
+ dcr->set_dev(vol->dev); /* temp point to other dev */
slot = get_autochanger_loaded_slot(dcr); /* get slot on other drive */
- dcr->dev = dev; /* restore dev */
+ dcr->set_dev(dev); /* restore dev */
vol->set_slot(slot); /* save slot */
vol->dev->set_unload(); /* unload the other drive */
vol->set_swapping(); /* swap from other drive */
return vol;
}
-/*
- * Switch from current device to given device
- * (not yet used)
- */
-#ifdef xxx
-void switch_device(DCR *dcr, DEVICE *dev)
-{
- DCR save_dcr;
-
- dev->dlock();
- memcpy(&save_dcr, dcr, sizeof(save_dcr));
- clean_device(dcr); /* clean up the dcr */
-
- dcr->dev = dev; /* get new device pointer */
- Jmsg(dcr->jcr, M_INFO, 0, _("Device switch. New device %s chosen.\n"),
- dcr->dev->print_name());
-
- bstrncpy(dcr->VolumeName, save_dcr.VolumeName, sizeof(dcr->VolumeName));
- bstrncpy(dcr->media_type, save_dcr.media_type, sizeof(dcr->media_type));
- dcr->VolCatInfo.Slot = save_dcr.VolCatInfo.Slot;
- bstrncpy(dcr->pool_name, save_dcr.pool_name, sizeof(dcr->pool_name));
- bstrncpy(dcr->pool_type, save_dcr.pool_type, sizeof(dcr->pool_type));
- bstrncpy(dcr->dev_name, dev->dev_name, sizeof(dcr->dev_name));
-
-// dcr->set_reserved();
-
- dev->dunlock();
-}
-#endif
-
/*
* Search for a Volume name in the Volume list.
*