From 6c49ff5ffd77f1ff27d950bfb1ac6575ff3d9731 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Tue, 12 Sep 2017 13:32:24 +0200 Subject: [PATCH] bvfs: Add clients= option to .bvfs_get_jobids to handle clusters --- bacula/src/cats/bvfs.c | 20 ++++++------ bacula/src/cats/bvfs.h | 7 ++++- bacula/src/dird/ua_dotcmds.c | 59 +++++++++++++++++++++++++----------- bacula/src/tools/bvfs_test.c | 6 ++-- 4 files changed, 63 insertions(+), 29 deletions(-) diff --git a/bacula/src/cats/bvfs.c b/bacula/src/cats/bvfs.c index 91d82785b..afd4fa330 100644 --- a/bacula/src/cats/bvfs.c +++ b/bacula/src/cats/bvfs.c @@ -875,22 +875,24 @@ bool Bvfs::ch_dir(const char *path) } /* - * Get all file versions for a specified client + * Get all file versions for a specified list of clients * TODO: Handle basejobs using different client */ -void Bvfs::get_all_file_versions(DBId_t pathid, FileId_t fnid, const char *client) +void Bvfs::get_all_file_versions(DBId_t pathid, FileId_t fnid, alist *clients) { - Dmsg3(dbglevel, "get_all_file_versions(%lld, %lld, %s)\n", (uint64_t)pathid, - (uint64_t)fnid, client); - char ed1[50], ed2[50]; - POOL_MEM q; + char ed1[50], ed2[50], *eclients; + POOL_MEM q, query; + if (see_copies) { Mmsg(q, " AND Job.Type IN ('C', 'B') "); } else { Mmsg(q, " AND Job.Type = 'B' "); } - POOL_MEM query; + eclients = escape_list(clients); + + Dmsg3(dbglevel, "get_all_file_versions(%lld, %lld, %s)\n", (uint64_t)pathid, + (uint64_t)fnid, eclients); Mmsg(query,// 1 2 3 4 "SELECT 'V', File.PathId, File.FilenameId, 0, File.JobId, " @@ -907,9 +909,9 @@ void Bvfs::get_all_file_versions(DBId_t pathid, FileId_t fnid, const char *clien "AND File.FileIndex <= JobMedia.LastIndex " "AND JobMedia.MediaId = Media.MediaId " "AND Job.ClientId = Client.ClientId " - "AND Client.Name = '%s' " + "AND Client.Name IN (%s) " "%s ORDER BY FileId LIMIT %d OFFSET %d" - ,edit_uint64(fnid, ed1), edit_uint64(pathid, ed2), client, q.c_str(), + ,edit_uint64(fnid, ed1), edit_uint64(pathid, ed2), eclients, q.c_str(), limit, offset); Dmsg1(dbglevel_sql, "q=%s\n", query.c_str()); db->bdb_sql_query(query.c_str(), list_entries, user_data); diff --git a/bacula/src/cats/bvfs.h b/bacula/src/cats/bvfs.h index a76bb5c69..db4246499 100644 --- a/bacula/src/cats/bvfs.h +++ b/bacula/src/cats/bvfs.h @@ -119,7 +119,12 @@ public: bool ls_files(); /* Returns true if we have more files to read */ bool ls_dirs(); /* Returns true if we have more dir to read */ void ls_special_dirs(); /* get . and .. */ - void get_all_file_versions(DBId_t pathid, FileId_t fnid, const char *client); + void get_all_file_versions(DBId_t pathid, FileId_t fnid, char *client) { + alist clients(1, not_owned_by_alist); + clients.append(client); + get_all_file_versions(pathid, fnid, &clients); + }; + void get_all_file_versions(DBId_t pathid, FileId_t fnid, alist *clients); void update_cache(); diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index a16562547..292d933c1 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -445,8 +445,27 @@ static int bvfs_result_handler(void *ctx, int fields, char **row) return 0; } +static void parse_list(char *items, alist *list) +{ + char *start; + for(char *p = start = items; *p ; p++) { + if (*p == ',') { + *p = 0; + if (p > start) { + list->append(bstrdup(start)); + } + *p = ','; + start = p + 1; + } + } + if (*start) { + list->append(bstrdup(start)); + } +} + static bool bvfs_parse_arg_version(UAContext *ua, char **client, + alist *clients, FileId_t *fnid, bool *versions, bool *copies) @@ -465,6 +484,14 @@ static bool bvfs_parse_arg_version(UAContext *ua, if (strcasecmp(ua->argk[i], NT_("client")) == 0) { *client = ua->argv[i]; + if (clients) { + clients->append(bstrdup(*client)); + } + } + + if (clients != NULL && strcasecmp(ua->argk[i], NT_("clients")) == 0) { + /* Turn client1,client2,client3 to a alist of clients */ + parse_list(ua->argv[i], clients); } if (copies && strcasecmp(ua->argk[i], NT_("copies")) == 0) { @@ -475,7 +502,7 @@ static bool bvfs_parse_arg_version(UAContext *ua, *versions = true; } } - return (*client && *fnid > 0); + return ((*client || (clients && clients->size() > 0)) && *fnid > 0); } static bool bvfs_parse_arg(UAContext *ua, @@ -907,6 +934,7 @@ static bool dot_bvfs_versions(UAContext *ua, const char *cmd) int limit=2000, offset=0; char *path=NULL, *client=NULL, *username=NULL; bool copies=false, versions=false; + alist clients(10, owned_by_alist); if (!bvfs_parse_arg(ua, &pathid, &path, NULL, &username, &limit, &offset)) { @@ -914,7 +942,7 @@ static bool dot_bvfs_versions(UAContext *ua, const char *cmd) return true; /* not enough param */ } - if (!bvfs_parse_arg_version(ua, &client, &fnid, &versions, &copies)) + if (!bvfs_parse_arg_version(ua, &client, &clients, &fnid, &versions, &copies)) { ua->error_msg("Can't find client or fnid argument\n"); return true; /* not enough param */ @@ -933,7 +961,7 @@ static bool dot_bvfs_versions(UAContext *ua, const char *cmd) fs.set_offset(offset); ua->bvfs = &fs; - fs.get_all_file_versions(pathid, fnid, client); + fs.get_all_file_versions(pathid, fnid, &clients); ua->bvfs = NULL; return true; @@ -1020,37 +1048,34 @@ static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd) } else if ((pos = find_arg_with_value(ua, "ujobid")) >= 0) { bstrncpy(jr.Job, ua->argv[pos], MAX_NAME_LENGTH); - /* Return all backup jobid for a client */ - } else if ((pos = find_arg_with_value(ua, "client")) >= 0) { - CLIENT *cli; + /* Return all backup jobid for a client list */ + } else if ((pos = find_arg_with_value(ua, "client")) >= 0 || + (pos = find_arg_with_value(ua, "clients")) >= 0) { POOL_MEM where; char limit[50]; bool ret; int nbjobs; + alist clients(10, owned_by_alist); - cli = GetClientResWithName(ua->argv[pos]); - if (!cli) { - ua->error_msg(_("Unable to get Client record for Client=%s\n"), - ua->argv[pos]); - return true; - } - db_lock(ua->db); + /* Turn client1,client2,client3 to a alist of clients */ + parse_list(ua->argv[pos], &clients); + db_lock(ua->db); bvfs_get_filter(ua, where, limit, sizeof(limit)); - Mmsg(ua->db->cmd, "SELECT JobId " "FROM Job JOIN Client USING (ClientId) " - "WHERE Client.Name = '%s' " + "WHERE Client.Name IN (%s) " "AND Job.Type = 'B' AND Job.JobStatus IN ('T', 'W') %s " "ORDER By JobTDate ASC %s", - cli->name(), where.c_str(), limit); + fs.escape_list(&clients), + where.c_str(), limit); ret = db_sql_query(ua->db, ua->db->cmd, db_list_handler, &jobids); db_unlock(ua->db); if (!ret) { ua->error_msg(_("Unable to get last Job record for Client=%s\n"), - cli->name()); + ua->argv[pos]); } nbjobs = fs.set_jobids(jobids.list); diff --git a/bacula/src/tools/bvfs_test.c b/bacula/src/tools/bvfs_test.c index 77c2edb40..21f9da987 100644 --- a/bacula/src/tools/bvfs_test.c +++ b/bacula/src/tools/bvfs_test.c @@ -270,9 +270,11 @@ int main (int argc, char *argv[]) } if (fnid && client) { + alist clients(1, not_owned_by_alist); + clients.append(client); Pmsg0(0, "---------------------------------------------\n"); Pmsg1(0, "Getting file version for %s\n", file); - fs.get_all_file_versions(fs.get_pwd(), fnid, client); + fs.get_all_file_versions(fs.get_pwd(), fnid, &clients); } exit (0); @@ -303,7 +305,7 @@ int main (int argc, char *argv[]) fs.ls_dirs(); fs.ls_files(); - fs.get_all_file_versions(1, 347, "zog4-fd"); + fs.get_all_file_versions(1, 347, (char*)"zog4-fd"); char p[200]; strcpy(p, "/tmp/toto/rep/"); -- 2.47.3