]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
pluginlib: Update execprog to better handle termination.
authorRadosław Korzeniewski <radoslaw@korzeniewski.net>
Tue, 26 Oct 2021 17:11:43 +0000 (19:11 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:56 +0000 (13:56 +0200)
bacula/src/plugins/fd/pluginlib/execprog.cpp
bacula/src/plugins/fd/pluginlib/execprog.h

index 8d4c8fb527a3d4955c09f7a81d1f7a50071890d5..74e629cef5888b3343358270501eb162dc2b2a71 100644 (file)
@@ -31,6 +31,7 @@
 /* Plugin compile time variables */
 #define PLUGINPREFIX                "execprog:"
 
+
 /*
  * Terminate the connection represented by BPIPE object.
  *    it shows a debug and job messages when connection close is unsuccessful
  * out:
  *    none
  */
-void EXECPROG::terminate(bpContext *ctx, bool raise_error)
+int EXECPROG::terminate(bpContext *ctx, bool raise_error)
 {
-   if (is_closed())
-   {
-      return;
-   }
+   // clear status
+   tstatus = 0;
+   pm_strcpy(m_errmsg, NULL);
 
-   // after close_bpipe it is no longer available
-   tstatus = close_bpipe(bpipe);
-   if (tstatus && raise_error)
+   if (!is_closed())
    {
-      /* error during close */
+      // after close_bpipe it is no longer available
+      pid_t wpid = bpipe->worker_pid;
+
+
+      tstatus = close_bpipe(bpipe);
       berrno be;
-      DMSG(ctx, DERROR, "Error closing command. Err=%s\n", be.bstrerror(tstatus));
-      JMSG(ctx, M_ERROR, "Error closing command. Err=%s\n", be.bstrerror(tstatus));
-   }
+      pm_strcpy(m_errmsg, be.bstrerror(tstatus));
+      if (tstatus)
+      {
+         /* error during close */
+         DMSG(ctx, DERROR, "Error closing command. Err=%s (%d)\n", m_errmsg.c_str());
+         if (raise_error)
+         {
+            // raise it on request
+            JMSG(ctx, M_ERROR, "Error closing command. Err=%s (%d)\n", m_errmsg.c_str());
+         }
+      }
+
+      if (wpid)
+      {
+         /* terminate the process command */
+         kill(wpid, SIGTERM);
+      }
 
-   // TODO: is it required to terminate the backend process?
-   // if (bpipe->worker_pid){
-   //    /* terminate the process command */
-   //    kill(bpipe->worker_pid, SIGTERM);
-   // }
+      bpipe = NULL;
+   }
 
-   bpipe = NULL;
-};
+   return tstatus;
+}
 
 /*
  * Run command and prepared parameters.
index e7700bb3cf76d5c6e89e69717de0eda216ce0afd..225efe8e3bc95ca336a9bae9e2113ef77a8aa35a 100644 (file)
@@ -40,7 +40,7 @@ private:
    int wfd;                   // backend `stdin` to plugin file descriptor
    int efd;                   // backend `stderr` to plugin file descriptor
    int maxfd;                 // max file descriptors from bpipe channels
-   POOL_MEM errmsg;           // message buffer for error string
+   POOL_MEM m_errmsg;         /// message buffer for error string
    int extpipe;               // set when data blast is performed using external pipe/file
    POOL_MEM extpipename;      // name of the external pipe/file for restore
    bool f_eod;                // the backend signaled EOD
@@ -59,7 +59,7 @@ public:
       wfd(0),
       efd(0),
       maxfd(0),
-      errmsg(PM_MESSAGE),
+      m_errmsg(PM_MESSAGE),
       extpipe(-1),
       extpipename(PM_FNAME),
       f_eod(false),
@@ -92,7 +92,7 @@ public:
     * @return true if connection is closed and we can't use bpipe object
     * @return false if connection is available
     */
-   inline bool is_open() { return bpipe != NULL; };
+   inline bool is_open() { return bpipe != NULL; }
 
    /**
     * @brief Checks if connection is closed and we can't use a bpipe object for communication.
@@ -100,7 +100,7 @@ public:
     * @return true if connection is closed and we can't use bpipe object
     * @return false if connection is available
     */
-   inline bool is_closed() { return bpipe == NULL; };
+   inline bool is_closed() { return bpipe == NULL; }
 
    /**
     * @brief Checks if backend sent us some error, backend error message is flagged on f_error.
@@ -108,7 +108,7 @@ public:
     * @return true
     * @return false
     */
-   inline bool is_error() { return f_error || f_fatal; };
+   inline bool is_error() { return f_error || f_fatal; }
 
    /**
     * @brief Checks if backend sent us fatal error, backend error message is flagged on f_fatal.
@@ -116,19 +116,19 @@ public:
     * @return true
     * @return false
     */
-   inline bool is_fatal() { return f_fatal || (f_error && abort_on_error); };
+   inline bool is_fatal() { return f_fatal || (f_error && abort_on_error); }
 
    /**
     * @brief Set the abort on error object
     *
     */
-   inline void set_abort_on_error() { abort_on_error = true; };
+   inline void set_abort_on_error() { abort_on_error = true; }
 
    /**
     * @brief Clear abort_on_error flag.
     *
     */
-   inline void clear_abort_on_error() { abort_on_error = false; };
+   inline void clear_abort_on_error() { abort_on_error = false; }
 
    /**
     * @brief Return abort_on_error flag.
@@ -136,7 +136,7 @@ public:
     * @return true
     * @return false
     */
-   inline bool is_abort_on_error() { return abort_on_error; };
+   inline bool is_abort_on_error() { return abort_on_error; }
 
    /**
     * @brief Checks if backend signaled EOD, eod from backend is flagged on f_eod.
@@ -144,14 +144,14 @@ public:
     * @return true when backend signaled EOD on last packet
     * @return false when backend did not signal EOD
     */
-   inline bool is_eod() { return f_eod; };
+   inline bool is_eod() { return f_eod; }
 
    /**
     * @brief Clears the EOD from backend flag, f_eod.
     *  The eod flag is set when EOD message received from backend and not cleared
     *  until next recvbackend() call.
     */
-   inline void clear_eod() { f_eod = false; };
+   inline void clear_eod() { f_eod = false; }
 
    /**
     * @brief Get the cmd pid.
@@ -167,7 +167,7 @@ public:
       return -1;
    };
 
-   inline int get_terminate_status() { return tstatus; };
+   inline int get_terminate_status() { return tstatus; }
 
    /* all you need is to simply execute the command first */
    bool execute_command(bpContext *ctx, const char *cmd, const char *args = "");
@@ -185,9 +185,10 @@ public:
    int32_t write_data(bpContext *ctx, POOLMEM *buf, int32_t len);
 
    /* and finally terminate execution when finish */
-   void terminate(bpContext *ctx, bool raise_error = true);
+   int terminate(bpContext *ctx, bool raise_error = true);
 
-   POOLMEM *get_error(bpContext *ctx);
+   inline POOL_MEM &get_error() noexcept { return m_errmsg; }
+   inline char *get_error_str() noexcept { return m_errmsg.c_str(); }
 
    /* direct pipe management */
    inline int close_wpipe() { return ::close_wpipe(bpipe); }