Release Notes for Bacula 1.30
- Bacula code: Total files = 233 Total lines = 65,765 (*.h *.c *.in)
+ Bacula code: Total files = 233 Total lines = 66,066 (*.h *.c *.in)
Major Changes this Release:
- The Windows Client now uses Cygwin 1.3.20 and should be much
- Support for SHA1 signatures in addition to MD5 (more secure).
- The btape "test" command is much more comprehensive and automatically
tries different options.
+- Implemented support for barcodes ("label barcodes", "update slots").
+- Make Incremental and Differential saves backup all files changed as
+ well as all files moved into save path (added st_ctime to check).
+- Preliminary support for cleaning tapes in autochangers.
Other Changes this Release:
- Added "BSF at EOM = yes/no" for supporting FreeBSD tape drives.
several other utility programs.
- Full listing of most catalog records (llist command).
- Relabel Purged tapes with the relabel command.
+- Correct misentered path separators on Win32 systems to
+ prevent creating files names with mixed conventions.
+- Print IP address on failed connections to servers.
+- Cancel command works much better (cancels waiting jobs in Dir
+ and in SD).
Items to note:
Kern's ToDo List
- 7 April 2003
+ 9 April 2003
Documentation to do: (a little bit at a time)
- Document running a test version.
- Document problems with Verify and pruning.
- Document how to use multiple databases.
- Document Maximum File Size
-
- Add a section to the doc on Manual cycling of Volumes.
+- Document logrotate
+- Document default file backup
+
Testing to do: (painful)
- that ALL console command line options work and are always implemented
- blocksize recognition code.
- multiple simultaneous Volumes
For 1.30 release:
-- Update volume=Test01 requests pool, then lists volumes.
-- Add IP address to authentication failures. Implement M_SECURITY
- message class.
-- Look at Python for a Bacula scripting language -- www.python.org
-- add #define ENABLE_NLS for Gnome compile on SuSE.
-- Figure out how to use ssh to protect Bacula communications.
+- Fix Bare Metal restore problem.
- Fix "access not allowed" for backup of files on WinXP.
+
+- Figure out how to use ssh or stunnel to protect Bacula communications.
+
+After 1.30:
+- Implement a M_SECURITY message class.
+- Allow multiple Storage specifications (or multiple names on
+ a single Storage specification) in the Job record. Thus a job
+ can be backed up to a number of storage devices.
+- Implement dump label to UA
+- Add prefixlinks to where or not where absolute links to FD.
+- Look at Python for a Bacula scripting language -- www.python.org
- Issue message to mount a new tape before the rewind.
- Simplified client job initiation for portables.
- If SD cannot open a drive, make it periodically retry.
- Implement LabelTemplate (at least first cut).
- Add more of the config info to the tape label.
-- Add a default File storage so that new users can do backup
- and restores right away.
- Implement a Mount Command and an Unmount Command where
the users could specify a system command to be performed
to do the mount, after which Bacula could attempt to
- Make Restore report an error if FD or SD term codes are not OK.
- CD into subdirectory when open()ing files for backup to
speed up things. Test with testfind().
-- Add prefixlinks to where or not where absolute links to FD.
- Priority job to go to top of list.
- Find out why Full saves run slower and slower (hashing?)
- Why are save/restore of device different sizes (sparse?) Yup! Fix it.
- bscan without -v is too quiet -- perhaps show jobs.
- Add code to reject whole blocks if not wanted on restore.
- Start working on Base jobs.
+- Check if we can increase Bacula FD priorty in Win2000
- Make sure the MaxVolFiles is fully implemented in SD
- Check if both CatalogFiles and UseCatalog are set to SD.
-- Check if we can increase Bacula FD priorty in Win2000
- Need return status on read_cb() from read_records(). Need multiple
records -- one per Job, maybe a JCR or some other structure with
a block and a record.
- Fix Autoprune for Volumes to respect need for full save.
- Fix Win32 config file definition name on /install
- No READLINE_SRC if found in alternate directory.
-- Add Client FS/OS id (Linux, Win95/98, ...).
- Test a second language e.g. french.
- Compare tape to Client files (attributes, or attributes and data)
- Make all database Ids 64 bit.
- Implement script driven addition of File daemon to config files.
- Think about how to make Bacula work better with File (non-tape) archives.
- Write Unix emulator for Windows.
-
- Implement new serialize subroutines
send(socket, "string", &Vol, "uint32", &i, NULL)
- Audit all UA commands to ensure that we always prompt where possible.
- Set flag for uname -a. Add to Volume label.
- Implement throttled work queue.
- Check for EOT at ENOSPC or EIO or ENXIO (unix Pc)
-- Allow multiple Storage specifications (or multiple names on
- a single Storage specification) in the Job record. Thus a job
- can be backed up to a number of storage devices.
-- Implement dump label to UA
-- Concept of VolumeSet during restore which is a list
- of Volume names needed.
- Restore files modified after date
- Restore file modified before date
- Emergency restore info:
- Need a structure for pending actions:
- buffered messages
- termination status (part of buffered msgs?)
-- Concept of grouping Storage devices and job can use
- any of a number of devices
- Drive management
Read, Write, Clean, Delete
- Login to Bacula; Bacula users with different permissions:
- Identify unchanged or "system" files and save them to a
special tape thus removing them from the standard
backup FileSet -- BASE backup.
-- Turn virutally all sprintfs into snprintfs.
- Heartbeat between daemons.
- Audit M_ error codes to ensure they are correct and consistent.
- Add variable break characters to lex analyzer.
- Remove kern and kelvin from mysql_grant...
- Install grant_mysql...
- Strip trailing / from Include
+- add #define ENABLE_NLS for Gnome compile on SuSE.
+- Add Client FS/OS id (Linux, Win95/98, ...).
+- Concept of VolumeSet during restore which is a list
+ of Volume names needed.
+- Turn virutally all sprintfs into snprintfs.
+- Update volume=Test01 requests pool, then lists volumes.
+ **** Test select_pool_and_media ...
+- Document relabel
+- Add IP address to authentication failures.
+- Add a default File storage so that new users can do backup
+ and restores right away.
+
stat = 1;
}
} else {
- Mmsg2(&mdb->errmsg, _("File record not found for PathId=%u FilenameId=%u\n"),
+ Mmsg2(&mdb->errmsg, _("File record for PathId=%u FilenameId=%u not found.\n"),
fdbr->PathId, fdbr->FilenameId);
}
sql_free_result(mdb);
sql_data_seek(mdb, mdb->num_rows-1);
}
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("Error: FileSet record \"%s\" not found\n"), fsr->FileSet);
+ Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet);
} else {
fsr->FileSetId = atoi(row[0]);
bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet));
stat = mr->MediaId;
}
} else {
- Mmsg0(&mdb->errmsg, _("Media record not found.\n"));
+ if (mr->MediaId != 0) {
+ Mmsg1(&mdb->errmsg, _("Media record MediaId=%u not found.\n"), mr->MediaId);
+ } else {
+ Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"),
+ mr->VolumeName);
+ }
}
sql_free_result(mdb);
}
#include "bacula.h"
#include "console_conf.h"
#include "jcr.h"
-#include <termios.h>
/* Imported functions */
int authenticate_director(JCR *jcr, DIRRES *director);
int ok;
if (ua->msglen < 16 || ua->msglen >= MAXSTRING-1) {
- Emsg1(M_ERROR, 0, _("UA Hello is invalid. Len=%d\n"), ua->msglen);
+ Emsg2(M_ERROR, 0, _("UA Hello from %s is invalid. Len=%d\n"), ua->who,
+ ua->msglen);
return 0;
}
if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) {
ua->msg[100] = 0; /* terminate string */
- Emsg1(M_ERROR, 0, _("UA Hello is invalid. Got: %s\n"), ua->msg);
+ Emsg2(M_ERROR, 0, _("UA Hello from %s is invalid. Got: %s\n"), ua->who,
+ ua->msg);
return 0;
}
if (!ok) {
bnet_fsend(ua, "%s", _(Dir_sorry));
- Emsg0(M_WARNING, 0, _("Unable to authenticate User Agent\n"));
+ Emsg1(M_WARNING, 0, _("Unable to authenticate User Agent at %s.\n"),
+ ua->who);
sleep(5);
return 0;
}
/
}
- Exclude = { }
+ Exclude = { /proc; /tmp }
}
#
AutoPrune = yes # Prune expired Jobs/Files
}
-
-# Definition of DLT tape storage device
-Storage {
- Name = DLTDrive
- Address = @hostname@ # N.B. Use a fully qualified name here
- SDPort = @sd_port@
- Password = "@sd_password@" # password for Storage daemon
- Device = "HP DLT 80" # must be same as Device in Storage daemon
- Media Type = DLT8000 # must be same as MediaType in Storage daemon
-}
-
-# Definition of DDS tape storage device
-Storage {
- Name = SDT-10000
- Address = @hostname@ # N.B. Use a fully qualified name here
- SDPort = @sd_port@
- Password = "@sd_password@" # password for Storage daemon
- Device = SDT-10000 # must be same as Device in Storage daemon
- Media Type = DDS-4 # must be same as MediaType in Storage daemon
-}
-
-# Definition of 8mm tape storage device
-Storage {
- Name = "8mmDrive"
- Address = @hostname@ # N.B. Use a fully qualified name here
- SDPort = @sd_port@
- Password = "@sd_password@"
- Device = "Exabyte 8mm"
- MediaType = "8mm"
-}
-
# Definiton of file storage device
Storage {
Name = File
Media Type = File
}
+# Definition of DLT tape storage device
+#Storage {
+# Name = DLTDrive
+# Address = @hostname@ # N.B. Use a fully qualified name here
+# SDPort = @sd_port@
+# Password = "@sd_password@" # password for Storage daemon
+# Device = "HP DLT 80" # must be same as Device in Storage daemon
+# Media Type = DLT8000 # must be same as MediaType in Storage daemon
+#}
+
+# Definition of DDS tape storage device
+#Storage {
+# Name = SDT-10000
+# Address = @hostname@ # N.B. Use a fully qualified name here
+# SDPort = @sd_port@
+# Password = "@sd_password@" # password for Storage daemon
+# Device = SDT-10000 # must be same as Device in Storage daemon
+# Media Type = DDS-4 # must be same as MediaType in Storage daemon
+#}
+
+# Definition of 8mm tape storage device
+#Storage {
+# Name = "8mmDrive"
+# Address = @hostname@ # N.B. Use a fully qualified name here
+# SDPort = @sd_port@
+# Password = "@sd_password@"
+# Device = "Exabyte 8mm"
+# MediaType = "8mm"
+#}
+
# Generic catalog service
Catalog {
AutoPrune = yes # Prune expired volumes
Volume Retention = 365d # one year
Accept Any Volume = yes # write on any volume in the pool
-}
+
/* fd_cmds.c */
extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int send_include_list(JCR *jcr);
extern int send_exclude_list(JCR *jcr);
extern int get_attributes_and_put_in_catalog(JCR *jcr);
extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
- char *link, char *attr, int stream);
+ char *link, char *attr, int stream);
/* job.c */
extern void set_jcr_defaults(JCR *jcr, JOB *job);
/* msgchan.c */
extern int connect_to_storage_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int start_storage_daemon_job(JCR *jcr);
extern int start_storage_daemon_message_thread(JCR *jcr);
extern int32_t bget_msg(BSOCK *bs, int type);
void bsendmsg(void *sock, char *fmt, ...);
/* ua_select.c */
-STORE *select_storage_resource(UAContext *ua);
-JOB *select_job_resource(UAContext *ua);
-JOB *select_restore_job_resource(UAContext *ua);
-CLIENT *select_client_resource(UAContext *ua);
+STORE *select_storage_resource(UAContext *ua);
+JOB *select_job_resource(UAContext *ua);
+JOB *select_restore_job_resource(UAContext *ua);
+CLIENT *select_client_resource(UAContext *ua);
FILESET *select_fileset_resource(UAContext *ua);
-int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-
-void start_prompt(UAContext *ua, char *msg);
-void add_prompt(UAContext *ua, char *prompt);
-int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt);
-CAT *get_catalog_resource(UAContext *ua);
+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
+int select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+
+void start_prompt(UAContext *ua, char *msg);
+void add_prompt(UAContext *ua, char *prompt);
+int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt);
+CAT *get_catalog_resource(UAContext *ua);
STORE *get_storage_resource(UAContext *ua, int use_default);
-int get_media_type(UAContext *ua, char *MediaType, int max_media);
-int get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+int get_media_type(UAContext *ua, char *MediaType, int max_media);
+int get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
POOL *get_pool_resource(UAContext *ua);
POOL *select_pool_resource(UAContext *ua);
CLIENT *get_client_resource(UAContext *ua);
-int get_job_dbr(UAContext *ua, JOB_DBR *jr);
+int get_job_dbr(UAContext *ua, JOB_DBR *jr);
int find_arg_keyword(UAContext *ua, char **list);
+int find_arg(UAContext *ua, char *keyword);
int do_keyword_prompt(UAContext *ua, char *msg, char **list);
int confirm_retention(UAContext *ua, utime_t *ret, char *msg);
*/
static int update_volume(UAContext *ua)
{
- POOL_DBR pr;
MEDIA_DBR mr;
POOLMEM *query;
char ed1[30];
- if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
- return 0;
- }
for (int done=0; !done; ) {
- if (!db_get_media_record(ua->jcr, ua->db, &mr)) {
- if (mr.MediaId != 0) {
- bsendmsg(ua, _("Volume record for MediaId %d not found.\n"), mr.MediaId);
- } else {
- bsendmsg(ua, _("Volume record for %s not found.\n"), mr.VolumeName);
- }
+ if (!select_media_dbr(ua, &mr)) {
return 0;
}
bsendmsg(ua, _("Updating Volume \"%s\"\n"), mr.VolumeName);
case 7: /* Slot */
int slot;
+ POOL_DBR pr;
+
+ memset(&pr, 0, sizeof(POOL_DBR));
+ pr.PoolId = mr.PoolId;
+ if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ return 0;
+ }
bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot);
if (!get_cmd(ua, _("Enter new Slot: "))) {
return 0;
*/
static int delete_volume(UAContext *ua)
{
- POOL_DBR pr;
MEDIA_DBR mr;
- if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
+ if (!select_media_dbr(ua, &mr)) {
return 1;
}
bsendmsg(ua, _("\nThis command will delete volume %s\n"
int ok = FALSE;
int mounted = FALSE;
int i;
- static char *name_keyword[] = {
- "name",
- NULL};
- static char *vol_keyword[] = {
- "volume",
- NULL};
static char *barcode_keyword[] = {
"barcode",
"barcodes",
/* If relabel get name of Volume to relabel */
if (relabel) {
/* Check for volume=OldVolume */
- i = find_arg_keyword(ua, vol_keyword);
+ i = find_arg(ua, "volume");
if (i >= 0 && ua->argv[i]) {
memset(&omr, 0, sizeof(omr));
bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName));
bsendmsg(ua, "%s", db_strerror(ua->db));
}
/* No keyword or Vol not found, ask user to select */
- if (!select_pool_and_media_dbr(ua, &pr, &omr)) {
+ if (!select_media_dbr(ua, &omr)) {
return 1;
}
}
/* Check for name=NewVolume */
- i = find_arg_keyword(ua, name_keyword);
- if (i >=0 && ua->argv[i]) {
+ i = find_arg(ua, "name");
+ if (i >= 0 && ua->argv[i]) {
pm_strcpy(&ua->cmd, ua->argv[i]);
goto checkName;
}
CLIENT *client;
POOL_DBR pr;
MEDIA_DBR mr;
+ int kw;
static char *keywords[] = {
N_("Files"),
N_("Jobs"),
N_("Volume"),
NULL};
+
if (!open_db(ua)) {
return 01;
}
- switch (find_arg_keyword(ua, keywords)) {
- case 0:
+
+ /* First search args */
+ kw = find_arg_keyword(ua, keywords);
+ if (kw < 0 || kw > 2) {
+ /* no args, so ask user */
+ kw = do_keyword_prompt(ua, _("Choose item to prune"), keywords);
+ }
+
+ switch (kw) {
+ case 0: /* prune files */
client = select_client_resource(ua);
if (!client || !confirm_retention(ua, &client->FileRetention, "File")) {
return 0;
}
prune_files(ua, client);
return 1;
- case 1:
+ case 1: /* prune jobs */
client = select_client_resource(ua);
if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) {
return 0;
/* ****FIXME**** allow user to select JobType */
prune_jobs(ua, client, JT_BACKUP);
return 1;
- case 2:
+ case 2: /* prune volume */
if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
return 0;
}
default:
break;
}
- switch (do_keyword_prompt(ua, _("Choose item to prune"), keywords)) {
- case 0:
- client = select_client_resource(ua);
- if (!client || !confirm_retention(ua, &client->FileRetention, "File")) {
- return 0;
- }
- prune_files(ua, client);
- break;
- case 1:
- client = select_client_resource(ua);
- if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) {
- return 0;
- }
- /* ****FIXME**** allow user to select JobType */
- prune_jobs(ua, client, JT_BACKUP);
- break;
- case 2:
- if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
- return 0;
- }
- if (!confirm_retention(ua, &mr.VolRetention, "Volume")) {
- return 0;
- }
- prune_volume(ua, &pr, &mr);
- return 1;
- }
+
return 1;
}
{
CLIENT *client;
MEDIA_DBR mr;
- POOL_DBR pr;
JOB_DBR jr;
static char *keywords[] = {
N_("files"),
NULL};
bsendmsg(ua, _(
- "This command is DANGEROUS!!!\n"
+ "\nThis command is can be DANGEROUS!!!\n\n"
"It purges (deletes) all Files from a Job,\n"
"JobId, Client or Volume; or it purges (deletes)\n"
- "all Jobs from a Client or Volume. Normally you\n"
- "should use the PRUNE command instead.\n"));
+ "all Jobs from a Client or Volume without regard\n"
+ "for retention periods. Normally you should use the\n"
+ "PRUNE command, which respects retention periods.\n"));
if (!open_db(ua)) {
return 1;
purge_files_from_client(ua, client);
return 1;
case 3: /* Volume */
- if (select_pool_and_media_dbr(ua, &pr, &mr)) {
+ if (select_media_dbr(ua, &mr)) {
purge_files_from_volume(ua, &mr);
}
return 1;
purge_jobs_from_client(ua, client);
return 1;
case 1: /* Volume */
- if (select_pool_and_media_dbr(ua, &pr, &mr)) {
+ if (select_media_dbr(ua, &mr)) {
purge_jobs_from_volume(ua, &mr);
}
return 1;
}
/* Volume */
case 2:
- if (select_pool_and_media_dbr(ua, &pr, &mr)) {
+ if (select_media_dbr(ua, &mr)) {
purge_jobs_from_volume(ua, &mr);
}
return 1;
purge_jobs_from_client(ua, client);
break;
case 2: /* Volume */
- if (select_pool_and_media_dbr(ua, &pr, &mr)) {
+ if (select_media_dbr(ua, &mr)) {
purge_jobs_from_volume(ua, &mr);
}
break;
return -1;
}
+/*
+ * Given a single keyword, find it in the argument list.
+ * Returns: -1 if not found
+ * list index (base 0) on success
+ */
+int find_arg(UAContext *ua, char *keyword)
+{
+ for (int i=1; i<ua->argc; i++) {
+ if (strcasecmp(keyword, ua->argk[i]) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
/*
* Given a list of keywords, prompt the user
* to choose one.
*/
int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr)
{
- int i;
- static char *kw[] = {
- N_("volume"),
- NULL};
+ if (!select_media_dbr(ua, mr)) {
+ return 0;
+ }
memset(pr, 0, sizeof(POOL_DBR));
- memset(mr, 0, sizeof(MEDIA_DBR));
-
- /* Get the pool, possibly from pool=<pool-name> */
- if (!get_pool_dbr(ua, pr)) {
+ pr->PoolId = mr->PoolId;
+ if (!db_get_pool_record(ua->jcr, ua->db, pr)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
return 0;
}
- mr->PoolId = pr->PoolId;
+ return 1;
+}
- i = find_arg_keyword(ua, kw);
- if (i == 0 && ua->argv[i]) {
+/* Select a Media (Volume) record from the database */
+int select_media_dbr(UAContext *ua, MEDIA_DBR *mr)
+{
+ int i;
+
+ memset(mr, 0, sizeof(MEDIA_DBR));
+
+ i = find_arg(ua, "volume");
+ if (i >= 0 && ua->argv[i]) {
bstrncpy(mr->VolumeName, ua->argv[i], sizeof(mr->VolumeName));
}
if (mr->VolumeName[0] == 0) {
+ POOL_DBR pr;
+ memset(&pr, 0, sizeof(pr));
+ /* Get the pool from pool=<pool-name> */
+ if (!get_pool_dbr(ua, &pr)) {
+ return 0;
+ }
+ mr->PoolId = pr.PoolId;
db_list_media_records(ua->jcr, ua->db, mr, prtit, ua, 0);
if (!get_cmd(ua, _("Enter MediaId or Volume name: "))) {
return 0;
{
STORE *store;
int i;
- static char *keyword[] = {
- "mediatype",
- NULL};
- i = find_arg_keyword(ua, keyword);
+ i = find_arg(ua, "mediatype");
if (i >= 0 && ua->argv[i]) {
bstrncpy(MediaType, ua->argv[i], max_media);
return 1;
return 0;
}
if (bs->msglen < 25 || bs->msglen > 200) {
- Emsg1(M_FATAL, 0, _("Bad Hello command from Director. Len=%d.\n"), bs->msglen);
+ Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
+ bs->who, bs->msglen);
return 0;
}
dirname = get_pool_memory(PM_MESSAGE);
if (sscanf(bs->msg, "Hello Director %s calling\n", dirname) != 1) {
free_pool_memory(dirname);
bs->msg[100] = 0;
- Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s\n"), bs->msg);
+ Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
+ bs->who, bs->msg);
return 0;
}
director = NULL;
}
UnlockRes();
if (!director) {
- Emsg1(M_FATAL, 0, _("Connection from unknown Director %s rejected.\n"), dirname);
+ Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"),
+ dirname, bs->who);
free_pool_memory(dirname);
return 0;
}
if (!cram_md5_auth(bs, director->password) ||
!cram_md5_get_auth(bs, director->password)) {
- Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"));
+ Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
+ bs->who);
director = NULL;
}
free_pool_memory(dirname);
#include <resolv.h>
#endif
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
#ifdef HAVE_LIBWRAP
#include "tcpd.h"
int allow_severity = LOG_NOTICE;
int deny_severity = LOG_WARNING;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
/* Become Threaded Network Server */
}
/* see who client is. i.e. who connected to us. */
- caller = inet_ntoa(cli_addr.sin_addr);
+ P(mutex);
+ caller = inet_ntoa(cli_addr.sin_addr); /* NOT thread safe, use mutex */
if (caller == NULL) {
caller = "unknown client";
}
/* Queue client to be served */
if ((stat = workq_add(client_wq,
(void *)init_bsock(NULL, newsockfd, "client", caller, port), NULL, 0)) != 0) {
+ V(mutex);
Jmsg1(NULL, M_ABORT, 0, _("Could not add job to client queue: ERR=%s\n"), strerror(stat));
}
+ V(mutex);
}
}
return 0;
}
if (bs->msglen < 25 || bs->msglen > 200) {
- Emsg1(M_FATAL, 0, _("Bad Hello command from Director. Len=%d.\n"), bs->msglen);
+ Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
+ bs->who, bs->msglen);
return 0;
}
dirname = get_pool_memory(PM_MESSAGE);
if (sscanf(bs->msg, "Hello Director %127s calling\n", dirname) != 1) {
bs->msg[100] = 0;
- Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s\n"), bs->msg);
+ Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
+ bs->who, bs->msg);
return 0;
}
director = NULL;
}
UnlockRes();
if (!director) {
- Emsg1(M_FATAL, 0, _("Connection from unknown Director %s rejected.\n"), dirname);
+ Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"),
+ dirname, bs->who);
goto bail_out;
}
if (!cram_md5_auth(bs, director->password) ||
if (!authenticate(R_DIRECTOR, dir)) {
bnet_fsend(dir, "%s", Dir_sorry);
- Emsg0(M_ERROR, 0, _("Unable to authenticate Director\n"));
+ Emsg1(M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who);
sleep(5);
return 0;
}
jcr->authenticated = TRUE;
}
if (!jcr->authenticated) {
- Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon rejected.\n"));
+ Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"),
+ fd->who);
}
return jcr->authenticated;
}
# To connect, the Director's bacula-dir.conf must have the
# same Name and MediaType.
#
+
Device {
- Name = "HP DLT 80"
- Media Type = DLT8000
- Archive Device = @TAPEDRIVE@
+ Name = FileStorage
+ Media Type = File
+ Archive Device = /tmp
+ LabelMedia = yes; # lets Bacula label unlabelled media
+ Random Access = Yes;
AutomaticMount = yes; # when device opened, read it
- AlwaysOpen = yes;
- RemovableMedia = yes;
+ RemovableMedia = no;
+ AlwaysOpen = no;
}
+#Device {
+# Name = "HP DLT 80"
+# Media Type = DLT8000
+# Archive Device = @TAPEDRIVE@
+# AutomaticMount = yes; # when device opened, read it
+# AlwaysOpen = yes;
+# RemovableMedia = yes;
+#}
+
#Device {
# Name = SDT-7000 #
# Media Type = DDS-2
# AlwaysOpen = no;
#}
-#Device {
-# Name = FileStorage
-# Media Type = File
-# Archive Device = /tmp
-# LabelMedia = yes; # lets Bacula label unlabelled media
-# Random Access = Yes;
-# AutomaticMount = yes; # when device opened, read it
-# RemovableMedia = no;
-# AlwaysOpen = no;
-#}
-
#
# A very old Exabyte with no end of media detection
#
Messages {
Name = Standard
director = @hostname@-dir = all
-# operator = @job_email@ = mount
}
dev->capabilities = device->cap_bits;
dev->min_block_size = device->min_block_size;
dev->max_block_size = device->max_block_size;
- dev->max_volume_jobs = device->max_volume_jobs;
- dev->max_volume_files = device->max_volume_files;
dev->max_volume_size = device->max_volume_size;
dev->max_file_size = device->max_file_size;
dev->volume_capacity = device->volume_capacity;
uint32_t EndFile; /* last file written */
uint32_t min_block_size; /* min block size */
uint32_t max_block_size; /* max block size */
- uint32_t max_volume_jobs; /* max jobs to put on one volume */
- uint64_t max_volume_files; /* max files to put on one volume */
uint64_t max_volume_size; /* max bytes to put on one volume */
uint64_t max_file_size; /* max file size to put in one file on volume */
uint64_t volume_capacity; /* advisory capacity */
{"maximumrewindwait", store_pint, ITEM(res_dev.max_rewind_wait), 0, ITEM_DEFAULT, 5 * 60},
{"minimumblocksize", store_pint, ITEM(res_dev.min_block_size), 0, 0, 0},
{"maximumblocksize", store_pint, ITEM(res_dev.max_block_size), 0, 0, 0},
- {"maximumvolumejobs", store_pint, ITEM(res_dev.max_volume_jobs), 0, 0, 0},
- {"maximumvolumefiles", store_int64, ITEM(res_dev.max_volume_files), 0, 0, 0},
{"maximumvolumesize", store_size, ITEM(res_dev.max_volume_size), 0, 0, 0},
{"maximumfilesize", store_size, ITEM(res_dev.max_file_size), 0, 0, 0},
{"volumecapacity", store_size, ITEM(res_dev.volume_capacity), 0, 0, 0},
/* */
#define VERSION "1.30"
#define VSTRING "1"
-#define BDATE "09 April 2003"
-#define LSMDATE "09Apr03"
+#define BDATE "10 April 2003"
+#define LSMDATE "10Apr03"
/* Debug flags */
#define DEBUG 1