From: Eric Bollengier Date: Wed, 13 Jan 2021 08:37:40 +0000 (+0100) Subject: Add .bvfs_ls_all_files command X-Git-Tag: Release-11.3.2~773 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=23ef2d7b402fc603e86f57730b5186391c9b6c16;p=thirdparty%2Fbacula.git Add .bvfs_ls_all_files command --- diff --git a/bacula/src/cats/bvfs.c b/bacula/src/cats/bvfs.c index 723748c45..0ccd54389 100644 --- a/bacula/src/cats/bvfs.c +++ b/bacula/src/cats/bvfs.c @@ -1207,7 +1207,41 @@ bool Bvfs::ls_dirs() return nb_record == limit; } -void build_ls_files_query(BDB *db, POOL_MEM &query, +/* List all files from a set of jobs */ +bool Bvfs::ls_all_files() +{ + POOL_MEM query; + POOL_MEM filter; + + if (*jobids == 0) { + return false; + } + + if (*pattern) { + Mmsg(filter, " AND File.Filename %s '%s' ", + match_query[db->bdb_get_type_index()], pattern); + + } else if (*filename) { + Mmsg(filter, " AND File.Filename = '%s' ", filename); + } + + Mmsg(query, sql_bvfs_list_all_files[db->bdb_get_type_index()], + filter.c_str(), jobids, limit, offset); + + /* TODO: check all parent directories to know if we can + * list the files here. + */ + Dmsg1(dbglevel_sql, "q=%s\n", query.c_str()); + + db->bdb_lock(); + db->bdb_sql_query(query.c_str(), list_entries, user_data); + nb_record = db->sql_num_rows(); + db->bdb_unlock(); + + return nb_record == limit; +} + +static void build_ls_files_query(BDB *db, POOL_MEM &query, const char *JobId, const char *PathId, const char *filter, int64_t limit, int64_t offset) { diff --git a/bacula/src/cats/bvfs.h b/bacula/src/cats/bvfs.h index 3544a9d5d..41a2299af 100644 --- a/bacula/src/cats/bvfs.h +++ b/bacula/src/cats/bvfs.h @@ -116,7 +116,7 @@ public: * Returns true if the directory exists */ bool ch_dir(const char *path); - + bool ls_all_files(); /* Returns true if we have more files to read */ 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 .. */ diff --git a/bacula/src/cats/sql_cmds.c b/bacula/src/cats/sql_cmds.c index e3d388e7a..d892e1e23 100644 --- a/bacula/src/cats/sql_cmds.c +++ b/bacula/src/cats/sql_cmds.c @@ -759,6 +759,34 @@ const char *sql_bvfs_select[] = default_sql_bvfs_select }; +static const char *sql_bvfs_list_all_files_default = +"SELECT 'F', File.PathId, Path.Path || File.Filename, " + "File.JobId, File.LStat, File.FileId " +"FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) " +"WHERE File.Filename != '' " + "AND File.FileIndex > 0 " + " %s " /* AND Name LIKE '' */ + "AND Job.JobId IN ( %s) ORDER BY File.FileId " // Needed to support LIMIT/OFFSET + "LIMIT %lld OFFSET %lld"; + +const char *sql_bvfs_list_all_files[] = { + /* MySQL */ +"SELECT 'F', File.PathId, CONCAT(Path.Path, File.Filename), " + "File.JobId, File.LStat, File.FileId " +"FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) " +"WHERE File.Filename != '' " + "AND File.FileIndex > 0 " + " %s " /* AND Name LIKE '' */ + "AND Job.JobId IN (%s) ORDER BY File.FileId " // Needed to support LIMIT/OFFSET + "LIMIT %lld OFFSET %lld", + + /* PostgreSQL */ + sql_bvfs_list_all_files_default, + + /* SQLite */ + sql_bvfs_list_all_files_default +}; + static const char *sql_bvfs_list_files_default = "SELECT 'F', T.PathId, T.Filename, " "File.JobId, File.LStat, File.FileId " diff --git a/bacula/src/cats/sql_cmds.h b/bacula/src/cats/sql_cmds.h index b8d6f0baa..bac92eaee 100644 --- a/bacula/src/cats/sql_cmds.h +++ b/bacula/src/cats/sql_cmds.h @@ -56,6 +56,7 @@ extern const char CATS_IMP_EXP *select_recent_version[]; extern const char CATS_IMP_EXP *select_recent_version_with_basejob[]; extern const char CATS_IMP_EXP *select_recent_version_with_basejob_and_delta[]; extern const char CATS_IMP_EXP *sel_JobMedia; +extern const char CATS_IMP_EXP *sql_bvfs_list_all_files[]; extern const char CATS_IMP_EXP *sql_bvfs_list_files[]; extern const char CATS_IMP_EXP *sql_bvfs_select[]; extern const char CATS_IMP_EXP *sql_get_max_connections[]; diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index 565f44c4b..96ac50193 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -70,6 +70,7 @@ static bool catalogscmd(UAContext *ua, const char *cmd); static bool dot_ls_cmd(UAContext *ua, const char *cmd); static bool dot_bvfs_lsdirs(UAContext *ua, const char *cmd); static bool dot_bvfs_lsfiles(UAContext *ua, const char *cmd); +static bool dot_bvfs_ls_all_files(UAContext *ua, const char *cmd); static bool dot_bvfs_update(UAContext *ua, const char *cmd); static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd); static bool dot_bvfs_versions(UAContext *ua, const char *cmd); @@ -127,6 +128,7 @@ static struct cmdstruct commands[] = { /* help */ /* can be used in runscript * { NT_(".actiononpurge"),aopcmd, NULL, true}, { NT_(".bvfs_lsdirs"), dot_bvfs_lsdirs, NULL, true}, { NT_(".bvfs_lsfiles"),dot_bvfs_lsfiles, NULL, true}, + { NT_(".bvfs_ls_all_files"),dot_bvfs_ls_all_files, NULL, true}, { NT_(".bvfs_get_volumes"),dot_bvfs_get_volumes,NULL, true}, { NT_(".bvfs_update"), dot_bvfs_update, NULL, true}, { NT_(".bvfs_get_jobids"), dot_bvfs_get_jobids, NULL, true}, @@ -580,10 +582,14 @@ static bool bvfs_parse_arg(UAContext *ua, char **username, int *limit, int *offset) { - *pathid=0; + if (pathid) { + *pathid=0; + } + if (path) { + *path=NULL; + } *limit=2000; *offset=0; - *path=NULL; *username=NULL; if (jobid) { *jobid=NULL; @@ -593,13 +599,13 @@ static bool bvfs_parse_arg(UAContext *ua, if (!ua->argv[i]) { continue; } - if (strcasecmp(ua->argk[i], NT_("pathid")) == 0) { + if (pathid && strcasecmp(ua->argk[i], NT_("pathid")) == 0) { if (is_a_number(ua->argv[i])) { *pathid = str_to_int64(ua->argv[i]); } } - if (strcasecmp(ua->argk[i], NT_("path")) == 0) { + if (path && strcasecmp(ua->argk[i], NT_("path")) == 0) { *path = ua->argv[i]; } @@ -649,8 +655,10 @@ static bool bvfs_parse_arg(UAContext *ua, return false; } - if (!(*pathid || *path)) { - return false; + if (path && pathid) { + if (!(*pathid || *path)) { + return false; + } } return true; @@ -1139,6 +1147,61 @@ bail_out: return true; } +/* + * .bvfs_ls_all_files jobid=1,2,3,4 + */ +static bool dot_bvfs_ls_all_files(UAContext *ua, const char *cmd) +{ + int limit=2000, offset=0; + char *jobid=NULL, *username=NULL; + char *pattern=NULL, *filename=NULL; + int i; + + if (!bvfs_parse_arg(ua, NULL, NULL, &jobid, &username, + &limit, &offset)) + { + ua->error_msg("Can't find jobid argument\n"); + return true; /* not enough param */ + } + if ((i = find_arg_with_value(ua, "pattern")) >= 0) { + pattern = ua->argv[i]; + } + if ((i = find_arg_with_value(ua, "filename")) >= 0) { + filename = ua->argv[i]; + } + + if (!open_new_client_db(ua)) { + return 1; + } + + Bvfs fs(ua->jcr, ua->db); + bvfs_set_acl(ua, &fs); + fs.set_username(username); + if (str_to_int64(jobid) == 0) { + if (get_client_jobids(ua, &fs) <= 0) { + goto bail_out; + } + } else { + fs.set_jobids(jobid); + } + fs.set_handler(bvfs_result_handler, ua); + fs.set_limit(limit); + ua->bvfs = &fs; + if (pattern) { + fs.set_pattern(pattern); + } + if (filename) { + fs.set_filename(filename); + } + + fs.set_offset(offset); + fs.ls_all_files(); + +bail_out: + ua->bvfs = NULL; + return true; +} + /* * .bvfs_lsdirs jobid=1,2,3,4 pathid=10 * .bvfs_lsdirs jobid=1,2,3,4 path=/