From 4c569766ebee936f6bbfb766659fca0105898c9d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 6 Feb 2006 13:49:59 +0000 Subject: [PATCH] - Implement first cut of Migration. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2778 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kes-1.39 | 4 + bacula/src/cats/cats.h | 3 +- bacula/src/cats/mysql.c | 20 ++- bacula/src/cats/sql_find.c | 9 +- bacula/src/cats/sql_list.c | 20 ++- bacula/src/dird/backup.c | 144 +++++++++++---------- bacula/src/dird/catreq.c | 25 ++-- bacula/src/dird/dird_conf.c | 16 ++- bacula/src/dird/dird_conf.h | 1 + bacula/src/dird/job.c | 32 +++-- bacula/src/dird/mac.c | 173 ++++++++++++-------------- bacula/src/dird/msgchan.c | 65 +++++----- bacula/src/dird/protos.h | 2 + bacula/src/dird/recycle.c | 6 +- bacula/src/dird/ua_dotcmds.c | 2 +- bacula/src/dird/ua_output.c | 13 +- bacula/src/dird/ua_prune.c | 30 ++--- bacula/src/dird/ua_purge.c | 14 +-- bacula/src/dird/ua_restore.c | 2 +- bacula/src/dird/ua_select.c | 13 +- bacula/src/gnome2-console/callbacks.c | 142 ++++++++++----------- bacula/src/jcr.h | 7 +- bacula/src/lib/attr.c | 6 +- bacula/src/lib/edit.c | 33 +++++ bacula/src/lib/jcr.c | 10 +- bacula/src/lib/protos.h | 1 + bacula/src/lib/watchdog.c | 20 ++- bacula/src/stored/acquire.c | 14 +-- bacula/src/stored/append.c | 1 + bacula/src/stored/bextract.c | 2 +- bacula/src/stored/bls.c | 3 +- bacula/src/stored/bscan.c | 2 +- bacula/src/stored/dev.c | 2 +- bacula/src/stored/dvd.c | 56 ++++----- bacula/src/stored/match_bsr.c | 10 +- bacula/src/stored/read_record.c | 4 +- bacula/src/stored/record.h | 37 +++--- bacula/src/stored/reserve.c | 4 +- bacula/src/stored/stored.c | 2 +- bacula/src/version.h | 4 +- 40 files changed, 525 insertions(+), 429 deletions(-) diff --git a/bacula/kes-1.39 b/bacula/kes-1.39 index 18fa97fcbf..6cb67deade 100644 --- a/bacula/kes-1.39 +++ b/bacula/kes-1.39 @@ -4,7 +4,11 @@ General: Changes to 1.39.5 +06Feb06 +- Implement first cut of Migration. 30Jan06 +- Apply user supplied patch for more readable rate output + in job report. - Continue implementing migration. - Implement support for removable filesystems in SD. - Ensure that btraceback scripts can be read by anyone. diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index 00ea5a0974..12e7a9b3be 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -14,7 +14,7 @@ * Version $Id$ */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -335,6 +335,7 @@ struct B_DB { /* "Generic" names for easier conversion */ #define sql_store_result(x) mysql_store_result((x)->db) +#define sql_use_result(x) mysql_use_result((x)->db) #define sql_free_result(x) mysql_free_result((x)->result) #define sql_fetch_row(x) mysql_fetch_row((x)->result) #define sql_query(x, y) mysql_query((x)->db, (y)) diff --git a/bacula/src/cats/mysql.c b/bacula/src/cats/mysql.c index 9b3f375db2..9d24a11658 100644 --- a/bacula/src/cats/mysql.c +++ b/bacula/src/cats/mysql.c @@ -7,24 +7,18 @@ * * Version $Id$ */ - /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -328,7 +322,7 @@ int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler return 0; } if (result_handler != NULL) { - if ((mdb->result = sql_store_result(mdb)) != NULL) { + if ((mdb->result = sql_use_result(mdb)) != NULL) { int num_fields = sql_num_fields(mdb); while ((row = sql_fetch_row(mdb)) != NULL) { diff --git a/bacula/src/cats/sql_find.c b/bacula/src/cats/sql_find.c index cac8a58cc3..a875d44528 100644 --- a/bacula/src/cats/sql_find.c +++ b/bacula/src/cats/sql_find.c @@ -263,7 +263,8 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr { SQL_ROW row; int numrows; - const char *changer, *order; + const char *order; + char ed1[50]; db_lock(mdb); @@ -280,11 +281,13 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr edit_int64(mr->PoolId, ed1), mr->MediaType); item = 1; } else { + char changer[100]; /* Find next available volume */ if (InChanger) { - changer = "AND InChanger=1"; + bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s", + edit_int64(mr->StorageId, ed1)); } else { - changer = ""; + changer[0] = 0; } if (strcmp(mr->VolStatus, "Recycled") == 0 || strcmp(mr->VolStatus, "Purged") == 0) { diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index d7d17fb4b8..8d180198dc 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -270,14 +270,22 @@ db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, edit_int64(jr->JobId, ed1)); } } else { - if (jr->JobId == 0 && jr->Job[0] == 0) { + if (jr->Name[0] != 0) { Mmsg(mdb->cmd, - "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " - "FROM Job ORDER BY StartTime%s", limit); + "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " + "FROM Job WHERE Name='%s' ORDER BY StartTime,JobId ASC", jr->Name); + } else if (jr->Job[0] != 0) { + Mmsg(mdb->cmd, + "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " + "FROM Job WHERE Job='%s' ORDER BY StartTime,JobId ASC", jr->Job); + } else if (jr->JobId != 0) { + Mmsg(mdb->cmd, + "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " + "FROM Job WHERE JobId=%s", edit_int64(jr->JobId, ed1)); } else { /* single record */ - Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level," - "JobFiles,JobBytes,JobStatus FROM Job WHERE JobId=%s", - edit_int64(jr->JobId, ed1)); + Mmsg(mdb->cmd, + "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " + "FROM Job ORDER BY StartTime,JobId ASC%s", limit); } } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 225ffe5fcc..f8107485b7 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -326,6 +326,7 @@ void backup_cleanup(JCR *jcr, int TermCode) { char sdt[50], edt[50], schedt[50]; char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], compress[50]; + char ec6[30], ec7[30], elapsed[50]; char term_code[100], fd_term_msg[100], sd_term_msg[100]; const char *term_msg; int msg_type; @@ -361,68 +362,8 @@ void backup_cleanup(JCR *jcr, int TermCode) set_jcr_job_status(jcr, JS_ErrorTerminated); } - /* Now update the bootstrap file if any */ - if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes && - jcr->job->WriteBootstrap) { - FILE *fd; - BPIPE *bpipe = NULL; - int got_pipe = 0; - char *fname = jcr->job->WriteBootstrap; - VOL_PARAMS *VolParams = NULL; - int VolCount; + update_bootstrap_file(jcr); - if (*fname == '|') { - fname++; - got_pipe = 1; - bpipe = open_bpipe(fname, 0, "w"); - fd = bpipe ? bpipe->wfd : NULL; - } else { - /* ***FIXME*** handle BASE */ - fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+"); - } - if (fd) { - VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId, - &VolParams); - if (VolCount == 0) { - Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to " - "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db)); - if (jcr->SDJobFiles != 0) { - set_jcr_job_status(jcr, JS_ErrorTerminated); - } - - } - /* Start output with when and who wrote it */ - bstrftimes(edt, sizeof(edt), time(NULL)); - fprintf(fd, "# %s - %s - %s%s\n", edt, jcr->jr.Job, - level_to_str(jcr->JobLevel), jcr->since); - for (int i=0; i < VolCount; i++) { - /* Write the record */ - fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName); - fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType); - fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId); - fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime); - fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile, - VolParams[i].EndFile); - fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock, - VolParams[i].EndBlock); - fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex, - VolParams[i].LastIndex); - } - if (VolParams) { - free(VolParams); - } - if (got_pipe) { - close_bpipe(bpipe); - } else { - fclose(fd); - } - } else { - berrno be; - Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n" - "%s: ERR=%s\n"), fname, be.strerror()); - set_jcr_job_status(jcr, JS_ErrorTerminated); - } - } msg_type = M_INFO; /* by default INFO message */ switch (jcr->JobStatus) { @@ -506,11 +447,12 @@ void backup_cleanup(JCR *jcr, int TermCode) " Scheduled time: %s\n" " Start time: %s\n" " End time: %s\n" +" Elapsed time: %s\n" " Priority: %d\n" " FD Files Written: %s\n" " SD Files Written: %s\n" -" FD Bytes Written: %s\n" -" SD Bytes Written: %s\n" +" FD Bytes Written: %s (%sB)\n" +" SD Bytes Written: %s (%sB)\n" " Rate: %.1f KB/s\n" " Software Compression: %s\n" " Volume name(s): %s\n" @@ -535,17 +477,20 @@ void backup_cleanup(JCR *jcr, int TermCode) schedt, sdt, edt, + edit_utime(RunTime, elapsed, sizeof(elapsed)), jcr->JobPriority, edit_uint64_with_commas(jcr->jr.JobFiles, ec1), - edit_uint64_with_commas(jcr->SDJobFiles, ec4), - edit_uint64_with_commas(jcr->jr.JobBytes, ec2), + edit_uint64_with_commas(jcr->SDJobFiles, ec2), + edit_uint64_with_commas(jcr->jr.JobBytes, ec3), + edit_uint64_with_suffix(jcr->jr.JobBytes, ec4), edit_uint64_with_commas(jcr->SDJobBytes, ec5), + edit_uint64_with_suffix(jcr->SDJobBytes, ec6), (float)kbps, compress, jcr->VolumeName, jcr->VolSessionId, jcr->VolSessionTime, - edit_uint64_with_commas(mr.VolBytes, ec3), + edit_uint64_with_commas(mr.VolBytes, ec7), jcr->Errors, jcr->SDErrors, fd_term_msg, @@ -554,3 +499,70 @@ void backup_cleanup(JCR *jcr, int TermCode) Dmsg0(100, "Leave backup_cleanup()\n"); } + +void update_bootstrap_file(JCR *jcr) +{ + /* Now update the bootstrap file if any */ + if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes && + jcr->job->WriteBootstrap) { + FILE *fd; + BPIPE *bpipe = NULL; + int got_pipe = 0; + char *fname = jcr->job->WriteBootstrap; + VOL_PARAMS *VolParams = NULL; + int VolCount; + char edt[50]; + + if (*fname == '|') { + fname++; + got_pipe = 1; + bpipe = open_bpipe(fname, 0, "w"); + fd = bpipe ? bpipe->wfd : NULL; + } else { + /* ***FIXME*** handle BASE */ + fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+"); + } + if (fd) { + VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId, + &VolParams); + if (VolCount == 0) { + Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to " + "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db)); + if (jcr->SDJobFiles != 0) { + set_jcr_job_status(jcr, JS_ErrorTerminated); + } + + } + /* Start output with when and who wrote it */ + bstrftimes(edt, sizeof(edt), time(NULL)); + fprintf(fd, "# %s - %s - %s%s\n", edt, jcr->jr.Job, + level_to_str(jcr->JobLevel), jcr->since); + for (int i=0; i < VolCount; i++) { + /* Write the record */ + fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName); + fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType); + fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId); + fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime); + fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile, + VolParams[i].EndFile); + fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock, + VolParams[i].EndBlock); + fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex, + VolParams[i].LastIndex); + } + if (VolParams) { + free(VolParams); + } + if (got_pipe) { + close_bpipe(bpipe); + } else { + fclose(fd); + } + } else { + berrno be; + Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n" + "%s: ERR=%s\n"), fname, be.strerror()); + set_jcr_job_status(jcr, JS_ErrorTerminated); + } + } +} diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 955d0469cc..62e4400077 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -13,7 +13,7 @@ * Version $Id$ */ /* - Copyright (C) 2001-2005 Kern Sibbald + Copyright (C) 2001-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -122,6 +122,9 @@ void catalog_request(JCR *jcr, BSOCK *bs) ok = db_get_pool_record(jcr, jcr->db, &pr); if (ok) { mr.PoolId = pr.PoolId; + if (jcr->store->StorageId) { + mr.StorageId = jcr->store->StorageId; + } ok = find_next_volume_for_append(jcr, &mr, index, true /*permit create new vol*/); } /* @@ -276,8 +279,13 @@ void catalog_request(JCR *jcr, BSOCK *bs) &jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile, &jm.StartBlock, &jm.EndBlock, &jm.Copy, &jm.Stripe) == 9) { - jm.JobId = jcr->JobId; - jm.MediaId = jcr->MediaId; + if (jcr->target_jcr) { + jm.JobId = jcr->target_jcr->JobId; + jm.MediaId = jcr->MediaId; + } else { + jm.JobId = jcr->JobId; + jm.MediaId = jcr->MediaId; + } Dmsg6(400, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n", jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); if (!db_create_jobmedia_record(jcr, jcr->db, &jm)) { @@ -386,7 +394,11 @@ void catalog_update(JCR *jcr, BSOCK *bs) ar->FileIndex = FileIndex; ar->Stream = Stream; ar->link = NULL; - ar->JobId = jcr->JobId; + if (jcr->target_jcr) { + ar->JobId = jcr->target_jcr->JobId; + } else { + ar->JobId = jcr->JobId; + } ar->Digest = NULL; ar->DigestType = CRYPTO_DIGEST_NONE; jcr->cached_attribute = true; @@ -394,11 +406,6 @@ void catalog_update(JCR *jcr, BSOCK *bs) Dmsg2(400, "dirddb, ar)) { - Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); - } -#endif } else if (crypto_digest_stream_type(Stream) != CRYPTO_DIGEST_NONE) { fname = p; if (ar->FileIndex != FileIndex) { diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 446f9478a5..38de435a16 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -331,7 +331,8 @@ static RES_ITEM pool_items[] = { {"migrationtime", store_time, ITEM(res_pool.MigrationTime), 0, 0, 0}, {"migrationhighbytes", store_size, ITEM(res_pool.MigrationHighBytes), 0, 0, 0}, {"migrationlowbytes", store_size, ITEM(res_pool.MigrationLowBytes), 0, 0, 0}, - {"nextpool", store_res, ITEM(res_pool.NextPool), R_POOL, 0, 0}, + {"nextpool", store_res, ITEM(res_pool.NextPool), R_POOL, 0, 0}, + {"storage", store_alist_res, ITEM(res_pool.storage), R_STORAGE, 0, 0}, {"autoprune", store_yesno, ITEM(res_pool.AutoPrune), 1, ITEM_DEFAULT, 1}, {"recycle", store_yesno, ITEM(res_pool.Recycle), 1, ITEM_DEFAULT, 1}, {NULL, NULL, NULL, 0, 0, 0} @@ -788,6 +789,13 @@ next_run: sendit(sock, _(" --> ")); dump_resource(-R_POOL, (RES *)res->res_pool.NextPool, sendit, sock); } + if (res->res_pool.storage) { + STORE *store; + foreach_alist(store, res->res_pool.storage) { + sendit(sock, _(" --> ")); + dump_resource(-R_STORAGE, (RES *)store, sendit, sock); + } + } break; case R_MSGS: sendit(sock, _("Messages: name=%s\n"), res->res_msgs.hdr.name); @@ -1035,6 +1043,9 @@ void free_resource(RES *sres, int type) if (res->res_pool.cleaning_prefix) { free(res->res_pool.cleaning_prefix); } + if (res->res_pool.storage) { + delete res->res_pool.storage; + } break; case R_SCHEDULE: if (res->res_sch.run) { @@ -1171,8 +1182,9 @@ void save_resource(int type, RES_ITEM *items, int pass) if ((res = (URES *)GetResWithName(R_POOL, res_all.res_con.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Pool resource %s\n"), res_all.res_con.hdr.name); } - /* Update it with pointer to NextPool from this pass (res_all) */ + /* Explicitly copy resource pointers from this pass (res_all) */ res->res_pool.NextPool = res_all.res_pool.NextPool; + res->res_pool.storage = res_all.res_pool.storage; break; case R_CONSOLE: if ((res = (URES *)GetResWithName(R_CONSOLE, res_all.res_con.hdr.name)) == NULL) { diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 4e95147f46..45b48eb51c 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -433,6 +433,7 @@ public: uint32_t MigrationHighBytes; /* When migration starts */ uint32_t MigrationLowBytes; /* When migration stops */ POOL *NextPool; /* Next pool for migration */ + alist *storage; /* Where is device -- list of Storage to be used */ int AutoPrune; /* default for pool auto prune */ int Recycle; /* default for media recycle yes/no */ }; diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index dfd3b1e1f3..2c9829e31f 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -73,8 +73,22 @@ void term_job_server() */ JobId_t run_job(JCR *jcr) { - int stat, errstat; - JobId_t JobId = 0; + int stat; + if (setup_job(jcr)) { + /* Queue the job to be run */ + if ((stat = jobq_add(&job_queue, jcr)) != 0) { + berrno be; + Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.strerror(stat)); + return 0; + } + return jcr->JobId; + } + return 0; +} + +bool setup_job(JCR *jcr) +{ + int errstat; P(jcr->mutex); sm_check(__FILE__, __LINE__, true); @@ -117,7 +131,7 @@ JobId_t run_job(JCR *jcr) Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); goto bail_out; } - JobId = jcr->JobId = jcr->jr.JobId; + jcr->JobId = jcr->jr.JobId; Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n", jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel); @@ -133,17 +147,9 @@ JobId_t run_job(JCR *jcr) Dmsg0(200, "Add jrc to work queue\n"); - /* Queue the job to be run */ - if ((stat = jobq_add(&job_queue, jcr)) != 0) { - berrno be; - Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.strerror(stat)); - JobId = 0; - goto bail_out; - } - Dmsg0(100, "Done run_job()\n"); V(jcr->mutex); - return JobId; + return true; bail_out: if (jcr->fname) { @@ -151,7 +157,7 @@ bail_out: jcr->fname = NULL; } V(jcr->mutex); - return JobId; + return false; } diff --git a/bacula/src/dird/mac.c b/bacula/src/dird/mac.c index eb1d7835e1..81c4003a43 100644 --- a/bacula/src/dird/mac.c +++ b/bacula/src/dird/mac.c @@ -170,10 +170,11 @@ bool do_mac_init(JCR *jcr) */ bool do_mac(JCR *jcr) { - int stat; const char *Type; char ed1[100]; BSOCK *sd; + JOB *job, *tjob; + JCR *tjcr; switch(jcr->JobType) { case JT_MIGRATE: @@ -191,10 +192,37 @@ bool do_mac(JCR *jcr) } + Dmsg4(100, "Target: Name=%s JobId=%d Type=%c Level=%c\n", + jcr->target_jr.Name, jcr->target_jr.JobId, + jcr->target_jr.JobType, jcr->target_jr.JobLevel); + + Dmsg4(100, "Current: Name=%s JobId=%d Type=%c Level=%c\n", + jcr->jr.Name, jcr->jr.JobId, + jcr->jr.JobType, jcr->jr.JobLevel); + + LockRes(); + job = (JOB *)GetResWithName(R_JOB, jcr->jr.Name); + tjob = (JOB *)GetResWithName(R_JOB, jcr->target_jr.Name); + UnlockRes(); + if (!job || !tjob) { + return false; + } + + tjcr = jcr->target_jcr = new_jcr(sizeof(JCR), dird_free_jcr); + set_jcr_defaults(tjcr, tjob); + + if (!setup_job(tjcr)) { + return false; + } + tjcr->PoolId = jcr->PoolId; + tjcr->jr.PoolId = jcr->jr.PoolId; + tjcr->jr.FileSetId = jcr->jr.FileSetId; + /* Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start %s JobId %s, Job=%s\n"), Type, edit_uint64(jcr->JobId, ed1), jcr->Job); + set_jcr_job_status(jcr, JS_Running); set_jcr_job_status(jcr, JS_Running); Dmsg2(100, "JobId=%d JobLevel=%c\n", jcr->jr.JobId, jcr->jr.JobLevel); if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { @@ -202,6 +230,12 @@ bool do_mac(JCR *jcr) return false; } + if (!db_update_job_start_record(tjcr, tjcr->db, &tjcr->jr)) { + Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(tjcr->db)); + return false; + } + + /* * Open a message channel connection with the Storage * daemon. This is to let him know that our client @@ -210,6 +244,7 @@ bool do_mac(JCR *jcr) */ Dmsg0(110, "Open connection with storage daemon\n"); set_jcr_job_status(jcr, JS_WaitSD); + set_jcr_job_status(tjcr, JS_WaitSD); /* * Start conversation with Storage daemon */ @@ -220,7 +255,7 @@ bool do_mac(JCR *jcr) /* * Now start a job with the Storage daemon */ - if (!start_storage_daemon_job(jcr, jcr->storage, NULL)) { + if (!start_storage_daemon_job(jcr, tjcr->storage, jcr->storage)) { return false; } Dmsg0(150, "Storage daemon connection OK\n"); @@ -242,19 +277,16 @@ bool do_mac(JCR *jcr) return false; } - /* Pickup Job termination data */ set_jcr_job_status(jcr, JS_Running); + set_jcr_job_status(tjcr, JS_Running); + /* Pickup Job termination data */ /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/Errors */ wait_for_storage_daemon_termination(jcr); - if (jcr->JobStatus != JS_Terminated) { - stat = jcr->JobStatus; - } else { - stat = jcr->SDJobStatus; - } - if (stat == JS_Terminated) { - mac_cleanup(jcr, stat); + jcr->JobStatus = jcr->SDJobStatus; + if (jcr->JobStatus == JS_Terminated) { + mac_cleanup(jcr, jcr->JobStatus); return true; } return false; @@ -266,15 +298,17 @@ bool do_mac(JCR *jcr) */ void mac_cleanup(JCR *jcr, int TermCode) { - char sdt[50], edt[50]; - char ec3[30], ec4[30], ec5[30], compress[50]; + char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH]; + char ec1[30], ec2[30], ec3[30]; char term_code[100], sd_term_msg[100]; const char *term_msg; int msg_type; MEDIA_DBR mr; - double kbps, compression; + double kbps; utime_t RunTime; const char *Type; + JCR *tjcr = jcr->target_jcr; + POOL_MEM query(PM_MESSAGE); switch(jcr->JobType) { case JT_MIGRATE: @@ -291,12 +325,31 @@ void mac_cleanup(JCR *jcr, int TermCode) break; } + /* Ensure target is defined to avoid a lot of testing */ + if (!tjcr) { + tjcr = jcr; + } + tjcr->JobFiles = jcr->JobFiles = jcr->SDJobFiles; + tjcr->JobBytes = jcr->JobBytes = jcr->SDJobBytes; + tjcr->VolSessionId = jcr->VolSessionId; + tjcr->VolSessionTime = jcr->VolSessionTime; + Dmsg2(100, "Enter mac_cleanup %d %c\n", TermCode, TermCode); dequeue_messages(jcr); /* display any queued messages */ memset(&mr, 0, sizeof(mr)); set_jcr_job_status(jcr, TermCode); + set_jcr_job_status(tjcr, TermCode); + update_job_end_record(jcr); /* update database */ + update_job_end_record(tjcr); + + Mmsg(query, "UPDATE Job SET StartTime='%s',EndTime='%s'," + "JobTDate=%s WHERE JobId=%s", + jcr->target_jr.cStartTime, jcr->target_jr.cEndTime, + edit_uint64(jcr->target_jr.JobTDate, ec1), + edit_uint64(tjcr->jr.JobId, ec2)); + db_sql_query(tjcr->db, query.c_str(), NULL, NULL); if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting job record for stats: %s"), @@ -311,64 +364,7 @@ void mac_cleanup(JCR *jcr, int TermCode) set_jcr_job_status(jcr, JS_ErrorTerminated); } - /* Now update the bootstrap file if any */ - if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes && - jcr->job->WriteBootstrap) { - FILE *fd; - BPIPE *bpipe = NULL; - int got_pipe = 0; - char *fname = jcr->job->WriteBootstrap; - VOL_PARAMS *VolParams = NULL; - int VolCount; - - if (*fname == '|') { - fname++; - got_pipe = 1; - bpipe = open_bpipe(fname, 0, "w"); - fd = bpipe ? bpipe->wfd : NULL; - } else { - /* ***FIXME*** handle BASE */ - fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+"); - } - if (fd) { - VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId, - &VolParams); - if (VolCount == 0) { - Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to " - "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db)); - if (jcr->SDJobFiles != 0) { - set_jcr_job_status(jcr, JS_ErrorTerminated); - } - - } - for (int i=0; i < VolCount; i++) { - /* Write the record */ - fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName); - fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType); - fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId); - fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime); - fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile, - VolParams[i].EndFile); - fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock, - VolParams[i].EndBlock); - fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex, - VolParams[i].LastIndex); - } - if (VolParams) { - free(VolParams); - } - if (got_pipe) { - close_bpipe(bpipe); - } else { - fclose(fd); - } - } else { - berrno be; - Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n" - "%s: ERR=%s\n"), fname, be.strerror()); - set_jcr_job_status(jcr, JS_ErrorTerminated); - } - } + update_bootstrap_file(tjcr); msg_type = M_INFO; /* by default INFO message */ switch (jcr->JobStatus) { @@ -412,7 +408,7 @@ void mac_cleanup(JCR *jcr, int TermCode) } else { kbps = (double)jcr->jr.JobBytes / (1000 * RunTime); } - if (!db_get_job_volume_names(jcr, jcr->db, jcr->jr.JobId, &jcr->VolumeName)) { + if (!db_get_job_volume_names(tjcr, tjcr->db, tjcr->jr.JobId, &tjcr->VolumeName)) { /* * Note, if the job has erred, most likely it did not write any * tape, so suppress this "error" message since in that case @@ -420,27 +416,18 @@ void mac_cleanup(JCR *jcr, int TermCode) * normal exit should we complain about this error. */ if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes) { - Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); + Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(tjcr->db)); } - jcr->VolumeName[0] = 0; /* none */ + tjcr->VolumeName[0] = 0; /* none */ } - if (jcr->ReadBytes == 0) { - bstrncpy(compress, "None", sizeof(compress)); - } else { - compression = (double)100 - 100.0 * ((double)jcr->JobBytes / (double)jcr->ReadBytes); - if (compression < 0.5) { - bstrncpy(compress, "None", sizeof(compress)); - } else { - bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression); - } - } jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg)); // bmicrosleep(15, 0); /* for debugging SIGHUP */ Jmsg(jcr, msg_type, 0, _("Bacula %s (%s): %s\n" -" JobId: %d\n" +" Migration JobId: %u\n" +" Backup JobId: %u\n" " Job: %s\n" " Backup Level: %s%s\n" " Client: %s\n" @@ -451,7 +438,6 @@ void mac_cleanup(JCR *jcr, int TermCode) " SD Files Written: %s\n" " SD Bytes Written: %s\n" " Rate: %.1f KB/s\n" -" Software Compression: %s\n" " Volume name(s): %s\n" " Volume Session Id: %d\n" " Volume Session Time: %d\n" @@ -461,8 +447,9 @@ void mac_cleanup(JCR *jcr, int TermCode) " Termination: %s\n\n"), VERSION, LSMDATE, - edt, + edt, jcr->jr.JobId, + tjcr->jr.JobId, jcr->jr.Job, level_to_str(jcr->JobLevel), jcr->since, jcr->client->hdr.name, @@ -470,17 +457,17 @@ void mac_cleanup(JCR *jcr, int TermCode) jcr->pool->hdr.name, sdt, edt, - edit_uint64_with_commas(jcr->SDJobFiles, ec4), - edit_uint64_with_commas(jcr->SDJobBytes, ec5), + edit_uint64_with_commas(jcr->SDJobFiles, ec2), + edit_uint64_with_commas(jcr->SDJobBytes, ec3), (float)kbps, - compress, - jcr->VolumeName, + tjcr->VolumeName, jcr->VolSessionId, jcr->VolSessionTime, - edit_uint64_with_commas(mr.VolBytes, ec3), + edit_uint64_with_commas(mr.VolBytes, ec1), jcr->SDErrors, sd_term_msg, term_code); - Dmsg0(100, "Leave mac_cleanup()\n"); + Dmsg1(100, "Leave mac_cleanup() target_jcr=0x%x\n", jcr->target_jcr); + free_jcr(jcr->target_jcr); } diff --git a/bacula/src/dird/msgchan.c b/bacula/src/dird/msgchan.c index 04ac72bfee..faaaceb3e7 100644 --- a/bacula/src/dird/msgchan.c +++ b/bacula/src/dird/msgchan.c @@ -49,7 +49,7 @@ static char OK_device[] = "3000 OK use device device=%s\n"; /* Storage Daemon requests */ static char Job_start[] = "3010 Job %127s start\n"; static char Job_end[] = - "3099 Job %127s end JobStatus=%d JobFiles=%d JobBytes=%" lld "\n"; + "3099 Job %127s end JobStatus=%d JobFiles=%d JobBytes=%lld\n"; /* Forward referenced functions */ extern "C" void *msg_thread(void *arg); @@ -198,20 +198,19 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore) Dmsg1(100, ">stored: %s", sd->msg); } bnet_sig(sd, BNET_EOD); /* end of Devices */ - bnet_sig(sd, BNET_EOD); /* end of Storages */ - if (bget_dirmsg(sd) > 0) { - Dmsg1(100, "msg); - /* ****FIXME**** save actual device name */ - ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; - } else { - POOL_MEM err_msg; - pm_strcpy(err_msg, sd->msg); /* save message */ - Jmsg(jcr, M_FATAL, 0, _("\n" - " Storage daemon didn't accept Device \"%s\" because:\n %s"), - device_name.c_str(), err_msg.c_str()/* sd->msg */); - ok = false; - } - break; + } + bnet_sig(sd, BNET_EOD); /* end of Storages */ + if (bget_dirmsg(sd) > 0) { + Dmsg1(100, "msg); + /* ****FIXME**** save actual device name */ + ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; + } else { + POOL_MEM err_msg; + pm_strcpy(err_msg, sd->msg); /* save message */ + Jmsg(jcr, M_FATAL, 0, _("\n" + " Storage daemon didn't accept Device \"%s\" because:\n %s"), + device_name.c_str(), err_msg.c_str()/* sd->msg */); + ok = false; } } @@ -234,20 +233,19 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore) Dmsg1(100, ">stored: %s", sd->msg); } bnet_sig(sd, BNET_EOD); /* end of Devices */ - bnet_sig(sd, BNET_EOD); /* end of Storages */ - if (bget_dirmsg(sd) > 0) { - Dmsg1(100, "msg); - /* ****FIXME**** save actual device name */ - ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; - } else { - POOL_MEM err_msg; - pm_strcpy(err_msg, sd->msg); /* save message */ - Jmsg(jcr, M_FATAL, 0, _("\n" - " Storage daemon didn't accept Device \"%s\" because:\n %s"), - device_name.c_str(), err_msg.c_str()/* sd->msg */); - ok = false; - } - break; + } + bnet_sig(sd, BNET_EOD); /* end of Storages */ + if (bget_dirmsg(sd) > 0) { + Dmsg1(100, "msg); + /* ****FIXME**** save actual device name */ + ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; + } else { + POOL_MEM err_msg; + pm_strcpy(err_msg, sd->msg); /* save message */ + Jmsg(jcr, M_FATAL, 0, _("\n" + " Storage daemon didn't accept Device \"%s\" because:\n %s"), + device_name.c_str(), err_msg.c_str()/* sd->msg */); + ok = false; } } return ok; @@ -317,12 +315,13 @@ extern "C" void *msg_thread(void *arg) */ Dmsg0(100, "Start msg_thread loop\n"); while ((stat=bget_dirmsg(sd)) >= 0) { - Dmsg1(200, "msg); - if (sscanf(sd->msg, Job_start, &Job) == 1) { + int stat; + Dmsg1(3400, "msg); + if (sscanf(sd->msg, Job_start, Job) == 1) { continue; } - if (sscanf(sd->msg, Job_end, &Job, &JobStatus, &JobFiles, - &JobBytes) == 4) { + if ((stat=sscanf(sd->msg, Job_end, Job, &JobStatus, &JobFiles, + &JobBytes)) == 4) { jcr->SDJobStatus = JobStatus; /* termination status */ jcr->SDJobFiles = JobFiles; jcr->SDJobBytes = JobBytes; diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index d65fa46a00..ef34968eb3 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -43,6 +43,7 @@ extern int wait_for_job_termination(JCR *jcr); extern bool do_backup_init(JCR *jcr); extern bool do_backup(JCR *jcr); extern void backup_cleanup(JCR *jcr, int TermCode); +extern void update_bootstrap_file(JCR *jcr); /* bsr.c */ RBSR *new_bsr(); @@ -98,6 +99,7 @@ extern bool cancel_job(UAContext *ua, JCR *jcr); extern void init_jcr_job_record(JCR *jcr); extern void copy_storage(JCR *new_jcr, JCR *old_jcr); extern void set_storage(JCR *jcr, STORE *store); +extern bool setup_job(JCR *jcr); /* mac.c */ extern bool do_mac(JCR *jcr); diff --git a/bacula/src/dird/recycle.c b/bacula/src/dird/recycle.c index 61da3577f7..20d5b5db3d 100644 --- a/bacula/src/dird/recycle.c +++ b/bacula/src/dird/recycle.c @@ -76,8 +76,10 @@ int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr) Dmsg0(100, "Enter recycle_oldest_purged_volume\n"); oldest.MediaId = 0; if (InChanger) { - Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType, - "AND InChanger=1 "); + char changer[100]; + bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s", + mr->StorageId); + Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType, changer); } else { Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType, ""); } diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index 747d7ff4ad..e426ed8969 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -258,7 +258,7 @@ static int defaultscmd(UAContext *ua, const char *cmd) STORE *storage; POOL *pool; - if (ua->argc != 2) { + if (ua->argc != 2 || !ua->argv[1]) { return 1; } diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 913adb9f1b..9a94681b0c 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -9,7 +9,7 @@ */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -266,7 +266,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist) } else if (strcasecmp(ua->argk[i], N_("jobtotals")) == 0) { db_list_job_totals(ua->jcr, ua->db, &jr, prtit, ua); - /* List JOBID */ + /* List JOBID=nn */ } else if (strcasecmp(ua->argk[i], N_("jobid")) == 0) { if (ua->argv[i]) { jobid = str_to_int64(ua->argv[i]); @@ -276,12 +276,19 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist) } } - /* List JOB */ + /* List JOB=xxx */ } else if (strcasecmp(ua->argk[i], N_("job")) == 0 && ua->argv[i]) { bstrncpy(jr.Job, ua->argv[i], MAX_NAME_LENGTH); jr.JobId = 0; db_list_job_records(ua->jcr, ua->db, &jr, prtit, ua, llist); + /* List JOBNAME=xxx */ + } else if (strcasecmp(ua->argk[i], N_("job")) == 0 && ua->argv[i]) { + bstrncpy(jr.Name, ua->argv[i], MAX_NAME_LENGTH); + jr.JobId = 0; + db_list_job_records(ua->jcr, ua->db, &jr, prtit, ua, llist); + + /* List FILES */ } else if (strcasecmp(ua->argk[i], N_("files")) == 0) { diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index d3c9a0f18f..137462ddb0 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -8,7 +8,7 @@ * Version $Id$ */ /* - Copyright (C) 2002-2005 Kern Sibbald + Copyright (C) 2002-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -163,7 +163,7 @@ int prunecmd(UAContext *ua, const char *cmd) NULL}; if (!open_db(ua)) { - return 01; + return false; } /* First search args */ @@ -177,32 +177,32 @@ int prunecmd(UAContext *ua, const char *cmd) case 0: /* prune files */ client = get_client_resource(ua); if (!client || !confirm_retention(ua, &client->FileRetention, "File")) { - return 0; + return false; } prune_files(ua, client); - return 1; + return true; case 1: /* prune jobs */ client = get_client_resource(ua); if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) { - return 0; + return false; } /* ****FIXME**** allow user to select JobType */ prune_jobs(ua, client, JT_BACKUP); return 1; case 2: /* prune volume */ if (!select_pool_and_media_dbr(ua, &pr, &mr)) { - return 0; + return false; } if (!confirm_retention(ua, &mr.VolRetention, "Volume")) { - return 0; + return false; } prune_volume(ua, &mr); - return 1; + return true; default: break; } - return 1; + return true; } /* @@ -240,7 +240,7 @@ int prune_files(UAContext *ua, CLIENT *client) /* Select Jobs -- for counting */ Mmsg(query, select_job, edit_uint64(now - period, ed1), edit_int64(cr.ClientId, ed2)); - Dmsg1(050, "select sql=%s\n", query); + Dmsg3(050, "select now=%u period=%u sql=%s\n", (uint32_t)now, (uint32_t)period, query); if (!db_sql_query(ua->db, query, file_count_handler, (void *)&del)) { if (ua->verbose) { bsendmsg(ua, "%s", db_strerror(ua->db)); @@ -270,7 +270,7 @@ int prune_files(UAContext *ua, CLIENT *client) for (i=0; i < del.num_ids; i++) { Mmsg(query, del_File, edit_int64(del.JobId[i], ed1)); - Dmsg1(050, "Delete JobId=%s\n", ed1); + Dmsg1(000, "Delete Files JobId=%s\n", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); /* * Now mark Job as having files purged. This is necessary to @@ -280,7 +280,7 @@ int prune_files(UAContext *ua, CLIENT *client) */ Mmsg(query, upd_Purged, edit_int64(del.JobId[i], ed1)); db_sql_query(ua->db, query, NULL, (void *)NULL); - Dmsg1(050, "Del sql=%s\n", query); + Dmsg1(000, "Update Purged sql=%s\n", query); } edit_uint64_with_commas(del.num_ids, ed1); bsendmsg(ua, _("Pruned Files from %s Jobs for client %s from catalog.\n"), @@ -304,7 +304,7 @@ static void drop_temp_tables(UAContext *ua) } } -static int create_temp_tables(UAContext *ua) +static bool create_temp_tables(UAContext *ua) { int i; /* Create temp tables and indicies */ @@ -312,10 +312,10 @@ static int create_temp_tables(UAContext *ua) if (!db_sql_query(ua->db, create_deltabs[i], NULL, (void *)NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); Dmsg0(050, "create DelTables table failed\n"); - return 0; + return false; } } - return 1; + return true; } diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index fb1874695c..49f6aa9f29 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -11,7 +11,7 @@ * Version $Id$ */ /* - Copyright (C) 2002-2005 Kern Sibbald + Copyright (C) 2002-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -309,7 +309,7 @@ static int purge_files_from_client(UAContext *ua, CLIENT *client) for (i=0; i < del.num_ids; i++) { edit_int64(del.JobId[i], ed1); - Dmsg1(050, "Delete JobId=%s\n", ed1); + Dmsg1(050, "Delete Files JobId=%s\n", ed1); Mmsg(query, "DELETE FROM File WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); /* @@ -320,7 +320,7 @@ static int purge_files_from_client(UAContext *ua, CLIENT *client) */ Mmsg(query, "UPDATE Job Set PurgedFiles=1 WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Dmsg1(050, "Del sql=%s\n", query); + Dmsg1(050, "Update Purged sql=%s\n", query); } bsendmsg(ua, _("%d Files for client \"%s\" purged from %s catalog.\n"), del.num_ids, client->hdr.name, client->catalog->hdr.name); @@ -395,7 +395,7 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client) */ for (i=0; i < del.num_ids; i++) { edit_int64(del.JobId[i], ed1); - Dmsg1(050, "Delete JobId=%s\n", ed1); + Dmsg1(050, "Delete Files JobId=%s\n", ed1); if (!del.PurgedFiles[i]) { Mmsg(query, "DELETE FROM File WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); @@ -404,11 +404,11 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client) Mmsg(query, "DELETE FROM Job WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Dmsg1(050, "Del sql=%s\n", query); + Dmsg1(050, "Delete Job sql=%s\n", query); Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", ed1); db_sql_query(ua->db, query, NULL, (void *)NULL); - Dmsg1(050, "Del sql=%s\n", query); + Dmsg1(050, "Delete JobMedia sql=%s\n", query); } bsendmsg(ua, _("%d Jobs for client %s purged from %s catalog.\n"), del.num_ids, client->hdr.name, client->catalog->hdr.name); @@ -580,5 +580,5 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) } else { bsendmsg(ua, _("Cannot purge Volume with VolStatus=%s\n"), mr->VolStatus); } - return strcpy(mr->VolStatus, "Purged") == 0; + return strcmp(mr->VolStatus, "Purged") == 0; } diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index e1578c1eba..57c5d9a734 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -194,7 +194,7 @@ int restore_cmd(UAContext *ua, const char *cmd) if (find_arg(ua, N_("yes")) > 0) { pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */ } - Dmsg1(400, "Submitting: %s\n", ua->cmd); + Dmsg1(100, "Submitting: %s\n", ua->cmd); parse_ua_args(ua); run_cmd(ua, ua->cmd); free_rx(&rx); diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 7a3b2e8254..17f9e1de7f 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -7,7 +7,7 @@ * Version $Id$ */ /* - Copyright (C) 2001-2005 Kern Sibbald + Copyright (C) 2001-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -631,6 +631,7 @@ int get_job_dbr(UAContext *ua, JOB_DBR *jr) bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job)); } else if (strcasecmp(ua->argk[i], N_("jobid")) == 0 && ua->argv[i]) { jr->JobId = str_to_int64(ua->argv[i]); + jr->Job[0] = 0; } else { continue; } @@ -643,6 +644,16 @@ int get_job_dbr(UAContext *ua, JOB_DBR *jr) return jr->JobId; } + jr->JobId = 0; + jr->Job[0] = 0; + + for (i=1; iargc; i++) { + if (strcasecmp(ua->argk[i], N_("jobname")) == 0 && ua->argv[i]) { + jr->JobId = 0; + bstrncpy(jr->Name, ua->argv[i], sizeof(jr->Name)); + break; + } + } if (!select_job_dbr(ua, jr)) { /* try once more */ return 0; } diff --git a/bacula/src/gnome2-console/callbacks.c b/bacula/src/gnome2-console/callbacks.c index f6fbfb930e..e46b575e71 100644 --- a/bacula/src/gnome2-console/callbacks.c +++ b/bacula/src/gnome2-console/callbacks.c @@ -14,7 +14,7 @@ #include "support.h" #define KEY_Enter 65293 -#define KEY_Up 65362 +#define KEY_Up 65362 #define KEY_Down 65364 #define KEY_Left 65361 #define KEY_Right 65363 @@ -127,9 +127,9 @@ static void add_to_history(gchar *ecmd) int i; GList *hp; for (i=0; idata); - hist = g_list_remove(hist, hp->data); + hp = g_list_next(hist); + free(hp->data); + hist = g_list_remove(hist, hp->data); } hist_len -= HIST_DEL; } @@ -153,34 +153,34 @@ on_entry1_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_d gtk_entry_set_text((GtkEntry *)entry1, ""); } else if (event->keyval == KEY_Up) { if (!hc) { - if (!hist) { - return FALSE; - } - hc = g_list_last(hist); + if (!hist) { + return FALSE; + } + hc = g_list_last(hist); } else { - hc = g_list_previous(hc); + hc = g_list_previous(hc); } if (!hc) { - if (!hist) { - return FALSE; - } - hc = g_list_first(hist); + if (!hist) { + return FALSE; + } + hc = g_list_first(hist); } gtk_entry_set_text((GtkEntry *)entry1, (gchar *)hc->data); } else if (event->keyval == KEY_Down) { if (!hc) { - if (!hist) { - return FALSE; - } - hc = g_list_first(hist); + if (!hist) { + return FALSE; + } + hc = g_list_first(hist); } else { - hc = g_list_next(hc); + hc = g_list_next(hc); } if (!hc) { - if (!hist) { - return FALSE; - } - hc = g_list_last(hist); + if (!hist) { + return FALSE; + } + hc = g_list_last(hist); } gtk_entry_set_text((GtkEntry *)entry1, (gchar *)hc->data); } @@ -294,30 +294,30 @@ static void set_run_defaults() while (bnet_recv(UA_sock) > 0) { def = strchr(UA_sock->msg, '='); if (!def) { - continue; + continue; } *def++ = 0; if (strcmp(UA_sock->msg, "job") == 0 || - strcmp(UA_sock->msg, "when") == 0) { - continue; + strcmp(UA_sock->msg, "when") == 0) { + continue; } /* Where is an entry box */ if (strcmp(UA_sock->msg, "where") == 0) { - entry = lookup_widget(run_dialog, "entry_where"); - gtk_entry_set_text(GTK_ENTRY(entry), def); - continue; + entry = lookup_widget(run_dialog, "entry_where"); + gtk_entry_set_text(GTK_ENTRY(entry), def); + continue; } /* Now handle combo boxes */ list = find_combo_list(UA_sock->msg); if (!list) { - continue; + continue; } item = g_list_find_custom(list, def, compare_func); bsnprintf(cmd, sizeof(cmd), "combo_%s", UA_sock->msg); combo = lookup_widget(run_dialog, cmd); if (!combo) { - continue; + continue; } pos = g_list_position(list, item); gtk_list_select_item(GTK_LIST(GTK_COMBO(combo)->list), pos); @@ -405,9 +405,9 @@ on_run_ok_clicked(GtkButton *button, gpointer user_data) } bsnprintf(cmd, sizeof(cmd), - "run job=\"%s\" fileset=\"%s\" level=%s client=\"%s\" pool=\"%s\" " - "when=\"%s\" where=\"%s\" storage=\"%s\"", - job, fileset, level, client, pool, when, where, storage); + "run job=\"%s\" fileset=\"%s\" level=%s client=\"%s\" pool=\"%s\" " + "when=\"%s\" where=\"%s\" storage=\"%s\"", + job, fileset, level, client, pool, when, where, storage); write_director(cmd); set_text(cmd, strlen(cmd)); write_director("yes"); @@ -479,8 +479,8 @@ on_label_ok_clicked(GtkButton *button, gpointer user_data) } bsnprintf(cmd, sizeof(cmd), - "label name=\"%s\" pool=\"%s\" storage=\"%s\" slot=%s", - volume, pool, storage, slot); + "label volume=\"%s\" pool=\"%s\" storage=\"%s\" slot=%s", + volume, pool, storage, slot); write_director(cmd); set_text(cmd, strlen(cmd)); } @@ -516,12 +516,12 @@ on_select_files_button_clicked(GtkButton *button, gpointer user_data) } bsnprintf(cmd, sizeof(cmd), - "restore select current fileset=\"%s\" client=\"%s\" pool=\"%s\" " - "storage=\"%s\"", fileset, client, pool, storage); + "restore select current fileset=\"%s\" client=\"%s\" pool=\"%s\" " + "storage=\"%s\"", fileset, client, pool, storage); write_director(cmd); set_text(cmd, strlen(cmd)); gtk_widget_show(restore_file_selection); - select_restore_files(); /* put up select files dialog */ + select_restore_files(); /* put up select files dialog */ } void @@ -554,96 +554,96 @@ on_restore_files_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_ void -on_new1_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_new1_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_open1_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_open1_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_save1_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_save1_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_save_as1_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_save_as1_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_quit1_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_quit1_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_cut2_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_cut2_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_copy2_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_copy2_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_paste2_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_paste2_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_clear2_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_clear2_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_properties1_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_properties1_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_preferences2_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_preferences2_activate (GtkMenuItem *menuitem, + gpointer user_data) { } void -on_about2_activate (GtkMenuItem *menuitem, - gpointer user_data) +on_about2_activate (GtkMenuItem *menuitem, + gpointer user_data) { } @@ -668,28 +668,28 @@ void set_restore_dialog_defaults() while (bnet_recv(UA_sock) > 0) { def = strchr(UA_sock->msg, '='); if (!def) { - continue; + continue; } *def++ = 0; if (strcmp(UA_sock->msg, "job") == 0 || - strcmp(UA_sock->msg, "when") == 0 || - strcmp(UA_sock->msg, "where") == 0 || - strcmp(UA_sock->msg, "messages") == 0 || - strcmp(UA_sock->msg, "level") == 0 || - strcmp(UA_sock->msg, "type") == 0) { - continue; + strcmp(UA_sock->msg, "when") == 0 || + strcmp(UA_sock->msg, "where") == 0 || + strcmp(UA_sock->msg, "messages") == 0 || + strcmp(UA_sock->msg, "level") == 0 || + strcmp(UA_sock->msg, "type") == 0) { + continue; } /* Now handle combo boxes */ list = find_combo_list(UA_sock->msg); if (!list) { - continue; + continue; } item = g_list_find_custom(list, def, compare_func); bsnprintf(cmd, sizeof(cmd), "combo_restore_%s", UA_sock->msg); combo = lookup_widget(restore_dialog, cmd); if (!combo) { - continue; + continue; } pos = g_list_position(list, item); gtk_list_select_item(GTK_LIST(GTK_COMBO(combo)->list), pos); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index bc6700de2c..5d5c761a7c 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -164,8 +164,10 @@ public: volatile bool sd_msg_thread_done; /* Set when Storage message thread terms */ BSOCK *ua; /* User agent */ JOB *job; /* Job resource */ - JOB *verify_job; /* Job resource of verify target job */ - JOB *migration_job; /* Job resource of migration target job */ + union { + JOB *verify_job; /* Job resource of verify target job */ + JOB *migration_job; /* Job resource of migration target job */ + }; alist *storage; /* Storage possibilities */ STORE *store; /* Storage daemon selected */ CLIENT *client; /* Client resource */ @@ -189,6 +191,7 @@ public: POOLMEM *fname; /* name to put into catalog */ JOB_DBR jr; /* Job DB record for current job */ JOB_DBR target_jr; /* target job */ + JCR *target_jcr; /* target job control record */ char FSCreateTime[MAX_TIME_LENGTH]; /* FileSet CreateTime as returned from DB */ char since[MAX_TIME_LENGTH]; /* since time */ uint32_t RestoreJobId; /* Id specified by UA */ diff --git a/bacula/src/lib/attr.c b/bacula/src/lib/attr.c index 379069075c..1b56f86618 100644 --- a/bacula/src/lib/attr.c +++ b/bacula/src/lib/attr.c @@ -59,13 +59,13 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) * */ attr->stream = stream; - Dmsg1(100, "Attr: %s\n", rec); + Dmsg1(400, "Attr: %s\n", rec); if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) { Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec); Dmsg1(100, "\nError scanning attributes. %s\n", rec); return 0; } - Dmsg2(100, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type); + Dmsg2(400, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type); if (attr->type & AR_DATA_STREAM) { attr->data_stream = 1; } else { @@ -96,7 +96,7 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) from_base64(&val, p); attr->data_stream = (int32_t)val; } - Dmsg7(200, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n", + Dmsg7(400, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n", attr->file_index, attr->type, attr->fname, attr->attr, attr->lname, attr->attrEx, attr->data_stream); *attr->ofname = 0; diff --git a/bacula/src/lib/edit.c b/bacula/src/lib/edit.c index 0903704375..a322931520 100644 --- a/bacula/src/lib/edit.c +++ b/bacula/src/lib/edit.c @@ -96,6 +96,39 @@ char *edit_uint64_with_commas(uint64_t val, char *buf) return add_commas(buf, buf); } +/* + * Edit an integer into "human-readable" format with four or fewer + * significant digits followed by a suffix that indicates the scale + * factor. The buf array inherits a 27 byte minimim length + * requirement from edit_unit64_with_commas(), although the output + * string is limited to eight characters. + */ +char *edit_uint64_with_suffix(uint64_t val, char *buf) +{ + int commas = 0; + char *c, mbuf[50]; + char *suffix[] = + { "", "K", "M", "G", "T", "P", "E", "Z", "Y", "FIX ME" }; + int suffixes = sizeof(suffix) / sizeof(*suffix); + + edit_uint64_with_commas(val, mbuf); + + if ((c = strchr(mbuf, ',')) != NULL) { + commas++; + *c++ = '.'; + while ((c = strchr(c, ',')) != NULL) { + commas++; + *c++ = '\0'; + } + mbuf[5] = '\0'; // drop this to get '123.456 TB' rather than '123.4 TB' + } + + if (commas >= suffixes) + commas = suffixes - 1; + bsnprintf(buf, 27, "%s %s", mbuf, suffix[commas]); + return buf; +} + /* * Edit an integer number, the supplied buffer * must be at least 27 bytes long. The incoming number diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index f52bed5c51..6c7d6daa0d 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -66,6 +66,9 @@ static pthread_mutex_t jcr_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t job_start_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t last_jobs_mutex = PTHREAD_MUTEX_INITIALIZER; + + void lock_jobs() { P(job_start_mutex); @@ -177,14 +180,12 @@ uint64_t write_last_jobs_list(int fd, uint64_t addr) void lock_last_jobs_list() { - /* Use jcr chain mutex */ - lock_jcr_chain(); + P(last_jobs_mutex); } void unlock_last_jobs_list() { - /* Use jcr chain mutex */ - unlock_jcr_chain(); + V(last_jobs_mutex); } /* @@ -667,6 +668,7 @@ static void jcr_timeout_check(watchdog_t *self) * blocked for more than specified max time. */ foreach_jcr(jcr) { + Dmsg2(3400, "jcr_timeout_check JobId=%u jcr=0x%x\n", jcr->JobId, jcr); if (jcr->JobId == 0) { continue; } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 4d54d50156..eedbc018cb 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -155,6 +155,7 @@ uint64_t str_to_uint64(char *str); int64_t str_to_int64(char *str); #define str_to_int32(str) ((int32_t)str_to_int64(str)) char * edit_uint64_with_commas (uint64_t val, char *buf); +char * edit_uint64_with_suffix (uint64_t val, char *buf); char * add_commas (char *val, char *buf); char * edit_uint64 (uint64_t val, char *buf); char * edit_int64 (int64_t val, char *buf); diff --git a/bacula/src/lib/watchdog.c b/bacula/src/lib/watchdog.c index 7784681161..43384ffc5d 100755 --- a/bacula/src/lib/watchdog.c +++ b/bacula/src/lib/watchdog.c @@ -7,22 +7,17 @@ * */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -262,6 +257,7 @@ walk_list: foreach_dlist(p, wd_queue) { if (p->next_fire <= watchdog_time) { /* Run the callback */ + Dmsg2(3400, "Watchdog callback p=0x%p fire=%d\n", p, p->next_fire); p->callback(p); /* Reschedule (or move to inactive list if it's a one-shot timer) */ @@ -273,7 +269,7 @@ walk_list: p->next_fire = watchdog_time + p->interval; } } - if (p->next_fire < next_time) { + if (p->next_fire <= next_time) { next_time = p->next_fire; } } diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index fa69e3b4fa..7977f5468b 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -190,12 +190,12 @@ DCR *acquire_device_for_read(DCR *dcr) Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName); if (dev->open(dcr, OPEN_READ_ONLY) < 0) { if (dev->dev_errno == EIO) { /* no tape loaded */ - Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed (EIO): ERR=%s\n"), + Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed (EIO): ERR=%s\n"), dev->print_name(), dcr->VolumeName, strerror_dev(dev)); goto default_path; } - Jmsg3(jcr, M_FATAL, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"), + Jmsg3(jcr, M_FATAL, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"), dev->print_name(), dcr->VolumeName, strerror_dev(dev)); goto get_out; } @@ -414,7 +414,6 @@ get_out: dcr->reserved_device = false; } V(dev->mutex); - free_dcr(dcr); dev->unblock(); return NULL; } @@ -429,7 +428,6 @@ bool release_device(DCR *dcr) JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; bool ok = true; - bool was_reading = false; lock_device(dev); Dmsg1(100, "release_device device is %s\n", dev->is_tape()?"tape":"disk"); @@ -443,7 +441,6 @@ bool release_device(DCR *dcr) if (dev->can_read()) { dev->clear_read(); /* clear read bit */ - was_reading = true; /******FIXME**** send read volume usage statistics to director */ @@ -516,11 +513,12 @@ bool release_device(DCR *dcr) free_pool_memory(alert); } unlock_device(dev); - free_dcr(dcr); - if (was_reading) { + if (jcr->read_dcr == dcr) { jcr->read_dcr = NULL; - } else { + } + if (jcr->dcr == dcr) { jcr->dcr = NULL; } + free_dcr(dcr); return ok; } diff --git a/bacula/src/stored/append.c b/bacula/src/stored/append.c index cfa936df02..89517246c8 100644 --- a/bacula/src/stored/append.c +++ b/bacula/src/stored/append.c @@ -69,6 +69,7 @@ bool do_append_data(JCR *jcr) if (!acquire_device_for_append(dcr)) { set_jcr_job_status(jcr, JS_ErrorTerminated); + jcr->dcr = NULL; return false; } diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index 167a7145b5..45cef4547c 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -8,7 +8,7 @@ * */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index ec05f86f35..ed15012579 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -5,7 +5,7 @@ * Version $Id$ */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -409,6 +409,7 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess case EOS_LABEL: rtype = _("End Job Session"); break; + case 0: case EOM_LABEL: rtype = _("End of Medium"); break; diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index a74f27554d..ab47d88fe9 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -10,7 +10,7 @@ * Version $Id$ */ /* - Copyright (C) 2001-2005 Kern Sibbald + Copyright (C) 2001-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 8e1e224f1e..6fadf6c981 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -612,7 +612,7 @@ bool DEVICE::rewind(DCR *dcr) unsigned int i; bool first = true; - Dmsg3(29, "rewind res=%d fd=%d %s\n", reserved_device, fd, print_name()); + Dmsg3(400, "rewind res=%d fd=%d %s\n", reserved_device, fd, print_name()); if (fd < 0) { if (!is_dvd()) { /* In case of major error, the fd is not open on DVD, so we don't want to abort. */ dev_errno = EBADF; diff --git a/bacula/src/stored/dvd.c b/bacula/src/stored/dvd.c index f68ac089d0..fd411fffaf 100644 --- a/bacula/src/stored/dvd.c +++ b/bacula/src/stored/dvd.c @@ -65,7 +65,7 @@ static void add_file_and_part_name(DEVICE *dev, POOL_MEM &archive_name) bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part); pm_strcat(archive_name, partnumber); } - Dmsg1(100, "Exit make_dvd_filename: arch=%s\n", archive_name.c_str()); + Dmsg1(400, "Exit make_dvd_filename: arch=%s\n", archive_name.c_str()); } /* Mount the device. @@ -259,7 +259,7 @@ void update_free_space_dev(DEVICE* dev) while (1) { if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) { - Dmsg1(100, "Free space program run : %s\n", results); + Dmsg1(400, "Free space program run : %s\n", results); free = str_to_int64(results); if (free >= 0) { dev->free_space = free; @@ -472,7 +472,7 @@ int dvd_open_next_part(DCR *dcr) } } - Dmsg2(100, "num_parts=%d part=%d\n", dev->num_parts, dev->part); + Dmsg2(400, "num_parts=%d part=%d\n", dev->num_parts, dev->part); dev->VolCatInfo.VolCatParts = dev->part; make_spooled_dvd_filename(dev, archive_name); /* makes spool name */ @@ -497,11 +497,11 @@ int dvd_open_next_part(DCR *dcr) * think it is not needed. */ if (dev->num_parts < dev->part) { - Dmsg2(100, "Set npart=%d to part=%d\n", dev->num_parts, dev->part); + Dmsg2(400, "Set npart=%d to part=%d\n", dev->num_parts, dev->part); dev->num_parts = dev->part; dev->VolCatInfo.VolCatParts = dev->part; } - Dmsg2(50, "Call dev->open(vol=%s, mode=%d\n", dev->VolCatInfo.VolCatName, + Dmsg2(400, "Call dev->open(vol=%s, mode=%d\n", dev->VolCatInfo.VolCatName, dev->openmode); /* Open next part */ @@ -537,17 +537,17 @@ int dvd_open_first_part(DCR *dcr, int mode) dev->part_start = 0; dev->part = 0; - Dmsg2(50, "Call dev->open(vol=%s, mode=%d)\n", dcr->VolCatInfo.VolCatName, + Dmsg2(400, "Call dev->open(vol=%s, mode=%d)\n", dcr->VolCatInfo.VolCatName, mode); int append = dev->can_append(); if (dev->open(dcr, mode) < 0) { - Dmsg0(50, "open dev() failed\n"); + Dmsg0(400, "open dev() failed\n"); return -1; } if (append && (dev->part == dev->num_parts)) { /* If needed, set the append flag back */ dev->set_append(); } - Dmsg2(50, "Leave open_first_part state=%s append=%d\n", dev->is_open()?"open":"not open", dev->can_append()); + Dmsg2(400, "Leave open_first_part state=%s append=%d\n", dev->is_open()?"open":"not open", dev->can_append()); return dev->fd; } @@ -560,17 +560,17 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) off_t pos; char ed1[50], ed2[50]; - Dmsg3(100, "Enter lseek_dev fd=%d part=%d nparts=%d\n", dev->fd, + Dmsg3(400, "Enter lseek_dev fd=%d part=%d nparts=%d\n", dev->fd, dev->part, dev->num_parts); if (!dev->is_dvd()) { - Dmsg0(100, "Using sys lseek\n"); + Dmsg0(400, "Using sys lseek\n"); return lseek(dev->fd, offset, whence); } dcr = (DCR *)dev->attached_dcrs->first(); /* any dcr will do */ switch(whence) { case SEEK_SET: - Dmsg2(100, "lseek_dev SEEK_SET to %s (part_start=%s)\n", + Dmsg2(400, "lseek_dev SEEK_SET to %s (part_start=%s)\n", edit_uint64(offset, ed1), edit_uint64(dev->part_start, ed2)); if ((uint64_t)offset >= dev->part_start) { if (((uint64_t)offset == dev->part_start) || ((uint64_t)offset < (dev->part_start+dev->part_size))) { @@ -583,7 +583,7 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) } else { /* Load next part, and start again */ if (dvd_open_next_part(dcr) < 0) { - Dmsg0(100, "lseek_dev failed while trying to open the next part\n"); + Dmsg0(400, "lseek_dev failed while trying to open the next part\n"); return -1; } return lseek_dev(dev, offset, SEEK_SET); @@ -596,27 +596,27 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) * until the right one is loaded */ if (dvd_open_first_part(dcr, dev->openmode) < 0) { - Dmsg0(100, "lseek_dev failed while trying to open the first part\n"); + Dmsg0(400, "lseek_dev failed while trying to open the first part\n"); return -1; } return lseek_dev(dev, offset, SEEK_SET); } break; case SEEK_CUR: - Dmsg1(100, "lseek_dev SEEK_CUR to %s\n", edit_uint64(offset, ed1)); + Dmsg1(400, "lseek_dev SEEK_CUR to %s\n", edit_uint64(offset, ed1)); if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) { return pos; } pos += dev->part_start; if (offset == 0) { - Dmsg1(100, "lseek_dev SEEK_CUR returns %s\n", edit_uint64(pos, ed1)); + Dmsg1(400, "lseek_dev SEEK_CUR returns %s\n", edit_uint64(pos, ed1)); return pos; } else { /* Not used in Bacula, but should work */ return lseek_dev(dev, pos, SEEK_SET); } break; case SEEK_END: - Dmsg1(100, "lseek_dev SEEK_END to %s\n", edit_uint64(offset, ed1)); + Dmsg1(400, "lseek_dev SEEK_END to %s\n", edit_uint64(offset, ed1)); /* * Bacula does not use offsets for SEEK_END * Also, Bacula uses seek_end only when it wants to @@ -625,7 +625,7 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) * itself is read-only (as currently implemented). */ if (offset > 0) { /* Not used by bacula */ - Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %s\n", + Dmsg1(400, "lseek_dev SEEK_END called with an invalid offset %s\n", edit_uint64(offset, ed1)); errno = EINVAL; return -1; @@ -637,7 +637,7 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) { return pos; } else { - Dmsg1(100, "lseek_dev SEEK_END returns %s\n", + Dmsg1(400, "lseek_dev SEEK_END returns %s\n", edit_uint64(pos + dev->part_start, ed1)); return pos + dev->part_start; } @@ -652,19 +652,19 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) int modesave = dev->openmode; /* Works because num_parts > 0. */ if (dvd_open_first_part(dcr, OPEN_READ_ONLY) < 0) { - Dmsg0(100, "lseek_dev failed while trying to open the first part\n"); + Dmsg0(400, "lseek_dev failed while trying to open the first part\n"); return -1; } if (dev->num_parts > 0) { while (dev->part < (dev->num_parts-1)) { if (dvd_open_next_part(dcr) < 0) { - Dmsg0(100, "lseek_dev failed while trying to open the next part\n"); + Dmsg0(400, "lseek_dev failed while trying to open the next part\n"); return -1; } } dev->openmode = modesave; if (dvd_open_next_part(dcr) < 0) { - Dmsg0(100, "lseek_dev failed while trying to open the next part\n"); + Dmsg0(400, "lseek_dev failed while trying to open the next part\n"); return -1; } } @@ -688,7 +688,7 @@ bool dvd_close_job(DCR *dcr) * that requires mount, it will be written to the device. */ if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) { - Dmsg1(100, "Writing last part=%d write_partafter_job is set.\n", + Dmsg1(400, "Writing last part=%d write_partafter_job is set.\n", dev->part); if (dev->part < dev->num_parts) { Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"), @@ -721,17 +721,17 @@ bool truncate_dvd(DCR *dcr) { dcr->VolCatInfo.VolCatParts = 0; dev->VolCatInfo.VolCatParts = 0; - Dmsg0(100, "truncate_dvd: Opening first part (1)...\n"); + Dmsg0(400, "truncate_dvd: Opening first part (1)...\n"); dev->truncating = true; if (dvd_open_first_part(dcr, OPEN_READ_WRITE) < 0) { - Dmsg0(100, "truncate_dvd: Error while opening first part (1).\n"); + Dmsg0(400, "truncate_dvd: Error while opening first part (1).\n"); dev->truncating = false; return false; } dev->truncating = false; - Dmsg0(100, "truncate_dvd: Truncating...\n"); + Dmsg0(400, "truncate_dvd: Truncating...\n"); /* If necessary, truncate it. */ if (ftruncate(dev->fd, 0) != 0) { @@ -745,10 +745,10 @@ bool truncate_dvd(DCR *dcr) { dev->fd = -1; dev->clear_opened(); - Dmsg0(100, "truncate_dvd: Opening first part (2)...\n"); + Dmsg0(400, "truncate_dvd: Opening first part (2)...\n"); if (!dvd_write_part(dcr)) { - Dmsg0(100, "truncate_dvd: Error while writing to DVD.\n"); + Dmsg0(400, "truncate_dvd: Error while writing to DVD.\n"); return false; } @@ -758,7 +758,7 @@ bool truncate_dvd(DCR *dcr) { dev->VolCatInfo.VolCatParts = 0; if (dvd_open_first_part(dcr, OPEN_READ_WRITE) < 0) { - Dmsg0(100, "truncate_dvd: Error while opening first part (2).\n"); + Dmsg0(400, "truncate_dvd: Error while opening first part (2).\n"); return false; } diff --git a/bacula/src/stored/match_bsr.c b/bacula/src/stored/match_bsr.c index b4aa6831c3..0b38996036 100755 --- a/bacula/src/stored/match_bsr.c +++ b/bacula/src/stored/match_bsr.c @@ -7,7 +7,7 @@ * Version $Id$ */ /* - Copyright (C) 2002-2005 Kern Sibbald + Copyright (C) 2002-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -278,9 +278,11 @@ static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec, bool done) { if (bsr->done) { + Dmsg0(300, "bsr->done set\n"); goto no_match; } if (!match_volume(bsr, bsr->volume, volrec, 1)) { + Dmsg2(300, "bsr vol=%s != rec vol=%s\n", bsr->volume, volrec); goto no_match; } if (!match_volfile(bsr, bsr->volfile, rec, 1)) { @@ -326,22 +328,28 @@ static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, * the rec->bsr = bsr optimization above. */ if (!match_jobid(bsr, bsr->JobId, sessrec, 1)) { + Dmsg0(300, "fail on JobId\n"); goto no_match; } if (!match_job(bsr, bsr->job, sessrec, 1)) { + Dmsg0(300, "fail on Job\n"); goto no_match; } if (!match_client(bsr, bsr->client, sessrec, 1)) { + Dmsg0(300, "fail on Client\n"); goto no_match; } if (!match_job_type(bsr, bsr->JobType, sessrec, 1)) { + Dmsg0(300, "fail on Job type\n"); goto no_match; } if (!match_job_level(bsr, bsr->JobLevel, sessrec, 1)) { + Dmsg0(300, "fail on Job level\n"); goto no_match; } if (!match_stream(bsr, bsr->stream, rec, 1)) { + Dmsg0(300, "fail on stream\n"); goto no_match; } return 1; diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index 42d5741d22..c6e77c0f1a 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -14,7 +14,7 @@ * Version $Id$ */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -205,7 +205,7 @@ bool read_records(DCR *dcr, Dmsg2(300, "All done=(file:block) %u:%u\n", dev->file, dev->block_num); break; } else if (stat == 0) { /* no match */ - Dmsg4(300, "Clear rem=%d FI=%d before set_eof pos %u:%u\n", + Dmsg4(300, "BSR no match: clear rem=%d FI=%d before set_eof pos %u:%u\n", rec->remainder, rec->FileIndex, dev->file, dev->block_num); rec->remainder = 0; rec->state &= ~REC_PARTIAL_RECORD; diff --git a/bacula/src/stored/record.h b/bacula/src/stored/record.h index e93465e9d3..1d50c54387 100644 --- a/bacula/src/stored/record.h +++ b/bacula/src/stored/record.h @@ -8,22 +8,17 @@ * */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -32,15 +27,17 @@ #define __RECORD_H 1 /* Return codes from read_device_volume_label() */ -#define VOL_NOT_READ 0 /* Volume label not read */ -#define VOL_OK 1 /* volume name OK */ -#define VOL_NO_LABEL 2 /* volume not labeled */ -#define VOL_IO_ERROR 3 /* volume I/O error */ -#define VOL_NAME_ERROR 4 /* Volume name mismatch */ -#define VOL_CREATE_ERROR 5 /* Error creating label */ -#define VOL_VERSION_ERROR 6 /* Bacula version error */ -#define VOL_LABEL_ERROR 7 /* Bad label type */ -#define VOL_NO_MEDIA 8 /* Hard error -- no media present */ +enum { + VOL_NOT_READ = 1, /* Volume label not read */ + VOL_OK, /* volume name OK */ + VOL_NO_LABEL, /* volume not labeled */ + VOL_IO_ERROR, /* volume I/O error */ + VOL_NAME_ERROR, /* Volume name mismatch */ + VOL_CREATE_ERROR, /* Error creating label */ + VOL_VERSION_ERROR, /* Bacula version error */ + VOL_LABEL_ERROR, /* Bad label type */ + VOL_NO_MEDIA /* Hard error -- no media present */ +}; /* See block.h for RECHDR_LENGTH */ diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index e0611f7505..25a030c9eb 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -358,9 +358,9 @@ static bool use_storage_cmd(JCR *jcr) /* ***FIXME**** remove after 1.38 release */ char *device_name; foreach_alist(store, jcr->dirstore) { - Dmsg4(100, "Storage=%s media_type=%s pool=%s pool_type=%s\n", + Dmsg5(100, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n", store->name, store->media_type, store->pool_name, - store->pool_type); + store->pool_type, store->append); foreach_alist(device_name, store->device) { Dmsg1(100, " Device=%s\n", device_name); } diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index 39eef88629..cc561a12df 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -215,7 +215,7 @@ int main (int argc, char *argv[]) /* Ensure that Volume Session Time and Id are both * set and are both non-zero. */ - VolSessionTime = (long)daemon_start_time; + VolSessionTime = (uint32_t)daemon_start_time; if (VolSessionTime == 0) { /* paranoid */ Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n")); } diff --git a/bacula/src/version.h b/bacula/src/version.h index 03ae06a43f..0bc3be13e7 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "1.39.5" -#define BDATE "30 January 2006" -#define LSMDATE "30Jan06" +#define BDATE "06 February 2006" +#define LSMDATE "06Feb06" /* Debug flags */ #undef DEBUG -- 2.39.5