*/
/* Forward referenced subroutines */
+#ifndef HAVE_BATCH_FILE_INSERT
static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
+#endif /* HAVE_BATCH_FILE_INSERT */
/* Create a new record for the Job
* how many times it occurs. This is this subroutine, we separate
* the file and the path and fill temporary tables with this three records.
*/
-int db_create_file_attributes_record(JCR *jcr, B_DB *_mdb, ATTR_DBR *ar)
+int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
{
-
Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
Dmsg0(dbglevel, "put_file_into_catalog\n");
if (!jcr->db_batch) {
jcr->db_batch = db_init_database(jcr,
- jcr->db->db_name,
- jcr->db->db_user,
- jcr->db->db_password,
- jcr->db->db_address,
- jcr->db->db_port,
- jcr->db->db_socket,
+ mdb->db_name,
+ mdb->db_user,
+ mdb->db_password,
+ mdb->db_address,
+ mdb->db_port,
+ mdb->db_socket,
1 /* multi_db = true */);
if (!jcr->db_batch || !db_open_database(jcr, jcr->db_batch)) {
sql_batch_start(jcr->db_batch);
}
- B_DB *mdb = jcr->db_batch;
+ B_DB *bdb = jcr->db_batch;
/*
* Make sure we have an acceptable attributes record.
*/
if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
- Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
+ Mmsg1(&bdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
ar->Stream);
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_ERROR, 0, "%s", bdb->errmsg);
return 0;
}
- split_path_and_file(jcr, mdb, ar->fname);
+ split_path_and_file(jcr, bdb, ar->fname);
/*
if (jcr->changes > 100000) {
- sql_batch_end(mdb, NULL);
- sql_batch_start(mdb);
+ sql_batch_end(bdb, NULL);
+ sql_batch_start(bdb);
jcr->changes = 0;
}
*/
- return (sql_batch_insert(mdb, ar) == 0);
+ return (sql_batch_insert(bdb, ar) == 0);
}
#else /* ! HAVE_BATCH_FILE_INSERT */
return 0;
}
-#endif /* ! HAVE_BATCH_FILE_INSERT */
/*
* This is the master File entry containing the attributes.
return ar->FilenameId > 0;
}
+#endif /* ! HAVE_BATCH_FILE_INSERT */
+
#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
-/*
- * Bacula Catalog Database routines specific to SQLite
- *
- * Kern Sibbald, January 2002
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * Bacula Catalog Database routines specific to SQLite
+ *
+ * Kern Sibbald, January 2002
+ *
+ * Version $Id$
+ */
-/*
- *
- * Bacula Director daemon -- this is the main program
- *
- * Kern Sibbald, March MM
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ *
+ * Bacula Director daemon -- this is the main program
+ *
+ * Kern Sibbald, March MM
+ *
+ * Version $Id$
+ */
#include "bacula.h"
#include "dird.h"
/* Forward referenced subroutines */
void terminate_dird(int sig);
-static int check_resources();
+static bool check_resources();
+static bool check_catalog();
static void dir_sql_query(JCR *jcr, const char *cmd);
/* Exported subroutines */
*
*/
#if defined(HAVE_WIN32)
+/* For Win32 main() is in src/win32 code ... */
#define main BaculaMain
#endif
create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
- drop(uid, gid); /* reduce priveleges if requested */
+ drop(uid, gid); /* reduce privileges if requested */
+
+ if (!check_catalog()) {
+ Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
+ }
#if !defined(HAVE_WIN32)
signal(SIGHUP, reload_config);
* **** FIXME **** this routine could be a lot more
* intelligent and comprehensive.
*/
-static int check_resources()
+static bool check_resources()
{
bool OK = true;
JOB *job;
}
} /* End loop over Job res */
+
+ /* Loop over Consoles */
+ CONRES *cons;
+ foreach_res(cons, R_CONSOLE) {
+ /* tls_require implies tls_enable */
+ if (cons->tls_require) {
+ if (have_tls) {
+ cons->tls_enable = true;
+ } else {
+ Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+ OK = false;
+ continue;
+ }
+ }
+
+ if (!cons->tls_certfile && cons->tls_enable) {
+ Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
+ cons->name(), configfile);
+ OK = false;
+ }
+
+ if (!cons->tls_keyfile && cons->tls_enable) {
+ Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
+ cons->name(), configfile);
+ OK = false;
+ }
+
+ if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
+ Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
+ " Certificate Dir\" are defined for Console \"%s\" in %s."
+ " At least one CA certificate store is required"
+ " when using \"TLS Verify Peer\".\n"),
+ cons->name(), configfile);
+ OK = false;
+ }
+ /* If everything is well, attempt to initialize our per-resource TLS context */
+ if (OK && (cons->tls_enable || cons->tls_require)) {
+ /* Initialize TLS context:
+ * Args: CA certfile, CA certdir, Certfile, Keyfile,
+ * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
+ cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
+ cons->tls_ca_certdir, cons->tls_certfile,
+ cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
+
+ if (!cons->tls_ctx) {
+ Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
+ cons->name(), configfile);
+ OK = false;
+ }
+ }
+
+ }
+
+ /* Loop over Clients */
+ CLIENT *client;
+ foreach_res(client, R_CLIENT) {
+ /* tls_require implies tls_enable */
+ if (client->tls_require) {
+ if (have_tls) {
+ client->tls_enable = true;
+ } else {
+ Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+ OK = false;
+ continue;
+ }
+ }
+
+ if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
+ Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
+ " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
+ client->name(), configfile);
+ OK = false;
+ }
+
+ /* If everything is well, attempt to initialize our per-resource TLS context */
+ if (OK && (client->tls_enable || client->tls_require)) {
+ /* Initialize TLS context:
+ * Args: CA certfile, CA certdir, Certfile, Keyfile,
+ * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
+ client->tls_ctx = new_tls_context(client->tls_ca_certfile,
+ client->tls_ca_certdir, client->tls_certfile,
+ client->tls_keyfile, NULL, NULL, NULL,
+ true);
+
+ if (!client->tls_ctx) {
+ Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
+ client->name(), configfile);
+ OK = false;
+ }
+ }
+ }
+
+ UnlockRes();
+ if (OK) {
+ close_msg(NULL); /* close temp message handler */
+ init_msg(NULL, director->messages); /* open daemon message handler */
+ }
+ return OK;
+}
+
+static bool check_catalog()
+{
+ bool OK = true;
+
/* Loop over databases */
CAT *catalog;
foreach_res(catalog, R_CATALOG) {
/* Loop over all pools for updating RecyclePool */
foreach_res(pool, R_POOL) {
- update_pool_recyclepool(NULL, db, pool);
+ update_pool_recyclepool(NULL, db, pool);
}
STORE *store;
}
db_close_database(NULL, db);
}
-
- /* Loop over Consoles */
- CONRES *cons;
- foreach_res(cons, R_CONSOLE) {
- /* tls_require implies tls_enable */
- if (cons->tls_require) {
- if (have_tls) {
- cons->tls_enable = true;
- } else {
- Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
- OK = false;
- continue;
- }
- }
-
- if (!cons->tls_certfile && cons->tls_enable) {
- Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
- cons->name(), configfile);
- OK = false;
- }
-
- if (!cons->tls_keyfile && cons->tls_enable) {
- Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
- cons->name(), configfile);
- OK = false;
- }
-
- if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
- Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
- " Certificate Dir\" are defined for Console \"%s\" in %s."
- " At least one CA certificate store is required"
- " when using \"TLS Verify Peer\".\n"),
- cons->name(), configfile);
- OK = false;
- }
- /* If everything is well, attempt to initialize our per-resource TLS context */
- if (OK && (cons->tls_enable || cons->tls_require)) {
- /* Initialize TLS context:
- * Args: CA certfile, CA certdir, Certfile, Keyfile,
- * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
- cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
- cons->tls_ca_certdir, cons->tls_certfile,
- cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
-
- if (!cons->tls_ctx) {
- Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
- cons->name(), configfile);
- OK = false;
- }
- }
-
- }
-
- /* Loop over Clients */
- CLIENT *client;
- foreach_res(client, R_CLIENT) {
- /* tls_require implies tls_enable */
- if (client->tls_require) {
- if (have_tls) {
- client->tls_enable = true;
- } else {
- Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
- OK = false;
- continue;
- }
- }
-
- if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
- Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
- " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
- client->name(), configfile);
- OK = false;
- }
-
- /* If everything is well, attempt to initialize our per-resource TLS context */
- if (OK && (client->tls_enable || client->tls_require)) {
- /* Initialize TLS context:
- * Args: CA certfile, CA certdir, Certfile, Keyfile,
- * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
- client->tls_ctx = new_tls_context(client->tls_ca_certfile,
- client->tls_ca_certdir, client->tls_certfile,
- client->tls_keyfile, NULL, NULL, NULL,
- true);
-
- if (!client->tls_ctx) {
- Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
- client->name(), configfile);
- OK = false;
- }
- }
- }
-
- UnlockRes();
- if (OK) {
- close_msg(NULL); /* close temp message handler */
- init_msg(NULL, director->messages); /* open daemon message handler */
- }
return OK;
}
static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
{
bool cancel = false;
- bool ok_to_cancel = false;
JOB *job = jcr->job;
if (job_canceled(jcr)) {
}
if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
(watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
- ok_to_cancel = true;
+ cancel = true;
} else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
(watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
- ok_to_cancel = true;
+ cancel = true;
} else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
(watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
- ok_to_cancel = true;
+ cancel = true;
} else if (job->MaxWaitTime != 0 &&
(watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
- ok_to_cancel = true;
- }
- if (!ok_to_cancel) {
- return false;
- }
-
-/*
- * I don't see the need for all this -- kes 17Dec06
- */
-#ifdef xxx
- Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
- "checking status\n",
- jcr->JobId, jcr->Job, job->MaxWaitTime);
- switch (jcr->JobStatus) {
- case JS_Created:
- case JS_Blocked:
- case JS_WaitFD:
- case JS_WaitSD:
- case JS_WaitStoreRes:
- case JS_WaitClientRes:
- case JS_WaitJobRes:
- case JS_WaitPriority:
- case JS_WaitMaxJobs:
- case JS_WaitStartTime:
cancel = true;
- Dmsg0(200, "JCR blocked in #1\n");
- break;
- case JS_Running:
- Dmsg0(800, "JCR running, checking SD status\n");
- switch (jcr->SDJobStatus) {
- case JS_WaitMount:
- case JS_WaitMedia:
- case JS_WaitFD:
- cancel = true;
- Dmsg0(800, "JCR blocked in #2\n");
- break;
- default:
- Dmsg0(800, "JCR not blocked in #2\n");
- break;
- }
- break;
- case JS_Terminated:
- case JS_ErrorTerminated:
- case JS_Canceled:
- case JS_FatalError:
- Dmsg0(800, "JCR already dead in #3\n");
- break;
- default:
- Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
- jcr->JobStatus);
}
- Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
- cancel ? "" : "do not ", jcr, jcr->Job);
-#endif
+
return cancel;
}
return false;
}
-#ifdef xxx
- switch (jcr->JobStatus) {
- case JS_Created:
- case JS_Running:
- case JS_Blocked:
- case JS_WaitFD:
- case JS_WaitSD:
- case JS_WaitStoreRes:
- case JS_WaitClientRes:
- case JS_WaitJobRes:
- case JS_WaitPriority:
- case JS_WaitMaxJobs:
- case JS_WaitStartTime:
- case JS_Differences:
- cancel = true;
- break;
- case JS_Terminated:
- case JS_ErrorTerminated:
- case JS_Canceled:
- case JS_FatalError:
- cancel = false;
- break;
- default:
- Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
- jcr->JobStatus);
- }
-
- Dmsg3(200, "MaxRunTime result: %scancel JCR %p (%s)\n",
- cancel ? "" : "do not ", jcr, jcr->Job);
-#endif
return true;
}
*/
static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
{
+ bool do_read = false;
int stat, data_stream;
int rtnstat = 0;
DIGEST *digest = NULL;
* Note, if is_win32_backup, we must open the Directory so that
* the BackupRead will save its permissions and ownership streams.
*/
- bool do_read = false;
if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
#ifdef HAVE_WIN32
/*
* Try to connect to host for max_retry_time at retry_time intervals.
*/
-BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
+BSOCK *bnet_connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
const char *name, char *host, char *service, int port,
int verbose)
{
int i;
BSOCK *bsock;
int fatal = 0;
+ time_t begin_time = time(NULL);
+ time_t now;
for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
i -= retry_interval) {
"Retrying ...\n"), name, host, port, be.strerror());
}
bmicrosleep(retry_interval, 0);
- max_retry_time -= retry_interval;
- if (max_retry_time <= 0) {
+ now = time(NULL);
+ if (begin_time + max_retry_time <= now) {
Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
name, host, port, be.strerror());
return NULL;
char *host() { return m_host; };
int port() { return m_port; };
JCR *jcr() { return m_jcr; };
-
};
/*
sscanf(pidbuf, "%d", &oldpid) != 1) {
Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, strerror(errno));
}
- /* See if other Bacula is still alive */
- if (kill(oldpid, 0) != -1 || errno != ESRCH) {
+ /* Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and
+ * since they use a deterministic algorithm for assigning PIDs, we can have
+ * pid conflicts with the old PID file after a reboot.
+ * The intent the following code is to check if the oldpid read from the pid
+ * file is the same as the currently executing process's pid,
+ * and if oldpid == getpid(), skip the attempt to
+ * kill(oldpid,0), since the attempt is guaranteed to succeed,
+ * but the success won't actually mean that there is an
+ * another Bacula process already running.
+ * For more details see bug #797.
+ */
+ if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) {
Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"),
progname, oldpid, fname);
}
alist *verify_list);
bool bnet_tls_client (TLS_CONTEXT *ctx, BSOCK *bsock);
BSOCK * bnet_connect (JCR *jcr, int retry_interval,
- int max_retry_time, const char *name, char *host, char *service,
+ utime_t max_retry_time, const char *name, char *host, char *service,
int port, int verbose);
void bnet_close (BSOCK *bsock);
BSOCK * init_bsock (JCR *jcr, int sockfd, const char *who, const char *ip,
dcr->VolumeName, dev->print_name());
get_out:
- P(dev->mutex);
+ dev->lock();
if (dcr->reserved_device) {
dev->reserved_device--;
Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
dcr->reserved_device = false;
}
- V(dev->mutex);
+ dev->unlock();
dev->unblock();
Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
return ok;
}
dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
dir_update_volume_info(dcr, false); /* send Volume info to Director */
- P(dev->mutex);
+ dev->lock();
if (dcr->reserved_device) {
dev->reserved_device--;
Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
dcr->reserved_device = false;
}
- V(dev->mutex);
+ dev->unlock();
dev->unblock();
return dcr;
* Error return
*/
get_out:
- P(dev->mutex);
+ dev->lock();
if (dcr->reserved_device) {
dev->reserved_device--;
Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
dcr->reserved_device = false;
}
- V(dev->mutex);
+ dev->unlock();
dev->unblock();
return NULL;
}
bool got_vol = false;
Dmsg0(400, "enter dir_ask_sysop_to_create_appendable_volume\n");
- ASSERT(dev->dev_blocked);
+ ASSERT(dev->blocked());
for ( ;; ) {
if (job_canceled(jcr)) {
Mmsg(dev->errmsg,
Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
return false;
}
- P(dev->mutex);
+ dev->lock();
got_vol = dir_find_next_appendable_volume(dcr); /* get suggested volume */
- V(dev->mutex);
+ dev->unlock();
if (got_vol) {
return true;
} else {
Mmsg0(dev->errmsg, _("Cannot request another volume: no volume name given.\n"));
return false;
}
- ASSERT(dev->dev_blocked);
+ ASSERT(dev->blocked());
for ( ;; ) {
if (job_canceled(jcr)) {
Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device %s.\n"),
}
break;
}
- P(dev->mutex);
+ dev->lock();
if (dev->is_busy()) {
Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" is in use by device %s\n"),
dcr->VolumeName, dev->print_name());
Dmsg4(100, "Vol %s for dev=%s is busy dev=%s slot=%d\n",
dcr->VolumeName, dcr->dev->print_name(), dev->print_name(), slot);
Dmsg2(100, "num_writ=%d reserv=%d\n", dev->num_writers, dev->reserved_device);
- V(dev->mutex);
+ dev->unlock();
return false;
}
Dmsg0(100, "Slot unloaded\n");
}
unlock_changer(dcr);
- V(dev->mutex);
+ dev->unlock();
free_pool_memory(changer_cmd);
return ok;
}
dev->errmsg = get_pool_memory(PM_EMSG);
*dev->errmsg = 0;
- if ((errstat = pthread_mutex_init(&dev->mutex, NULL)) != 0) {
+ if ((errstat = pthread_mutex_init(&dev->m_mutex, NULL)) != 0) {
berrno be;
dev->dev_errno = errstat;
Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
}
+#ifdef xxx
if ((errstat = rwl_init(&dev->lock)) != 0) {
berrno be;
dev->dev_errno = errstat;
Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
}
+#endif
dev->clear_opened();
dev->attached_dcrs = New(dlist(dcr, &dcr->dev_link));
{
lock_device(this);
block_device(this, why);
- V(mutex);
+ unlock();
}
void DEVICE::unblock()
{
- P(mutex);
+ lock();
unblock_device(this);
- V(mutex);
+ unlock();
}
const char *DEVICE::print_blocked() const
{
- switch (dev_blocked) {
+ switch (m_blocked) {
case BST_NOT_BLOCKED:
return "BST_NOT_BLOCKED";
case BST_UNMOUNTED:
free_pool_memory(errmsg);
errmsg = NULL;
}
- pthread_mutex_destroy(&mutex);
+ pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&wait);
pthread_cond_destroy(&wait_next_vol);
pthread_mutex_destroy(&spool_mutex);
- rwl_destroy(&lock);
+// rwl_destroy(&lock);
if (attached_dcrs) {
delete attached_dcrs;
attached_dcrs = NULL;
-/*
- * Definitions for using the Device functions in Bacula
- * Tape and File storage access
- *
- * Kern Sibbald, MM
- *
- * Version $Id$
- *
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * Definitions for using the Device functions in Bacula
+ * Tape and File storage access
+ *
+ * Kern Sibbald, MM
+ *
+ * Version $Id$
+ *
+ */
#ifndef __DEV_H
#define ST_PART_SPOOLED (1<<18) /* spooling part */
#define ST_FREESPACE_OK (1<<19) /* Have valid freespace for DVD */
-/* dev_blocked states (mutually exclusive) */
+/* m_blocked states (mutually exclusive) */
enum {
BST_NOT_BLOCKED = 0, /* not blocked */
BST_UNMOUNTED, /* User unmounted device */
class DEVICE {
private:
int m_fd; /* file descriptor */
+ int m_blocked; /* set if we must wait (i.e. change tape) */
public:
dlist *attached_dcrs; /* attached DCR list */
- pthread_mutex_t mutex; /* access control */
+ pthread_mutex_t m_mutex; /* access control */
pthread_mutex_t spool_mutex; /* mutex for updating spool_size */
pthread_cond_t wait; /* thread wait variable */
pthread_cond_t wait_next_vol; /* wait for tape to be mounted */
pthread_t no_wait_id; /* this thread must not wait */
- int dev_blocked; /* set if we must wait (i.e. change tape) */
int dev_prev_blocked; /* previous blocked state */
int num_waiting; /* number of threads waiting */
int num_writers; /* number of writing threads */
int reserved_device; /* number of device reservations */
/* New access control in process of being implemented */
- brwlock_t lock; /* New mutual exclusion lock */
+// brwlock_t xlock; /* New mutual exclusion lock */
int capabilities; /* capabilities mask */
int state; /* state mask */
int can_write() const { return is_open() && can_append() &&
is_labeled() && !at_weot(); }
int can_read() const { return state & ST_READ; }
- bool can_steal_lock() const { return dev_blocked &&
- (dev_blocked == BST_UNMOUNTED ||
- dev_blocked == BST_WAITING_FOR_SYSOP ||
- dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); };
+ bool can_steal_lock() const { return m_blocked &&
+ (m_blocked == BST_UNMOUNTED ||
+ m_blocked == BST_WAITING_FOR_SYSOP ||
+ m_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); };
bool waiting_for_mount() const { return
- (dev_blocked == BST_UNMOUNTED ||
- dev_blocked == BST_WAITING_FOR_SYSOP ||
- dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); };
+ (m_blocked == BST_UNMOUNTED ||
+ m_blocked == BST_WAITING_FOR_SYSOP ||
+ m_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); };
const char *strerror() const;
const char *archive_name() const;
const char *name() const;
void clear_freespace_ok() { state &= ~ST_FREESPACE_OK; };
char *bstrerror(void) { return errmsg; };
char *print_errmsg() { return errmsg; };
+ void lock() { P(m_mutex); }
+ void unlock() { V(m_mutex); }
void block(int why); /* in dev.c */
void unblock(); /* in dev.c */
bool update_pos(DCR *dcr); /* in dev.c */
bool update_freespace(); /* in dvd.c */
- void set_blocked(int block) { dev_blocked = block; };
- int get_blocked() const { return dev_blocked; };
+ void set_blocked(int block) { m_blocked = block; };
+ int blocked() const { return m_blocked; };
uint32_t get_file() const { return file; };
uint32_t get_block() const { return block_num; };
const char *print_blocked() const; /* in dev.c */
- bool is_blocked() const { return dev_blocked != BST_NOT_BLOCKED; };
+ bool is_blocked() const { return m_blocked != BST_NOT_BLOCKED; };
int fd() const { return m_fd; };
private:
+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2000-2007 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.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation plus additions
+ that are listed in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
/*
*
* Higher Level Device routines.
*
* Version $Id$
*/
-/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2000-2006 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.
- This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation plus additions
- that are listed in the file LICENSE.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Bacula® is a registered trademark of John Walker.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-*/
#include "bacula.h" /* pull in global headers */
#include "stored.h" /* pull in Storage Deamon headers */
if (!mount_next_write_volume(dcr, 1)) {
free_block(label_blk);
dcr->block = block;
- P(dev->mutex);
+ dev->lock();
unblock_device(dev);
return false; /* device locked */
}
- P(dev->mutex); /* lock again */
+ dev->lock(); /* lock again */
dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
dir_update_volume_info(dcr, false); /* send Volume info to Director */
+#ifdef xxx
void dev_lock(DEVICE *dev)
{
int errstat;
Emsg1(M_ABORT, 0, _("Device write unlock failure. ERR=%s\n"), strerror(errstat));
}
}
+#endif
/*
* When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
void _lock_device(const char *file, int line, DEVICE *dev)
{
int stat;
- Dmsg3(500, "lock %d from %s:%d\n", dev->dev_blocked, file, line);
- P(dev->mutex);
- if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
+ Dmsg3(500, "lock %d from %s:%d\n", dev->blocked(), file, line);
+ dev->lock();
+ if (dev->blocked() && !pthread_equal(dev->no_wait_id, pthread_self())) {
dev->num_waiting++; /* indicate that I am waiting */
- while (dev->dev_blocked) {
- if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
- V(dev->mutex);
+ while (dev->blocked()) {
+ if ((stat = pthread_cond_wait(&dev->wait, &dev->m_mutex)) != 0) {
+ dev->unlock();
Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
strerror(stat));
}
bool is_device_unmounted(DEVICE *dev)
{
bool stat;
- int blocked = dev->dev_blocked;
+ int blocked = dev->blocked();
stat = (blocked == BST_UNMOUNTED) ||
(blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
return stat;
void _unlock_device(const char *file, int line, DEVICE *dev)
{
Dmsg2(500, "unlock from %s:%d\n", file, line);
- V(dev->mutex);
+ dev->unlock();
}
/*
void _block_device(const char *file, int line, DEVICE *dev, int state)
{
Dmsg3(500, "block set %d from %s:%d\n", state, file, line);
- ASSERT(dev->get_blocked() == BST_NOT_BLOCKED);
+ ASSERT(dev->blocked() == BST_NOT_BLOCKED);
dev->set_blocked(state); /* make other threads wait */
dev->no_wait_id = pthread_self(); /* allow us to continue */
}
-
-
/*
* Unblock the device, and wake up anyone who went to sleep.
*/
void _unblock_device(const char *file, int line, DEVICE *dev)
{
Dmsg3(500, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
- ASSERT(dev->dev_blocked);
+ ASSERT(dev->blocked());
dev->set_blocked(BST_NOT_BLOCKED);
dev->no_wait_id = 0;
if (dev->num_waiting > 0) {
Dmsg3(400, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
file, line);
- hold->dev_blocked = dev->get_blocked();
+ hold->dev_blocked = dev->blocked();
hold->dev_prev_blocked = dev->dev_prev_blocked;
hold->no_wait_id = dev->no_wait_id;
dev->set_blocked(state);
Dmsg1(400, "steal lock. new=%s\n", dev->print_blocked());
dev->no_wait_id = pthread_self();
- V(dev->mutex);
+ dev->unlock();
}
/*
{
Dmsg3(400, "return lock. old=%s from %s:%d\n",
dev->print_blocked(), file, line);
- P(dev->mutex);
- dev->dev_blocked = hold->dev_blocked;
+ dev->lock();
+ dev->set_blocked(hold->dev_blocked);
dev->dev_prev_blocked = hold->dev_prev_blocked;
dev->no_wait_id = hold->no_wait_id;
Dmsg1(400, "return lock. new=%s\n", dev->print_blocked());
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2001-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * This file handles accepting Director Commands
+ *
+ * Most Director commands are handled here, with the
+ * exception of the Job command command and subsequent
+ * subcommands that are handled
+ * in job.c.
+ *
+ * N.B. in this file, in general we must use P(dev->mutex) rather
+ * than lock_device(dev) so that we can examine the blocked
+ * state rather than blocking ourselves because a Job
+ * thread has the device blocked. In some "safe" cases,
+ * we can do things to a blocked device. CAREFUL!!!!
+ *
+ * File daemon commands are handled in fdcmd.c
+ *
+ * Kern Sibbald, May MMI
+ *
+ * Version $Id$
+ *
+ */
#include "bacula.h"
#include "stored.h"
int bnet_stat = 0;
char name[MAX_NAME_LENGTH];
- if (bnet_recv(bs) <= 0) {
+ if (bs->recv() <= 0) {
Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
bnet_close(bs);
return NULL;
for (quit=false; !quit;) {
/* Read command */
- if ((bnet_stat = bnet_recv(bs)) <= 0) {
+ if ((bnet_stat = bs->recv()) <= 0) {
break; /* connection terminated */
}
Dmsg1(199, "<dird: %s\n", bs->msg);
if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
bnet_fsend(bs, invalid_cmd);
- bnet_sig(bs, BNET_EOD);
+ bs->signal(BNET_EOD);
break;
}
Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
dcr = find_device(jcr, dev_name, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
+ dev->lock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
Dmsg0(400, "Can relabel. device not used\n");
label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
}
- V(dev->mutex);
+ dev->unlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
- Dmsg1(100, "mount cmd blocked=%d\n", dev->dev_blocked);
- switch (dev->dev_blocked) { /* device blocked? */
+ dev->lock(); /* Use P to avoid indefinite block */
+ Dmsg1(100, "mount cmd blocked=%d\n", dev->blocked());
+ switch (dev->blocked()) { /* device blocked? */
case BST_WAITING_FOR_SYSOP:
/* Someone is waiting, wake him */
Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
- dev->dev_blocked = BST_MOUNT;
+ dev->set_blocked(BST_MOUNT);
bnet_fsend(dir, "3001 OK mount. Device=%s\n",
dev->print_name());
pthread_cond_broadcast(&dev->wait_next_vol);
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
dev->bstrerror());
- if (dev->dev_blocked == BST_UNMOUNTED) {
+ if (dev->blocked() == BST_UNMOUNTED) {
/* We blocked the device, so unblock it */
Dmsg0(100, "Unmounted. Unblocking device\n");
unblock_device(dev);
break;
}
read_dev_volume_label(dcr);
- if (dev->dev_blocked == BST_UNMOUNTED) {
+ if (dev->blocked() == BST_UNMOUNTED) {
/* We blocked the device, so unblock it */
Dmsg0(100, "Unmounted. Unblocking device\n");
read_label(dcr); /* this should not be necessary */
unblock_device(dev);
} else {
Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
- dev->dev_blocked = BST_MOUNT;
+ dev->set_blocked(BST_MOUNT);
}
if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
break;
default:
- bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
+ bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->blocked());
break;
}
- V(dev->mutex);
+ dev->unlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
+ dev->lock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
if (!dev->is_busy()) {
unload_autochanger(dcr, -1);
bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"),
dev->print_name());
}
- } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
+ } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
- dev->dev_blocked);
+ dev->blocked());
if (!unload_autochanger(dcr, -1)) {
/* ***FIXME**** what is this ???? */
dev->close();
if (dev->is_dvd() && !dev->unmount(0)) {
bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
} else {
- dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
+ dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP);
bnet_fsend(dir, _("3001 Device %s unmounted.\n"),
dev->print_name());
}
- } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
+ } else if (dev->blocked() == BST_DOING_ACQUIRE) {
bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_WRITING_LABEL) {
+ } else if (dev->blocked() == BST_WRITING_LABEL) {
bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
dev->print_name());
* we simply do it by hand. Gross, but a solution.
*/
/* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
- dev->dev_blocked = BST_UNMOUNTED;
+ dev->set_blocked(BST_UNMOUNTED);
dev->no_wait_id = 0;
if (!unload_autochanger(dcr, -1)) {
dev->close();
dev->print_name());
}
}
- V(dev->mutex);
+ dev->unlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
+ dev->lock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
if (!dev->is_busy()) {
unload_autochanger(dcr, -1);
bnet_fsend(dir, _("3921 Device %s already released.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
+ } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
- dev->dev_blocked);
+ dev->blocked());
unload_autochanger(dcr, -1);
bnet_fsend(dir, _("3922 Device %s waiting for sysop.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
+ } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
- dev->dev_blocked);
+ dev->blocked());
bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
+ } else if (dev->blocked() == BST_DOING_ACQUIRE) {
bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_WRITING_LABEL) {
+ } else if (dev->blocked() == BST_WRITING_LABEL) {
bnet_fsend(dir, _("3914 Device %s is being labeled.\n"),
dev->print_name());
bnet_fsend(dir, _("3022 Device %s released.\n"),
dev->print_name());
}
- V(dev->mutex);
+ dev->unlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
dcr = find_device(jcr, devname, -1);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
+ dev->lock(); /* Use P to avoid indefinite block */
if (!dev->device->changer_res) {
bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"),
dev->print_name());
} else { /* device not being used */
autochanger_cmd(dcr, dir, cmd);
}
- V(dev->mutex);
+ dev->unlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
jcr->errmsg);
}
- bnet_sig(dir, BNET_EOD);
+ dir->signal(BNET_EOD);
return true;
}
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
+ dev->lock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
read_volume_label(jcr, dev, Slot);
dev->close();
} else { /* device not being used */
read_volume_label(jcr, dev, Slot);
}
- V(dev->mutex);
+ dev->unlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
pm_strcpy(jcr->errmsg, dir->msg);
bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
}
- bnet_sig(dir, BNET_EOD);
+ dir->signal(BNET_EOD);
return true;
}
static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
{
if (dev->is_blocked()) {
- switch (dev->dev_blocked) {
+ switch (dev->blocked()) {
case BST_UNMOUNTED:
bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
dev->print_name());
void set_new_volume_parameters(DCR *dcr);
void set_new_file_parameters(DCR *dcr);
bool is_device_unmounted(DEVICE *dev);
-void dev_lock(DEVICE *dev);
-void dev_unlock(DEVICE *dev);
/* From dircmd.c */
void *handle_connection_request(void *arg);
-/*
- * Drive reservation functions for Storage Daemon
- *
- * Kern Sibbald, MM
- *
- * Split from job.c and acquire.c June 2005
- *
- * Version $Id$
- *
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * Drive reservation functions for Storage Daemon
+ *
+ * Kern Sibbald, MM
+ *
+ * Split from job.c and acquire.c June 2005
+ *
+ * Version $Id$
+ *
+ */
#include "bacula.h"
#include "stored.h"
store->append = append;
/* Now get all devices */
- while (bnet_recv(dir) >= 0) {
+ while (dir->recv() >= 0) {
Dmsg1(100, "<dird device: %s", dir->msg);
ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
if (!ok) {
unbash_spaces(dev_name);
store->device->append(bstrdup(dev_name.c_str()));
}
- } while (ok && bnet_recv(dir) >= 0);
+ } while (ok && dir->recv() >= 0);
#ifdef DEVELOPER
/* This loop is debug code and can be removed */
/* Get locks in correct order */
unlock_reservations();
- P(dev->mutex);
+ dev->lock();
lock_reservations();
if (is_device_unmounted(dev)) {
dcr->reserved_device = true;
bail_out:
- V(dev->mutex);
+ dev->unlock();
return ok;
}
/* Get locks in correct order */
unlock_reservations();
- P(dev->mutex);
+ dev->lock();
lock_reservations();
/* If device is being read, we cannot write it */
ok = true;
bail_out:
- V(dev->mutex);
+ dev->unlock();
return ok;
}
-/*
- * This file handles the status command
- *
- * Kern Sibbald, May MMIII
- *
- * Version $Id$
- *
- */
/*
Bacula® - The Network Backup Solution
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * This file handles the status command
+ *
+ * Kern Sibbald, May MMIII
+ *
+ * Version $Id$
+ *
+ */
#include "bacula.h"
#include "stored.h"
free_pool_memory(msg);
return;
}
- switch (dev->dev_blocked) {
+ switch (dev->blocked()) {
case BST_UNMOUNTED:
len = Mmsg(msg, _(" Device is BLOCKED. User unmounted.\n"));
sendit(msg, len, arg);
dev->state & ST_MOUNTED ? "" : "!");
sendit(msg, len, arg);
- len = Mmsg(msg, _("num_writers=%d block=%d\n\n"), dev->num_writers, dev->dev_blocked);
+ len = Mmsg(msg, _("num_writers=%d block=%d\n\n"), dev->num_writers, dev->blocked());
sendit(msg, len, arg);
len = Mmsg(msg, _("Device parameters:\n"));
-/*
- * Second generation Storage daemon.
- *
- * Kern Sibbald, MM
- *
- * It accepts a number of simple commands from the File daemon
- * and acts on them. When a request to append data is made,
- * it opens a data channel and accepts data from the
- * File daemon.
- *
- * Version $Id$
- *
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * Second generation Storage daemon.
+ *
+ * Kern Sibbald, MM
+ *
+ * It accepts a number of simple commands from the File daemon
+ * and acts on them. When a request to append data is made,
+ * it opens a data channel and accepts data from the
+ * File daemon.
+ *
+ * Version $Id$
+ *
+ */
#include "bacula.h"
#include "stored.h"
Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
/* ***FIXME*** wiffle through all dcrs */
- if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
+ if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->blocked()) {
pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
pthread_cond_broadcast(&wait_device_release);
}
- if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->dev_blocked) {
+ if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->blocked()) {
pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
pthread_cond_broadcast(&wait_device_release);
}
-/*
- * Subroutines to handle waiting for operator intervention
- * or waiting for a Device to be released
- *
- * Code for wait_for_sysop() pulled from askdir.c
- *
- * Kern Sibbald, March 2005
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * Subroutines to handle waiting for operator intervention
+ * or waiting for a Device to be released
+ *
+ * Code for wait_for_sysop() pulled from askdir.c
+ *
+ * Kern Sibbald, March 2005
+ *
+ * Version $Id$
+ */
#include "bacula.h" /* pull in global headers */
DEVICE *dev = dcr->dev;
JCR *jcr = dcr->jcr;
- P(dev->mutex);
+ dev->lock();
Dmsg1(100, "Enter blocked=%s\n", dev->print_blocked());
unmounted = is_device_unmounted(dev);
if (!unmounted) {
Dmsg1(400, "blocked=%s\n", dev->print_blocked());
- dev->dev_prev_blocked = dev->dev_blocked;
+ dev->dev_prev_blocked = dev->blocked();
dev->set_blocked(BST_WAITING_FOR_SYSOP); /* indicate waiting for mount */
}
dev->print_name(), (int)me->heartbeat_interval, dev->wait_sec, add_wait);
start = time(NULL);
/* Wait required time */
- stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->mutex, &timeout);
+ stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->m_mutex, &timeout);
Dmsg2(400, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
dev->print_blocked());
/*
* Check if user mounted the device while we were waiting
*/
- if (dev->get_blocked() == BST_MOUNT) { /* mount request ? */
+ if (dev->blocked() == BST_MOUNT) { /* mount request ? */
stat = W_MOUNT;
break;
}
Dmsg1(400, "set %s\n", dev->print_blocked());
}
Dmsg1(400, "Exit blocked=%s\n", dev->print_blocked());
- V(dev->mutex);
+ dev->unlock();
return stat;
}
#undef VERSION
#define VERSION "2.1.5"
-#define BDATE "16 March 2007"
-#define LSMDATE "16Mar07"
+#define BDATE "18 March 2007"
+#define LSMDATE "18Mar07"
#define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
#define BYEAR "2007" /* year for copyright messages in progs */
/* Turn on the following flag to enable batch attribute inserts
* in the catalog. This gives a large speedup.
*/
-/* #define HAVE_BATCH_FILE_INSERT 1 */
+#define HAVE_BATCH_FILE_INSERT 1
/* Debug flags not normally turned on */
Technical notes on version 2.1
General:
+18Mar07
+kes Move the checking of the database in initializion of the Director
+ to after we drop privileges. This avoids the need for both root
+ and bacula access to the DB.
+kes Correct a misplaced variable definition in src/filed/backup.c
+kes Correct how the new batch insert db_create_attributes_record()
+ uses the arguments. Caused a seg fault in bscan.
+kes Implement lock() and unlock() methods in DEVICE class.
+ Implement block() and set_block(xx) methods in DEVICE class.
+kes Modify bnet_connect() so that it uses time() to check for the
+ wait time expiring (on some OSes, some system calls may not
+ return immediately).
+kes Modify Verify to obtain the previous JobId when it is actually
+ running rather than at schedule time (as it was in 1.38.x).
+kes Fix src/job.c to handle MaxWaitTime correctly. This should
+ fix bug #802.
+kes When checking pid in pid file, continue running if the pid is
+ the same as ours. This occurs on IRIX after a system crash.
+ Fixes bug #797.
10Mar07
kes Extend new GUI API.
kes Make the ua structure a class, and implement send_msg(),