]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
metaplugin: Fix #7678 About issue with queryParameter with an invalid plugin
authorRadosław Korzeniewski <radoslaw@korzeniewski.net>
Mon, 24 May 2021 15:14:13 +0000 (17:14 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:02 +0000 (09:03 +0100)
bacula/src/plugins/fd/pluginlib/metaplugin.cpp
bacula/src/plugins/fd/pluginlib/metaplugin.h
bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c
regress/scripts/metaplugin-protocol-tests.sh

index c39c55db41ff332dc844b1be460c5b8fd9dd7a5c..59c963e360e0c3982f4507798d040dd46f8dde51 100644 (file)
@@ -157,7 +157,7 @@ METAPLUGIN::METAPLUGIN(bpContext *bpctx) :
       replace(0),
       robjsent(false),
       estimate(false),
-      listing(ListingNone),
+      listing(None),
       nodata(false),
       nextfile(false),
       openerror(false),
@@ -382,7 +382,7 @@ bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, alist
       if (strcasecmp(parser.argk[i], "listing") == 0){
          /* found, so check the value if provided */
          if (parser.argv[i]){
-            listing = ListingMode;
+            listing = Listing;
             DMSG0(ctx, DINFO, "listing procedure param found\n");
          }
       }
@@ -390,7 +390,7 @@ bRC METAPLUGIN::parse_plugin_command(bpContext *ctx, const char *command, alist
       if (strcasecmp(parser.argk[i], "query") == 0){
          /* found, so check the value if provided */
          if (parser.argv[i]){
-            listing = ListingQueryParams;
+            listing = Query;
             DMSG0(ctx, DINFO, "query procedure param found\n");
          }
       }
@@ -927,6 +927,21 @@ bRC METAPLUGIN::send_startlisting(bpContext *ctx)
    return send_startjob(ctx, "ListingStart\n");
 }
 
+/*
+ * Send "QueryStart" protocol command.
+ *    more info at PLUGIN::send_startjob
+ *
+ * in:
+ *    bpContext - for Bacula debug and jobinfo messages
+ * out:
+ *    bRC_OK - when send command was successful
+ *    bRC_Error - on any error
+ */
+bRC METAPLUGIN::send_startquery(bpContext *ctx)
+{
+   return send_startjob(ctx, "QueryStart\n");
+}
+
 /*
  * Send "RestoreStart" protocol command.
  *    more info at METAPLUGIN::send_startjob
@@ -1041,8 +1056,7 @@ bRC METAPLUGIN::prepare_backend(bpContext *ctx, char type, char *command)
    }
 
    // check for prohibitted command duplication
-   if (type != BACKEND_JOB_INFO_RESTORE && backend.check_command(command))
-   {
+   if (type != BACKEND_JOB_INFO_RESTORE && backend.check_command(command)) {
       // already exist, report
       DMSG1(ctx, DERROR, "Plugin command=%s already defined, cannot proceed.\n", command);
       JMSG1(ctx, M_FATAL, "Plugin command already defined: \"%s\" Cannot proceed. You should correct FileSet configuration.\n", command);
@@ -1062,58 +1076,80 @@ bRC METAPLUGIN::prepare_backend(bpContext *ctx, char type, char *command)
    }
    /* handshake (1) */
    DMSG0(ctx, DINFO, "Backend handshake...\n");
-   if (!backend.ctx->handshake(ctx, PLUGINNAME, PLUGINAPI))
-   {
+   if (!backend.ctx->handshake(ctx, PLUGINNAME, PLUGINAPI)) {
       backend.ctx->terminate(ctx);
       return bRC_Error;
    }
    /* Job Info (2) */
    DMSG0(ctx, DINFO, "Job Info (2) ...\n");
-   if (send_jobinfo(ctx, type) != bRC_OK){
+   if (send_jobinfo(ctx, type) != bRC_OK) {
       backend.ctx->terminate(ctx);
       return bRC_Error;
    }
    /* Plugin Params (3) */
    DMSG0(ctx, DINFO, "Plugin Params (3) ...\n");
-   if (send_parameters(ctx, command) != bRC_OK){
+   if (send_parameters(ctx, command) != bRC_OK) {
       backend.ctx->terminate(ctx);
       return bRC_Error;
    }
-   switch (type){
-      case BACKEND_JOB_INFO_BACKUP:
-         /* Start Backup (4) */
-         DMSG0(ctx, DINFO, "Start Backup (4) ...\n");
-         if (send_startbackup(ctx) != bRC_OK){
-            backend.ctx->terminate(ctx);
-            return bRC_Error;
-         }
-         break;
-      case BACKEND_JOB_INFO_ESTIMATE:
-         /* Start Estimate or Listing (4) */
-         if (listing != ListingNone){
+   switch (type)
+   {
+   case BACKEND_JOB_INFO_BACKUP:
+      /* Start Backup (4) */
+      DMSG0(ctx, DINFO, "Start Backup (4) ...\n");
+      if (send_startbackup(ctx) != bRC_OK){
+         backend.ctx->terminate(ctx);
+         return bRC_Error;
+      }
+      break;
+   case BACKEND_JOB_INFO_ESTIMATE:
+      {
+         /* Start Estimate or Listing/Query (4) */
+         bRC rc = bRC_Error;
+         switch (listing)
+         {
+         case Listing:
             DMSG0(ctx, DINFO, "Start Listing (4) ...\n");
-            if (send_startlisting(ctx) != bRC_OK){
-               backend.ctx->terminate(ctx);
-               return bRC_Error;
-            }
-         } else {
+            rc = send_startlisting(ctx);
+            break;
+         case Query:
+            DMSG0(ctx, DINFO, "Start Query Params (4) ...\n");
+            rc = send_startquery(ctx);
+            break;
+         default:
             DMSG0(ctx, DINFO, "Start Estimate (4) ...\n");
-            if (send_startestimate(ctx) != bRC_OK){
-               backend.ctx->terminate(ctx);
-               return bRC_Error;
-            }
+            rc = send_startestimate(ctx);
+            break;
          }
-         break;
-      case BACKEND_JOB_INFO_RESTORE:
-         /* Start Restore (4) */
-         DMSG0(ctx, DINFO, "Start Restore (4) ...\n");
-         if (send_startrestore(ctx) != bRC_OK){
+         if (rc != bRC_OK) {
             backend.ctx->terminate(ctx);
             return bRC_Error;
          }
-         break;
-      default:
+      }
+         // if (listing != ListingNone){
+         //    DMSG0(ctx, DINFO, "Start Listing (4) ...\n");
+         //    if (send_startlisting(ctx) != bRC_OK){
+         //       backend.ctx->terminate(ctx);
+         //       return bRC_Error;
+         //    }
+         // } else {
+         //    DMSG0(ctx, DINFO, "Start Estimate (4) ...\n");
+         //    if (send_startestimate(ctx) != bRC_OK){
+         //       backend.ctx->terminate(ctx);
+         //       return bRC_Error;
+         //    }
+         // }
+      break;
+   case BACKEND_JOB_INFO_RESTORE:
+      /* Start Restore (4) */
+      DMSG0(ctx, DINFO, "Start Restore (4) ...\n");
+      if (send_startrestore(ctx) != bRC_OK) {
+         backend.ctx->terminate(ctx);
          return bRC_Error;
+      }
+      break;
+   default:
+      return bRC_Error;
    }
    DMSG0(ctx, DINFO, "Prepare backend done.\n");
    return bRC_OK;
@@ -2383,8 +2419,14 @@ bRC METAPLUGIN::queryParameter(bpContext *ctx, struct query_pkt *qp)
 
    DMSG0(ctx, D1, "METAPLUGIN::queryParameter\n");
 
-   if (listing == ListingNone){
-      listing = ListingQueryParams;
+   // check if it is our Plugin command
+   if (!isourplugincommand(PLUGINPREFIX, qp->command) != 0){
+      // it is not our plugin prefix
+      return bRC_OK;
+   }
+
+   if (listing == None) {
+      listing = Query;
       Mmsg(cmd, "%s query=%s", qp->command, qp->parameter);
       if (prepare_backend(ctx, BACKEND_JOB_INFO_ESTIMATE, cmd.c_str()) == bRC_Error){
          return bRC_Error;
@@ -2404,6 +2446,7 @@ bRC METAPLUGIN::queryParameter(bpContext *ctx, struct query_pkt *qp)
       DMSG0(ctx, D1, "METAPLUGIN::queryParameter: got EOD\n");
       backend.ctx->signal_term(ctx);
       backend.ctx->terminate(ctx);
+      qp->result = NULL;
       ret = bRC_OK;
    } else {
       /*
@@ -2736,7 +2779,7 @@ static bRC queryParameter(bpContext *ctx, struct query_pkt *qp)
 {
    ASSERT_CTX;
 
-   DMSG2(ctx, D1, "queryParameter: %s:%s\n", qp->command, qp->parameter);
+   DMSG2(ctx, D1, "queryParameter: cmd:%s param:%s\n", qp->command, qp->parameter);
    METAPLUGIN *self = pluginclass(ctx);
    return self->queryParameter(ctx, qp);
 }
index 379d48f231fe2bcfb77dbc06c6718186d286972d..2e8408f51108e3fa37fbc010184cf85b220c0ebe 100644 (file)
@@ -91,12 +91,17 @@ public:
    enum MODE
    {
       NONE = 0,
-      BACKUP_FULL,
-      BACKUP_INCR,
-      BACKUP_DIFF,
-      Estimate,
-      Listing,
-      QueryParams,
+      Backup_Full,
+      BACKUP_FULL = Backup_Full,
+      Backup_Incr,
+      BACKUP_INCR = Backup_Incr,
+      Backup_Diff,
+      BACKUP_DIFF = Backup_Diff,
+      Estimate_Full,
+      Estimate_Incr,
+      Estimate_Diff,
+      // Listing,
+      // QueryParams,
       RESTORE,
    };
 
@@ -128,9 +133,9 @@ public:
 private:
    enum LISTING
    {
-      ListingNone,
-      ListingMode,
-      ListingQueryParams,
+      None,
+      Listing,
+      Query,
    };
 
    // TODO: define a variable which will signal job cancel
@@ -184,6 +189,7 @@ private:
    bRC send_startbackup(bpContext *ctx);
    bRC send_startestimate(bpContext *ctx);
    bRC send_startlisting(bpContext *ctx);
+   bRC send_startquery(bpContext *ctx);
    bRC send_startrestore(bpContext *ctx);
    bRC send_endjob(bpContext *ctx);
    bRC prepare_backend(bpContext *ctx, char type, char *command);
index 4977d6e97067075b2e591b922660222cae4337b4..dd1d2ae97741a01c1296a9f0dc594a989fc1791a 100644 (file)
@@ -702,10 +702,29 @@ void perform_listing(char *listing){
    signal_eod();
 }
 
-void perform_restore(){
+/*
+ * The query param procedure
+ *    return 3 simple parameters
+ */
+void perform_queryparam(char *query)
+{
+   /* Query Loop (5) */
+   snprintf(buf, BIGBUFLEN, "%s=test1\n", query);
+   write_plugin('C', buf);
+   snprintf(buf, BIGBUFLEN, "%s=test2\n", query);
+   write_plugin('C', buf);
+   snprintf(buf, BIGBUFLEN, "%s=test3\n", query);
+   write_plugin('C', buf);
 
-   int len;
-   int fsize;
+   /* this is the end of all data */
+   signal_eod();
+}
+
+/*
+ * The main and universal restore procedure
+ */
+void perform_restore()
+{
    bool loopgo = true;
    bool restore_skip_create = false;
    bool restore_with_core = false;
@@ -792,7 +811,7 @@ void perform_restore(){
 
       /* check if DATA command, so read the data packets */
       if (strcmp(buf, "DATA\n") == 0){
-         len = read_plugin(buf);
+         int len = read_plugin(buf);
          if (len == 0){
             /* empty file to restore */
             LOG("#> Empty file.");
@@ -801,7 +820,7 @@ void perform_restore(){
             LOG("#> file data saved.");
          }
          loopgo = true;
-         fsize = len;
+         int fsize = len;
          while (loopgo){
             len = read_plugin(buf);
             fsize += len;
@@ -833,6 +852,7 @@ int main(int argc, char** argv) {
 
    int len;
    char *listing;
+   char *query;
 
    buf = (char*)malloc(BIGBUFLEN);
    if (buf == NULL){
@@ -846,6 +866,10 @@ int main(int argc, char** argv) {
    if (listing == NULL){
       exit(255);
    }
+   query = (char*)malloc(BUFLEN);
+   if (query == NULL){
+      exit(255);
+   }
 
    mypid = getpid();
    snprintf(buf, 4096, "%s/%s_backend_%d.log", LOGDIR, PLUGINNAME, mypid);
@@ -929,6 +953,10 @@ int main(int argc, char** argv) {
          strcpy(listing, buf);
          continue;
       }
+      if (sscanf(buf, "query=%s\n", buf) == 1){
+         strcpy(query, buf);
+         continue;
+      }
    }
    write_plugin('I', "TEST3");
    if (!regress_error_plugin_params){
@@ -959,6 +987,9 @@ int main(int argc, char** argv) {
    if (strcmp(buf, "ListingStart\n") == 0){
       perform_listing(listing);
    } else
+   if (strcmp(buf, "QueryStart\n") == 0){
+      perform_queryparam(query);
+   } else
    if (strcmp(buf, "RestoreStart\n") == 0){
       perform_restore();
    }
index d0fdeaa5349d04ef9d4a476dbd48dee7729e2e77..6fc8e7e1e642a8a6546e92dba7c35e1e2ff2b3b1 100755 (executable)
@@ -281,6 +281,41 @@ TEST=$((TEST+1))
 
 done
 
+# test query mode
+TEST=1
+
+cat <<END_OF_DATA >${cwd}/tmp/bconcmds
+@#
+@# Query
+@#
+@output /dev/null
+messages
+@$out ${cwd}/tmp/qlog${TEST}.out
+setdebug level=500 client=$CLIENT trace=1
+.query client=$CLIENT plugin="$Plugin" parameter="m_id"
+messages
+@output
+quit
+END_OF_DATA
+run_bconsole
+TEST=$((TEST+1))
+
+cat <<END_OF_DATA >${cwd}/tmp/bconcmds
+@#
+@# Query
+@#
+@output /dev/null
+messages
+@$out ${cwd}/tmp/qlog${TEST}.out
+setdebug level=500 client=$CLIENT trace=1
+.query client=$CLIENT plugin="invalid" parameter="invalid"
+messages
+@output
+quit
+END_OF_DATA
+run_bconsole
+TEST=$((TEST+1))
+
 stop_bacula
 
 RET=$(grep "jobstatus:" ${cwd}/tmp/log1.out | awk '{print $2}')
@@ -407,4 +442,18 @@ then
    rstat=5
 fi
 
+RET=$(grep -c "m_id=test" ${cwd}/tmp/qlog1.out)
+if [ "$RET" -ne 3 ]
+then
+   echo "qlog1" "$RET"
+   estat=2
+fi
+
+RET=$(grep -c "invalid=test" ${cwd}/tmp/qlog2.out)
+if [ "$RET" -gt 0 ]
+then
+   echo "qlog2" "$RET"
+   estat=3
+fi
+
 end_test