]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add list jobmedia volume=x option
authorEric Bollengier <eric@baculasystems.com>
Mon, 12 Jul 2021 12:41:41 +0000 (14:41 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:02 +0000 (09:03 +0100)
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.

bacula/src/cats/bdb.h
bacula/src/cats/protos.h
bacula/src/cats/sql_list.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_output.c
bacula/src/tools/cdp-client/folderwatcher.cpp

index 5cc4b0bd3d8da1213c770e745fe4a6fdf6c70006..306c46eec19f04d3d721a53bef1cd111154e4eab 100644 (file)
@@ -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);
index 74f9e3dab5957909e65736ca6b403ff7af449741..199d5a08c82bd5c72bf1ba6d3cdffd7077486b8c 100644 (file)
@@ -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)      \
index 4f881a503276bec5cc758d2ae075955207d6d631..bc180fd45a11abfe0ebad3fcee8870fec296f234 100644 (file)
@@ -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);
 
index ed16f9a831fe74c0b151e88a3cbb642d1dbb5f11..8f2a7aca2330e74cbc0a2a72feaa517ba6fd8c51 100644 (file)
@@ -134,7 +134,7 @@ static struct cmdstruct commands[] = {                                      /* C
    NT_("jobs [client=<cli>] [jobid=<nn>] [ujobid=<name>] [job=<name>] [tag=<name>] [joberrors] [jobstatus=<s>] [level=<l>] [jobtype=<t>] [days=<n>] [hours=<n>] [limit=<n>] [order=<asc|desc>]|\n"
        "\tjobtotals | pools | volume | media <pool=pool-name> | files [type=<deleted|all>] jobid=<nn> | copies jobid=<nn> |\n"
        "\tjoblog jobid=<nn> | pluginrestoreconf jobid=<nn> restoreobjectid=<nn> | snapshot | \n"
-       "\tfilemedia jobid=<nn> fileindex=<mm> | clients\n"
+       "\tfilemedia jobid=<nn> fileindex=<mm> | clients | jobmedia [jobid=<nn> volume=<s>] |\n"
        "\tevents [type=<str> | limit=<int> | order=<asc|desc> | days=<int> | start=<time-specification> | end=<time-specification> |\n"
        "\t\t source=<str> | code=<str> | type=<str> ]\n"
        "\tobjects [jobid=<jobid> client=<cli> type=<str> | category=<str> | status=<S> | limit=<int> | order=<asc|desc> ]\n"
index ce0505b5e6e8b11eb2fac13e4bc1e68d9c127ae8..b89ac403b880665b80b8a64e7ab9b9415b310e30 100644 (file)
@@ -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))) {
index 980c7b9a84e3a6fb8646b16262f89ec77c79794b..83ae464e555b33d7b4c4b47603e456061401693c 100644 (file)
@@ -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; j<ua->argc; 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;
index 72ee4eb2300c6d97a61cb86566fee26ad342991d..bb437837ad5ff9c6697cdc528a013b8c51cce71a 100644 (file)
@@ -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)