General:
Changes to 1.37.20:
+01Jun05
+- Add more documentation to mtx-changer.in
+- Correct link to manual in authenticate.c in various
+ directories.
+- Create a new src/stored/reserve.c file where the
+ Use Storage command is processed and drives are
+ reserved.
+- Modify src/stored/autochanger.c to keep track of each
+ Slot that is loaded for each device.
+- Ensure that changer_command and changer_name are picked
+ up from Autochanger resource if not specified, and if
+ neither is specified, err.
30May05
- Fix bextract.c compile problem
- Create bacula.man
# Changer Command = "path-to-this-script/mtx-changer" %c %o %S %a %d
# you will have the following input to this script:
#
+# So Bacula will always call with all the following arguments, even though
+# in come cases, not all are used.
+
# mtx-changer "changer-device" "command" "slot" "archive-device" "drive-index"
# $1 $2 $3 $4 $5
#
# for example:
#
# mtx-changer /dev/sg0 load 1 /dev/nst0 0 (on a Linux system)
+#
+# will request to load the first cartidge into drive 0, where
+# the SCSI control channel is /dev/sg0, and the read/write device
+# is /dev/nst0.
#
# If you need to an offline, refer to the drive as $4
# e.g. mt -f $4 offline
;;
list)
-# echo "Requested list"
+# echo "Doing mtx -f $ctl -- to list volumes"
${MTX} -f $ctl status | grep " *Storage Element [0-9]*:.*Full" | awk "{print \$3 \$4}" | sed "s/Full *\(:VolumeTag=\)*//"
# Comment out the previous line and add a line here
# to print "fake" barcodes.
;;
loaded)
+# echo "Doing mtx -f $ctl $drive -- to find what is loaded"
${MTX} -f $ctl status >${TMPDIR}/mtx.$$
rtn=$?
cat ${TMPDIR}/mtx.$$ | grep "^Data Transfer Element $drive:Full" | awk "{print \$7}"
;;
slots)
-# echo "Request slots"
+# echo "Doing mtx -f $ctl -- to get count of slots"
${MTX} -f $ctl status | grep " *Storage Changer" | awk "{print \$5}"
;;
esac
#ifdef HAVE_TLS
/* TLS Requirement */
if (cons->tls_enable) {
- if (cons->tls_require) {
- tls_local_need = BNET_TLS_REQUIRED;
- } else {
- tls_local_need = BNET_TLS_OK;
- }
+ if (cons->tls_require) {
+ tls_local_need = BNET_TLS_REQUIRED;
+ } else {
+ tls_local_need = BNET_TLS_OK;
+ }
}
tls_ctx = cons->tls_ctx;
#ifdef HAVE_TLS
/* TLS Requirement */
if (director->tls_enable) {
- if (director->tls_require) {
- tls_local_need = BNET_TLS_REQUIRED;
- } else {
- tls_local_need = BNET_TLS_OK;
- }
+ if (director->tls_require) {
+ tls_local_need = BNET_TLS_REQUIRED;
+ } else {
+ tls_local_need = BNET_TLS_OK;
+ }
}
tls_ctx = director->tls_ctx;
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_client(tls_ctx, dir)) {
- sendit(_("TLS negotiation failed\n"));
- auth_success = false;
- goto auth_done;
+ sendit(_("TLS negotiation failed\n"));
+ auth_success = false;
+ goto auth_done;
}
auth_success = true;
}
if (!auth_success) {
stop_bsock_timer(tid);
sendit( _("Director authorization problem.\n"
- "Most likely the passwords do not agree.\n"
- "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
+ "Most likely the passwords do not agree.\n"
+ "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n"
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
return 0;
}
if (bnet_recv(dir) <= 0) {
stop_bsock_timer(tid);
senditf(_("Bad response to Hello command: ERR=%s\n"),
- bnet_strerror(dir));
+ bnet_strerror(dir));
senditf(_("If you are using TLS, it is possible that your client"
" certificate was not accepted. Check the server messages.\n"));
return 0;
/* TLS Requirement */
if (store->tls_enable) {
if (store->tls_require) {
- tls_local_need = BNET_TLS_REQUIRED;
+ tls_local_need = BNET_TLS_REQUIRED;
} else {
- tls_local_need = BNET_TLS_OK;
+ tls_local_need = BNET_TLS_OK;
}
}
#endif
if (auth_success) {
auth_success = cram_md5_auth(sd, store->password, tls_local_need);
if (!auth_success) {
- Dmsg1(50, "cram_auth failed for %s\n", sd->who);
+ Dmsg1(50, "cram_auth failed for %s\n", sd->who);
}
} else {
Dmsg1(50, "cram_get_auth failed for %s\n", sd->who);
stop_bsock_timer(tid);
Dmsg0(50, _("Director and Storage daemon passwords or names not the same.\n"));
Jmsg0(jcr, M_FATAL, 0,
- _("Unable to authenticate with Storage daemon. Possible causes:\n"
- "Passwords or names not the same or\n"
- "Maximum Concurrent Jobs exceeded on the SD or\n"
- "SD networking messed up (restart daemon).\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
+ _("Unable to authenticate with Storage daemon. Possible causes:\n"
+ "Passwords or names not the same or\n"
+ "Maximum Concurrent Jobs exceeded on the SD or\n"
+ "SD networking messed up (restart daemon).\n"
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
return 0;
}
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_client(store->tls_ctx, sd)) {
- stop_bsock_timer(tid);
- Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
- return 0;
+ stop_bsock_timer(tid);
+ Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
+ return 0;
}
}
#endif
if (bnet_recv(sd) <= 0) {
stop_bsock_timer(tid);
Jmsg1(jcr, M_FATAL, 0, _("bdird<stored: bad response to Hello command: ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return 0;
}
Dmsg1(110, "<stored: %s", sd->msg);
/* TLS Requirement */
if (client->tls_enable) {
if (client->tls_require) {
- tls_local_need = BNET_TLS_REQUIRED;
+ tls_local_need = BNET_TLS_REQUIRED;
} else {
- tls_local_need = BNET_TLS_OK;
+ tls_local_need = BNET_TLS_OK;
}
}
#endif
if (auth_success) {
auth_success = cram_md5_auth(fd, client->password, tls_local_need);
if (!auth_success) {
- Dmsg1(50, "cram_auth failed for %s\n", fd->who);
+ Dmsg1(50, "cram_auth failed for %s\n", fd->who);
}
} else {
Dmsg1(50, "cram_get_auth failed for %s\n", fd->who);
stop_bsock_timer(tid);
Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
Jmsg(jcr, M_FATAL, 0,
- _("Unable to authenticate with File daemon. Possible causes:\n"
- "Passwords or names not the same or\n"
- "Maximum Concurrent Jobs exceeded on the FD or\n"
- "FD networking messed up (restart daemon).\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
+ _("Unable to authenticate with File daemon. Possible causes:\n"
+ "Passwords or names not the same or\n"
+ "Maximum Concurrent Jobs exceeded on the FD or\n"
+ "FD networking messed up (restart daemon).\n"
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
return 0;
}
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_client(client->tls_ctx, fd)) {
- stop_bsock_timer(tid);
- Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
- return 0;
+ stop_bsock_timer(tid);
+ Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
+ return 0;
}
}
#endif
if (bnet_recv(fd) <= 0) {
stop_bsock_timer(tid);
Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"),
- bnet_strerror(fd));
+ bnet_strerror(fd));
Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
- bnet_strerror(fd));
+ bnet_strerror(fd));
return 0;
}
Dmsg1(110, "<stored: %s", fd->msg);
// Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
-// ua->host, ua->port, ua->msglen);
+// ua->host, ua->port, ua->msglen);
if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) {
Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who,
- ua->host, ua->port, ua->msglen);
+ ua->host, ua->port, ua->msglen);
return 0;
}
if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
- ua->msg[100] = 0; /* terminate string */
+ ua->msg[100] = 0; /* terminate string */
Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who,
- ua->host, ua->port, ua->msg);
+ ua->host, ua->port, ua->msg);
return 0;
}
- name[sizeof(name)-1] = 0; /* terminate name */
+ name[sizeof(name)-1] = 0; /* terminate name */
if (strcmp(name, "*UserAgent*") == 0) { /* default console */
#ifdef HAVE_TLS
/* TLS Requirement */
if (director->tls_require) {
tls_local_need = BNET_TLS_REQUIRED;
} else {
- tls_local_need = BNET_TLS_OK;
+ tls_local_need = BNET_TLS_OK;
}
}
#endif /* HAVE_TLS */
auth_success = cram_md5_auth(ua, director->password, tls_local_need) &&
- cram_md5_get_auth(ua, director->password, &tls_remote_need);
+ cram_md5_get_auth(ua, director->password, &tls_remote_need);
} else {
unbash_spaces(name);
cons = (CONRES *)GetResWithName(R_CONSOLE, name);
if (cons) {
#ifdef HAVE_TLS
- /* TLS Requirement */
+ /* TLS Requirement */
if (cons->tls_enable) {
if (cons->tls_require) {
- tls_local_need = BNET_TLS_REQUIRED;
+ tls_local_need = BNET_TLS_REQUIRED;
} else {
- tls_local_need = BNET_TLS_OK;
+ tls_local_need = BNET_TLS_OK;
}
}
- if (cons->tls_verify_peer) {
+ if (cons->tls_verify_peer) {
verify_list = cons->tls_allowed_cns;
- }
+ }
#endif /* HAVE_TLS */
- auth_success = cram_md5_auth(ua, cons->password, tls_local_need) &&
- cram_md5_get_auth(ua, cons->password, &tls_remote_need);
+ auth_success = cram_md5_auth(ua, cons->password, tls_local_need) &&
+ cram_md5_get_auth(ua, cons->password, &tls_remote_need);
- if (auth_success) {
- uac->cons = cons; /* save console resource pointer */
- }
+ if (auth_success) {
+ uac->cons = cons; /* save console resource pointer */
+ }
} else {
- auth_success = false;
- goto auth_done;
+ auth_success = false;
+ goto auth_done;
}
}
#ifdef HAVE_TLS
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
if (cons) {
- tls_ctx = cons->tls_ctx;
+ tls_ctx = cons->tls_ctx;
} else {
- tls_ctx = director->tls_ctx;
+ tls_ctx = director->tls_ctx;
}
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_server(tls_ctx, ua, verify_list)) {
- Emsg0(M_ERROR, 0, "TLS negotiation failed.\n");
- auth_success = false;
- goto auth_done;
+ Emsg0(M_ERROR, 0, "TLS negotiation failed.\n");
+ auth_success = false;
+ goto auth_done;
}
}
#endif /* HAVE_TLS */
if (!auth_success) {
bnet_fsend(ua, "%s", _(Dir_sorry));
Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"),
- name, ua->who, ua->host, ua->port);
+ name, ua->who, ua->host, ua->port);
sleep(5);
return 0;
}
}
if (bs->msglen < 25 || bs->msglen > 200) {
Dmsg2(50, _("Bad Hello command from Director at %s. Len=%d.\n"),
- bs->who, bs->msglen);
+ bs->who, bs->msglen);
Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
- bs->who, bs->msglen);
+ bs->who, bs->msglen);
return 0;
}
dirname = get_pool_memory(PM_MESSAGE);
free_pool_memory(dirname);
bs->msg[100] = 0;
Dmsg2(50, _("Bad Hello command from Director at %s: %s\n"),
- bs->who, bs->msg);
+ bs->who, bs->msg);
Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
- bs->who, bs->msg);
+ bs->who, bs->msg);
return 0;
}
unbash_spaces(dirname);
LockRes();
foreach_res(director, R_DIRECTOR) {
if (strcmp(director->hdr.name, dirname) == 0)
- break;
+ break;
}
UnlockRes();
if (!director) {
Dmsg2(50, _("Connection from unknown Director %s at %s rejected.\n"),
- dirname, bs->who);
+ dirname, bs->who);
Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"),
- dirname, bs->who);
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
+ dirname, bs->who);
free_pool_memory(dirname);
return 0;
}
if (director->tls_require) {
tls_local_need = BNET_TLS_REQUIRED;
} else {
- tls_local_need = BNET_TLS_OK;
+ tls_local_need = BNET_TLS_OK;
}
}
if (auth_success) {
auth_success = cram_md5_get_auth(bs, director->password, &tls_remote_need);
if (!auth_success) {
- Dmsg1(50, "cram_get_auth failed for %s\n", bs->who);
+ Dmsg1(50, "cram_get_auth failed for %s\n", bs->who);
}
} else {
Dmsg1(50, "cram_auth failed for %s\n", bs->who);
}
if (!auth_success) {
Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"),
- bs->who);
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
+ bs->who);
director = NULL;
goto auth_fatal;
}
/* Verify that the remote host is willing to meet our TLS requirements */
if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
Emsg0(M_FATAL, 0, _("Authorization problem: Remote server did not"
- " advertise required TLS support.\n"));
+ " advertise required TLS support.\n"));
director = NULL;
goto auth_fatal;
}
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) {
- Emsg0(M_FATAL, 0, "TLS negotiation failed.\n");
- director = NULL;
- goto auth_fatal;
+ Emsg0(M_FATAL, 0, "TLS negotiation failed.\n");
+ director = NULL;
+ goto auth_fatal;
}
}
#endif /* HAVE_TLS */
if (me->tls_require) {
tls_local_need = BNET_TLS_REQUIRED;
} else {
- tls_local_need = BNET_TLS_OK;
+ tls_local_need = BNET_TLS_OK;
}
}
#endif /* HAVE_TLS */
} else {
auth_success = cram_md5_auth(sd, jcr->sd_auth_key, tls_local_need);
if (!auth_success) {
- Dmsg1(50, "cram_auth failed for %s\n", sd->who);
+ Dmsg1(50, "cram_auth failed for %s\n", sd->who);
}
}
if (!auth_success) {
Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
goto auth_fatal;
}
/* Verify that the remote host is willing to meet our TLS requirements */
if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not"
- " advertise required TLS support.\n"));
+ " advertise required TLS support.\n"));
auth_success = false;
goto auth_fatal;
}
if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_client(me->tls_ctx, sd)) {
- Jmsg(jcr, M_FATAL, 0, "TLS negotiation failed.\n");
- auth_success = false;
- goto auth_fatal;
+ Jmsg(jcr, M_FATAL, 0, "TLS negotiation failed.\n");
+ auth_success = false;
+ goto auth_fatal;
}
}
#endif /* HAVE_TLS */
printf(_("%s: Director authorization problem.\n"), my_name);
set_text(_("Director authorization problem.\n"), -1);
set_text(_(
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"),
- -1);
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
+ -1);
return 0;
}
if (bnet_recv(dir) <= 0) {
stop_bsock_timer(tid);
set_textf(_("Bad response to Hello command: ERR=%s\n"),
- bnet_strerror(dir));
+ bnet_strerror(dir));
printf(_("%s: Bad response to Hello command: ERR=%s\n"),
- my_name, bnet_strerror(dir));
+ my_name, bnet_strerror(dir));
set_text(_("The Director is probably not running.\n"), -1);
return 0;
}
block.c butil.c dev.c \
device.c dircmd.c dvd.c ebcdic.c fd_cmds.c job.c \
label.c match_bsr.c mount.c parse_bsr.c \
- pythonsd.c \
- read.c read_record.c record.c \
+ pythonsd.c read.c read_record.c record.c \
+ reserve.c \
spool.c status.c stored_conf.c wait.c
SVROBJS = stored.o ansi_label.o \
autochanger.o acquire.o append.o \
block.o butil.o dev.o \
device.o dircmd.o dvd.o ebcdic.c fd_cmds.o job.o \
label.o match_bsr.o mount.o parse_bsr.o \
- pythonsd.o \
- read.o read_record.o record.o \
+ pythonsd.o read.o read_record.o record.o \
+ reserve.o \
spool.o status.o stored_conf.o wait.o
# btape
#include "bacula.h" /* pull in global headers */
#include "stored.h" /* pull in Storage Deamon headers */
-static int can_reserve_drive(DCR *dcr);
-
/*
* Create a new Device Control Record and attach
* it to the device (if this is a real job).
free(dcr);
}
-
-/*
- * We "reserve" the drive by setting the ST_READ bit. No one else
- * should touch the drive until that is cleared.
- * This allows the DIR to "reserve" the device before actually
- * starting the job.
- */
-bool reserve_device_for_read(DCR *dcr)
-{
- DEVICE *dev = dcr->dev;
- JCR *jcr = dcr->jcr;
- bool ok = false;
-
- ASSERT(dcr);
-
- dev->block(BST_DOING_ACQUIRE);
-
- if (device_is_unmounted(dev)) {
- Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"),
- dev->print_name());
- goto bail_out;
- }
-
- if (dev->is_busy()) {
- Mmsg1(jcr->errmsg, _("Device %s is busy.\n"),
- dev->print_name());
- goto bail_out;
- }
-
- dev->clear_append();
- dev->set_read();
- ok = true;
-
-bail_out:
- dev->unblock();
- return ok;
-}
-
-
/*********************************************************************
* Acquire device for reading.
* The drive should have previously been reserved by calling
return dcr;
}
-/*
- * We reserve the device for appending by incrementing the
- * reserved_device. We do virtually all the same work that
- * is done in acquire_device_for_append(), but we do
- * not attempt to mount the device. This routine allows
- * the DIR to reserve multiple devices before *really*
- * starting the job. It also permits the SD to refuse
- * certain devices (not up, ...).
- *
- * Note, in reserving a device, if the device is for the
- * same pool and the same pool type, then it is acceptable.
- * The Media Type has already been checked. If we are
- * the first tor reserve the device, we put the pool
- * name and pool type in the device record.
- */
-bool reserve_device_for_append(DCR *dcr)
-{
- JCR *jcr = dcr->jcr;
- DEVICE *dev = dcr->dev;
- bool ok = false;
-
- ASSERT(dcr);
-
- dev->block(BST_DOING_ACQUIRE);
-
- if (dev->can_read()) {
- Mmsg1(jcr->errmsg, _("Device %s is busy reading.\n"), dev->print_name());
- goto bail_out;
- }
-
- if (device_is_unmounted(dev)) {
- Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"), dev->print_name());
- goto bail_out;
- }
-
- Dmsg1(190, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
-
- if (can_reserve_drive(dcr) != 1) {
- Mmsg1(jcr->errmsg, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
- goto bail_out;
- }
-
- dev->reserved_device++;
- dcr->reserved_device = true;
- ok = true;
-
-bail_out:
- dev->unblock();
- return ok;
-}
-
-/*
- * Returns: 1 if drive can be reserved
- * 0 if we should wait
- * -1 on error
- */
-static int can_reserve_drive(DCR *dcr)
-{
- DEVICE *dev = dcr->dev;
- JCR *jcr = dcr->jcr;
- /*
- * First handle the case that the drive is not yet in append mode
- */
- if (!dev->can_append() && dev->num_writers == 0) {
- /* Now check if there are any reservations on the drive */
- if (dev->reserved_device) {
- /* Yes, now check if we want the same Pool and pool type */
- if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
- strcmp(dev->pool_type, dcr->pool_type) == 0) {
- /* OK, compatible device */
- } else {
- /* Drive not suitable for us */
- return 0; /* wait */
- }
- } else {
- /* Device is available but not yet reserved, reserve it for us */
- bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
- bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
- }
- return 1; /* reserve drive */
- }
-
- /*
- * Check if device in append mode with no writers (i.e. available)
- */
- if (dev->can_append() && dev->num_writers == 0) {
- /* Device is available but not yet reserved, reserve it for us */
- bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
- bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
- return 1;
- }
-
- /*
- * Now check if the device is in append mode with writers (i.e.
- * available if pool is the same).
- */
- if (dev->can_append() || dev->num_writers > 0) {
- Dmsg0(190, "device already in append.\n");
- /* Yes, now check if we want the same Pool and pool type */
- if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
- strcmp(dev->pool_type, dcr->pool_type) == 0) {
- /* OK, compatible device */
- } else {
- /* Drive not suitable for us */
- Jmsg(jcr, M_WARNING, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
- return 0; /* wait */
- }
- } else {
- Pmsg0(000, "Logic error!!!! Should not get here.\n");
- Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
- return -1; /* error, should not get here */
- }
- return 1; /* reserve drive */
-}
/*
* Acquire device for writing. We permit multiple writers.
Dmsg2(50, _("Connection from unknown Director %s at %s rejected.\n"),
dirname, bs->who);
Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"),
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
dirname, bs->who);
free_pool_memory(dirname);
return 0;
if (!auth_success) {
Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
auth_success = false;
goto auth_fatal;
}
if (!auth_success) {
Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"),
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
fd->who);
auth_success = false;
goto auth_fatal;
stop_bsock_timer(tid);
if (!auth_success) {
Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"),
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
fd->who);
}
jcr->authenticated = auth_success;
* Version $Id$
*/
/*
- Copyright (C) 2000-2005 Kern Sibbald
+ Copyright (C) 2002-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
+ modify it under the terms of the GNU General Public License
+ version 2 as ammended with additional clauses defined in the
+ file LICENSE in the main source directory.
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., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional details.
*/
slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
/*
* Handle autoloaders here. If we cannot autoload it, we
- * will return FALSE to ask the sysop.
+ * will return 0 so that the sysop will be asked to load it.
*/
if (writing && dev_cap(dev, CAP_AUTOCHANGER) && slot <= 0) {
if (dir) {
Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
slot, drive, be.strerror());
goto bail_out;
+ } else {
+ dev->Slot = 0; /* nothing loaded now */
}
-
Dmsg1(400, "unload status=%d\n", status);
}
/*
if (status == 0) {
Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"),
slot, drive);
+ dev->Slot = slot; /* set currently loaded slot */
} else {
berrno be;
be.set_errno(status);
Dmsg2(400, "load slot %d status=%d\n", slot, status);
} else {
status = 0; /* we got what we want */
+ dev->Slot = slot; /* set currently loaded slot */
}
Dmsg1(400, "After changer, status=%d\n", status);
if (status == 0) { /* did we succeed? */
if (loaded > 0) {
Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result is Slot %d.\n"),
drive, loaded);
+ dcr->dev->Slot = loaded;
} else {
Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result: nothing loaded.\n"),
drive);
+ dcr->dev->Slot = 0;
}
} else {
berrno be;
be.set_errno(stat);
Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
slot, drive, be.strerror());
+ } else {
+ dev->Slot = 0; /* nothing loaded */
}
dcr->VolCatInfo.Slot = slot;
}
bool autoselect; /* Autoselect in autochanger */
bool open_nowait; /* If set, don t wait on open */
int label_type; /* Bacula/ANSI/IBM label types */
- uint32_t drive_index; /* Autochanger drive index */
+ uint32_t drive_index; /* Autochanger drive index (base 0) */
+ int32_t Slot; /* Slot currently in drive (base 1) */
POOLMEM *dev_name; /* Physical device name */
POOLMEM *prt_name; /* Name used for display purposes */
char *errmsg; /* nicely edited error message */
char pool_name[MAX_NAME_LENGTH]; /* pool name */
char pool_type[MAX_NAME_LENGTH]; /* pool type */
-
-
-
-
/* Device wait times ***FIXME*** look at durations */
char BadVolName[MAX_NAME_LENGTH]; /* Last wrong Volume mounted */
bool poll; /* set to poll Volume */
/* Imported functions */
extern uint32_t newVolSessionId();
-/* Forward referenced functions */
-static bool use_storage_cmd(JCR *jcr);
-
/* Requests from the Director daemon */
static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
"type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
"SpoolData=%d WritePartAfterJob=%d NewVol=%d\n";
-static char use_storage[] = "use storage=%127s media_type=%127s "
- "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
-static char use_device[] = "use device=%127s\n";
-//static char query_device[] = "query device=%127s";
/* Responses sent to Director daemon */
static char OKjob[] = "3000 OK Job SDid=%u SDtime=%u Authorization=%s\n";
-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 NOT_open[] = "3925 Device \"%s\" could not be opened or does not exist.\n";
-static char BAD_use[] = "3913 Bad use command: %s\n";
static char BAD_job[] = "3915 Bad Job command: %s\n";
//static char OK_query[] = "3001 OK query\n";
//static char NO_query[] = "3918 Query failed\n";
return true;
}
-bool use_cmd(JCR *jcr)
-{
- /*
- * Wait for the device, media, and pool information
- */
- if (!use_storage_cmd(jcr)) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
- return false;
- }
- return true;
-}
-
bool run_cmd(JCR *jcr)
{
struct timeval tv;
}
-/*
- * Use Device command from Director
- * He tells is what Device Name to use, the Media Type,
- * the Pool Name, and the Pool Type.
- *
- * Ensure that the device exists and is opened, then store
- * the media and pool info in the JCR.
- */
-class DIRSTORE {
-public:
- alist *device;
- char name[MAX_NAME_LENGTH];
- char media_type[MAX_NAME_LENGTH];
- char pool_name[MAX_NAME_LENGTH];
- char pool_type[MAX_NAME_LENGTH];
-};
-
-static int search_res_for_device(JCR *jcr, DIRSTORE *store, char *device_name, int append);
-static int reserve_device(JCR *jcr, DIRSTORE *store, DEVRES *device, char *device_name, int append);
-
-static bool use_storage_cmd(JCR *jcr)
-{
- POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
- BSOCK *dir = jcr->dir_bsock;
- int append;
- bool ok;
- int Copy, Stripe;
- alist *dirstore;
- DIRSTORE *store;
- char *device_name;
- DCR *dcr = NULL;
- /*
- * If there are multiple devices, the director sends us
- * use_device for each device that it wants to use.
- */
- Dmsg1(100, "<dird: %s", dir->msg);
- dirstore = New(alist(10, not_owned_by_alist));
- do {
- ok = sscanf(dir->msg, use_storage, store_name.c_str(),
- media_type.c_str(), pool_name.c_str(),
- pool_type.c_str(), &append, &Copy, &Stripe) == 7;
- if (!ok) {
- break;
- }
- unbash_spaces(store_name);
- unbash_spaces(media_type);
- unbash_spaces(pool_name);
- unbash_spaces(pool_type);
- store = new DIRSTORE;
- dirstore->append(store);
- memset(store, 0, sizeof(DIRSTORE));
- store->device = New(alist(10));
- bstrncpy(store->name, store_name, sizeof(store->name));
- bstrncpy(store->media_type, media_type, sizeof(store->media_type));
- bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
- bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
-
- /* Now get all devices */
- while (bnet_recv(dir) >= 0) {
- ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
- if (!ok) {
- break;
- }
- unbash_spaces(dev_name);
- store->device->append(bstrdup(dev_name.c_str()));
- }
- } while (ok && bnet_recv(dir) >= 0);
-
-#ifdef DEVELOPER
- /* This loop is debug code and can be removed */
- /* ***FIXME**** remove after 1.38 release */
- foreach_alist(store, dirstore) {
- Dmsg4(100, "Storage=%s media_type=%s pool=%s pool_type=%s\n",
- store->name, store->media_type, store->pool_name,
- store->pool_type);
- foreach_alist(device_name, store->device) {
- Dmsg1(100, " Device=%s\n", device_name);
- }
- }
-#endif
-
- /*
- * At this point, we have a list of all the Director's Storage
- * resources indicated for this Job, which include Pool, PoolType,
- * storage name, and Media type.
- * Then for each of the Storage resources, we have a list of
- * device names that were given.
- *
- * Wiffle through them and find one that can do the backup.
- */
- if (ok) {
- bool first = true;
- init_jcr_device_wait_timers(jcr);
- for ( ;; ) {
- int need_wait = false;
- foreach_alist(store, dirstore) {
- foreach_alist(device_name, store->device) {
- int stat;
- stat = search_res_for_device(jcr, store, device_name, append);
- if (stat == 1) { /* found available device */
- dcr = jcr->dcr;
- dcr->Copy = Copy;
- dcr->Stripe = Stripe;
- ok = true;
- goto done;
- } else if (stat == 0) { /* device busy */
- need_wait = true;
- }
- }
- }
- /*
- * If there is some device for which we can wait, then
- * wait and try again until the wait time expires
- */
- if (!need_wait || !wait_for_device(jcr, jcr->errmsg, first)) {
- break;
- }
- first = false;
- }
- if (verbose) {
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
- Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
- }
- Jmsg(jcr, M_FATAL, 0, _("\n"
- " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
- dev_name.c_str(), media_type.c_str());
- bnet_fsend(dir, NO_device, dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- ok = false;
- } else {
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
- if (verbose) {
- Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
- }
- Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg);
- bnet_fsend(dir, BAD_use, jcr->errmsg);
- Dmsg1(100, ">dird: %s\n", dir->msg);
- ok = false;
- }
-
-done:
- foreach_alist(store, dirstore) {
- delete store->device;
- delete store;
- }
- delete dirstore;
- if (!ok && dcr) {
- free_dcr(dcr);
- }
- return ok;
-}
-
-static int search_res_for_device(JCR *jcr, DIRSTORE *store, char *device_name, int append)
-{
- DEVRES *device;
- AUTOCHANGER *changer;
- BSOCK *dir = jcr->dir_bsock;
- bool ok;
- int stat;
-
- Dmsg1(100, "Search res for %s\n", device_name);
- foreach_res(device, R_DEVICE) {
- Dmsg1(100, "Try res=%s\n", device->hdr.name);
- /* Find resource, and make sure we were able to open it */
- if (fnmatch(device_name, device->hdr.name, 0) == 0 &&
- strcmp(device->media_type, store->media_type) == 0) {
- stat = reserve_device(jcr, store, device, device_name, append);
- if (stat != 1) {
- return stat;
- }
- Dmsg1(220, "Got: %s", dir->msg);
- bash_spaces(device_name);
- ok = bnet_fsend(dir, OK_device, device_name);
- Dmsg1(100, ">dird: %s\n", dir->msg);
- return ok ? 1 : -1;
- }
- }
- foreach_res(changer, R_AUTOCHANGER) {
- Dmsg1(100, "Try changer res=%s\n", changer->hdr.name);
- /* Find resource, and make sure we were able to open it */
- if (fnmatch(device_name, changer->hdr.name, 0) == 0) {
- /* Try each device in this AutoChanger */
- foreach_alist(device, changer->device) {
- Dmsg1(100, "Try changer device %s\n", device->hdr.name);
- stat = reserve_device(jcr, store, device, device_name, append);
- if (stat == -1) { /* hard error */
- return -1;
- }
- if (stat == 0) { /* must wait, try next one */
- continue;
- }
- POOL_MEM dev_name;
- Dmsg1(100, "Device %s opened.\n", device_name);
- pm_strcpy(dev_name, device->hdr.name);
- bash_spaces(dev_name);
- ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
- Dmsg1(100, ">dird: %s\n", dir->msg);
- return ok ? 1 : -1;
- }
- }
- }
- return 0; /* nothing found */
-}
-
-/*
- * Returns: 1 -- OK, have DCR
- * 0 -- must wait
- * -1 -- fatal error
- */
-static int reserve_device(JCR *jcr, DIRSTORE *store, DEVRES *device, char *device_name, int append)
-{
- bool ok;
- DCR *dcr;
- const int name_len = MAX_NAME_LENGTH;
- if (!device->dev) {
- device->dev = init_dev(jcr, NULL, device);
- }
- if (!device->dev) {
- if (dev_cap(device->dev, CAP_AUTOCHANGER)) {
- Jmsg(jcr, M_WARNING, 0, _("\n"
- " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
- device->hdr.name, device_name);
- } else {
- Jmsg(jcr, M_WARNING, 0, _("\n"
- " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
- device_name);
- }
- return 0;
- }
- Dmsg1(100, "Found device %s\n", device->hdr.name);
- dcr = new_dcr(jcr, device->dev);
- if (!dcr) {
- BSOCK *dir = jcr->dir_bsock;
- bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), device_name);
- Dmsg1(100, ">dird: %s\n", dir->msg);
- return -1;
- }
- jcr->dcr = dcr;
- bstrncpy(dcr->pool_name, store->pool_name, name_len);
- bstrncpy(dcr->pool_type, store->pool_type, name_len);
- bstrncpy(dcr->media_type, store->media_type, name_len);
- bstrncpy(dcr->dev_name, device_name, name_len);
- if (append == SD_APPEND) {
- ok = reserve_device_for_append(dcr);
- } else {
- ok = reserve_device_for_read(dcr);
- }
- if (!ok) {
- free_dcr(jcr->dcr);
- return 0;
- }
- return 1;
-}
-
-
#ifdef needed
/*
* Query Device command from Director
uint32_t new_VolSessionId();
/* From acquire.c */
-bool reserve_device_for_append(DCR *dcr);
DCR *acquire_device_for_append(DCR *dcr);
-bool reserve_device_for_read(DCR *dcr);
DCR *acquire_device_for_read(DCR *dcr);
bool release_device(DCR *dcr);
DCR *new_dcr(JCR *jcr, DEVICE *dev);
Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
+ modify it under the terms of the GNU General Public License
+ version 2 as ammended with additional clauses defined in the
+ file LICENSE in the main source directory.
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., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional details.
*/
DEVRES *device;
char *media_type = NULL;
foreach_alist(device, changer->device) {
+ /*
+ * If the device does not have a changer name or changer command
+ * defined, used the one from the Autochanger resource
+ */
+ if (!device->changer_name && changer->changer_name) {
+ device->changer_name = bstrdup(changer->changer_name);
+ }
+ if (!device->changer_command && changer->changer_command) {
+ device->changer_command = bstrdup(changer->changer_command);
+ }
+ if (!device->changer_name) {
+ Jmsg(NULL, M_ERROR, 0,
+ _("No Changer Name given for device %s. Cannot continue.\n"),
+ device->hdr.name);
+ OK = false;
+ }
+ if (!device->changer_command) {
+ Jmsg(NULL, M_ERROR, 0,
+ _("No Changer Command given for device %s. Cannot continue.\n"),
+ device->hdr.name);
+ OK = false;
+ }
+
if (media_type == NULL) {
- media_type = device->media_type;
+ 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"),
OK = false;
continue;
}
- /*
- * If the device does not have a changer name or changer command
- * defined, used the one from the Autochanger resource
- */
- if (!device->changer_name) {
- device->changer_name = bstrdup(changer->changer_name);
- }
- if (!device->changer_command) {
- device->changer_command = bstrdup(changer->changer_command);
- }
}
}
-// UnlockRes();
-
if (OK) {
close_msg(NULL); /* close temp message handler */
init_msg(NULL, me->messages); /* open daemon message handler */
/* */
#undef VERSION
#define VERSION "1.37.20"
-#define BDATE "29 May 2005"
-#define LSMDATE "29May05"
+#define BDATE "01 June 2005"
+#define LSMDATE "01Jun05"
/* Debug flags */
#undef DEBUG
stop_bsock_timer(tid);
csprint("Director authorization problem.\nMost likely the passwords do not agree.\n", CS_DATA);
csprint(
- "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n", CS_DATA);
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n", CS_DATA);
return 0;
}
}
return 1;
}
-