From: Eric B. <ri...@us...> - 2010-09-13 18:33:39
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Bacula". The branch, Branch-5.1 has been updated via 138c425da88e7959f681262becaeb27a34ac3bb3 (commit) via 3b0154314d02dd2008c5fd5099858bea5222498d (commit) via 09e8fe304e47cc2e2dfa26ec86153db7ab232e98 (commit) via 637087a5169079e0a9be38b2fa70c1dcffe2be85 (commit) via 6660e0b2cb6966c329b9fbfe69f8506df07c8a06 (commit) via 688386b20627430841cfa440bcfec507cabbcd36 (commit) via 8694fe83738792584b6c7c1a42a6225159dbf998 (commit) via 4a6192047270b944d2321db3165e51905d98d398 (commit) via a1c305628a2e26c4653917ecfdc39f7779eeaf93 (commit) via a0db7e301f083a19f08b3c574f4562cde4a13d1c (commit) via d15aa121fce83be8c9ea3914c00c4f53c450d34a (commit) via dc1b6d374f257840aec9b3c1d74a6150583c7e03 (commit) via b1826ecc71c9b00f3e34232f7dfb53fe7ae83f2d (commit) via 46d681e7c561a3afc0da6f8d488ea574052f8409 (commit) via 089ffeb330bf0f780a0dc4ffda9b9e0957ddbba9 (commit) via 6b67f953ed9d47382b457e0ce322fd1feba10ac1 (commit) via 702d7d05cca461cab518ba4fa9298faf85cdf3bd (commit) via 81a1c0f6311afc3e1670a47aff5a7636d7e63810 (commit) via c3193c757470782877afd39ff81cf15ec36c8e37 (commit) from 7ca694355d447562b1ad8a02edcfad3fad20f57e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 138c425da88e7959f681262becaeb27a34ac3bb3 Author: Eric Bollengier <er...@eb...> Date: Sat Sep 4 22:47:31 2010 +0200 regress: Add test for new jobid= option in verify-voltocat-test commit 3b0154314d02dd2008c5fd5099858bea5222498d Author: Eric Bollengier <er...@eb...> Date: Sat Sep 4 22:21:23 2010 +0200 Display job information on jobid in Verify screen commit 09e8fe304e47cc2e2dfa26ec86153db7ab232e98 Author: Eric Bollengier <er...@eb...> Date: Sat Sep 4 14:51:57 2010 +0200 tweak copyright commit 637087a5169079e0a9be38b2fa70c1dcffe2be85 Author: Eric Bollengier <er...@eb...> Date: Sat Sep 4 14:35:07 2010 +0200 Allow to verify any job specified in argument commit 6660e0b2cb6966c329b9fbfe69f8506df07c8a06 Author: Kern Sibbald <ke...@si...> Date: Fri Sep 3 19:33:48 2010 +0200 Send back updated jobs status from FD commit 688386b20627430841cfa440bcfec507cabbcd36 Author: Kern Sibbald <ke...@si...> Date: Fri Sep 3 19:29:05 2010 +0200 Tweak handle skip code 900 in vss plugin commit 8694fe83738792584b6c7c1a42a6225159dbf998 Author: Kern Sibbald <ke...@si...> Date: Fri Sep 3 17:43:39 2010 +0200 Allow plugin to skip restore if problem commit 4a6192047270b944d2321db3165e51905d98d398 Author: Kern Sibbald <ke...@si...> Date: Fri Sep 3 17:42:39 2010 +0200 Attempt to eliminate waiting on Storage message during restore commit a1c305628a2e26c4653917ecfdc39f7779eeaf93 Author: Kern Sibbald <ke...@si...> Date: Fri Sep 3 17:42:05 2010 +0200 Add quotes around resource name in status output commit a0db7e301f083a19f08b3c574f4562cde4a13d1c Author: Eric Bollengier <er...@eb...> Date: Fri Sep 3 17:24:15 2010 +0200 Change FD protocol version to avoid error message when sending RestoreObjects commit d15aa121fce83be8c9ea3914c00c4f53c450d34a Author: Eric Bollengier <er...@eb...> Date: Sun Aug 22 18:34:13 2010 +0200 Allow limit= for all list sub commands commit dc1b6d374f257840aec9b3c1d74a6150583c7e03 Author: Marco van Wieringen <mv...@pl...> Date: Tue Aug 17 19:00:38 2010 +0200 Tweak readdir return code check saves a compiler warning. commit b1826ecc71c9b00f3e34232f7dfb53fe7ae83f2d Author: Eric Bollengier <er...@eb...> Date: Thu Aug 12 15:24:21 2010 +0200 Make third argument of DEVICE::d_ioctl optionnal to emulate varg commit 46d681e7c561a3afc0da6f8d488ea574052f8409 Author: Eric Bollengier <er...@eb...> Date: Thu Aug 12 15:20:08 2010 +0200 Use SMARTALLOC+memset instead of overload new/delete that doesn't work in bat The global overload of new/delete in smartalloc.h crashes bat (seems to be incompatible with QT) I added memset(0) in default SMARTALLOC class, and now DEVICE uses it. commit 089ffeb330bf0f780a0dc4ffda9b9e0957ddbba9 Author: Marco van Wieringen <mv...@pl...> Date: Wed Aug 11 15:30:25 2010 +0200 Fix typo so things compile on systems without vtape support. commit 6b67f953ed9d47382b457e0ce322fd1feba10ac1 Author: Eric Bollengier <er...@eb...> Date: Thu Sep 2 15:52:23 2010 +0200 Fix bug #1601 where prune client pool=xx apply pool retention for all volumes. commit 702d7d05cca461cab518ba4fa9298faf85cdf3bd Author: Eric Bollengier <er...@eb...> Date: Tue Aug 31 23:01:50 2010 +0200 Add level option to estimate help command commit 81a1c0f6311afc3e1670a47aff5a7636d7e63810 Author: Bastian Friedrich <bas...@co...> Date: Tue Aug 31 14:43:44 2010 +0200 Fix #1633 Windows service is not removed if still running Signed-off-by: Eric Bollengier <er...@eb...> commit c3193c757470782877afd39ff81cf15ec36c8e37 Author: Eric Bollengier <er...@eb...> Date: Mon Aug 30 19:01:25 2010 +0200 Fix #1624 about segfault in dvd driver when calling rewind(NULL) ----------------------------------------------------------------------- Summary of changes: diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index f704fbe..9ab945a 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -166,6 +166,9 @@ void InitWinAPIWrapper(); /* Maximum Name length including EOS */ #define MAX_NAME_LENGTH 128 +/* Maximum escaped Name lenght including EOS 2*MAX_NAME_LENGTH+1 */ +#define MAX_ESCAPE_NAME_LENGTH 257 + /* Maximume number of user entered command args */ #define MAX_CMD_ARGS 30 diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 57c38dd..6c51d03 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -677,6 +677,14 @@ static int restore_object_handler(void *ctx, int num_fields, char **row) if (jcr->is_job_canceled()) { return 1; } + /* Old File Daemon doesn't handle restore objects */ + if (jcr->FDVersion < 3) { + Jmsg(jcr, M_WARNING, 0, _("Client \"%s\" may not be used to restore " + "this job. Please upgrade your client.\n"), + jcr->client->name()); + return 1; + } + fd->fsend("restoreobject JobId=%s %s,%s,%s,%s,%s,%s\n", row[0], row[1], row[2], row[3], row[4], row[5], row[6]); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 5672353..7d63765 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -127,7 +127,7 @@ static struct cmdstruct commands[] = { /* C { NT_("disable"), disable_cmd, _("Disable a job"), NT_("job=<name>"), true}, { NT_("enable"), enable_cmd, _("Enable a job"), NT_("job=<name>"), true}, { NT_("estimate"), estimate_cmd, _("Performs FileSet estimate, listing gives full listing"), - NT_("fileset=<fs> client=<cli> accurate=<yes/no> job=<job> listing"), true}, + NT_("fileset=<fs> client=<cli> level=<level> accurate=<yes/no> job=<job> listing"), true}, { NT_("exit"), quit_cmd, _("Terminate Bconsole session"), NT_(""), false}, { NT_("gui"), gui_cmd, _("Non-interactive gui mode"), NT_("on | off"), false}, diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 8623677..35e8e7a 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -288,15 +288,16 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist) ua->error_msg(_("Hey! DB is NULL\n")); } + /* Apply any limit */ + j = find_arg_with_value(ua, NT_("limit")); + if (j >= 0) { + jr.limit = atoi(ua->argv[j]); + } + /* Scan arguments looking for things to do */ for (i=1; i<ua->argc; i++) { /* List JOBS */ if (strcasecmp(ua->argk[i], NT_("jobs")) == 0) { - /* Apply any limit */ - j = find_arg_with_value(ua, NT_("limit")); - if (j >= 0) { - jr.limit = atoi(ua->argv[j]); - } db_list_job_records(ua->jcr, ua->db, &jr, prtit, ua, llist); /* List JOBTOTALS */ diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index edef66d..ef5131d 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -215,6 +215,46 @@ int prune_stats(UAContext *ua, utime_t retention) return true; } +/* + * Use pool and client specified by user to select jobs to prune + * returns add_from string to add in FROM clause + * add_where string to add in WHERE clause + */ +bool prune_set_filter(UAContext *ua, CLIENT *client, POOL *pool, utime_t period, + POOL_MEM *add_from, POOL_MEM *add_where) +{ + utime_t now; + char ed1[50], ed2[MAX_ESCAPE_NAME_LENGTH]; + POOL_MEM tmp(PM_MESSAGE); + + now = (utime_t)time(NULL); + edit_int64(now - period, ed1); + Dmsg3(150, "now=%lld period=%lld JobTDate=%s\n", now, period, ed1); + Mmsg(tmp, " AND JobTDate < %s ", ed1); + pm_strcat(*add_where, tmp.c_str()); + + db_lock(ua->db); + if (client) { + db_escape_string(ua->jcr, ua->db, ed2, + client->name(), strlen(client->name())); + Mmsg(tmp, " AND Client.Name = '%s' ", ed2); + pm_strcat(*add_where, tmp.c_str()); + pm_strcat(*add_from, " JOIN Client USING (ClientId) "); + } + + if (pool) { + db_escape_string(ua->jcr, ua->db, ed2, + pool->name(), strlen(pool->name())); + Mmsg(tmp, " AND Pool.Name = '%s' ", ed2); + pm_strcat(*add_where, tmp.c_str()); + /* Use ON() instead of USING for some old SQLite */ + pm_strcat(*add_from, " JOIN Pool ON (Job.PoolId = Pool.PoolId) "); + } + Dmsg2(150, "f=%s w=%s\n", add_from->c_str(), add_where->c_str()); + db_unlock(ua->db); + return true; +} + /* * Prune File records from the database. For any Job which * is older than the retention period, we unconditionally delete @@ -226,41 +266,44 @@ int prune_stats(UAContext *ua, utime_t retention) * This routine assumes you want the pruning to be done. All checking * must be done before calling this routine. * - * Note: pool can possibly be NULL. + * Note: client or pool can possibly be NULL (not both). */ int prune_files(UAContext *ua, CLIENT *client, POOL *pool) { struct del_ctx del; struct s_count_ctx cnt; POOL_MEM query(PM_MESSAGE); - utime_t now, period; - CLIENT_DBR cr; - char ed1[50], ed2[50]; - - db_lock(ua->db); - memset(&cr, 0, sizeof(cr)); + POOL_MEM sql_where(PM_MESSAGE); + POOL_MEM sql_from(PM_MESSAGE); + utime_t period; + char ed1[50]; + memset(&del, 0, sizeof(del)); - bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); - if (!db_create_client_record(ua->jcr, ua->db, &cr)) { - db_unlock(ua->db); - return 0; - } if (pool && pool->FileRetention > 0) { period = pool->FileRetention; - } else { + + } else if (client) { period = client->FileRetention; + + } else { /* should specify at least pool or client */ + return false; + } + + db_lock(ua->db); + /* Specify JobTDate and Pool.Name= and/or Client.Name= in the query */ + if (!prune_set_filter(ua, client, pool, period, &sql_from, &sql_where)) { + goto bail_out; } - now = (utime_t)time(NULL); // edit_utime(now-period, ed1, sizeof(ed1)); // Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s secs.\n"), ed1); Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs.\n")); /* Select Jobs -- for counting */ - edit_int64(now - period, ed1); - Mmsg(query, count_select_job, ed1, edit_int64(cr.ClientId, ed2)); - Dmsg3(050, "select now=%u period=%u sql=%s\n", (uint32_t)now, - (uint32_t)period, query.c_str()); + Mmsg(query, + "SELECT COUNT(1) FROM Job %s WHERE PurgedFiles=0 %s", + sql_from.c_str(), sql_where.c_str()); + Dmsg1(050, "select sql=%s\n", query.c_str()); cnt.count = 0; if (!db_sql_query(ua->db, query.c_str(), del_count_handler, (void *)&cnt)) { ua->error_msg("%s", db_strerror(ua->db)); @@ -285,8 +328,9 @@ int prune_files(UAContext *ua, CLIENT *client, POOL *pool) del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); /* Now process same set but making a delete list */ - Mmsg(query, select_job, edit_int64(now - period, ed1), - edit_int64(cr.ClientId, ed2)); + Mmsg(query, "SELECT JobId FROM Job %s WHERE PurgedFiles=0 %s", + sql_from.c_str(), sql_where.c_str()); + Dmsg1(050, "select sql=%s\n", query.c_str()); db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del); purge_files_from_job_list(ua, del); @@ -398,31 +442,32 @@ static int job_select_handler(void *ctx, int num_fields, char **row) */ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) { - struct del_ctx del; POOL_MEM query(PM_MESSAGE); - utime_t now, period; - CLIENT_DBR cr ; - char ed1[50], ed2[50]; + POOL_MEM sql_where(PM_MESSAGE); + POOL_MEM sql_from(PM_MESSAGE); + utime_t period; + char ed1[50]; alist *jobids_check=NULL; struct accurate_check_ctx *elt; db_list_ctx jobids, tempids; JOB_DBR jr; - - db_lock(ua->db); - memset(&cr, 0, sizeof(cr)); - - bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); - if (!db_create_client_record(ua->jcr, ua->db, &cr)) { - db_unlock(ua->db); - return 0; - } + struct del_ctx del; + memset(&del, 0, sizeof(del)); if (pool && pool->JobRetention > 0) { period = pool->JobRetention; - } else { + + } else if (client) { period = client->JobRetention; + + } else { /* should specify at least pool or client */ + return false; + } + + db_lock(ua->db); + if (!prune_set_filter(ua, client, pool, period, &sql_from, &sql_where)) { + goto bail_out; } - now = (utime_t)time(NULL); /* Drop any previous temporary tables still there */ drop_temp_tables(ua); @@ -435,10 +480,6 @@ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) edit_utime(period, ed1, sizeof(ed1)); Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s.\n"), ed1); - edit_int64(now - period, ed1); /* Jobs older than ed1 are good candidates */ - edit_int64(cr.ClientId, ed2); - - memset(&del, 0, sizeof(del)); del.max_ids = 100; del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); del.PurgedFiles = (char *)malloc(del.max_ids); @@ -450,11 +491,12 @@ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) Mmsg(query, "INSERT INTO DelCandidates " "SELECT JobId,PurgedFiles,FileSetId,JobFiles,JobStatus " - "FROM Job " + "FROM Job %s " /* JOIN Pool/Client */ "WHERE Type IN ('B', 'C', 'M', 'V', 'D', 'R', 'c', 'm', 'g') " - "AND JobTDate<%s AND ClientId=%s", - ed1, ed2); + " %s ", /* Pool/Client + JobTDate */ + sql_from.c_str(), sql_where.c_str()); + Dmsg1(050, "select sql=%s\n", query.c_str()); if (!db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL)) { if (ua->verbose) { ua->error_msg("%s", db_strerror(ua->db)); @@ -505,11 +547,11 @@ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) */ Mmsg(query, "SELECT JobId, JobTDate " - "FROM Job " - "WHERE JobTDate<%s AND ClientId=%s " - "AND Type='V' AND Level='V' " + "FROM Job %s " /* JOIN Client/Pool */ + "WHERE Type='V' AND Level='V' " + " %s " /* Pool, JobTDate, Client */ "ORDER BY JobTDate DESC LIMIT 1", - ed1, ed2); + sql_from.c_str(), sql_where.c_str()); if (!db_sql_query(ua->db, query.c_str(), db_list_handler, &jobids)) { ua->error_msg("%s", db_strerror(ua->db)); diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 42f7182..1d79adc 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2008 Free Software Foundation Europe e.V. + Copyright (C) 2001-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -31,7 +31,6 @@ * * Kern Sibbald, December MMI * - * Version $Id$ */ #include "bacula.h" @@ -546,7 +545,7 @@ static bool reset_restore_context(UAContext *ua, JCR *jcr, run_ctx &rc) rc.level_name = NULL; } if (rc.jid) { - /* Note, this is also MigrateJobId */ + /* Note, this is also MigrateJobId and a VerifyJobId */ jcr->RestoreJobId = str_to_int64(rc.jid); rc.jid = 0; } @@ -753,10 +752,11 @@ static void select_job_level(UAContext *ua, JCR *jcr) static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, const char *verify_list, char *jid, const char *replace, char *client_name) { + char ec1[30]; + char dt[MAX_TIME_LENGTH]; + Dmsg1(800, "JobType=%c\n", jcr->getJobType()); switch (jcr->getJobType()) { - char ec1[30]; - char dt[MAX_TIME_LENGTH]; case JT_ADMIN: if (ua->api) ua->signal(BNET_RUN_CMD); ua->send_msg(_("Run %s job\n" @@ -802,9 +802,19 @@ static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, const char jcr->plugin_options?jcr->plugin_options:"", jcr->plugin_options?"\n":""); } else { /* JT_VERIFY */ + JOB_DBR jr; const char *Name; if (jcr->verify_job) { Name = jcr->verify_job->name(); + } else if (jcr->RestoreJobId) { /* Display job name if jobid requested */ + memset(&jr, 0, sizeof(jr)); + jr.JobId = jcr->RestoreJobId; + if (!db_get_job_record(jcr, ua->db, &jr)) { + ua->error_msg(_("Could not get job record for selected JobId. ERR=%s"), + db_strerror(ua->db)); + return false; + } + Name = jr.Job; } else { Name = ""; } diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index b6d2b0d..b1483f8 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -678,9 +678,9 @@ static void list_running_jobs(UAContext *ua) case JS_WaitSD: emsg = (char *) get_pool_memory(PM_FNAME); if (jcr->wstore) { - Mmsg(emsg, _("is waiting on Storage %s"), jcr->wstore->name()); + Mmsg(emsg, _("is waiting on Storage \"%s\""), jcr->wstore->name()); } else if (jcr->rstore) { - Mmsg(emsg, _("is waiting on Storage %s"), jcr->rstore->name()); + Mmsg(emsg, _("is waiting on Storage \"%s\""), jcr->rstore->name()); } else { Mmsg(emsg, _("is waiting on Storage")); } diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index b3a27dc..92b29ed 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -130,24 +130,32 @@ bool do_verify(JCR *jcr) if (jcr->verify_job && (jcr->getJobLevel() == L_VERIFY_VOLUME_TO_CATALOG || jcr->getJobLevel() == L_VERIFY_DISK_TO_CATALOG)) { - Name = jcr->verify_job->name(); + Name = jcr->verify_job->name(); } else { Name = NULL; } Dmsg1(100, "find last jobid for: %s\n", NPRT(Name)); - if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) { - if (jcr->getJobLevel() == L_VERIFY_CATALOG) { - Jmsg(jcr, M_FATAL, 0, _( - "Unable to find JobId of previous InitCatalog Job.\n" - "Please run a Verify with Level=InitCatalog before\n" - "running the current Job.\n")); - } else { - Jmsg(jcr, M_FATAL, 0, _( - "Unable to find JobId of previous Job for this client.\n")); + + /* see if user supplied a jobid= as run argument or from menu */ + if (jcr->RestoreJobId) { + verify_jobid = jcr->RestoreJobId; + Dmsg1(100, "Supplied jobid=%d\n", verify_jobid); + + } else { + if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) { + if (jcr->getJobLevel() == L_VERIFY_CATALOG) { + Jmsg(jcr, M_FATAL, 0, _( + "Unable to find JobId of previous InitCatalog Job.\n" + "Please run a Verify with Level=InitCatalog before\n" + "running the current Job.\n")); + } else { + Jmsg(jcr, M_FATAL, 0, _( + "Unable to find JobId of previous Job for this client.\n")); + } + return false; } - return false; + verify_jobid = jr.JobId; } - verify_jobid = jr.JobId; Dmsg1(100, "Last full jobid=%d\n", verify_jobid); } /* diff --git a/bacula/src/filed/authenticate.c b/bacula/src/filed/authenticate.c index ae926f3..2bff4e0 100644 --- a/bacula/src/filed/authenticate.c +++ b/bacula/src/filed/authenticate.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2009 Free Software Foundation Europe e.V. + Copyright (C) 2000-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -30,8 +30,6 @@ * * Kern Sibbald, October 2000 * - * Version $Id$ - * */ #include "bacula.h" @@ -43,8 +41,9 @@ const int dbglvl = 50; * prior to 10Mar08 no version * 1 10Mar08 * 2 13Mar09 - added the ability to restore from multiple storages + * 3 03Sep10 - added the restore object command for vss plugin */ -static char OK_hello[] = "2000 OK Hello 2\n"; +static char OK_hello[] = "2000 OK Hello 3\n"; static char Dir_sorry[] = "2999 Authentication failed.\n"; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/bacula/src/filed/fd_plugins.c b/bacula/src/filed/fd_plugins.c index 683b51d..d235d0c 100644 --- a/bacula/src/filed/fd_plugins.c +++ b/bacula/src/filed/fd_plugins.c @@ -570,6 +570,9 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) rc, attr->ofname); return CF_ERROR; } + if (rp.create_status == CF_SKIP) { + return CF_SKIP; + } if (rp.create_status == CF_ERROR) { Qmsg1(jcr, M_ERROR, 0, _("Plugin createFile call failed. Returned CF_ERROR file=%s\n"), attr->ofname); diff --git a/bacula/src/filed/xattr.c b/bacula/src/filed/xattr.c index c0ed4dc..2c4fa7c 100644 --- a/bacula/src/filed/xattr.c +++ b/bacula/src/filed/xattr.c @@ -1815,7 +1815,7 @@ static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespac /* * Walk the namespace. */ - while (dp = readdir(dirp)) { + while ((dp = readdir(dirp)) != NULL) { /* * Skip only the toplevel . dir. */ diff --git a/bacula/src/lib/smartall.h b/bacula/src/lib/smartall.h index c8cb0a8..4a2f90a 100644 --- a/bacula/src/lib/smartall.h +++ b/bacula/src/lib/smartall.h @@ -103,20 +103,29 @@ extern void *b_malloc(); #define New(type) new(__FILE__, __LINE__) type +/* We do memset(0) because it's not possible to memset a class when + * using subclass with virtual functions + */ + class SMARTALLOC { public: void *operator new(size_t s, const char *fname, int line) { - void *p = sm_malloc(fname, line, s > sizeof(int) ? (unsigned int)s : sizeof(int)); - return p; + size_t size = s > sizeof(int) ? (unsigned int)s : sizeof(int); + void *p = sm_malloc(fname, line, size); + memset(p, 0, size); + return p; } void *operator new[](size_t s, const char *fname, int line) { - void *p = sm_malloc(fname, line, s > sizeof(int) ? (unsigned int)s : sizeof(int)); + size_t size = s > sizeof(int) ? (unsigned int)s : sizeof(int); + void *p = sm_malloc(fname, line, size); + memset(p, 0, size); return p; } + void operator delete(void *ptr) { free(ptr); @@ -130,12 +139,12 @@ void operator delete(void *ptr, const char * /*fname*/, int /*line*/) { free(ptr); } -void operator delete[](void *ptr, size_t /*i*/, const char * /*fname*/, int /*line*/) +void operator delete[](void *ptr, size_t /*i*/, + const char * /*fname*/, int /*line*/) { free(ptr); } - private: void *operator new(size_t s) throw() { (void)s; return 0; } void *operator new[](size_t s) throw() { (void)s; return 0; } @@ -149,10 +158,14 @@ class SMARTALLOC { public: void *operator new(size_t s) { - return malloc(s); + void *p = malloc(s); + memset(p, 0, s); + return p; } void *operator new[](size_t s) { - return malloc(s); + void *p = malloc(s); + memset(p, 0, s); + return p; } void operator delete(void *ptr) { free(ptr); @@ -162,51 +175,5 @@ class SMARTALLOC } }; #endif /* SMARTALLOC */ - -/* We do memset(0) because it's not possible to memset a class when - * using subclass with virtual functions - */ - -/* Now, sm_malloc and sm_free can be smartalloc or normal function */ -inline void *operator new(size_t size, char const * file, int line) -{ - void *pnew = sm_malloc(file,line, size); - memset((char *)pnew, 0, size); - return pnew; -} - -inline void *operator new[](size_t size, char const * file, int line) -{ - void *pnew = sm_malloc(file, line, size); - memset((char *)pnew, 0, size); - return pnew; -} - -inline void *operator new(size_t size) -{ - void *pnew = sm_malloc(__FILE__, __LINE__, size); - memset((char *)pnew, 0, size); - return pnew; -} - -inline void *operator new[](size_t size) -{ - void *pnew = sm_malloc(__FILE__, __LINE__, size); - memset((char *)pnew, 0, size); - return pnew; -} - -//#define new new(__FILE__, __LINE__) - -inline void operator delete(void *buf) -{ - sm_free( __FILE__, __LINE__, buf); -} - -inline void operator delete[] (void *buf) -{ - sm_free(__FILE__, __LINE__, buf); -} - - + #endif /* !SMARTALLOC_H */ diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 1ac7629..9fa2e31 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -147,26 +147,26 @@ init_dev(JCR *jcr, DEVRES *device) Jmsg0(jcr, M_FATAL, 0, _("DVD support is now deprecated\n")); return NULL; case B_VTAPE_DEV: - dev = new vtape; + dev = New(vtape); break; #ifdef USE_FTP case B_FTP_DEV: - dev = new ftp_device; + dev = New(ftp_device); break; #endif #ifdef HAVE_WIN32 /* TODO: defined in src/win32/stored/mtops.cpp */ case B_TAPE_DEV: - dev = new win32_tape_device; + dev = New(win32_tape_device); break; case B_FILE_DEV: - dev = new win32_file_device; + dev = New(win32_file_device); break; #else case B_TAPE_DEV: case B_FILE_DEV: case B_FIFO_DEV: - dev = new DEVICE; + dev = New(DEVICE); break; #endif default: diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 8d6abad..38fb9ff 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -206,7 +206,7 @@ class VOLRES; /* forward reference */ * each physical device. Everything here is "global" to * that device and effects all jobs using the device. */ -class DEVICE { +class DEVICE: public SMARTALLOC { protected: int m_fd; /* file descriptor */ private: @@ -441,7 +441,7 @@ public: int fd() const { return m_fd; }; /* low level operations */ - virtual int d_ioctl(int fd, ioctl_req_t request, char *mt_com); + virtual int d_ioctl(int fd, ioctl_req_t request, char *mt_com=NULL); virtual int d_open(const char *pathname, int flags); virtual int d_close(int fd); virtual ssize_t d_read(int fd, void *buffer, size_t count); diff --git a/bacula/src/stored/dvd.c b/bacula/src/stored/dvd.c index 97ecf64..dcb6a8e 100644 --- a/bacula/src/stored/dvd.c +++ b/bacula/src/stored/dvd.c @@ -430,9 +430,14 @@ static bool dvd_open_first_part(DCR *dcr, int mode) */ boffset_t lseek_dvd(DCR *dcr, boffset_t offset, int whence) { - DEVICE *dev = dcr->dev; + DEVICE *dev; boffset_t pos; char ed1[50], ed2[50]; + + if (!dcr) { /* can be NULL when called from rewind(NULL) */ + return -1; + } + dev = dcr->dev; Dmsg5(400, "Enter lseek_dvd fd=%d off=%s w=%d part=%d nparts=%d\n", dev->fd(), edit_int64(offset, ed1), whence, dev->part, dev->num_dvd_parts); diff --git a/bacula/src/stored/fd_cmds.c b/bacula/src/stored/fd_cmds.c index f2a822f..110a6bf 100644 --- a/bacula/src/stored/fd_cmds.c +++ b/bacula/src/stored/fd_cmds.c @@ -36,7 +36,6 @@ * the File daemon, control is passed here to handle the * subsequent File daemon commands. * - * Version $Id$ * */ diff --git a/bacula/src/stored/read.c b/bacula/src/stored/read.c index e154f80..c0f87e9 100644 --- a/bacula/src/stored/read.c +++ b/bacula/src/stored/read.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2009 Free Software Foundation Europe e.V. + Copyright (C) 2000-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -30,7 +30,6 @@ * * Kern Sibbald, November MM * - * Version $Id$ */ #include "bacula.h" @@ -79,6 +78,8 @@ bool do_read_data(JCR *jcr) /* Tell File daemon we will send data */ fd->fsend(OK_data); + set_jcr_job_status(jcr, JS_Running); + dir_send_job_status(jcr); ok = read_records(dcr, record_cb, mount_next_read_volume); /* Send end of data to FD */ diff --git a/bacula/src/stored/vtape.h b/bacula/src/stored/vtape.h index b2bef53..057ecda 100644 --- a/bacula/src/stored/vtape.h +++ b/bacula/src/stored/vtape.h @@ -51,7 +51,7 @@ typedef enum { VT_SKIP_EOF /* Have already read the EOF byte */ } VT_READ_FM_MODE; -class vtape: public DEVICE{ +class vtape: public DEVICE { private: int fd; /* Our file descriptor */ @@ -95,7 +95,7 @@ public: /* interface from DEVICE */ int d_close(int); int d_open(const char *pathname, int flags); - int d_ioctl(int fd, ioctl_req_t request, char *mt); + int d_ioctl(int fd, ioctl_req_t request, char *mt=NULL); ssize_t d_read(int, void *buffer, size_t count); ssize_t d_write(int, const void *buffer, size_t count); @@ -116,9 +116,9 @@ public: ssize_t d_read(void *buffer, size_t count) { return -1; } ssize_t d_write(const void *buffer, size_t count) { return -1; } int d_close(int) { return -1; } - int d_ioctl(int fd, ioctl_req_t request, char *mt) { return -1; } + int d_ioctl(int fd, ioctl_req_t request, char *mt=NULL) { return -1; } boffset_t lseek(DCR *dcr, off_t offset, int whence) { return -1; } -} +}; #endif /* USE_VTAPE */ diff --git a/bacula/src/win32/filed/plugins/root_node.c b/bacula/src/win32/filed/plugins/root_node.c index 8e9ed41..d5ba41d 100644 --- a/bacula/src/win32/filed/plugins/root_node.c +++ b/bacula/src/win32/filed/plugins/root_node.c @@ -77,7 +77,7 @@ root_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp case 999: return bRC_Error; default: - _JobMessage(M_FATAL, "Invalid internal state %d", state); + _JobMessage(M_FATAL, "startBackupFile: invalid internal state %d", state); state = 999; } return retval; @@ -102,7 +102,7 @@ root_node_t::endBackupFile(exchange_fd_context_t *context) case 999: retval = bRC_Error; default: - _JobMessage(M_FATAL, "Invalid internal state %d", state); + _JobMessage(M_FATAL, "endBackupFile: invalid internal state %d", state); state = 999; return bRC_Error; } @@ -113,11 +113,9 @@ bRC root_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp) { _DebugMessage(0, "createFile_ROOT state = %d\n", state); - switch (state) - { + switch (state) { case 0: - if (strcmp(name, PLUGIN_PATH_PREFIX_BASE) != 0) - { + if (strcmp(name, PLUGIN_PATH_PREFIX_BASE) != 0) { _JobMessage(M_FATAL, "Invalid restore path specified, must start with '/" PLUGIN_PATH_PREFIX_BASE "/'\n"); state = 999; return bRC_Error; @@ -128,10 +126,16 @@ root_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp) case 1: rp->create_status = CF_CREATED; return bRC_OK; + + /* Skip this file */ + case 900: + rp->create_status = CF_SKIP; + return bRC_OK; + /* Error */ case 999: return bRC_Error; default: - _JobMessage(M_FATAL, "Invalid internal state %d", state); + _JobMessage(M_FATAL, "createFile: invalid internal state %d", state); state = 999; } return bRC_Error; @@ -141,16 +145,17 @@ bRC root_node_t::endRestoreFile(exchange_fd_context_t *context) { _DebugMessage(0, "endRestoreFile_ROOT state = %d\n", state); - switch (state) - { + switch (state) { case 0: delete service_node; state = 1; return bRC_OK; case 1: return bRC_OK; + case 900: + return bRC_OK; default: - _JobMessage(M_FATAL, "Invalid internal state %d", state); + _JobMessage(M_FATAL, "endRestore: invalid internal state %d", state); state = 999; } return bRC_Error; diff --git a/bacula/src/win32/libwin32/service.cpp b/bacula/src/win32/libwin32/service.cpp index 735a867..4537f79 100644 --- a/bacula/src/win32/libwin32/service.cpp +++ b/bacula/src/win32/libwin32/service.cpp @@ -357,7 +357,7 @@ int removeService() if (status.dwCurrentState == SERVICE_STOP_PENDING) { sleep(1); } else { - return 0; + break; } } if (status.dwCurrentState != SERVICE_STOPPED) { diff --git a/regress/tests/verify-voltocat-test b/regress/tests/verify-voltocat-test index 99f758e..206c65f 100755 --- a/regress/tests/verify-voltocat-test +++ b/regress/tests/verify-voltocat-test @@ -18,10 +18,14 @@ start_test cat <<END_OF_DATA >tmp/bconcmds @$out /dev/null messages -@$out tmp/log1.out +@$out tmp/log0.out setdebug level=1 storage=File sd label storage=File volume=TestVolume001 -run job=$JobName yes +run level=full job=$JobName yes +wait +messages +@$out tmp/log1.out +run level=full job=$JobName yes wait messages @# @@ -33,6 +37,12 @@ run job=VerifyVolume level=VolumeToCatalog yes wait messages +@$out ${cwd}/tmp/log4.out +setdebug level=12 dir +run job=VerifyVolume jobid=1 level=VolumeToCatalog +yes +wait +messages @$out ${cwd}/tmp/log3.out @# @# Now a backup with nothing changed @@ -58,4 +68,11 @@ grep "^ Termination: *Verify OK" tmp/log2.out 2>&1 >/dev/null rstat=$? grep "^ Termination: *Verify OK" tmp/log3.out 2>&1 >/dev/null dstat=$? +grep "Verify JobId: *2" tmp/log2.out 2>&1 >/dev/null +dstat=$(($dstat + $?)) +grep "Verify JobId: *1" tmp/log4.out 2>&1 >/dev/null +dstat=$(($dstat + $?)) +grep "Verify Job: *VerifyVol" tmp/log4.out 2>&1 >/dev/null +dstat=$(($dstat + $?)) + end_test hooks/post-receive -- Bacula |