From: Eric Bollengier Date: Mon, 12 Jul 2021 12:41:41 +0000 (+0200) Subject: Add list jobmedia volume=x option X-Git-Tag: Release-11.3.2~454 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=37952b3ac833ce66c333d5e13cf210cf48bcb786;p=thirdparty%2Fbacula.git Add list jobmedia volume=x option The "list jobmedia" command now supports the volume= keyword to display the JobMedia for a given volume. The JobId keyword can be combined as well. --- diff --git a/bacula/src/cats/bdb.h b/bacula/src/cats/bdb.h index 5cc4b0bd3..306c46eec 100644 --- a/bacula/src/cats/bdb.h +++ b/bacula/src/cats/bdb.h @@ -259,7 +259,7 @@ public: void bdb_list_job_totals(JCR *jcr, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx); void bdb_list_files_for_job(JCR *jcr, uint32_t jobid, int deleted, DB_LIST_HANDLER sendit, void *ctx); void bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); - void bdb_list_jobmedia_records(JCR *jcr, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); + void bdb_list_jobmedia_records(JCR *jcr, JobId_t JobId, char *volume, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void bdb_list_filemedia_records(JCR *jcr, JobId_t JobId, uint32_t FileIndex, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void bdb_list_joblog_records(JCR *jcr, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); int bdb_list_sql_query(JCR *jcr, const char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type); diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h index 74f9e3dab..199d5a08c 100644 --- a/bacula/src/cats/protos.h +++ b/bacula/src/cats/protos.h @@ -272,8 +272,8 @@ void bdb_free_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr); mdb->bdb_list_files_for_job(jcr, jobid, deleted, sendit, ctx) #define db_list_media_records(jcr, mdb, mdbr, sendit, ctx, type) \ mdb->bdb_list_media_records(jcr, mdbr, sendit, ctx, type) -#define db_list_jobmedia_records(jcr, mdb, JobId, sendit, ctx, type) \ - mdb->bdb_list_jobmedia_records(jcr, JobId, sendit, ctx, type) +#define db_list_jobmedia_records(jcr, mdb, JobId, volume, sendit, ctx, type) \ + mdb->bdb_list_jobmedia_records(jcr, JobId, volume, sendit, ctx, type) #define db_list_filemedia_records(jcr, mdb, JobId, FI, sendit, ctx, type) \ mdb->bdb_list_filemedia_records(jcr, JobId, FI, sendit, ctx, type) #define db_list_joblog_records(jcr, mdb, JobId, sendit, ctx, type) \ diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index 4f881a503..bc180fd45 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -391,54 +391,51 @@ void BDB::bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, bdb_unlock(); } -void BDB::bdb_list_jobmedia_records(JCR *jcr, uint32_t JobId, +void BDB::bdb_list_jobmedia_records(JCR *jcr, uint32_t JobId, char *volume, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { - char ed1[50]; - + POOL_MEM where2; bdb_lock(); /* Get some extra SQL parameters if needed */ const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB) | DB_ACL_BIT(DB_ACL_FILESET) | - DB_ACL_BIT(DB_ACL_CLIENT), (JobId == 0)); + DB_ACL_BIT(DB_ACL_POOL) | + DB_ACL_BIT(DB_ACL_CLIENT), (JobId == 0 || volume != NULL)); const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) | DB_ACL_BIT(DB_ACL_FILESET) | + DB_ACL_BIT(DB_ACL_POOL) | DB_ACL_BIT(DB_ACL_CLIENT)) : ""; + if (JobId) { + Mmsg(where2, " WHERE JobMedia.JobId=%lu ", JobId); + } + + if (volume) { + POOL_MEM tmp, tmp2; + int len = strlen(volume); + tmp.check_size(len*2+1); + db_escape_string(jcr, this, tmp.c_str(), volume, len); + Mmsg(tmp2, " %s Media.VolumeName = '%s' ", JobId == 0 ?"WHERE": "AND", tmp.c_str()); + pm_strcat(where2, tmp2.c_str()); + } + if (type == VERT_LIST || type == JSON_LIST) { - if (JobId > 0) { /* do by JobId */ - Mmsg(cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," - "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," - "JobMedia.EndBlock " - "FROM JobMedia JOIN Media USING (MediaId) %s " - "WHERE JobMedia.JobId=%s %s", - join, - edit_int64(JobId, ed1), - where); - } else { - Mmsg(cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," - "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," - "JobMedia.EndBlock " - "FROM JobMedia JOIN Media USING (MediaId) %s %s", - join, - where); - } + Mmsg(cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," + "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," + "JobMedia.EndBlock " + "FROM JobMedia JOIN Media USING (MediaId) %s " + "%s %s ORDER BY JobMediaId ASC", + join, + where2.c_str(), + where); } else { - if (JobId > 0) { /* do by JobId */ - Mmsg(cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " - "FROM JobMedia JOIN Media USING (MediaId) %s WHERE " - "JobMedia.JobId=%s %s", - join, - edit_int64(JobId, ed1), - where); - } else { - Mmsg(cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " - "FROM JobMedia JOIN Media USING (MediaId) %s %s", - join, - where); - } + Mmsg(cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " + "FROM JobMedia JOIN Media USING (MediaId) %s %s %s ORDER BY JobMediaId ASC", + join, + where2.c_str(), + where); } Dmsg1(DT_SQL|50, "q=%s\n", cmd); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index ed16f9a83..8f2a7aca2 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -134,7 +134,7 @@ static struct cmdstruct commands[] = { /* C NT_("jobs [client=] [jobid=] [ujobid=] [job=] [tag=] [joberrors] [jobstatus=] [level=] [jobtype=] [days=] [hours=] [limit=] [order=]|\n" "\tjobtotals | pools | volume | media | files [type=] jobid= | copies jobid= |\n" "\tjoblog jobid= | pluginrestoreconf jobid= restoreobjectid= | snapshot | \n" - "\tfilemedia jobid= fileindex= | clients\n" + "\tfilemedia jobid= fileindex= | clients | jobmedia [jobid= volume=] |\n" "\tevents [type= | limit= | order= | days= | start= | end= |\n" "\t\t source= | code= | type= ]\n" "\tobjects [jobid= client= type= | category= | status= | limit= | order= ]\n" diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index ce0505b5e..b89ac403b 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -637,6 +637,13 @@ bool is_volume_name_legal(UAContext *ua, const char *name) const char *p; const char *accept = ":.-_"; + if (!name) { + if (ua) { + ua->error_msg(_("No volume specified.\n")); + } + return 0; + } + /* Restrict the characters permitted in the Volume name */ for (p=name; *p; p++) { if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) { diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 980c7b9a8..83ae464e5 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -543,26 +543,31 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist) /* List JOBMEDIA */ } else if (strcasecmp(ua->argk[i], NT_("jobmedia")) == 0) { - bool done = false; + char *volume = NULL; + jobid = 0; + for (j=i+1; jargc; j++) { - if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j]) { + if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j] && is_name_valid(ua->argv[j], NULL)) { bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH); jr.JobId = 0; db_get_job_record(ua->jcr, ua->db, &jr); jobid = jr.JobId; + } else if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) { jobid = str_to_int64(ua->argv[j]); + + } else if (strcasecmp(ua->argk[j], NT_("volume")) == 0 && + ua->argv[j] && is_volume_name_legal(ua, ua->argv[j])) { + volume = ua->argv[j]; + } else { continue; } - db_list_jobmedia_records(ua->jcr, ua->db, jobid, prtit, ua, llist); - done = true; - } - if (!done) { - /* List for all jobs (jobid=0) */ - db_list_jobmedia_records(ua->jcr, ua->db, 0, prtit, ua, llist); } + db_list_jobmedia_records(ua->jcr, ua->db, jobid, volume, prtit, ua, llist); + return 1; + /* list filemedia */ } else if (strcasecmp(ua->argk[i], NT_("filemedia")) == 0) { int32_t findex=0; diff --git a/bacula/src/tools/cdp-client/folderwatcher.cpp b/bacula/src/tools/cdp-client/folderwatcher.cpp index 72ee4eb23..bb437837a 100644 --- a/bacula/src/tools/cdp-client/folderwatcher.cpp +++ b/bacula/src/tools/cdp-client/folderwatcher.cpp @@ -75,13 +75,13 @@ POOLMEM *FolderWatcher::watch(const char *folder) return this->watchDirRecursive(folder); } -POOLMEM *FolderWatcher::watchDirRecursive(const char *dir) +char *FolderWatcher::watchDirRecursive(const char *dir, POOLMEM **err_msg) { DIR *dirReader = NULL; struct dirent *dirFile = NULL; const char *separator = NULL; POOLMEM *subdirPath = NULL; - char *err_msg = NULL; + pm_strcpy(err_msg, ""); uint32_t mask = IN_CLOSE | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_OPEN @@ -90,8 +90,6 @@ POOLMEM *FolderWatcher::watchDirRecursive(const char *dir) int wd = inotify_add_watch(_fd, dir, mask); if (wd < 0) { - err_msg = get_pool_memory(PM_EMSG); - switch (errno) { case EACCES: Mmsg(err_msg, "Could not watch Directory. Access Denied for: %s", dir); @@ -185,7 +183,8 @@ void FolderWatcher::handleEvent(struct inotify_event *event) } else if (closeNoWriteFileEvent) { _openedFiles.erase(event->wd); } else if (createEvent && isDir) { - this->watchDirRecursive(fpath); + POOLMEM *tmp = this->watchDirRecursive(fpath); + free_and_null_pool_memory(tmp); } else if (movedToEvent) { _changeHandler->onChange(fpath); } else if ((modifyEvent || attribsChangeEvent)