From cbf3e60cb8c2d35d1cd3fe0ca05e8d087a310e07 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 26 May 2003 20:25:21 +0000 Subject: [PATCH] Clean up old structs in dird + remove Slot invalidation code git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@552 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 51 ++--- bacula/src/dird/dird_conf.h | 371 ++++++++++++++++---------------- bacula/src/dird/protos.h | 40 ++-- bacula/src/dird/ua_cmds.c | 10 +- bacula/src/dird/ua_restore.c | 6 +- bacula/src/dird/ua_run.c | 31 ++- bacula/src/dird/ua_select.c | 26 +-- bacula/src/dird/ua_status.c | 2 +- bacula/src/stored/acquire.c | 3 - bacula/src/stored/mount.c | 7 +- bacula/src/stored/read_record.c | 2 +- 11 files changed, 281 insertions(+), 268 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 9b70b938ec..fec3d93a0e 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -21,37 +21,25 @@ Testing to do: (painful) - multiple simultaneous Volumes - Test if rewind at end of tape waits for tape to rewind. - Test cancel at EOM. +- Test not zeroing Autochanger slot when it is wrong. - Figure out how to use ssh or stunnel to protect Bacula communications. For 1.31 release: -- If bootstrap is non-zero for restore, do not show JobId in the - OK to run? (yes/mod/no): list. +- Currently in mount.c:236 the SD simply creates a Volume. It should have + explicit permission to do so. It should also mark the tape in error + if there is an error. - The bsr for Dan's job has file indexes covering the whole range rather than only the range contained on the volume. Constrain FileIndex to be within range for Volume. -- Don't zero the Slot when the wrong volume is found -- simply ask - the operator. - Make sure all restore counters are working correctly in the FD. -- When all cassettes in magazine are used, got: - 22-May-2003 18:24 undef-sd: 3304 Autochanger "load slot 1" status is OK. - 22-May-2003 18:24 undef-sd: NightlySave.2003-05-22_14.08.16 Warning: mount.c:245 Director wanted Volume "TestVolume0009". - Current Volume "TestVolume0005" not acceptable because: - 1998 Volume "TestVolume0005" not Append or Recycle. - 22-May-2003 18:24 undef-sd: NightlySave.2003-05-22_14.08.16 Error: Autochanger Volume "TestVolume0009" not found in slot 1. - Setting slot to zero in catalog. - 22-May-2003 18:24 undef-sd: Please mount Volume "TestVolume0009" on Storage Device "ARCHIVE 4586" for Job NightlySave.2003-05-22_14 - .08.16 - Use "mount" command to release Job. - 22-May-2003 19:24 undef-sd: Please mount Volume "TestVolume0009" on Storage Device "ARCHIVE 4586" for Job NightlySave.2003-05-22_14 - .08.16 - Use "mount" command to release Job. - - SD Bytes Read is wrong. - Configure mtx-changer to have correct path to mtx. - Look at ALL higher level routines that call block.c to be sure they don't expect something in errmsg. + - Fix Verify VolumeToCatalog to use BSRs -- it is broken. + - Use switch() in backup.c and restore.c in FD instead of giant if statement. - Investigate doing RAW backup of Win32 partition. - Add JobName= to VerifyToCatalog so that all verifies can be done at the end. @@ -66,14 +54,9 @@ For 1.31 release: - Make restore more robust in counting error and not immediately bailing out. Also print error message once, but try to continue. - Add code to check that blocks are sequential on restore. -- File the Automatically selected: xxx - to say Automatically selected Pool: xxx - Should Bacula make an Append tape as Purged when purging? -- Shell expansion fails for working_directory in SD from time to time. - Possibly update all client records at startup. -- Implement MTIOCERRSTAT on FreeBSD to clear tape error conditions. - - Add Progress command that periodically reports the progress of a job or all jobs. - Implement "Reschedule OnError=yes interval=nnn times=xxx" @@ -913,4 +896,24 @@ Done: (see kernsdone for more) Building directory tree for JobId 74 ... 134645140 items inserted into the tree and marked for extraction. - Add SDWriteSeqNo to SD, and probably Read on FD side. - +- If bootstrap is non-zero for restore, do not show JobId in the + OK to run? (yes/mod/no): list. +- When all cassettes in magazine are used, got: + 22-May-2003 18:24 undef-sd: 3304 Autochanger "load slot 1" status is OK. + 22-May-2003 18:24 undef-sd: NightlySave.2003-05-22_14.08.16 Warning: mount.c:245 Director wanted Volume "TestVolume0009". + Current Volume "TestVolume0005" not acceptable because: + 1998 Volume "TestVolume0005" not Append or Recycle. + 22-May-2003 18:24 undef-sd: NightlySave.2003-05-22_14.08.16 Error: Autochanger Volume "TestVolume0009" not found in slot 1. + Setting slot to zero in catalog. + 22-May-2003 18:24 undef-sd: Please mount Volume "TestVolume0009" on Storage Device "ARCHIVE 4586" for Job NightlySave.2003-05-22_14 + .08.16 + Use "mount" command to release Job. + 22-May-2003 19:24 undef-sd: Please mount Volume "TestVolume0009" on Storage Device "ARCHIVE 4586" for Job NightlySave.2003-05-22_14 + .08.16 + Use "mount" command to release Job. +- Don't zero the Slot when the wrong volume is found -- simply ask + the operator. +- Implement MTIOCERRSTAT on FreeBSD to clear tape error conditions. +- Shell expansion fails for working_directory in SD from time to time. +- File the Automatically selected: xxx + to say Automatically selected Pool: xxx diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 14f47e98a4..62531405af 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -30,44 +30,44 @@ /* * Resource codes -- they must be sequential for indexing */ -#define R_FIRST 1001 - -#define R_DIRECTOR 1001 -#define R_CLIENT 1002 -#define R_JOB 1003 -#define R_STORAGE 1004 -#define R_CATALOG 1005 -#define R_SCHEDULE 1006 -#define R_FILESET 1007 -#define R_GROUP 1008 -#define R_POOL 1009 -#define R_MSGS 1010 -#define R_COUNTER 1011 -#define R_CONSOLE 1012 - -#define R_LAST R_CONSOLE +#define R_FIRST 1001 + +#define R_DIRECTOR 1001 +#define R_CLIENT 1002 +#define R_JOB 1003 +#define R_STORAGE 1004 +#define R_CATALOG 1005 +#define R_SCHEDULE 1006 +#define R_FILESET 1007 +#define R_GROUP 1008 +#define R_POOL 1009 +#define R_MSGS 1010 +#define R_COUNTER 1011 +#define R_CONSOLE 1012 + +#define R_LAST R_CONSOLE /* * Some resource attributes */ -#define R_NAME 1020 -#define R_ADDRESS 1021 -#define R_PASSWORD 1022 -#define R_TYPE 1023 -#define R_BACKUP 1024 +#define R_NAME 1020 +#define R_ADDRESS 1021 +#define R_PASSWORD 1022 +#define R_TYPE 1023 +#define R_BACKUP 1024 /* Used for certain KeyWord tables */ -struct s_kw { +struct s_kw { char *name; - int token; + int token; }; /* Job Level keyword structure */ struct s_jl { - char *level_name; /* level keyword */ - int level; /* level */ - int job_type; /* JobType permitting this level */ + char *level_name; /* level keyword */ + int level; /* level */ + int job_type; /* JobType permitting this level */ }; /* Job Type keyword structure */ @@ -77,151 +77,153 @@ struct s_jt { }; /* Definition of the contents of each Resource */ +/* Needed for forward references */ +struct SCHED; +struct CLIENT; +struct FILESET; +struct POOL; +struct RUN; /* - * Director Resource + * Director Resource * */ -struct s_res_dir { - RES hdr; - int DIRport; /* where we listen -- UA port server port */ - char *DIRaddr; /* bind address */ - char *password; /* Password for UA access */ - int enable_ssl; /* Use SSL for UA */ - char *query_file; /* SQL query file */ - char *working_directory; /* WorkingDirectory */ - char *pid_directory; /* PidDirectory */ - char *subsys_directory; /* SubsysDirectory */ - int require_ssl; /* Require SSL for all connections */ +struct DIRRES { + RES hdr; + int DIRport; /* where we listen -- UA port server port */ + char *DIRaddr; /* bind address */ + char *password; /* Password for UA access */ + int enable_ssl; /* Use SSL for UA */ + char *query_file; /* SQL query file */ + char *working_directory; /* WorkingDirectory */ + char *pid_directory; /* PidDirectory */ + char *subsys_directory; /* SubsysDirectory */ + int require_ssl; /* Require SSL for all connections */ struct s_res_msgs *messages; /* Daemon message handler */ - uint32_t MaxConcurrentJobs; /* Max concurrent jobs for whole director */ - utime_t FDConnectTimeout; /* timeout for connect in seconds */ - utime_t SDConnectTimeout; /* timeout in seconds */ + uint32_t MaxConcurrentJobs; /* Max concurrent jobs for whole director */ + utime_t FDConnectTimeout; /* timeout for connect in seconds */ + utime_t SDConnectTimeout; /* timeout in seconds */ }; -typedef struct s_res_dir DIRRES; /* * Console Resource */ -struct s_res_con { - RES hdr; - char *password; /* UA server password */ - int enable_ssl; /* Use SSL */ +struct CONRES { + RES hdr; + char *password; /* UA server password */ + int enable_ssl; /* Use SSL */ +}; + + +/* + * Catalog Resource + * + */ +struct CAT { + RES hdr; + + int db_port; /* Port -- not yet implemented */ + char *db_address; /* host name for remote access */ + char *db_socket; /* Socket for local access */ + char *db_password; + char *db_user; + char *db_name; }; -typedef struct s_res_con CONRES; /* * Client Resource * */ -struct s_res_client { - RES hdr; +struct CLIENT { + RES hdr; - int FDport; /* Where File daemon listens */ - int AutoPrune; /* Do automatic pruning? */ - utime_t FileRetention; /* file retention period in seconds */ - utime_t JobRetention; /* job retention period in seconds */ + int FDport; /* Where File daemon listens */ + int AutoPrune; /* Do automatic pruning? */ + utime_t FileRetention; /* file retention period in seconds */ + utime_t JobRetention; /* job retention period in seconds */ char *address; char *password; - struct s_res_cat *catalog; /* Catalog resource */ - uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */ - semlock_t sem; /* client semaphore */ - int enable_ssl; /* Use SSL */ + CAT *catalog; /* Catalog resource */ + uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */ + semlock_t sem; /* client semaphore */ + int enable_ssl; /* Use SSL */ }; -typedef struct s_res_client CLIENT; /* * Store Resource * */ -struct s_res_store { - RES hdr; +struct STORE { + RES hdr; - int SDport; /* port where Directors connect */ - int SDDport; /* data port for File daemon */ + int SDport; /* port where Directors connect */ + int SDDport; /* data port for File daemon */ char *address; char *password; char *media_type; char *dev_name; - int autochanger; /* set if autochanger */ - uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */ - semlock_t sem; /* storage semaphore */ - int enable_ssl; /* Use SSL */ + int autochanger; /* set if autochanger */ + uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */ + semlock_t sem; /* storage semaphore */ + int enable_ssl; /* Use SSL */ }; -typedef struct s_res_store STORE; - -/* - * Catalog Resource - * - */ -struct s_res_cat { - RES hdr; - int db_port; /* Port -- not yet implemented */ - char *db_address; /* host name for remote access */ - char *db_socket; /* Socket for local access */ - char *db_password; - char *db_user; - char *db_name; -}; -typedef struct s_res_cat CAT; /* * Job Resource * */ -struct s_res_job { - RES hdr; - - int JobType; /* job type (backup, verify, restore */ - int level; /* default backup/verify level */ - int RestoreJobId; /* What -- JobId to restore */ - char *RestoreWhere; /* Where on disk to restore -- directory */ - char *RestoreBootstrap; /* Bootstrap file */ - char *RunBeforeJob; /* Run program before Job */ - char *RunAfterJob; /* Run program after Job */ - char *WriteBootstrap; /* Where to write bootstrap Job updates */ - int replace; /* How (overwrite, ..) */ - utime_t MaxRunTime; /* max run time in seconds */ - utime_t MaxStartDelay; /* max start delay in seconds */ - int PrefixLinks; /* prefix soft links with Where path */ - int PruneJobs; /* Force pruning of Jobs */ - int PruneFiles; /* Force pruning of Files */ - int PruneVolumes; /* Force pruning of Volumes */ - int SpoolAttributes; /* Set to spool attributes in SD */ - uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */ +struct JOB { + RES hdr; + + int JobType; /* job type (backup, verify, restore */ + int level; /* default backup/verify level */ + int RestoreJobId; /* What -- JobId to restore */ + char *RestoreWhere; /* Where on disk to restore -- directory */ + char *RestoreBootstrap; /* Bootstrap file */ + char *RunBeforeJob; /* Run program before Job */ + char *RunAfterJob; /* Run program after Job */ + char *WriteBootstrap; /* Where to write bootstrap Job updates */ + int replace; /* How (overwrite, ..) */ + utime_t MaxRunTime; /* max run time in seconds */ + utime_t MaxStartDelay; /* max start delay in seconds */ + int PrefixLinks; /* prefix soft links with Where path */ + int PruneJobs; /* Force pruning of Jobs */ + int PruneFiles; /* Force pruning of Files */ + int PruneVolumes; /* Force pruning of Volumes */ + int SpoolAttributes; /* Set to spool attributes in SD */ + uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */ - struct s_res_msgs *messages; /* How and where to send messages */ - struct s_res_sch *schedule; /* When -- Automatic schedule */ - struct s_res_client *client; /* Who to backup */ - struct s_res_fs *fileset; /* What to backup -- Fileset */ - struct s_res_store *storage; /* Where is device -- Storage daemon */ - struct s_res_pool *pool; /* Where is media -- Media Pool */ - - semlock_t sem; /* Job semaphore */ + MSGS *messages; /* How and where to send messages */ + SCHED *schedule; /* When -- Automatic schedule */ + CLIENT *client; /* Who to backup */ + FILESET *fileset; /* What to backup -- Fileset */ + STORE *storage; /* Where is device -- Storage daemon */ + POOL *pool; /* Where is media -- Media Pool */ + + semlock_t sem; /* Job semaphore */ }; -typedef struct s_res_job JOB; #define MAX_FOPTS 30 struct s_fopts_item { - char opts[MAX_FOPTS]; /* options string */ - char *match; /* match string */ - char **base_list; /* list of base job names */ - int num_base; /* number of bases in list */ + char opts[MAX_FOPTS]; /* options string */ + char *match; /* match string */ + char **base_list; /* list of base job names */ + int num_base; /* number of bases in list */ }; typedef struct s_fopts_item FOPTS; /* This is either an include item or an exclude item */ struct s_incexc_item { - FOPTS *current_opts; /* points to current options structure */ - FOPTS **opts_list; /* options list */ - int num_opts; /* number of options items */ - char **name_list; /* filename list */ + FOPTS *current_opts; /* points to current options structure */ + FOPTS **opts_list; /* options list */ + int num_opts; /* number of options items */ + char **name_list; /* filename list */ int max_names; /* malloc'ed size of name list */ - int num_names; /* number of names in the list */ + int num_names; /* number of names in the list */ }; typedef struct s_incexc_item INCEXE; @@ -229,121 +231,114 @@ typedef struct s_incexc_item INCEXE; * FileSet Resource * */ -struct s_res_fs { - RES hdr; +struct FILESET { + RES hdr; - int finclude; /* Set if finclude/fexclude used */ - INCEXE **include_items; /* array of incexe structures */ - int num_includes; /* number in array */ + int finclude; /* Set if finclude/fexclude used */ + INCEXE **include_items; /* array of incexe structures */ + int num_includes; /* number in array */ INCEXE **exclude_items; int num_excludes; - int have_MD5; /* set if MD5 initialized */ - struct MD5Context md5c; /* MD5 of include/exclude */ - char MD5[30]; /* base 64 representation of MD5 */ + int have_MD5; /* set if MD5 initialized */ + struct MD5Context md5c; /* MD5 of include/exclude */ + char MD5[30]; /* base 64 representation of MD5 */ }; -typedef struct s_res_fs FILESET; /* * Schedule Resource * */ -struct s_res_sch { - RES hdr; +struct SCHED { + RES hdr; - struct s_run *run; + RUN *run; }; -typedef struct s_res_sch SCHED; /* * Group Resource (not used) * */ -struct s_res_group { - RES hdr; +struct GROUP { + RES hdr; }; -typedef struct s_res_group GROUP; /* * Counter Resource */ -struct s_res_counter { - RES hdr; +struct COUNTER { + RES hdr; - int32_t MinValue; /* Minimum value */ - int32_t MaxValue; /* Maximum value */ - int Global; /* global/local */ - char *WrapCounter; /* Wrap counter name */ + int32_t MinValue; /* Minimum value */ + int32_t MaxValue; /* Maximum value */ + int Global; /* global/local */ + char *WrapCounter; /* Wrap counter name */ }; -typedef struct s_res_counter COUNTER; /* * Pool Resource * */ -struct s_res_pool { - RES hdr; - - struct s_res_counter counter; /* Counter resources */ - char *pool_type; /* Pool type */ - char *label_format; /* Label format string */ - char *cleaning_prefix; /* Cleaning label prefix */ - int use_catalog; /* maintain catalog for media */ - int catalog_files; /* maintain file entries in catalog */ - int use_volume_once; /* write on volume only once */ - int accept_any_volume; /* accept any volume */ - int recycle_oldest_volume; /* recycle oldest volume */ - uint32_t max_volumes; /* max number of volumes */ - utime_t VolRetention; /* volume retention period in seconds */ - utime_t VolUseDuration; /* duration volume can be used */ - uint32_t MaxVolJobs; /* Maximum jobs on the Volume */ - uint32_t MaxVolFiles; /* Maximum files on the Volume */ - uint64_t MaxVolBytes; /* Maximum bytes on the Volume */ - int AutoPrune; /* default for pool auto prune */ - int Recycle; /* default for media recycle yes/no */ +struct POOL { + RES hdr; + + COUNTER counter; /* Counter resources */ + char *pool_type; /* Pool type */ + char *label_format; /* Label format string */ + char *cleaning_prefix; /* Cleaning label prefix */ + int use_catalog; /* maintain catalog for media */ + int catalog_files; /* maintain file entries in catalog */ + int use_volume_once; /* write on volume only once */ + int accept_any_volume; /* accept any volume */ + int recycle_oldest_volume; /* recycle oldest volume */ + uint32_t max_volumes; /* max number of volumes */ + utime_t VolRetention; /* volume retention period in seconds */ + utime_t VolUseDuration; /* duration volume can be used */ + uint32_t MaxVolJobs; /* Maximum jobs on the Volume */ + uint32_t MaxVolFiles; /* Maximum files on the Volume */ + uint64_t MaxVolBytes; /* Maximum bytes on the Volume */ + int AutoPrune; /* default for pool auto prune */ + int Recycle; /* default for media recycle yes/no */ }; -typedef struct s_res_pool POOL; /* Define the Union of all the above * resource structure definitions. */ -union u_res { - struct s_res_dir res_dir; - struct s_res_con res_con; - struct s_res_client res_client; - struct s_res_store res_store; - struct s_res_cat res_cat; - struct s_res_job res_job; - struct s_res_fs res_fs; - struct s_res_sch res_sch; - struct s_res_group res_group; - struct s_res_pool res_pool; - struct s_res_msgs res_msgs; - struct s_res_counter res_counter; +union URES { + DIRRES res_dir; + CONRES res_con; + CLIENT res_client; + STORE res_store; + CAT res_cat; + JOB res_job; + FILESET res_fs; + SCHED res_sch; + GROUP res_group; + POOL res_pool; + MSGS res_msgs; + COUNTER res_counter; RES hdr; }; -typedef union u_res URES; /* Run structure contained in Schedule Resource */ -struct s_run { - struct s_run *next; /* points to next run record */ - int level; /* level override */ +struct RUN { + RUN *next; /* points to next run record */ + int level; /* level override */ int job_type; - POOL *pool; /* Pool override */ - STORE *storage; /* Storage override */ - MSGS *msgs; /* Messages override */ + POOL *pool; /* Pool override */ + STORE *storage; /* Storage override */ + MSGS *msgs; /* Messages override */ char *since; int level_no; - int minute; /* minute to run job */ - time_t last_run; /* last time run */ - time_t next_run; /* next time to run */ + int minute; /* minute to run job */ + time_t last_run; /* last time run */ + time_t next_run; /* next time to run */ char hour[nbytes_for_bits(24)]; /* bit set for each hour */ char mday[nbytes_for_bits(31)]; /* bit set for each day of month */ char month[nbytes_for_bits(12)]; /* bit set for each month */ char wday[nbytes_for_bits(7)]; /* bit set for each day of the week */ char wpos[nbytes_for_bits(5)]; /* week position */ }; -typedef struct s_run RUN; diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 4c57e6f7bc..388511b0bf 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 int bget_dirmsg(BSOCK *bs); @@ -102,28 +102,28 @@ 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_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); +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 *automsg, 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); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index ac104bcadd..f39890d573 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -400,7 +400,7 @@ static int cancelcmd(UAContext *ua, char *cmd) } unlock_jcr_chain(); - if (do_prompt(ua, _("Choose Job to cancel"), JobName, sizeof(JobName)) < 0) { + if (do_prompt(ua, _("Job"), _("Choose Job to cancel"), JobName, sizeof(JobName)) < 0) { return 1; } if (njobs == 1) { @@ -628,7 +628,7 @@ static int updatecmd(UAContext *ua, char *cmd) add_prompt(ua, _("Volume parameters")); add_prompt(ua, _("Pool from resource")); add_prompt(ua, _("Slots from autochanger")); - switch (do_prompt(ua, _("Choose catalog item to update"), NULL, 0)) { + switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) { case 0: update_volume(ua); break; @@ -673,7 +673,7 @@ static int update_volume(UAContext *ua) add_prompt(ua, _("Slot")); add_prompt(ua, _("Volume Files")); add_prompt(ua, _("Done")); - switch (do_prompt(ua, _("Select parameter to modify"), NULL, 0)) { + switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { case 0: /* Volume Status */ /* Modify Volume Status */ bsendmsg(ua, _("Current Volume status is: %s\n"), mr.VolStatus); @@ -688,7 +688,7 @@ static int update_volume(UAContext *ua) add_prompt(ua, "Recycle"); } add_prompt(ua, "Read-Only"); - if (do_prompt(ua, _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) { + if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) { return 1; } bstrncpy(mr.VolStatus, ua->cmd, sizeof(mr.VolStatus)); @@ -1133,7 +1133,7 @@ static int setdebugcmd(UAContext *ua, char *cmd) add_prompt(ua, _("Storage")); add_prompt(ua, _("Client")); add_prompt(ua, _("All")); - switch(do_prompt(ua, _("Select daemon type to set debug level"), NULL, 0)) { + switch(do_prompt(ua, "", _("Select daemon type to set debug level"), NULL, 0)) { case 0: /* Director */ debug_level = level; break; diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 61c2556d7c..47bc7401f2 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -337,7 +337,7 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji) add_prompt(ua, list[i]); } done = 1; - switch (do_prompt(ua, "Select item: ", NULL, 0)) { + switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) { case -1: /* error */ return 0; case 0: /* list last 20 Jobs run */ @@ -403,7 +403,7 @@ static int user_select_jobids(UAContext *ua, JOBIDS *ji) if (!db_sql_query(ua->db, query, fileset_handler, (void *)ua)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); } - if (do_prompt(ua, _("Select FileSet resource"), + if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), fileset_name, sizeof(fileset_name)) < 0) { free_pool_memory(query); db_sql_query(ua->db, uar_del_temp, NULL, NULL); @@ -1307,7 +1307,7 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, JOBI } } UnlockRes(); - do_prompt(ua, _("Select Storage resource"), name, sizeof(name)); + do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)); ji->store = (STORE *)GetResWithName(R_STORAGE, name); if (!ji->store) { bsendmsg(ua, _("\nWarning. Unable to find Storage resource for\n" diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 957d6cc9d5..d72f18962a 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -402,7 +402,26 @@ When: %s\n"), } jcr->JobLevel = L_FULL; /* default level */ Dmsg1(20, "JobId to restore=%d\n", jcr->RestoreJobId); - bsendmsg(ua, _("Run Restore job\n\ + if (jcr->RestoreJobId == 0) { + bsendmsg(ua, _("Run Restore job\n\ +JobName: %s\n\ +Bootstrap: %s\n\ +Where: %s\n\ +Replace: %s\n\ +FileSet: %s\n\ +Client: %s\n\ +Storage: %s\n\ +When: %s\n"), + job->hdr.name, + NPRT(jcr->RestoreBootstrap), + jcr->RestoreWhere?jcr->RestoreWhere:NPRT(job->RestoreWhere), + replace, + jcr->fileset->hdr.name, + jcr->client->hdr.name, + jcr->store->hdr.name, + bstrutime(dt, sizeof(dt), jcr->sched_time)); + } else { + bsendmsg(ua, _("Run Restore job\n\ JobName: %s\n\ Bootstrap: %s\n\ Where: %s\n\ @@ -410,7 +429,6 @@ Replace: %s\n\ FileSet: %s\n\ Client: %s\n\ Storage: %s\n\ -JobId: %s\n\ When: %s\n"), job->hdr.name, NPRT(jcr->RestoreBootstrap), @@ -421,6 +439,7 @@ When: %s\n"), jcr->store->hdr.name, jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1), bstrutime(dt, sizeof(dt), jcr->sched_time)); + } break; default: bsendmsg(ua, _("Unknown Job Type=%d\n"), jcr->JobType); @@ -458,7 +477,7 @@ When: %s\n"), add_prompt(ua, _("Replace")); /* 8 */ add_prompt(ua, _("JobId")); /* 9 */ } - switch (do_prompt(ua, _("Select parameter to modify"), NULL, 0)) { + switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { case 0: /* Level */ if (jcr->JobType == JT_BACKUP) { @@ -468,7 +487,7 @@ When: %s\n"), add_prompt(ua, _("Incremental")); add_prompt(ua, _("Differential")); add_prompt(ua, _("Since")); - switch (do_prompt(ua, _("Select level"), NULL, 0)) { + switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { case 0: jcr->JobLevel = L_BASE; break; @@ -494,7 +513,7 @@ When: %s\n"), add_prompt(ua, _("Verify Catalog")); add_prompt(ua, _("Verify Volume")); add_prompt(ua, _("Verify Volume Data")); - switch (do_prompt(ua, _("Select level"), NULL, 0)) { + switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { case 0: jcr->JobLevel = L_VERIFY_INIT; break; @@ -615,7 +634,7 @@ When: %s\n"), for (i=0; ReplaceOptions[i].name; i++) { add_prompt(ua, ReplaceOptions[i].name); } - opt = do_prompt(ua, _("Select replace option"), NULL, 0); + opt = do_prompt(ua, "", _("Select replace option"), NULL, 0); if (opt >= 0) { jcr->replace = ReplaceOptions[opt].token; } diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 277a9e3fb8..b6ec85e84c 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -130,7 +130,7 @@ int do_keyword_prompt(UAContext *ua, char *msg, char **list) for (i=0; list[i]; i++) { add_prompt(ua, list[i]); } - return do_prompt(ua, msg, NULL, 0); + return do_prompt(ua, "", msg, NULL, 0); } @@ -148,7 +148,7 @@ STORE *select_storage_resource(UAContext *ua) add_prompt(ua, store->hdr.name); } UnlockRes(); - do_prompt(ua, _("Select Storage resource"), name, sizeof(name)); + do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)); store = (STORE *)GetResWithName(R_STORAGE, name); return store; } @@ -167,7 +167,7 @@ FILESET *select_fileset_resource(UAContext *ua) add_prompt(ua, fs->hdr.name); } UnlockRes(); - do_prompt(ua, _("Select FileSet resource"), name, sizeof(name)); + do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)); fs = (FILESET *)GetResWithName(R_FILESET, name); return fs; } @@ -195,7 +195,7 @@ CAT *get_catalog_resource(UAContext *ua) add_prompt(ua, catalog->hdr.name); } UnlockRes(); - do_prompt(ua, _("Select Catalog resource"), name, sizeof(name)); + do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)); catalog = (CAT *)GetResWithName(R_CATALOG, name); } return catalog; @@ -216,7 +216,7 @@ JOB *select_job_resource(UAContext *ua) add_prompt(ua, job->hdr.name); } UnlockRes(); - do_prompt(ua, _("Select Job resource"), name, sizeof(name)); + do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)); job = (JOB *)GetResWithName(R_JOB, name); return job; } @@ -237,7 +237,7 @@ JOB *select_restore_job_resource(UAContext *ua) } } UnlockRes(); - do_prompt(ua, _("Select Restore Job"), name, sizeof(name)); + do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)); job = (JOB *)GetResWithName(R_JOB, name); return job; } @@ -258,7 +258,7 @@ CLIENT *select_client_resource(UAContext *ua) add_prompt(ua, client->hdr.name); } UnlockRes(); - do_prompt(ua, _("Select Client (File daemon) resource"), name, sizeof(name)); + do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)); client = (CLIENT *)GetResWithName(R_CLIENT, name); return client; } @@ -356,7 +356,7 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr) add_prompt(ua, ocr.Name); } free(ids); - if (do_prompt(ua, _("Select the Client"), name, sizeof(name)) < 0) { + if (do_prompt(ua, _("Client"), _("Select the Client"), name, sizeof(name)) < 0) { return 0; } memset(&ocr, 0, sizeof(ocr)); @@ -438,7 +438,7 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr) add_prompt(ua, opr.Name); } free(ids); - if (do_prompt(ua, _("Select the Pool"), name, sizeof(name)) < 0) { + if (do_prompt(ua, _("Pool"), _("Select the Pool"), name, sizeof(name)) < 0) { return 0; } memset(&opr, 0, sizeof(opr)); @@ -522,7 +522,7 @@ POOL *select_pool_resource(UAContext *ua) add_prompt(ua, pool->hdr.name); } UnlockRes(); - do_prompt(ua, _("Select Pool resource"), name, sizeof(name)); + do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)); pool = (POOL *)GetResWithName(R_POOL, name); return pool; } @@ -645,7 +645,7 @@ void add_prompt(UAContext *ua, char *prompt) * index base 0 on success, and choice * is copied to prompt if not NULL */ -int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt) +int do_prompt(UAContext *ua, char *automsg, char *msg, char *prompt, int max_prompt) { int i, item; char pmsg[MAXSTRING]; @@ -655,7 +655,7 @@ int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt) if (prompt) { bstrncpy(prompt, ua->prompt[1], max_prompt); } - bsendmsg(ua, _("Automatically selected: %s\n"), ua->prompt[1]); + bsendmsg(ua, _("Automatically selected %s: %s\n"), automsg, ua->prompt[1]); goto done; } bsendmsg(ua, ua->prompt[0]); @@ -816,5 +816,5 @@ int get_media_type(UAContext *ua, char *MediaType, int max_media) add_prompt(ua, store->media_type); } UnlockRes(); - return (do_prompt(ua, _("Select the Media Type"), MediaType, max_media) < 0) ? 0 : 1; + return (do_prompt(ua, _("Media Type"), _("Select the Media Type"), MediaType, max_media) < 0) ? 0 : 1; } diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 3969f4556c..4340034ba4 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -84,7 +84,7 @@ int statuscmd(UAContext *ua, char *cmd) add_prompt(ua, _("Client")); add_prompt(ua, _("All")); Dmsg0(20, "do_prompt: select daemon\n"); - if ((item=do_prompt(ua, _("Select daemon type for status"), cmd, MAX_NAME_LENGTH)) < 0) { + if ((item=do_prompt(ua, "", _("Select daemon type for status"), cmd, MAX_NAME_LENGTH)) < 0) { return 1; } Dmsg1(20, "item=%d\n", item); diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 7e92fed826..fac5985531 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -107,9 +107,6 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); default_path: tape_previously_mounted = 1; - if (autochanger) { - invalidate_slot_in_catalog(jcr); - } Dmsg0(200, "dir_get_volume_info\n"); if (!dir_get_volume_info(jcr, 0)) { Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index e02f791944..609fea59e8 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -148,6 +148,7 @@ mount_next_vol: release = 1; /* release next time if we "recurse" */ +ask_again: if (ask && !dir_ask_sysop_to_mount_next_volume(jcr, dev)) { Dmsg0(100, "Error return ask_sysop ...\n"); return 0; /* error return */ @@ -243,11 +244,9 @@ read_volume: mount_error: /* Send error message */ Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); - if (autochanger) { - invalidate_slot_in_catalog(jcr); - } Dmsg0(100, "Default\n"); - goto mount_next_vol; + ask = 1; + goto ask_again; } break; } diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index 323b05d918..d2287dea60 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -61,7 +61,7 @@ int read_records(JCR *jcr, DEVICE *dev, if (dev->state & ST_EOT) { DEV_RECORD *trec = new_record(); - Pmsg3(000, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), + Dmsg3(100, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), block->BlockNumber, rec->remainder); if (!mount_cb(jcr, dev, block)) { Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), -- 2.39.5