From 13bba8315847b06f69a9e6f2768a5bfb0d5ebbb2 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 16 Jun 2003 16:20:47 +0000 Subject: [PATCH] Add Environment arrays + Rescheduling of jobs + cancel FD when blocked on SD write git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@582 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ReleaseNotes | 2 + bacula/kernstodo | 14 +- bacula/src/baconfig.h | 2 +- bacula/src/dird/backup.c | 7 - bacula/src/dird/bacula-dir.conf.in | 13 +- bacula/src/dird/dird_conf.c | 700 ++++++++++++++-------------- bacula/src/dird/dird_conf.h | 3 + bacula/src/dird/job.c | 236 ++++++---- bacula/src/dird/newvol.c | 63 ++- bacula/src/dird/ua_cmds.c | 1 - bacula/src/dird/ua_output.c | 1 - bacula/src/dird/ua_server.c | 1 - bacula/src/filed/job.c | 9 + bacula/src/jcr.h | 5 +- bacula/src/lib/bnet.c | 15 +- bacula/src/lib/btime.c | 3 +- bacula/src/lib/btime.h | 40 +- bacula/src/lib/jcr.c | 4 +- bacula/src/lib/mem_pool.c | 31 +- bacula/src/lib/mem_pool.h | 23 +- bacula/src/stored/bacula-sd.conf.in | 23 +- bacula/src/stored/device.c | 10 +- bacula/src/version.h | 4 +- 23 files changed, 641 insertions(+), 569 deletions(-) diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index ec16a51d78..55bab38cd1 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -48,6 +48,8 @@ Other Changes this Release: Items to note: !!!!! +- The default time interval is now days instead of seconds. Please + check your .conf files! - For MySQL users, you must have the thread safe client libraries available. If you build MySQL yourself, add the --enable-thread-safe-client option on the ./configure. You will most likely need to do an ldconfig. diff --git a/bacula/kernstodo b/bacula/kernstodo index dfec9674b7..ec97e8ec6b 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -26,18 +26,15 @@ Testing to do: (painful) - Test cancel at EOM. - Test not zeroing Autochanger slot when it is wrong. - Test multiple simultaneous Volumes -- That restoring a hard link that already exists works correctly. - Same for soft link. - Test of last block is correct in JobMedia when splitting file over two volumes. - Figure out how to use ssh or stunnel to protect Bacula communications. For 1.31 release: +- Move JobFiles and JobBytes to SD rather than FD -- more correct. - Add client name to cram-md5 challenge so Director can immediately verify if it is the correct client. -- Implement a record that suppresses errors if the Client is not - available. - Use runbeforejob to unload, then reload a volume previously used, then the next job run gets an error reading the drive. - Implement non-blocking writes and bsock->terminate in heartbeat thread, @@ -54,7 +51,6 @@ For 1.31 release: (Phil's problem). - Add next Volume to be used to status output. - Make bootstrap filename unique. -- Sort JobIds entered into recover tree. - 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. @@ -86,7 +82,6 @@ For 1.31 release: - Prohibit backing up archive device (findlib/find_one.c:128) - Make Restore report an error if FD or SD term codes are not OK. - Add JobLevel in FD status (but make sure it is defined). -- Make Pool resource handle Counter resources. - Restrict characters permitted in a Resource name, and don't permit duplicate names. - Implement new serialize subroutines @@ -118,7 +113,6 @@ After 1.31: - Add Progress command that periodically reports the progress of a job or all jobs. -- Implement "Reschedule OnError=yes interval=nnn times=xxx" - One block was orphaned in the SD probably after cancel. - Add all command line arguments to "update", e.g. slot=nn volStatus=append, ... @@ -981,3 +975,9 @@ Done: (see kernsdone for more) Do lstat() to see if it is already properly linked. Same for symlinked file. Make sure ifnewer, ifolder, never, ... apply correctly. +- Flag so that no connect does not error, and Reschedule a job. +- Implement "Reschedule OnError=yes interval=nnn times=xxx" +- That restoring a hard link that already exists works correctly. + Same for soft link. +- Make Pool resource handle Counter resources. + diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index be964a624f..e003c9394a 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -71,7 +71,7 @@ #define MAXSTRING 500 /* Maximum length to edit time/date */ -#define MAX_TIME_LENGTH 30 +#define MAX_TIME_LENGTH 50 /* Maximum Name length including EOS */ #define MAX_NAME_LENGTH 128 diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index e9151ec85b..a96206f4ce 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -232,8 +232,6 @@ int do_backup(JCR *jcr) case L_DIFFERENTIAL: case L_INCREMENTAL: bnet_fsend(fd, levelcmd, "since ", jcr->stime, 0); - free_pool_memory(jcr->stime); - jcr->stime = NULL; break; case L_SINCE: default: @@ -258,13 +256,8 @@ int do_backup(JCR *jcr) return 1; bail_out: - if (jcr->stime) { - free_pool_memory(jcr->stime); - jcr->stime = NULL; - } backup_cleanup(jcr, JS_ErrorTerminated, since, &fsr); return 0; - } /* diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index a51ab2b870..7b84639831 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -143,23 +143,14 @@ 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 +# Name = DDS-4 # 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 +# Device = DDS-4 # must be same as Device in Storage daemon # Media Type = DDS-4 # must be same as MediaType in Storage daemon #} diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index d485ffb042..2dd78efde9 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -8,14 +8,14 @@ * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and - * lib/parse_config.h. - * These files contain the parser code, some utility - * routines, and the common store routines (name, int, - * string). + * lib/parse_config.h. + * These files contain the parser code, some utility + * routines, and the common store routines (name, int, + * string). * * 3. The daemon specific file, which contains the Resource - * definitions as well as any specific store routines - * for the resource records. + * definitions as well as any specific store routines + * for the resource records. * * Kern Sibbald, January MM * @@ -83,7 +83,7 @@ int res_all_size = sizeof(res_all); /* * Director Resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items dir_items[] = { {"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -107,7 +107,7 @@ static struct res_items dir_items[] = { /* * Console Resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items con_items[] = { {"name", store_name, ITEM(res_con.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -121,7 +121,7 @@ static struct res_items con_items[] = { /* * Client or File daemon resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items cli_items[] = { @@ -141,7 +141,7 @@ static struct res_items cli_items[] = { /* Storage daemon resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items store_items[] = { {"name", store_name, ITEM(res_store.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -161,7 +161,7 @@ static struct res_items store_items[] = { /* * Catalog Resource Directives * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items cat_items[] = { {"name", store_name, ITEM(res_cat.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -180,7 +180,7 @@ static struct res_items cat_items[] = { /* * Job Resource Directives * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items job_items[] = { {"name", store_name, ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -197,7 +197,7 @@ static struct res_items job_items[] = { {"client", store_res, ITEM(res_job.client), R_CLIENT, 0, 0}, {"fileset", store_res, ITEM(res_job.fileset), R_FILESET, 0, 0}, {"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0}, - {"replace", store_replace, ITEM(res_job.replace), REPLACE_ALWAYS, ITEM_DEFAULT, 0}, + {"replace", store_replace, ITEM(res_job.replace), 0, ITEM_DEFAULT, REPLACE_ALWAYS}, {"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0}, {"maxruntime", store_time, ITEM(res_job.MaxRunTime), 0, 0, 0}, {"maxstartdelay", store_time,ITEM(res_job.MaxStartDelay), 0, 0, 0}, @@ -210,12 +210,15 @@ static struct res_items job_items[] = { {"spoolattributes", store_yesno, ITEM(res_job.SpoolAttributes), 1, ITEM_DEFAULT, 0}, {"writebootstrap", store_dir, ITEM(res_job.WriteBootstrap), 0, 0, 0}, {"maximumconcurrentjobs", store_pint, ITEM(res_job.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1}, + {"rescheduleonerror", store_yesno, ITEM(res_job.RescheduleOnError), 1, ITEM_DEFAULT, 0}, + {"rescheduleinterval", store_time, ITEM(res_job.RescheduleInterval), 0, ITEM_DEFAULT, 60 * 30}, + {"rescheduletimes", store_pint, ITEM(res_job.RescheduleTimes), 0, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; /* FileSet resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items fs_items[] = { {"name", store_name, ITEM(res_fs.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -224,13 +227,13 @@ static struct res_items fs_items[] = { {"finclude", store_finc, NULL, 0, ITEM_NO_EQUALS, 0}, {"exclude", store_inc, NULL, 1, 0, 0}, {"fexclude", store_finc, NULL, 1, ITEM_NO_EQUALS, 0}, - {NULL, NULL, NULL, 0, 0, 0} + {NULL, NULL, NULL, 0, 0, 0} }; /* Schedule -- see run_conf.c */ /* Schedule * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items sch_items[] = { {"name", store_name, ITEM(res_sch.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -241,7 +244,7 @@ static struct res_items sch_items[] = { /* Group resource -- not implemented * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items group_items[] = { {"name", store_name, ITEM(res_group.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -251,7 +254,7 @@ static struct res_items group_items[] = { /* Pool resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items pool_items[] = { {"name", store_name, ITEM(res_pool.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -277,7 +280,7 @@ static struct res_items pool_items[] = { /* * Counter Resource - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items counter_items[] = { {"name", store_name, ITEM(res_counter.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -297,7 +300,7 @@ extern struct res_items msgs_items[]; * This is the master resource definition. * It must have one item for each of the resources. * - * name items rcode res_head + * name items rcode res_head */ struct s_res resources[] = { {"director", dir_items, R_DIRECTOR, NULL}, @@ -312,13 +315,13 @@ struct s_res resources[] = { {"pool", pool_items, R_POOL, NULL}, {"messages", msgs_items, R_MSGS, NULL}, {"counter", counter_items, R_COUNTER, NULL}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} }; /* Keywords (RHS) permitted in Job Level records * - * level_name level job_type + * level_name level job_type */ struct s_jl joblevels[] = { {"Full", L_FULL, JT_BACKUP}, @@ -330,19 +333,19 @@ struct s_jl joblevels[] = { {"Initcatalog", L_VERIFY_INIT, JT_VERIFY}, {"VolumeToCatalog", L_VERIFY_VOLUME_TO_CATALOG, JT_VERIFY}, {"Data", L_VERIFY_DATA, JT_VERIFY}, - {NULL, 0} + {NULL, 0} }; /* Keywords (RHS) permitted in Job type records * - * type_name job_type + * type_name job_type */ struct s_jt jobtypes[] = { {"backup", JT_BACKUP}, {"admin", JT_ADMIN}, {"verify", JT_VERIFY}, {"restore", JT_RESTORE}, - {NULL, 0} + {NULL, 0} }; @@ -351,7 +354,7 @@ static struct s_kw BakVerFields[] = { {"client", 'C'}, {"fileset", 'F'}, {"level", 'L'}, - {NULL, 0} + {NULL, 0} }; /* Keywords (RHS) permitted in Restore records */ @@ -362,7 +365,7 @@ static struct s_kw RestoreFields[] = { {"where", 'W'}, /* root of restore */ {"replace", 'R'}, /* replacement options */ {"bootstrap", 'B'}, /* bootstrap file */ - {NULL, 0} + {NULL, 0} }; /* Options permitted in Restore replace= */ @@ -371,7 +374,7 @@ struct s_kw ReplaceOptions[] = { {"ifnewer", REPLACE_IFNEWER}, {"ifolder", REPLACE_IFOLDER}, {"never", REPLACE_NEVER}, - {NULL, 0} + {NULL, 0} }; char *level_to_str(int level) @@ -383,8 +386,8 @@ char *level_to_str(int level) sprintf(level_no, "%d", level); /* default if not found */ for (i=0; joblevels[i].level_name; i++) { if (level == joblevels[i].level) { - str = joblevels[i].level_name; - break; + str = joblevels[i].level_name; + break; } } return str; @@ -395,90 +398,93 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... { URES *res = (URES *)reshdr; int recurse = 1; + char ed1[30], ed2[30]; if (res == NULL) { sendit(sock, "No %s resource defined\n", res_to_str(type)); return; } - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { case R_DIRECTOR: - char ed1[30], ed2[30]; sendit(sock, "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n", - reshdr->name, res->res_dir.MaxConcurrentJobs, - edit_uint64(res->res_dir.FDConnectTimeout, ed1), - edit_uint64(res->res_dir.SDConnectTimeout, ed2)); + reshdr->name, res->res_dir.MaxConcurrentJobs, + edit_uint64(res->res_dir.FDConnectTimeout, ed1), + edit_uint64(res->res_dir.SDConnectTimeout, ed2)); if (res->res_dir.query_file) { sendit(sock, " query_file=%s\n", res->res_dir.query_file); } if (res->res_dir.messages) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock); + dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock); } break; case R_CONSOLE: sendit(sock, "Console: name=%s SSL=%d\n", - res->res_con.hdr.name, res->res_con.enable_ssl); + res->res_con.hdr.name, res->res_con.enable_ssl); break; case R_COUNTER: sendit(sock, "Counter: name=%s min=%d max=%d\n", - res->res_counter.hdr.name, res->res_counter.MinValue, - res->res_counter.MaxValue); + res->res_counter.hdr.name, res->res_counter.MinValue, + res->res_counter.MaxValue); if (res->res_counter.Catalog) { sendit(sock, " --> "); - dump_resource(-R_CATALOG, (RES *)res->res_counter.Catalog, sendit, sock); + dump_resource(-R_CATALOG, (RES *)res->res_counter.Catalog, sendit, sock); } if (res->res_counter.WrapCounter) { sendit(sock, " --> "); - dump_resource(-R_COUNTER, (RES *)res->res_counter.WrapCounter, sendit, sock); + dump_resource(-R_COUNTER, (RES *)res->res_counter.WrapCounter, sendit, sock); } - break; + break; case R_CLIENT: sendit(sock, "Client: name=%s address=%s FDport=%d MaxJobs=%u\n", - res->res_client.hdr.name, res->res_client.address, res->res_client.FDport, - res->res_client.MaxConcurrentJobs); + res->res_client.hdr.name, res->res_client.address, res->res_client.FDport, + res->res_client.MaxConcurrentJobs); sendit(sock, " JobRetention=%" lld " FileRetention=%" lld " AutoPrune=%d\n", - res->res_client.JobRetention, res->res_client.FileRetention, - res->res_client.AutoPrune); + res->res_client.JobRetention, res->res_client.FileRetention, + res->res_client.AutoPrune); if (res->res_client.catalog) { sendit(sock, " --> "); - dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock); + dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock); } break; case R_STORAGE: sendit(sock, "Storage: name=%s address=%s SDport=%d MaxJobs=%u\n\ DeviceName=%s MediaType=%s\n", - res->res_store.hdr.name, res->res_store.address, res->res_store.SDport, - res->res_store.MaxConcurrentJobs, - res->res_store.dev_name, res->res_store.media_type); + res->res_store.hdr.name, res->res_store.address, res->res_store.SDport, + res->res_store.MaxConcurrentJobs, + res->res_store.dev_name, res->res_store.media_type); break; case R_CATALOG: sendit(sock, "Catalog: name=%s address=%s DBport=%d db_name=%s\n\ db_user=%s\n", - res->res_cat.hdr.name, NPRT(res->res_cat.db_address), - res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user)); + res->res_cat.hdr.name, NPRT(res->res_cat.db_address), + res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user)); break; case R_JOB: sendit(sock, "Job: name=%s JobType=%d level=%s MaxJobs=%u\n", - res->res_job.hdr.name, res->res_job.JobType, - level_to_str(res->res_job.level), res->res_job.MaxConcurrentJobs); + res->res_job.hdr.name, res->res_job.JobType, + level_to_str(res->res_job.level), res->res_job.MaxConcurrentJobs); + sendit(sock, " Resched=%d Times=%d Interval=%s\n", + res->res_job.RescheduleOnError, res->res_job.RescheduleTimes, + edit_uint64_with_commas(res->res_job.RescheduleInterval, ed1)); if (res->res_job.client) { sendit(sock, " --> "); - dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock); + dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock); } if (res->res_job.fileset) { sendit(sock, " --> "); - dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock); + dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock); } if (res->res_job.schedule) { sendit(sock, " --> "); - dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock); + dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock); } if (res->res_job.RestoreWhere) { sendit(sock, " --> Where=%s\n", NPRT(res->res_job.RestoreWhere)); @@ -497,108 +503,108 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... } if (res->res_job.storage) { sendit(sock, " --> "); - dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock); + dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock); } if (res->res_job.pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock); + dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock); } else { sendit(sock, "!!! No Pool resource\n"); } if (res->res_job.messages) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock); + dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock); } break; case R_FILESET: sendit(sock, "FileSet: name=%s\n", res->res_fs.hdr.name); for (int i=0; ires_fs.num_includes; i++) { - INCEXE *incexe = res->res_fs.include_items[i]; - for (int j=0; jnum_names; j++) { + INCEXE *incexe = res->res_fs.include_items[i]; + for (int j=0; jnum_names; j++) { sendit(sock, " Inc: %s\n", incexe->name_list[j]); - } + } } for (int i=0; ires_fs.num_excludes; i++) { - INCEXE *incexe = res->res_fs.exclude_items[i]; - for (int j=0; jnum_names; j++) { + INCEXE *incexe = res->res_fs.exclude_items[i]; + for (int j=0; jnum_names; j++) { sendit(sock, " Exc: %s\n", incexe->name_list[j]); - } + } } break; case R_SCHEDULE: if (res->res_sch.run) { - int i; - RUN *run = res->res_sch.run; - char buf[1000], num[10]; + int i; + RUN *run = res->res_sch.run; + char buf[1000], num[10]; sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); - if (!run) { - break; - } + if (!run) { + break; + } next_run: sendit(sock, " --> Run Level=%s\n", level_to_str(run->level)); strcpy(buf, " hour="); - for (i=0; i<24; i++) { - if (bit_is_set(i, run->hour)) { + for (i=0; i<24; i++) { + if (bit_is_set(i, run->hour)) { sprintf(num, "%d ", i); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " mday="); - for (i=0; i<31; i++) { - if (bit_is_set(i, run->mday)) { + for (i=0; i<31; i++) { + if (bit_is_set(i, run->mday)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " month="); - for (i=0; i<12; i++) { - if (bit_is_set(i, run->month)) { + for (i=0; i<12; i++) { + if (bit_is_set(i, run->month)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " wday="); - for (i=0; i<7; i++) { - if (bit_is_set(i, run->wday)) { + for (i=0; i<7; i++) { + if (bit_is_set(i, run->wday)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " wpos="); - for (i=0; i<5; i++) { - if (bit_is_set(i, run->wpos)) { + for (i=0; i<5; i++) { + if (bit_is_set(i, run->wpos)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); sendit(sock, " mins=%d\n", run->minute); - if (run->pool) { + if (run->pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)run->pool, sendit, sock); - } - if (run->storage) { + dump_resource(-R_POOL, (RES *)run->pool, sendit, sock); + } + if (run->storage) { sendit(sock, " --> "); - dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock); - } - if (run->msgs) { + dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock); + } + if (run->msgs) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock); - } - /* If another Run record is chained in, go print it */ - if (run->next) { - run = run->next; - goto next_run; - } + dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock); + } + /* If another Run record is chained in, go print it */ + if (run->next) { + run = run->next; + goto next_run; + } } else { sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); } @@ -608,20 +614,20 @@ next_run: break; case R_POOL: sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name, - res->res_pool.pool_type); + res->res_pool.pool_type); sendit(sock, " use_cat=%d use_once=%d acpt_any=%d cat_files=%d\n", - res->res_pool.use_catalog, res->res_pool.use_volume_once, - res->res_pool.accept_any_volume, res->res_pool.catalog_files); + res->res_pool.use_catalog, res->res_pool.use_volume_once, + res->res_pool.accept_any_volume, res->res_pool.catalog_files); sendit(sock, " max_vols=%d auto_prune=%d VolRetention=%" lld "\n", - res->res_pool.max_volumes, res->res_pool.AutoPrune, - res->res_pool.VolRetention); + res->res_pool.max_volumes, res->res_pool.AutoPrune, + res->res_pool.VolRetention); sendit(sock, " recycle=%d LabelFormat=%s\n", res->res_pool.Recycle, - NPRT(res->res_pool.label_format)); + NPRT(res->res_pool.label_format)); sendit(sock, " CleaningPrefix=%s\n", - NPRT(res->res_pool.cleaning_prefix)); + NPRT(res->res_pool.cleaning_prefix)); sendit(sock, " recyleOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n", - res->res_pool.recycle_oldest_volume, - res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles); + res->res_pool.recycle_oldest_volume, + res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles); break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); @@ -653,13 +659,13 @@ static void free_incexe(INCEXE *incexe) for (int i=0; inum_opts; i++) { FOPTS *fopt = incexe->opts_list[i]; if (fopt->match) { - free(fopt->match); + free(fopt->match); } for (int j=0; jnum_base; j++) { - free(fopt->base_list[j]); + free(fopt->base_list[j]); } if (fopt->base_list) { - free(fopt->base_list); + free(fopt->base_list); } free(fopt); } @@ -700,130 +706,130 @@ void free_resource(int type) switch (type) { case R_DIRECTOR: if (res->res_dir.working_directory) { - free(res->res_dir.working_directory); + free(res->res_dir.working_directory); } if (res->res_dir.pid_directory) { - free(res->res_dir.pid_directory); + free(res->res_dir.pid_directory); } if (res->res_dir.subsys_directory) { - free(res->res_dir.subsys_directory); + free(res->res_dir.subsys_directory); } if (res->res_dir.password) { - free(res->res_dir.password); + free(res->res_dir.password); } if (res->res_dir.query_file) { - free(res->res_dir.query_file); + free(res->res_dir.query_file); } if (res->res_dir.DIRaddr) { - free(res->res_dir.DIRaddr); + free(res->res_dir.DIRaddr); } break; case R_COUNTER: break; case R_CONSOLE: if (res->res_con.password) { - free(res->res_con.password); + free(res->res_con.password); } break; case R_CLIENT: if (res->res_client.address) { - free(res->res_client.address); + free(res->res_client.address); } if (res->res_client.password) { - free(res->res_client.password); + free(res->res_client.password); } break; case R_STORAGE: if (res->res_store.address) { - free(res->res_store.address); + free(res->res_store.address); } if (res->res_store.password) { - free(res->res_store.password); + free(res->res_store.password); } if (res->res_store.media_type) { - free(res->res_store.media_type); + free(res->res_store.media_type); } if (res->res_store.dev_name) { - free(res->res_store.dev_name); + free(res->res_store.dev_name); } break; case R_CATALOG: if (res->res_cat.db_address) { - free(res->res_cat.db_address); + free(res->res_cat.db_address); } if (res->res_cat.db_socket) { - free(res->res_cat.db_socket); + free(res->res_cat.db_socket); } if (res->res_cat.db_user) { - free(res->res_cat.db_user); + free(res->res_cat.db_user); } if (res->res_cat.db_name) { - free(res->res_cat.db_name); + free(res->res_cat.db_name); } if (res->res_cat.db_password) { - free(res->res_cat.db_password); + free(res->res_cat.db_password); } break; case R_FILESET: if ((num=res->res_fs.num_includes)) { - while (--num >= 0) { - free_incexe(res->res_fs.include_items[num]); - } - free(res->res_fs.include_items); + while (--num >= 0) { + free_incexe(res->res_fs.include_items[num]); + } + free(res->res_fs.include_items); } res->res_fs.num_includes = 0; if ((num=res->res_fs.num_excludes)) { - while (--num >= 0) { - free_incexe(res->res_fs.exclude_items[num]); - } - free(res->res_fs.exclude_items); + while (--num >= 0) { + free_incexe(res->res_fs.exclude_items[num]); + } + free(res->res_fs.exclude_items); } res->res_fs.num_excludes = 0; break; case R_POOL: if (res->res_pool.pool_type) { - free(res->res_pool.pool_type); + free(res->res_pool.pool_type); } if (res->res_pool.label_format) { - free(res->res_pool.label_format); + free(res->res_pool.label_format); } if (res->res_pool.cleaning_prefix) { - free(res->res_pool.cleaning_prefix); + free(res->res_pool.cleaning_prefix); } break; case R_SCHEDULE: if (res->res_sch.run) { - RUN *nrun, *next; - nrun = res->res_sch.run; - while (nrun) { - next = nrun->next; - free(nrun); - nrun = next; - } + RUN *nrun, *next; + nrun = res->res_sch.run; + while (nrun) { + next = nrun->next; + free(nrun); + nrun = next; + } } break; case R_JOB: if (res->res_job.RestoreWhere) { - free(res->res_job.RestoreWhere); + free(res->res_job.RestoreWhere); } if (res->res_job.RestoreBootstrap) { - free(res->res_job.RestoreBootstrap); + free(res->res_job.RestoreBootstrap); } if (res->res_job.WriteBootstrap) { - free(res->res_job.WriteBootstrap); + free(res->res_job.WriteBootstrap); } if (res->res_job.RunBeforeJob) { - free(res->res_job.RunBeforeJob); + free(res->res_job.RunBeforeJob); } if (res->res_job.RunAfterJob) { - free(res->res_job.RunAfterJob); + free(res->res_job.RunAfterJob); } break; case R_MSGS: if (res->res_msgs.mail_cmd) - free(res->res_msgs.mail_cmd); + free(res->res_msgs.mail_cmd); if (res->res_msgs.operator_cmd) - free(res->res_msgs.operator_cmd); + free(res->res_msgs.operator_cmd); free_msgs_res((MSGS *)res); /* free message resource */ res = NULL; break; @@ -860,10 +866,10 @@ void save_resource(int type, struct res_items *items, int pass) */ for (i=0; items[i].name; i++) { if (items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { + if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n", - items[i].name, resources[rindex]); - } + items[i].name, resources[rindex]); + } } /* If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { @@ -886,83 +892,83 @@ void save_resource(int type, struct res_items *items, int pass) case R_POOL: case R_MSGS: case R_FILESET: - break; + break; /* Resources containing another resource */ case R_DIRECTOR: - if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name); - } - res->res_dir.messages = res_all.res_dir.messages; - break; + } + res->res_dir.messages = res_all.res_dir.messages; + break; case R_JOB: - if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Job resource %s\n", res_all.res_dir.hdr.name); - } - res->res_job.messages = res_all.res_job.messages; - res->res_job.schedule = res_all.res_job.schedule; - res->res_job.client = res_all.res_job.client; - res->res_job.fileset = res_all.res_job.fileset; - res->res_job.storage = res_all.res_job.storage; - res->res_job.pool = res_all.res_job.pool; - if (res->res_job.JobType == 0) { + } + res->res_job.messages = res_all.res_job.messages; + res->res_job.schedule = res_all.res_job.schedule; + res->res_job.client = res_all.res_job.client; + res->res_job.fileset = res_all.res_job.fileset; + res->res_job.storage = res_all.res_job.storage; + res->res_job.pool = res_all.res_job.pool; + if (res->res_job.JobType == 0) { Emsg1(M_ERROR_TERM, 0, "Job Type not defined for Job resource %s\n", res_all.res_dir.hdr.name); - } - if (res->res_job.level != 0) { - int i; - for (i=0; joblevels[i].level_name; i++) { - if (joblevels[i].level == res->res_job.level && - joblevels[i].job_type == res->res_job.JobType) { - i = 0; - break; - } - } - if (i != 0) { + } + if (res->res_job.level != 0) { + int i; + for (i=0; joblevels[i].level_name; i++) { + if (joblevels[i].level == res->res_job.level && + joblevels[i].job_type == res->res_job.JobType) { + i = 0; + break; + } + } + if (i != 0) { Emsg1(M_ERROR_TERM, 0, "Inappropriate level specified in Job resource %s\n", - res_all.res_dir.hdr.name); - } - } - break; + res_all.res_dir.hdr.name); + } + } + break; case R_COUNTER: - if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Counter resource %s\n", res_all.res_counter.hdr.name); - } - res->res_counter.Catalog = res_all.res_counter.Catalog; - res->res_counter.WrapCounter = res_all.res_counter.WrapCounter; - break; + } + res->res_counter.Catalog = res_all.res_counter.Catalog; + res->res_counter.WrapCounter = res_all.res_counter.WrapCounter; + break; case R_CLIENT: - if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { + if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Client resource %s\n", res_all.res_client.hdr.name); - } - res->res_client.catalog = res_all.res_client.catalog; - break; + } + res->res_client.catalog = res_all.res_client.catalog; + break; case R_SCHEDULE: - /* Schedule is a bit different in that it contains a RUN record + /* Schedule is a bit different in that it contains a RUN record * chain which isn't a "named" resource. This chain was linked - * in by run_conf.c during pass 2, so here we jam the pointer - * into the Schedule resource. - */ - if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) { + * in by run_conf.c during pass 2, so here we jam the pointer + * into the Schedule resource. + */ + if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Schedule resource %s\n", res_all.res_client.hdr.name); - } - res->res_sch.run = res_all.res_sch.run; - break; + } + res->res_sch.run = res_all.res_sch.run; + break; default: Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type); - error = 1; - break; + error = 1; + break; } /* Note, the resource name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { - free(res_all.res_dir.hdr.name); - res_all.res_dir.hdr.name = NULL; + free(res_all.res_dir.hdr.name); + res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { - free(res_all.res_dir.hdr.desc); - res_all.res_dir.hdr.desc = NULL; + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; } return; } @@ -1016,17 +1022,17 @@ void save_resource(int type, struct res_items *items, int pass) res = (URES *)malloc(size); memcpy(res, &res_all, size); if (!resources[rindex].res_head) { - resources[rindex].res_head = (RES *)res; /* store first entry */ + resources[rindex].res_head = (RES *)res; /* store first entry */ Dmsg3(200, "Inserting first %s res: %s index=%d\n", res_to_str(type), - res->res_dir.hdr.name, rindex); + res->res_dir.hdr.name, rindex); } else { - RES *next; - /* Add new res to end of chain */ - for (next=resources[rindex].res_head; next->next; next=next->next) - { } - next->next = (RES *)res; + RES *next; + /* Add new res to end of chain */ + for (next=resources[rindex].res_head; next->next; next=next->next) + { } + next->next = (RES *)res; Dmsg3(200, "Inserting %s res: %s index=%d\n", res_to_str(type), - res->res_dir.hdr.name, rindex); + res->res_dir.hdr.name, rindex); } } } @@ -1043,9 +1049,9 @@ static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass) /* Store the type both pass 1 and pass 2 */ for (i=0; jobtypes[i].type_name; i++) { if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) { - ((JOB *)(item->value))->JobType = jobtypes[i].job_type; - i = 0; - break; + ((JOB *)(item->value))->JobType = jobtypes[i].job_type; + i = 0; + break; } } if (i != 0) { @@ -1067,9 +1073,9 @@ static void store_level(LEX *lc, struct res_items *item, int index, int pass) /* Store the level pass 2 so that type is defined */ for (i=0; joblevels[i].level_name; i++) { if (strcasecmp(lc->str, joblevels[i].level_name) == 0) { - ((JOB *)(item->value))->level = joblevels[i].level; - i = 0; - break; + ((JOB *)(item->value))->level = joblevels[i].level; + i = 0; + break; } } if (i != 0) { @@ -1086,9 +1092,9 @@ static void store_replace(LEX *lc, struct res_items *item, int index, int pass) /* Scan Replacement options */ for (i=0; ReplaceOptions[i].name; i++) { if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { - *(int *)(item->value) = ReplaceOptions[i].token; - i = 0; - break; + *(int *)(item->value) = ReplaceOptions[i].token; + i = 0; + break; } } if (i != 0) { @@ -1126,59 +1132,59 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass) Dmsg1(190, "Got keyword: %s\n", lc->str); found = FALSE; for (i=0; BakVerFields[i].name; i++) { - if (strcasecmp(lc->str, BakVerFields[i].name) == 0) { - found = TRUE; - if (lex_get_token(lc, T_ALL) != T_EQUALS) { + if (strcasecmp(lc->str, BakVerFields[i].name) == 0) { + found = TRUE; + if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, "Expected an equals, got: %s", lc->str); - } - token = lex_get_token(lc, T_NAME); + } + token = lex_get_token(lc, T_NAME); Dmsg1(190, "Got value: %s\n", lc->str); - switch (BakVerFields[i].token) { + switch (BakVerFields[i].token) { case 'C': - /* Find Client Resource */ - if (pass == 2) { - res = GetResWithName(R_CLIENT, lc->str); - if (res == NULL) { + /* Find Client Resource */ + if (pass == 2) { + res = GetResWithName(R_CLIENT, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified Client Resource: %s", - lc->str); - } - res_all.res_job.client = (CLIENT *)res; - } - break; + lc->str); + } + res_all.res_job.client = (CLIENT *)res; + } + break; case 'F': - /* Find FileSet Resource */ - if (pass == 2) { - res = GetResWithName(R_FILESET, lc->str); - if (res == NULL) { + /* Find FileSet Resource */ + if (pass == 2) { + res = GetResWithName(R_FILESET, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified FileSet Resource: %s\n", - lc->str); - } - res_all.res_job.fileset = (FILESET *)res; - } - break; + lc->str); + } + res_all.res_job.fileset = (FILESET *)res; + } + break; case 'L': - /* Get level */ - for (i=0; joblevels[i].level_name; i++) { - if (joblevels[i].job_type == item->code && - strcasecmp(lc->str, joblevels[i].level_name) == 0) { - ((JOB *)(item->value))->level = joblevels[i].level; - i = 0; - break; - } - } - if (i != 0) { + /* Get level */ + for (i=0; joblevels[i].level_name; i++) { + if (joblevels[i].job_type == item->code && + strcasecmp(lc->str, joblevels[i].level_name) == 0) { + ((JOB *)(item->value))->level = joblevels[i].level; + i = 0; + break; + } + } + if (i != 0) { scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str); - } - break; - } /* end switch */ - break; - } /* end if strcmp() */ + } + break; + } /* end switch */ + break; + } /* end if strcmp() */ } /* end for */ if (!found) { scan_err1(lc, "%s not a valid Backup/verify keyword", lc->str); } } /* end while */ - lc->options = options; /* reset original options */ + lc->options = options; /* reset original options */ set_bit(index, res_all.hdr.item_present); } @@ -1208,91 +1214,91 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass) found = FALSE; for (i=0; RestoreFields[i].name; i++) { Dmsg1(190, "Restore kw=%s\n", lc->str); - if (strcasecmp(lc->str, RestoreFields[i].name) == 0) { - found = TRUE; - if (lex_get_token(lc, T_ALL) != T_EQUALS) { + if (strcasecmp(lc->str, RestoreFields[i].name) == 0) { + found = TRUE; + if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, "Expected an equals, got: %s", lc->str); - } - token = lex_get_token(lc, T_ALL); + } + token = lex_get_token(lc, T_ALL); Dmsg1(190, "Restore value=%s\n", lc->str); - switch (RestoreFields[i].token) { + switch (RestoreFields[i].token) { case 'B': - /* Bootstrap */ - if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { + /* Bootstrap */ + if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a Restore bootstrap file, got: %s", lc->str); - } - if (pass == 1) { - res_all.res_job.RestoreBootstrap = bstrdup(lc->str); - } - break; + } + if (pass == 1) { + res_all.res_job.RestoreBootstrap = bstrdup(lc->str); + } + break; case 'C': - /* Find Client Resource */ - if (pass == 2) { - res = GetResWithName(R_CLIENT, lc->str); - if (res == NULL) { + /* Find Client Resource */ + if (pass == 2) { + res = GetResWithName(R_CLIENT, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified Client Resource: %s", - lc->str); - } - res_all.res_job.client = (CLIENT *)res; - } - break; + lc->str); + } + res_all.res_job.client = (CLIENT *)res; + } + break; case 'F': - /* Find FileSet Resource */ - if (pass == 2) { - res = GetResWithName(R_FILESET, lc->str); - if (res == NULL) { + /* Find FileSet Resource */ + if (pass == 2) { + res = GetResWithName(R_FILESET, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified FileSet Resource: %s\n", - lc->str); - } - res_all.res_job.fileset = (FILESET *)res; - } - break; + lc->str); + } + res_all.res_job.fileset = (FILESET *)res; + } + break; case 'J': - /* JobId */ - if (token != T_NUMBER) { + /* JobId */ + if (token != T_NUMBER) { scan_err1(lc, "expected an integer number, got: %s", lc->str); - } - errno = 0; - res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0); + } + errno = 0; + res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0); Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId); - if (errno != 0) { + if (errno != 0) { scan_err1(lc, "expected an integer number, got: %s", lc->str); - } - break; + } + break; case 'W': - /* Where */ - if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { + /* Where */ + if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a Restore root directory, got: %s", lc->str); - } - if (pass == 1) { - res_all.res_job.RestoreWhere = bstrdup(lc->str); - } - break; + } + if (pass == 1) { + res_all.res_job.RestoreWhere = bstrdup(lc->str); + } + break; case 'R': - /* Replacement options */ - if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { + /* Replacement options */ + if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a keyword name, got: %s", lc->str); - } - /* Fix to scan Replacement options */ - for (i=0; ReplaceOptions[i].name; i++) { - if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { - ((JOB *)(item->value))->replace = ReplaceOptions[i].token; - i = 0; - break; - } - } - if (i != 0) { + } + /* Fix to scan Replacement options */ + for (i=0; ReplaceOptions[i].name; i++) { + if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { + ((JOB *)(item->value))->replace = ReplaceOptions[i].token; + i = 0; + break; + } + } + if (i != 0) { scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str); - } - break; - } /* end switch */ - break; - } /* end if strcmp() */ + } + break; + } /* end switch */ + break; + } /* end if strcmp() */ } /* end for */ if (!found) { scan_err1(lc, "%s not a valid Restore keyword", lc->str); } } /* end while */ - lc->options = options; /* reset original options */ + lc->options = options; /* reset original options */ set_bit(index, res_all.hdr.item_present); } diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 41dc341b6d..869343b245 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -194,6 +194,9 @@ struct JOB { int PruneVolumes; /* Force pruning of Volumes */ int SpoolAttributes; /* Set to spool attributes in SD */ uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */ + int RescheduleOnError; /* Set to reschedule on error */ + int RescheduleTimes; /* Number of times to reschedule job */ + utime_t RescheduleInterval; /* Reschedule interval */ MSGS *messages; /* How and where to send messages */ SCHED *schedule; /* When -- Automatic schedule */ diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index c67c4a0129..83ca5d876d 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -174,99 +174,121 @@ static void *job_thread(void *arg) pthread_detach(pthread_self()); sm_check(__FILE__, __LINE__, True); - if (!acquire_resource_locks(jcr)) { - set_jcr_job_status(jcr, JS_Canceled); - } - - Dmsg0(200, "=====Start Job=========\n"); - jcr->start_time = time(NULL); /* set the real start time */ - set_jcr_job_status(jcr, JS_Running); - - if (job_canceled(jcr)) { - update_job_end_record(jcr); - } else if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay < - (utime_t)(jcr->start_time - jcr->sched_time)) { - Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n")); - set_jcr_job_status(jcr, JS_Canceled); - update_job_end_record(jcr); - } else { - - /* Run Job */ - if (jcr->job->RunBeforeJob) { - POOLMEM *before = get_pool_memory(PM_FNAME); - int status; - BPIPE *bpipe; - char line[MAXSTRING]; - - before = edit_run_codes(jcr, before, jcr->job->RunBeforeJob); - bpipe = open_bpipe(before, 0, "r"); - while (fgets(line, sizeof(line), bpipe->rfd)) { - Jmsg(jcr, M_INFO, 0, _("RunBefore: %s"), line); - } - status = close_bpipe(bpipe); - if (status != 0) { - Jmsg(jcr, M_FATAL, 0, _("RunBeforeJob returned non-zero status=%d\n"), - status); - set_jcr_job_status(jcr, JS_FatalError); - update_job_end_record(jcr); - free_pool_memory(before); - goto bail_out; - } - free_pool_memory(before); + for ( ;; ) { + if (!acquire_resource_locks(jcr)) { + set_jcr_job_status(jcr, JS_Canceled); } - switch (jcr->JobType) { - case JT_BACKUP: - do_backup(jcr); - if (jcr->JobStatus == JS_Terminated) { - do_autoprune(jcr); + + Dmsg0(200, "=====Start Job=========\n"); + jcr->start_time = time(NULL); /* set the real start time */ + set_jcr_job_status(jcr, JS_Running); + + if (job_canceled(jcr)) { + update_job_end_record(jcr); + } else if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay < + (utime_t)(jcr->start_time - jcr->sched_time)) { + Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n")); + set_jcr_job_status(jcr, JS_Canceled); + update_job_end_record(jcr); + } else { + + /* Run Job */ + if (jcr->job->RunBeforeJob) { + POOLMEM *before = get_pool_memory(PM_FNAME); + int status; + BPIPE *bpipe; + char line[MAXSTRING]; + + before = edit_run_codes(jcr, before, jcr->job->RunBeforeJob); + bpipe = open_bpipe(before, 0, "r"); + while (fgets(line, sizeof(line), bpipe->rfd)) { + Jmsg(jcr, M_INFO, 0, _("RunBefore: %s"), line); } - break; - case JT_VERIFY: - do_verify(jcr); - if (jcr->JobStatus == JS_Terminated) { - do_autoprune(jcr); + status = close_bpipe(bpipe); + if (status != 0) { + Jmsg(jcr, M_FATAL, 0, _("RunBeforeJob returned non-zero status=%d\n"), + status); + set_jcr_job_status(jcr, JS_FatalError); + update_job_end_record(jcr); + free_pool_memory(before); + goto bail_out; } - break; - case JT_RESTORE: - do_restore(jcr); - if (jcr->JobStatus == JS_Terminated) { - do_autoprune(jcr); + free_pool_memory(before); + } + switch (jcr->JobType) { + case JT_BACKUP: + do_backup(jcr); + if (jcr->JobStatus == JS_Terminated) { + do_autoprune(jcr); + } + break; + case JT_VERIFY: + do_verify(jcr); + if (jcr->JobStatus == JS_Terminated) { + do_autoprune(jcr); + } + break; + case JT_RESTORE: + do_restore(jcr); + if (jcr->JobStatus == JS_Terminated) { + do_autoprune(jcr); + } + break; + case JT_ADMIN: + do_admin(jcr); + if (jcr->JobStatus == JS_Terminated) { + do_autoprune(jcr); + } + break; + default: + Pmsg1(0, "Unimplemented job type: %d\n", jcr->JobType); + break; } - break; - case JT_ADMIN: - do_admin(jcr); - if (jcr->JobStatus == JS_Terminated) { - do_autoprune(jcr); + if (jcr->job->RunAfterJob) { + POOLMEM *after = get_pool_memory(PM_FNAME); + int status; + BPIPE *bpipe; + char line[MAXSTRING]; + + after = edit_run_codes(jcr, after, jcr->job->RunAfterJob); + bpipe = open_bpipe(after, 0, "r"); + while (fgets(line, sizeof(line), bpipe->rfd)) { + Jmsg(jcr, M_INFO, 0, _("RunAfter: %s"), line); } - break; - default: - Pmsg1(0, "Unimplemented job type: %d\n", jcr->JobType); - break; - } - if (jcr->job->RunAfterJob) { - POOLMEM *after = get_pool_memory(PM_FNAME); - int status; - BPIPE *bpipe; - char line[MAXSTRING]; - - after = edit_run_codes(jcr, after, jcr->job->RunAfterJob); - bpipe = open_bpipe(after, 0, "r"); - while (fgets(line, sizeof(line), bpipe->rfd)) { - Jmsg(jcr, M_INFO, 0, _("RunAfter: %s"), line); - } - status = close_bpipe(bpipe); - if (status != 0) { - Jmsg(jcr, M_FATAL, 0, _("RunAfterJob returned non-zero status=%d\n"), - status); - set_jcr_job_status(jcr, JS_FatalError); - update_job_end_record(jcr); + status = close_bpipe(bpipe); + if (status != 0) { + Jmsg(jcr, M_FATAL, 0, _("RunAfterJob returned non-zero status=%d\n"), + status); + set_jcr_job_status(jcr, JS_FatalError); + update_job_end_record(jcr); + } + free_pool_memory(after); } - free_pool_memory(after); } - } bail_out: - release_resource_locks(jcr); - Dmsg0(50, "Before free jcr\n"); + release_resource_locks(jcr); + if (jcr->job->RescheduleOnError && + jcr->JobStatus != JS_Terminated && + jcr->JobStatus != JS_Canceled && + jcr->job->RescheduleTimes > 0 && + jcr->reschedule_count < jcr->job->RescheduleTimes) { + + jcr->reschedule_count++; + jcr->sched_time = time(NULL) + jcr->job->RescheduleInterval; + Dmsg2(000, "Reschedule Job %s in %d seconds.\n", jcr->Job, + (int)jcr->job->RescheduleInterval); + jcr->JobStatus = JS_Created; /* force new status */ + dird_free_jcr(jcr); /* partial cleanup old stuff */ + continue; /* reschedule the job */ + } + break; + } + + if (jcr->db) { + Dmsg0(200, "Close DB\n"); + db_close_database(jcr, jcr->db); + jcr->db = NULL; + } free_jcr(jcr); Dmsg0(50, "======== End Job ==========\n"); sm_check(__FILE__, __LINE__, True); @@ -285,9 +307,11 @@ static int acquire_resource_locks(JCR *jcr) /* Wait until scheduled time arrives */ if (wtime > 0 && verbose) { - Jmsg(jcr, M_INFO, 0, _("Waiting %d seconds for start time.\n"), wtime); + Jmsg(jcr, M_INFO, 0, _("Job %s waiting %d seconds for scheduled start time.\n"), + jcr->Job, wtime); set_jcr_job_status(jcr, JS_WaitStartTime); } + /* Check every 30 seconds if canceled */ while (wtime > 0) { Dmsg2(100, "Waiting on sched time, jobid=%d secs=%d\n", jcr->JobId, wtime); if (wtime > 30) { @@ -298,7 +322,6 @@ static int acquire_resource_locks(JCR *jcr) return 0; } wtime = jcr->sched_time - time(NULL); - } @@ -446,11 +469,10 @@ int get_or_create_client_record(JCR *jcr) cr.AutoPrune = jcr->client->AutoPrune; cr.FileRetention = jcr->client->FileRetention; cr.JobRetention = jcr->client->JobRetention; - if (jcr->client_name) { - free_pool_memory(jcr->client_name); + if (!jcr->client_name) { + jcr->client_name = get_pool_memory(PM_NAME); } - jcr->client_name = get_memory(strlen(jcr->client->hdr.name) + 1); - strcpy(jcr->client_name, jcr->client->hdr.name); + pm_strcpy(&jcr->client_name, jcr->client->hdr.name); if (!db_create_client_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"), db_strerror(jcr->db)); @@ -458,10 +480,9 @@ int get_or_create_client_record(JCR *jcr) } jcr->jr.ClientId = cr.ClientId; if (cr.Uname[0]) { - if (jcr->client_uname) { - free_pool_memory(jcr->client_uname); + if (!jcr->client_uname) { + jcr->client_uname = get_pool_memory(PM_NAME); } - jcr->client_uname = get_memory(strlen(cr.Uname) + 1); pm_strcpy(&jcr->client_uname, cr.Uname); } Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name, @@ -527,7 +548,7 @@ void create_unique_job_name(JCR *jcr, char *base_name) strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm); bstrncpy(name, base_name, sizeof(name)); name[sizeof(name)-22] = 0; /* truncate if too long */ - sprintf(jcr->Job, "%s.%s", name, dt); /* add date & time */ + bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s", name, dt); /* add date & time */ /* Convert spaces into underscores */ for (p=jcr->Job; *p; p++) { if (*p == ' ') { @@ -545,31 +566,41 @@ void dird_free_jcr(JCR *jcr) { Dmsg0(200, "Start dird free_jcr\n"); + if (jcr->sd_auth_key) { + free(jcr->sd_auth_key); + jcr->sd_auth_key = NULL; + } + if (jcr->where) { + free(jcr->where); + jcr->where = NULL; + } if (jcr->file_bsock) { Dmsg0(200, "Close File bsock\n"); bnet_close(jcr->file_bsock); + jcr->file_bsock = NULL; } if (jcr->store_bsock) { Dmsg0(200, "Close Store bsock\n"); bnet_close(jcr->store_bsock); + jcr->store_bsock = NULL; } if (jcr->fname) { Dmsg0(200, "Free JCR fname\n"); free_pool_memory(jcr->fname); + jcr->fname = NULL; } if (jcr->stime) { Dmsg0(200, "Free JCR stime\n"); free_pool_memory(jcr->stime); - } - if (jcr->db) { - Dmsg0(200, "Close DB\n"); - db_close_database(jcr, jcr->db); + jcr->stime = NULL; } if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); + jcr->RestoreBootstrap = NULL; } if (jcr->client_uname) { free_pool_memory(jcr->client_uname); + jcr->client_uname = NULL; } Dmsg0(200, "End dird free_jcr\n"); } @@ -588,11 +619,10 @@ void set_jcr_defaults(JCR *jcr, JOB *job) jcr->JobLevel = job->level; jcr->store = job->storage; jcr->client = job->client; - if (jcr->client_name) { - free_pool_memory(jcr->client_name); + if (!jcr->client_name) { + jcr->client_name = get_pool_memory(PM_NAME); } - jcr->client_name = get_memory(strlen(jcr->client->hdr.name) + 1); - strcpy(jcr->client_name, jcr->client->hdr.name); + pm_strcpy(&jcr->client_name, jcr->client->hdr.name); jcr->pool = job->pool; jcr->catalog = job->client->catalog; jcr->fileset = job->fileset; diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index 1c5c162e2e..1b96e510d0 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -307,8 +307,9 @@ static var_rc_t lookup_var(var_t *ctx, void *my_ctx, const char *var_ptr, int var_len, int var_inc, int var_index, const char **val_ptr, int *val_len, int *val_size) { - char buf[MAXSTRING]; + char buf[MAXSTRING], *val, *p, *v; var_rc_t stat; + int count; if ((stat = lookup_built_in_var(ctx, my_ctx, var_ptr, var_len, var_index, val_ptr, val_len, val_size)) == VAR_OK) { @@ -321,21 +322,63 @@ static var_rc_t lookup_var(var_t *ctx, void *my_ctx, } /* Look in environment */ - if (var_index != 0) { - return VAR_ERR_ARRAY_LOOKUPS_ARE_UNSUPPORTED; - } if (var_len > (int)sizeof(buf) - 1) { return VAR_ERR_OUT_OF_MEMORY; } - memcpy(buf, var_ptr, var_len+1); - buf[var_len+1] = 0; - Dmsg1(000, "Var=%s\n", buf); + memcpy(buf, var_ptr, var_len + 1); + buf[var_len] = 0; +// Dmsg1(000, "Var=%s\n", buf); - if ((*val_ptr = getenv(buf)) == NULL) { + if ((val = getenv(buf)) == NULL) { return VAR_ERR_UNDEFINED_VARIABLE; } - *val_len = strlen(*val_ptr); - *val_size = 0; + if (var_index == 0) { + *val_ptr = val; + *val_len = strlen(val); + *val_size = 0; + return VAR_OK; + } + /* He wants to index the "array" */ + count = 0; + /* Find the size of the "array" + * each element is separated by a | + */ + for (p = val; *p; p++) { + if (*p == '|') { + count++; + } + } + count++; +// Dmsg3(000, "For %s, reqest index=%d have=%d\n", +// buf, var_index, count); + if (var_index < 0 || var_index > count) { + return VAR_ERR_SUBMATCH_OUT_OF_RANGE; + } + /* Now find the particular item (var_index) he wants */ + count = 1; + for (p=val; *p; ) { + if (*p == '|') { + if (count < var_index) { + val = ++p; + count++; + continue; + } + break; + } + p++; + } + if (p-val > (int)sizeof(buf) - 1) { + return VAR_ERR_OUT_OF_MEMORY; + } +// Dmsg2(000, "val=%s len=%d\n", val, p-val); + /* Make a copy of item, and pass it back */ + v = (char *)malloc(p-val+1); + memcpy(v, val, p-val); + v[p-val] = 0; + *val_ptr = v; + *val_len = p-val; + *val_size = p-val; +// Dmsg1(000, "v=%s\n", v); return VAR_OK; } diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 118e91c1d0..5430903d66 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -31,7 +31,6 @@ #include "dird.h" /* Imported subroutines */ -extern void run_job(JCR *jcr); /* Imported variables */ extern int r_first; diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 479eb80087..8723e08875 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -32,7 +32,6 @@ #include "dird.h" /* Imported subroutines */ -extern void run_job(JCR *jcr); /* Imported variables */ extern int r_first; diff --git a/bacula/src/dird/ua_server.c b/bacula/src/dird/ua_server.c index 7e710d39d7..9c737011a1 100644 --- a/bacula/src/dird/ua_server.c +++ b/bacula/src/dird/ua_server.c @@ -31,7 +31,6 @@ #include "dird.h" /* Imported subroutines */ -extern void run_job(JCR *jcr); /* Imported variables */ extern int r_first; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 343f1d2f7e..a5f365c51a 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -240,6 +240,15 @@ static int cancel_cmd(JCR *jcr) if (!(cjcr=get_jcr_by_full_name(Job))) { bnet_fsend(dir, "2901 Job %s not found.\n", Job); } else { + if (cjcr->store_bsock) { + P(cjcr->mutex); + cjcr->store_bsock->timed_out = 1; + cjcr->store_bsock->terminated = 1; +#ifndef HAVE_CYGWIN + pthread_kill(cjcr->my_thread_id, TIMEOUT_SIGNAL); +#endif + V(cjcr->mutex); + } set_jcr_job_status(cjcr, JS_Canceled); free_jcr(cjcr); bnet_fsend(dir, "2001 Job %s marked to be canceled.\n", Job); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 4b09ccfc07..1f9f0693e2 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -86,13 +86,13 @@ struct JCR { /* Global part of JCR common to all daemons */ JCR *next; JCR *prev; + volatile int use_count; /* use count */ pthread_t my_thread_id; /* id of thread controlling jcr */ pthread_mutex_t mutex; /* jcr mutex */ BSOCK *dir_bsock; /* Director bsock or NULL if we are him */ BSOCK *store_bsock; /* Storage connection socket */ BSOCK *file_bsock; /* File daemon connection socket */ JCR_free_HANDLER *daemon_free_jcr; /* Local free routine */ - volatile int use_count; /* use count */ POOLMEM *errmsg; /* edited error message */ char Job[MAX_NAME_LENGTH]; /* Unique name of this Job */ uint32_t JobId; /* Director's JobId */ @@ -153,6 +153,7 @@ struct JCR { int replace; /* Replace option */ int acquired_resource_locks; /* set if resource locks acquired */ int NumVols; /* Number of Volume used in pool */ + int reschedule_count; /* Number of times rescheduled */ #endif /* DIRECTOR_DAEMON */ @@ -164,7 +165,6 @@ struct JCR { int incremental; /* set if incremental for SINCE */ time_t mtime; /* begin time for SINCE */ int mtime_only; /* compare only mtime and not ctime as well */ - int mode; /* manual/auto run */ int status; /* job status */ long Ticket; /* Ticket */ int save_level; /* save level */ @@ -202,7 +202,6 @@ struct JCR { VOL_LIST *VolList; /* list to read */ long NumVolumes; /* number of volumes used */ long CurVolume; /* current volume number */ - int mode; /* manual/auto run */ int spool_attributes; /* set if spooling attributes */ int no_attributes; /* set if no attributes wanted */ int label_status; /* device volume label status */ diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 58868caf09..a05702c553 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -43,6 +43,8 @@ extern time_t watchdog_time; #endif + + /* * Read a nbytes from the network. * It is possible that the total bytes require in several @@ -99,12 +101,19 @@ static int32_t write_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes) } } while (nwritten == -1 && errno == EINTR); /* - * If connection is non-blocking, we will get eagain, so - * sleep long enough to keep from consuming all the CPU + * If connection is non-blocking, we will get EAGAIN, so + * use select() to keep from consuming all the CPU * and try again. */ if (nwritten == -1 && errno == EAGAIN) { - bmicrosleep(0, 50); /* sleep 50 ms */ + fd_set fdset; + struct timeval tv; + + FD_ZERO(&fdset); + FD_SET(bsock->fd, &fdset); + tv.tv_sec = 10; + tv.tv_usec = 0; + select(bsock->fd + 1, NULL, &fdset, NULL, &tv); continue; } if (nwritten <= 0) { diff --git a/bacula/src/lib/btime.c b/bacula/src/lib/btime.c index 317740c948..10a2ff7925 100644 --- a/bacula/src/lib/btime.c +++ b/bacula/src/lib/btime.c @@ -42,7 +42,7 @@ #include /* Formatted time for user display: dd-Mon-yyyy hh:mm */ -void bstrftime(char *dt, int maxlen, utime_t tim) +char *bstrftime(char *dt, int maxlen, utime_t tim) { time_t ttime = tim; struct tm tm; @@ -50,6 +50,7 @@ void bstrftime(char *dt, int maxlen, utime_t tim) /* ***FIXME**** the format and localtime_r() should be user configurable */ localtime_r(&ttime, &tm); strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm); + return dt; } /* Unix time to standard time string yyyy-mm-dd hh:mm:ss */ diff --git a/bacula/src/lib/btime.h b/bacula/src/lib/btime.h index 00f9be3edb..a35756947e 100644 --- a/bacula/src/lib/btime.h +++ b/bacula/src/lib/btime.h @@ -44,53 +44,53 @@ extern btime_t get_current_btime(void); extern time_t btime_to_unix(btime_t bt); /* bacula time to epoch time */ extern utime_t btime_to_utime(btime_t bt); /* bacula time to utime_t */ -extern void bstrftime(char *dt, int maxlen, utime_t tim); +extern char *bstrftime(char *dt, int maxlen, utime_t tim); extern char *bstrutime(char *dt, int maxlen, utime_t tim); extern utime_t str_to_utime(char *str); /* =========================================================== */ -/* old code deprecated below. Do not use. */ +/* old code deprecated below. Do not use. */ -typedef float64_t fdate_t; /* Date type */ -typedef float64_t ftime_t; /* Time type */ +typedef float64_t fdate_t; /* Date type */ +typedef float64_t ftime_t; /* Time type */ struct date_time { - fdate_t julian_day_number; /* Julian day number */ + fdate_t julian_day_number; /* Julian day number */ ftime_t julian_day_fraction; /* Julian day fraction */ }; /* In arguments and results of the following functions, quantities are expressed as follows. - year Year in the Common Era. The canonical - date of adoption of the Gregorian calendar - (October 5, 1582 in the Julian calendar) - is assumed. + year Year in the Common Era. The canonical + date of adoption of the Gregorian calendar + (October 5, 1582 in the Julian calendar) + is assumed. - month Month index with January 0, December 11. + month Month index with January 0, December 11. - day Day number of month, 1 to 31. + day Day number of month, 1 to 31. */ extern fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day); extern ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second, - float32_t second_fraction); + float32_t second_fraction); extern void date_time_encode(struct date_time *dt, - uint32_t year, uint8_t month, uint8_t day, - uint8_t hour, uint8_t minute, uint8_t second, - float32_t second_fraction); + uint32_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second, + float32_t second_fraction); extern void date_decode(fdate_t date, uint32_t *year, uint8_t *month, - uint8_t *day); + uint8_t *day); extern void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute, - uint8_t *second, float32_t *second_fraction); + uint8_t *second, float32_t *second_fraction); extern void date_time_decode(struct date_time *dt, - uint32_t *year, uint8_t *month, uint8_t *day, - uint8_t *hour, uint8_t *minute, uint8_t *second, - float32_t *second_fraction); + uint32_t *year, uint8_t *month, uint8_t *day, + uint8_t *hour, uint8_t *minute, uint8_t *second, + float32_t *second_fraction); extern int date_time_compare(struct date_time *dt1, struct date_time *dt2); diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 630ada2f5b..5e84ab179b 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -104,7 +104,8 @@ static void remove_jcr(JCR *jcr) } /* - * Free stuff common to all JCRs + * Free stuff common to all JCRs. N.B. Be careful to include only + * generic stuff in the common part of the jcr. */ static void free_common_jcr(JCR *jcr) { @@ -139,7 +140,6 @@ static void free_common_jcr(JCR *jcr) } if (jcr->sd_auth_key) { - Dmsg0(200, "Free JCR sd_auth_key\n"); free(jcr->sd_auth_key); jcr->sd_auth_key = NULL; } diff --git a/bacula/src/lib/mem_pool.c b/bacula/src/lib/mem_pool.c index 50bb16463b..5d123b426e 100644 --- a/bacula/src/lib/mem_pool.c +++ b/bacula/src/lib/mem_pool.c @@ -43,13 +43,16 @@ #include "bacula.h" struct s_pool_ctl { - size_t size; /* default size */ - size_t max_size; /* max allocated */ - size_t max_used; /* max buffers used */ - size_t in_use; /* number in use */ + int32_t size; /* default size */ + int32_t max_size; /* max allocated */ + int32_t max_used; /* max buffers used */ + int32_t in_use; /* number in use */ struct abufhead *free_buf; /* pointer to free buffers */ }; +/* Bacula Name length plus extra */ +#define NLEN (MAX_NAME_LENGTH+2) + /* #define STRESS_TEST_POOL */ #ifndef STRESS_TEST_POOL /* @@ -57,6 +60,7 @@ struct s_pool_ctl { */ static struct s_pool_ctl pool_ctl[] = { { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */ + { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */ { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */ { 1024, 1024, 0, 0, NULL } /* PM_EMSG error message buffer */ @@ -66,6 +70,7 @@ static struct s_pool_ctl pool_ctl[] = { /* This is used ONLY when stress testing the code */ static struct s_pool_ctl pool_ctl[] = { { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */ + { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */ { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */ { 20, 20, 0, 0, NULL } /* PM_EMSG error message buffer */ @@ -75,7 +80,7 @@ static struct s_pool_ctl pool_ctl[] = { /* Memory allocation control structures and storage. */ struct abufhead { - size_t ablen; /* Buffer length in bytes */ + int32_t ablen; /* Buffer length in bytes */ int32_t pool; /* pool */ struct abufhead *next; /* pointer to next free buffer */ }; @@ -124,7 +129,7 @@ POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool) } /* Get nonpool memory of size requested */ -POOLMEM *sm_get_memory(char *fname, int lineno, size_t size) +POOLMEM *sm_get_memory(char *fname, int lineno, int32_t size) { struct abufhead *buf; int pool = 0; @@ -143,7 +148,7 @@ POOLMEM *sm_get_memory(char *fname, int lineno, size_t size) /* Return the size of a memory buffer */ -size_t sm_sizeof_pool_memory(char *fname, int lineno, POOLMEM *obuf) +int32_t sm_sizeof_pool_memory(char *fname, int lineno, POOLMEM *obuf) { char *cp = (char *)obuf; @@ -153,7 +158,7 @@ size_t sm_sizeof_pool_memory(char *fname, int lineno, POOLMEM *obuf) } /* Realloc pool memory buffer */ -POOLMEM *sm_realloc_pool_memory(char *fname, int lineno, POOLMEM *obuf, size_t size) +POOLMEM *sm_realloc_pool_memory(char *fname, int lineno, POOLMEM *obuf, int32_t size) { char *cp = (char *)obuf; void *buf; @@ -176,7 +181,7 @@ POOLMEM *sm_realloc_pool_memory(char *fname, int lineno, POOLMEM *obuf, size_t s return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } -POOLMEM *sm_check_pool_memory_size(char *fname, int lineno, POOLMEM *obuf, size_t size) +POOLMEM *sm_check_pool_memory_size(char *fname, int lineno, POOLMEM *obuf, int32_t size) { ASSERT(obuf); if (size <= sizeof_pool_memory(obuf)) { @@ -246,7 +251,7 @@ POOLMEM *get_pool_memory(int pool) } /* Get nonpool memory of size requested */ -POOLMEM *get_memory(size_t size) +POOLMEM *get_memory(int32_t size) { struct abufhead *buf; int pool = 0; @@ -266,7 +271,7 @@ POOLMEM *get_memory(size_t size) /* Return the size of a memory buffer */ -size_t sizeof_pool_memory(POOLMEM *obuf) +int32_t sizeof_pool_memory(POOLMEM *obuf) { char *cp = (char *)obuf; @@ -276,7 +281,7 @@ size_t sizeof_pool_memory(POOLMEM *obuf) } /* Realloc pool memory buffer */ -POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size) +POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size) { char *cp = (char *)obuf; void *buf; @@ -299,7 +304,7 @@ POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size) return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } -POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size) +POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size) { ASSERT(obuf); if (size <= sizeof_pool_memory(obuf)) { diff --git a/bacula/src/lib/mem_pool.h b/bacula/src/lib/mem_pool.h index ef39a3dc1d..6c7c928bda 100644 --- a/bacula/src/lib/mem_pool.h +++ b/bacula/src/lib/mem_pool.h @@ -31,16 +31,16 @@ extern POOLMEM *sm_get_pool_memory(char *file, int line, int pool); #define get_memory(size) sm_get_memory(__FILE__, __LINE__, size) -extern POOLMEM *sm_get_memory(char *fname, int line, size_t size); +extern POOLMEM *sm_get_memory(char *fname, int line, int32_t size); #define sizeof_pool_memory(buf) sm_sizeof_pool_memory(__FILE__, __LINE__, buf) -extern size_t sm_sizeof_pool_memory(char *fname, int line, POOLMEM *buf); +extern int32_t sm_sizeof_pool_memory(char *fname, int line, POOLMEM *buf); #define realloc_pool_memory(buf,size) sm_realloc_pool_memory(__FILE__, __LINE__, buf, size) -extern POOLMEM *sm_realloc_pool_memory(char *fname, int line, POOLMEM *buf, size_t size); +extern POOLMEM *sm_realloc_pool_memory(char *fname, int line, POOLMEM *buf, int32_t size); #define check_pool_memory_size(buf,size) sm_check_pool_memory_size(__FILE__, __LINE__, buf, size) -extern POOLMEM *sm_check_pool_memory_size(char *fname, int line, POOLMEM *buf, size_t size); +extern POOLMEM *sm_check_pool_memory_size(char *fname, int line, POOLMEM *buf, int32_t size); #define free_pool_memory(x) sm_free_pool_memory(__FILE__, __LINE__, x) #define free_memory(x) sm_free_pool_memory(__FILE__, __LINE__, x) @@ -50,10 +50,10 @@ extern void sm_free_pool_memory(char *fname, int line, POOLMEM *buf); #else extern POOLMEM *get_pool_memory(int pool); -extern POOLMEM *get_memory(size_t size); -extern size_t sizeof_pool_memory(POOLMEM *buf); -extern POOLMEM *realloc_pool_memory(POOLMEM *buf, size_t size); -extern POOLMEM *check_pool_memory_size(POOLMEM *buf, size_t size); +extern POOLMEM *get_memory(int32_t size); +extern int32_t sizeof_pool_memory(POOLMEM *buf); +extern POOLMEM *realloc_pool_memory(POOLMEM *buf, int32_t size); +extern POOLMEM *check_pool_memory_size(POOLMEM *buf, int32_t size); #define free_memory(x) free_pool_memory(x) extern void free_pool_memory(POOLMEM *buf); @@ -63,7 +63,8 @@ extern void close_memory_pool(); extern void print_memory_pool_stats(); #define PM_NOPOOL 0 /* nonpooled memory */ -#define PM_FNAME 1 /* file name buffer */ -#define PM_MESSAGE 2 /* daemon message */ -#define PM_EMSG 3 /* error message */ +#define PM_NAME 1 /* Bacula name */ +#define PM_FNAME 2 /* file name buffer */ +#define PM_MESSAGE 3 /* daemon message */ +#define PM_EMSG 4 /* error message */ #define PM_MAX PM_EMSG /* Number of types */ diff --git a/bacula/src/stored/bacula-sd.conf.in b/bacula/src/stored/bacula-sd.conf.in index 6db6582f7b..f18a7a6a08 100644 --- a/bacula/src/stored/bacula-sd.conf.in +++ b/bacula/src/stored/bacula-sd.conf.in @@ -43,33 +43,14 @@ Device { } #Device { -# Name = "HP DLT 80" -# Media Type = DLT8000 +# Name = DDS-4 # +# Media Type = DDS-4 # Archive Device = @TAPEDRIVE@ # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = yes; # RemovableMedia = yes; #} -#Device { -# Name = SDT-7000 # -# Media Type = DDS-2 -# Archive Device = @TAPEDRIVE@ -# AutomaticMount = yes; # when device opened, read it -# AlwaysOpen = yes; -# RemovableMedia = yes; -#} - -#Device { -# Name = Floppy -# Media Type = Floppy -# Archive Device = /mnt/floppy -# RemovableMedia = yes; -# Random Access = Yes; -# AutomaticMount = yes; # when device opened, read it -# AlwaysOpen = no; -#} - # # A very old Exabyte with no end of media detection # diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 01dc503607..1d4e26411c 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -76,6 +76,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) DEV_BLOCK *label_blk; char b1[30], b2[30]; time_t wait_time; + char dt[MAX_TIME_LENGTH]; wait_time = time(NULL); status_dev(dev, &stat); @@ -132,9 +133,10 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) label_blk = new_block(dev); /* Inform User about end of medium */ - Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s.\n"), + Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"), PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1), - edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2)); + edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2), + bstrftime(dt, sizeof(dt), time(NULL))); if (!mount_next_write_volume(jcr, dev, label_blk, 1)) { free_block(label_blk); @@ -144,8 +146,8 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) } P(dev->mutex); /* lock again */ - Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s\n"), - jcr->VolumeName, dev_name(dev)); + Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"), + jcr->VolumeName, dev_name(dev), bstrftime(dt, sizeof(dt), time(NULL))); /* * If this is a new tape, the label_blk will contain the diff --git a/bacula/src/version.h b/bacula/src/version.h index 3f069734af..52659d533e 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.31" #define VSTRING "1" -#define BDATE "14 Jun 2003" -#define LSMDATE "14Jun03" +#define BDATE "16 Jun 2003" +#define LSMDATE "16Jun03" /* Debug flags */ #define DEBUG 1 -- 2.39.5