From: Kern Sibbald Date: Thu, 10 Apr 2003 21:22:40 +0000 (+0000) Subject: Doc, Vol name scan, misc X-Git-Tag: Release-1.30~35 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6cee586a50e25cb35eaa872aaa2f992409f72972;p=bacula%2Fbacula Doc, Vol name scan, misc git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@432 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index b5e8ae3ddd..75972c52c0 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -1,6 +1,6 @@ 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 @@ -10,6 +10,10 @@ Major Changes this Release: - 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. @@ -28,6 +32,11 @@ Other Changes this Release: 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: diff --git a/bacula/kernstodo b/bacula/kernstodo index 208a7a7804..eefc410c7a 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -1,5 +1,5 @@ Kern's ToDo List - 7 April 2003 + 9 April 2003 Documentation to do: (a little bit at a time) - Document running a test version. @@ -9,29 +9,35 @@ Documentation to do: (a little bit at a time) - 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 @@ -72,7 +78,6 @@ For 1.30 release: - 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. @@ -85,9 +90,9 @@ For 1.30 release: - 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. @@ -116,7 +121,6 @@ For 1.30 release: - 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. @@ -145,7 +149,6 @@ For 1.30 release: - 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. @@ -156,12 +159,6 @@ For 1.30 release: - 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: @@ -243,8 +240,6 @@ For 1.30 release: - 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: @@ -258,7 +253,6 @@ Longer term to do: - 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. @@ -915,3 +909,15 @@ rufus-dir: Volume used once. Marking Volume "File0003" as Used. - 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. + diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index bc6af6899d..0cac11d31a 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -132,7 +132,7 @@ File.FilenameId=%u", fdbr->JobId, fdbr->PathId, fdbr->FilenameId); 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); @@ -640,7 +640,7 @@ int db_get_fileset_record(void *jcr, B_DB *mdb, FILESET_DBR *fsr) 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)); @@ -781,7 +781,12 @@ FROM Media WHERE VolumeName='%s'", mr->VolumeName); 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); } diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 82af3448a5..69597b46ea 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -28,7 +28,6 @@ #include "bacula.h" #include "console_conf.h" #include "jcr.h" -#include /* Imported functions */ int authenticate_director(JCR *jcr, DIRRES *director); diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index f6a11fb325..a794b06b0f 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -130,13 +130,15 @@ int authenticate_user_agent(BSOCK *ua) 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; } @@ -145,7 +147,8 @@ int authenticate_user_agent(BSOCK *ua) 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; } diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index e9c0b6ec45..d2ec68e234 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -85,7 +85,7 @@ FileSet { / } - Exclude = { } + Exclude = { /proc; /tmp } } # @@ -125,37 +125,6 @@ Client { 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 @@ -166,6 +135,36 @@ Storage { 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 { @@ -198,4 +197,4 @@ Pool { AutoPrune = yes # Prune expired volumes Volume Retention = 365d # one year Accept Any Volume = yes # write on any volume in the pool -} + diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index bb35959ff6..d5acce284d 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -48,13 +48,13 @@ extern char *level_to_str(int level); /* 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); @@ -67,7 +67,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf); /* 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); @@ -98,29 +98,31 @@ void prtit(void *ctx, char *msg); 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); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 0c479ccd7c..43cb7a1b3b 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -649,22 +649,13 @@ static int updatecmd(UAContext *ua, char *cmd) */ 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); @@ -846,6 +837,14 @@ static int update_volume(UAContext *ua) 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; @@ -1250,10 +1249,9 @@ static int deletecmd(UAContext *ua, char *cmd) */ 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" diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index c967f92085..09fdae2914 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -149,12 +149,6 @@ static int do_label(UAContext *ua, char *cmd, int relabel) 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", @@ -179,7 +173,7 @@ static int do_label(UAContext *ua, char *cmd, int relabel) /* 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)); @@ -189,7 +183,7 @@ static int do_label(UAContext *ua, char *cmd, int relabel) 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; } @@ -203,8 +197,8 @@ checkVol: } /* 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; } diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index 251b18fb2c..196cf3d408 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -163,24 +163,34 @@ int prunecmd(UAContext *ua, char *cmd) 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; @@ -188,7 +198,7 @@ int prunecmd(UAContext *ua, char *cmd) /* ****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; } @@ -200,32 +210,7 @@ int prunecmd(UAContext *ua, char *cmd) 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; } diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index 4942e74f33..e5eb298c87 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -164,7 +164,6 @@ int purgecmd(UAContext *ua, char *cmd) { CLIENT *client; MEDIA_DBR mr; - POOL_DBR pr; JOB_DBR jr; static char *keywords[] = { N_("files"), @@ -185,11 +184,12 @@ int purgecmd(UAContext *ua, char *cmd) 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; @@ -209,7 +209,7 @@ int purgecmd(UAContext *ua, char *cmd) 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; @@ -222,14 +222,14 @@ int purgecmd(UAContext *ua, char *cmd) 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; @@ -252,7 +252,7 @@ int purgecmd(UAContext *ua, char *cmd) 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; diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 6965095727..da1d99f07d 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -82,6 +82,22 @@ int find_arg_keyword(UAContext *ua, char **list) 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; iargc; i++) { + if (strcasecmp(keyword, ua->argk[i]) == 0) { + return i; + } + } + return -1; +} + + /* * Given a list of keywords, prompt the user * to choose one. @@ -425,25 +441,38 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr) */ 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= */ - 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= */ + 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; @@ -751,11 +780,8 @@ int get_media_type(UAContext *ua, char *MediaType, int max_media) { 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; diff --git a/bacula/src/filed/authenticate.c b/bacula/src/filed/authenticate.c index 93ea4195e2..cc9d23f12d 100644 --- a/bacula/src/filed/authenticate.c +++ b/bacula/src/filed/authenticate.c @@ -46,7 +46,8 @@ static int authenticate(int rcode, BSOCK *bs) 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); @@ -55,7 +56,8 @@ static int authenticate(int rcode, BSOCK *bs) 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; @@ -67,13 +69,15 @@ static int authenticate(int rcode, BSOCK *bs) } 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); diff --git a/bacula/src/lib/bnet_server.c b/bacula/src/lib/bnet_server.c index ecf8fa38f2..9798fb6f7a 100644 --- a/bacula/src/lib/bnet_server.c +++ b/bacula/src/lib/bnet_server.c @@ -36,11 +36,12 @@ #include #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 */ @@ -159,7 +160,8 @@ bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_w } /* 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"; } @@ -167,8 +169,10 @@ bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_w /* 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); } } diff --git a/bacula/src/stored/authenticate.c b/bacula/src/stored/authenticate.c index 46cc07818b..fa9b215497 100644 --- a/bacula/src/stored/authenticate.c +++ b/bacula/src/stored/authenticate.c @@ -47,7 +47,8 @@ static int authenticate(int rcode, BSOCK *bs) 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); @@ -55,7 +56,8 @@ static int authenticate(int rcode, BSOCK *bs) 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; @@ -67,7 +69,8 @@ static int authenticate(int rcode, BSOCK *bs) } 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) || @@ -101,7 +104,7 @@ int authenticate_director(JCR *jcr) 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; } @@ -117,7 +120,8 @@ int authenticate_filed(JCR *jcr) 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; } diff --git a/bacula/src/stored/bacula-sd.conf.in b/bacula/src/stored/bacula-sd.conf.in index 0e936dd705..37f415e4a2 100644 --- a/bacula/src/stored/bacula-sd.conf.in +++ b/bacula/src/stored/bacula-sd.conf.in @@ -31,15 +31,27 @@ Director { # 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 @@ -59,17 +71,6 @@ Device { # 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 # @@ -90,5 +91,4 @@ Device { Messages { Name = Standard director = @hostname@-dir = all -# operator = @job_email@ = mount } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 11a9cd3fd3..e222876882 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -146,8 +146,6 @@ init_dev(DEVICE *dev, DEVRES *device) 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; diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 2d558d93b7..ffcd90781e 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -165,8 +165,6 @@ typedef struct s_device { 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 */ diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index 4fdb287020..9279ca9155 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -105,8 +105,6 @@ static struct res_items dev_items[] = { {"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}, diff --git a/bacula/src/version.h b/bacula/src/version.h index da58822d23..2b1eb3cc19 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #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