jcr->inc_use_count();
db = mdb; /* need to inc ref count */
prev_dir = get_pool_memory(PM_NAME);
- jobids = get_pool_memory(PM_NAME);
pattern = get_pool_memory(PM_NAME);
- *prev_dir = *pattern = *jobids = 0;
+ *prev_dir = *pattern = 0;
dir_filenameid = pwd_id = offset = 0;
see_copies = see_all_version = false;
limit = 1000;
}
Bvfs::~Bvfs() {
- free_pool_memory(jobids);
free_pool_memory(pattern);
free_pool_memory(prev_dir);
free_attr(attr);
void bvfs_update_cache(JCR *jcr, B_DB *mdb)
{
uint32_t nb=0;
+ db_list_ctx jobids;
+
db_lock(mdb);
db_start_transaction(jcr, mdb);
}
- POOLMEM *jobids = get_pool_memory(PM_NAME);
- *jobids = 0;
-
Mmsg(mdb->cmd,
"SELECT JobId from Job "
"WHERE JobId NOT IN (SELECT JobId FROM brestore_knownjobid) "
"AND Type IN ('B') AND JobStatus IN ('T', 'f', 'A') "
"ORDER BY JobId");
- db_sql_query(mdb, mdb->cmd, db_get_int_handler, jobids);
+ db_sql_query(mdb, mdb->cmd, db_list_handler, &jobids);
- bvfs_update_path_hierarchy_cache(jcr, mdb, jobids);
+ bvfs_update_path_hierarchy_cache(jcr, mdb, &jobids);
db_end_transaction(jcr, mdb);
db_start_transaction(jcr, mdb);
Dmsg1(dbglevel, "Affected row(s) = %d\n", nb);
db_end_transaction(jcr, mdb);
- free_pool_memory(jobids);
}
/*
* Update the bvfs cache for given jobids (1,2,3,4)
*/
void
-bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, char *jobids)
+bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, db_list_ctx *jobids)
{
pathid_cache ppathid_cache;
JobId_t JobId;
char *p;
- for (p=jobids; ; ) {
+ for (p=jobids->list; ; ) {
int stat = get_next_jobid_from_list(&p, &JobId);
+ Dmsg1(dbglevel, "Updating cache for %lld\n", (uint64_t)JobId);
if (stat < 0) {
return;
}
if (stat == 0) {
break;
}
- Dmsg1(dbglevel, "Updating cache for %lld\n", (uint64_t) JobId);
+ Dmsg1(dbglevel, "Updating cache for %lld\n", (uint64_t)JobId);
update_path_hierarchy_cache(jcr, mdb, ppathid_cache, JobId);
}
}
*/
void Bvfs::update_cache()
{
- bvfs_update_path_hierarchy_cache(jcr, db, jobids);
+ bvfs_update_path_hierarchy_cache(jcr, db, &jobids);
}
/* Change the current directory, returns true if the path exists */
{
Dmsg1(dbglevel, "ls_special_dirs(%lld)\n", (uint64_t)pwd_id);
char ed1[50], ed2[50];
- if (!*jobids) {
+ if (jobids.count == 0) {
return;
}
if (!dir_filenameid) {
"AND File1.JobId IN (%s)) AS listfile1 "
"ON (tmp.PathId = listfile1.PathId) "
"ORDER BY tmp.Path, JobId DESC ",
- query.c_str(), edit_uint64(dir_filenameid, ed2), jobids);
+ query.c_str(), edit_uint64(dir_filenameid, ed2), jobids.list);
Dmsg1(dbglevel_sql, "q=%s\n", query2.c_str());
db_sql_query(db, query2.c_str(), path_handler, this);
{
Dmsg1(dbglevel, "ls_dirs(%lld)\n", (uint64_t)pwd_id);
char ed1[50], ed2[50];
- if (!*jobids) {
+ if (jobids.count == 0) {
return false;
}
"ON (listpath1.PathId = listfile1.PathId) "
") AS A ORDER BY 2,3 DESC LIMIT %d OFFSET %d",
edit_uint64(pwd_id, ed1),
- jobids,
+ jobids.list,
filter.c_str(),
edit_uint64(dir_filenameid, ed2),
- jobids,
+ jobids.list,
limit, offset);
Dmsg1(dbglevel_sql, "q=%s\n", query.c_str());
{
Dmsg1(dbglevel, "ls_files(%lld)\n", (uint64_t)pwd_id);
char ed1[50];
- if (!*jobids) {
+ if (jobids.count == 0) {
return false;
}
") AS listfiles "
"WHERE File.FileId = listfiles.id",
edit_uint64(pwd_id, ed1),
- jobids,
+ jobids.list,
filter.c_str(),
limit,
offset);
virtual ~Bvfs();
void set_jobid(JobId_t id) {
- Mmsg(jobids, "%lld", (uint64_t)id);
+ Mmsg(jobids.list, "%lld", (uint64_t)id);
}
void set_jobids(char *ids) {
- pm_strcpy(jobids, ids);
+ pm_strcpy(jobids.list, ids);
}
void set_limit(uint32_t max) {
private:
JCR *jcr;
B_DB *db;
- POOLMEM *jobids;
+ db_list_ctx jobids;
uint32_t limit;
uint32_t offset;
uint32_t nb_record; /* number of records of the last query */
void *user_data;
};
-void bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, char *jobids);
+void bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, db_list_ctx *jobids);
void bvfs_update_cache(JCR *jcr, B_DB *mdb);
char *bvfs_parent_dir(char *path);
int count; /* number of values seen */
};
+/* Call back context for getting a list of comma separated strings from the database */
+class db_list_ctx {
+public:
+ POOLMEM *list; /* list */
+ int count; /* number of values seen */
+
+ db_list_ctx() { list = get_pool_memory(PM_FNAME); *list = 0; count = 0; }
+ ~db_list_ctx() { free_pool_memory(list); list = NULL; }
+};
+
#include "protos.h"
#include "jcr.h"
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2009 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.
void db_start_transaction(JCR *jcr, B_DB *mdb);
void db_end_transaction(JCR *jcr, B_DB *mdb);
int db_int64_handler(void *ctx, int num_fields, char **row);
+int db_list_handler(void *ctx, int num_fields, char **row);
void db_thread_cleanup();
void _dbg_print_db(JCR *jcr, FILE *fp);
int db_int_handler(void *ctx, int num_fields, char **row);
int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
bool db_get_query_dbids(JCR *jcr, B_DB *mdb, POOL_MEM &query, dbid_list &ids);
bool db_get_file_list(JCR *jcr, B_DB *mdb, char *jobids, DB_RESULT_HANDLER *result_handler, void *ctx);
-bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *jobids);
-int db_get_int_handler(void *ctx, int num_fields, char **row);
+bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, db_list_ctx *jobids);
+int db_get_int_handler(void *list, int num_fields, char **row);
/* sql_list.c */
return 0;
}
-
+/*
+ * Use to build a comma separated list of values from a query. "10,20,30"
+ */
+int db_list_handler(void *ctx, int num_fields, char **row)
+{
+ db_list_ctx *lctx = (db_list_ctx *)ctx;
+ if (num_fields == 1 && row[0]) {
+ if (lctx->list[0]) {
+ pm_strcat(lctx->list, ",");
+ }
+ pm_strcat(lctx->list, row[0]);
+ lctx->count++;
+ }
+ return 0;
+}
/* NOTE!!! The following routines expect that the
* calling subroutine sets and clears the mutex
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2009 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.
* TODO: look and merge from ua_restore.c
*/
bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
- JOB_DBR *jr, POOLMEM *jobids)
+ JOB_DBR *jr, db_list_ctx *jobids)
{
bool ret=false;
char clientid[50], jobid[50], filesetid[50];
utime_t StartTime = (jr->StartTime)?jr->StartTime:time(NULL);
bstrutime(date, sizeof(date), StartTime + 1);
- jobids[0]='\0';
+ jobids->list[0] = 0;
+ jobids->count = 0;
/* First, find the last good Full backup for this job/client/fileset */
Mmsg(query,
/* build a jobid list ie: 1,2,3,4 */
Mmsg(query, "SELECT JobId FROM btemp3%s ORDER by JobTDate", jobid);
- db_sql_query(mdb, query.c_str(), db_get_int_handler, jobids);
- Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids);
+ db_sql_query(mdb, query.c_str(), db_list_handler, jobids);
+ Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids->list);
ret = true;
bail_out:
return ret;
}
-/*
- * Use to build a string of int list from a query. "10,20,30"
- */
-int db_get_int_handler(void *ctx, int num_fields, char **row)
-{
- POOLMEM *ret = (POOLMEM *)ctx;
- if (num_fields == 1 && row[0]) {
- if (ret[0]) {
- pm_strcat(ret, ",");
- }
- pm_strcat(ret, row[0]);
- }
- return 0;
-}
-
#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL || HAVE_DBI */
bool send_accurate_current_files(JCR *jcr)
{
POOL_MEM buf;
- POOLMEM *jobids;
- POOLMEM *nb;
+ db_list_ctx jobids;
+ db_list_ctx nb;
if (!jcr->accurate || job_canceled(jcr) || jcr->get_JobLevel()==L_FULL) {
return true;
}
- jobids = get_pool_memory(PM_FNAME);
+ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
-
- if (*jobids == 0) {
- free_pool_memory(jobids);
+ if (jobids.count == 0) {
Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
return false;
}
Jmsg(jcr, M_INFO, 0, _("Sending Accurate information.\n"));
}
/* to be able to allocate the right size for htable */
- nb = get_pool_memory(PM_FNAME);
- *nb = 0; /* clear buffer */
- Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)",jobids);
- db_sql_query(jcr->db, buf.c_str(), db_get_int_handler, nb);
- Dmsg2(200, "jobids=%s nb=%s\n", jobids, nb);
- jcr->file_bsock->fsend("accurate files=%s\n", nb);
+ Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)", jobids.list);
+ db_sql_query(jcr->db, buf.c_str(), db_list_handler, &nb);
+ Dmsg2(200, "jobids=%s nb=%s\n", jobids.list, nb.list);
+ jcr->file_bsock->fsend("accurate files=%s\n", nb.list);
if (!db_open_batch_connexion(jcr, jcr->db)) {
- free_pool_memory(jobids);
- free_pool_memory(nb);
Jmsg0(jcr, M_FATAL, 0, "Can't get batch sql connexion");
return false;
}
- db_get_file_list(jcr, jcr->db_batch, jobids, accurate_list_handler, (void *)jcr);
+ db_get_file_list(jcr, jcr->db_batch, jobids.list, accurate_list_handler, (void *)jcr);
/* TODO: close the batch connexion ? (can be used very soon) */
- free_pool_memory(jobids);
- free_pool_memory(nb);
-
jcr->file_bsock->signal(BNET_EOD);
return true;
static bool dot_update(UAContext *ua, const char *cmd)
{
+
if (!open_client_db(ua)) {
return 1;
}
int pos = find_arg_with_value(ua, "jobid");
- if (pos != -1) { /* find jobid arg */
- if (is_a_number_list(ua->argv[pos])) {
- bvfs_update_path_hierarchy_cache(ua->jcr, ua->db, ua->argv[pos]);
- }
+ if (pos != -1 && is_a_number_list(ua->argv[pos])) {
+ db_list_ctx jobids;
+ pm_strcpy(jobids.list, ua->argv[pos]);
+ bvfs_update_path_hierarchy_cache(ua->jcr, ua->db, &jobids);
} else {
/* update cache for all jobids */
bvfs_update_cache(ua->jcr, ua->db);
}
list_nextvol(ua, n);
} else if (strcasecmp(ua->argk[i], NT_("copies")) == 0) {
- char *jobids=NULL;
+ char *jobids = NULL;
uint32_t limit=0;
for (j=i+1; j<ua->argc; j++) {
if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2002-2009 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.
char *fname;
int len;
bool gui_save;
+ db_list_ctx jobids;
start_prompt(ua, _("To select the JobIds, you have the following choices:\n"));
for (int i=0; list[i]; i++) {
return 0;
}
jr.JobLevel = L_INCREMENTAL; /* Take Full+Diff+Incr */
- if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, rx->JobIds)) {
+ if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, &jobids)) {
return 0;
}
+ pm_strcpy(rx->JobIds, jobids.list);
Dmsg1(30, "Item 12: jobids = %s\n", rx->JobIds);
break;
case 12: /* Cancel or quit */
static const int dbglevel = 10;
-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids);
+static bool create_bootstrap_file(JCR *jcr, char *jobids);
void vbackup_cleanup(JCR *jcr, int TermCode);
/*
char ed1[100];
BSOCK *sd;
char *p;
+ db_list_ctx jobids;
Dmsg2(100, "rstorage=%p wstorage=%p\n", jcr->rstorage, jcr->wstorage);
Dmsg2(100, "Read store=%s, write store=%s\n",
_("This Job is not an Accurate backup so is not equivalent to a Full backup.\n"));
}
- POOLMEM *jobids = get_pool_memory(PM_FNAME);
jcr->jr.JobLevel = L_VIRTUAL_FULL;
- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
- jcr->jr.JobLevel = L_FULL;
- Dmsg1(10, "Accurate jobids=%s\n", jobids);
- if (*jobids == 0) {
- free_pool_memory(jobids);
+ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
+ Dmsg1(10, "Accurate jobids=%s\n", jobids.list);
+ if (jobids.count == 0) {
Jmsg(jcr, M_FATAL, 0, _("No previous Jobs found.\n"));
return false;
}
+ jcr->jr.JobLevel = L_FULL;
+
/*
* Now we find the last job that ran and store it's info in
* the previous_jr record. We will set our times to the
* values from that job so that anything changed after that
* time will be picked up on the next backup.
*/
- p = strrchr(jobids, ','); /* find last jobid */
+ p = strrchr(jobids.list, ','); /* find last jobid */
if (p != NULL) {
p++;
} else {
- p = jobids;
+ p = jobids.list;
}
memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
jcr->previous_jr.JobId = str_to_int64(p);
return false;
}
- if (!create_bootstrap_file(jcr, jobids)) {
+ if (!create_bootstrap_file(jcr, jobids.list)) {
Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
- free_pool_memory(jobids);
return false;
}
- free_pool_memory(jobids);
/*
* Open a message channel connection with the Storage
}
-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids)
+static bool create_bootstrap_file(JCR *jcr, char *jobids)
{
RESTORE_CTX rx;
UAContext *ua;
-/*
- * edit.c edit string to ascii, and ascii to internal
- *
- * Kern Sibbald, December MMII
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2002-2009 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * edit.c edit string to ascii, and ascii to internal
+ *
+ * Kern Sibbald, December MMII
+ *
+ * Version $Id$
+ */
#include "bacula.h"
#include <math.h>
}
/*
- * Check if specified string is a list of number or not
+ * Check if specified string is a list of numbers or not
*/
bool is_a_number_list(const char *n)
{
General:
+30Aug09
+kes Fix bug #1355 Director crashes with double free in Accurate SQL query
28Aug09
kes Fix bug #1357 Verify jobs fail when job has zero files
26Aug09