From: Radosław Korzeniewski Date: Thu, 24 Jun 2021 09:22:04 +0000 (+0200) Subject: metaplugin: Update backend termination procedure on cancel. X-Git-Tag: Release-11.3.2~446 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03e6fd004c8760456fd7845f6fe5d71cb7af631d;p=thirdparty%2Fbacula.git metaplugin: Update backend termination procedure on cancel. --- diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp index 57903333b..99928787b 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp @@ -586,16 +586,11 @@ bRC backendctx_cancel_func(PTCOMM *ptcomm, void *cp) // cancel procedure // 1. get backend pid // 2. send SIGUSR1 to backend pid - // 3. wait default 5 sec or defined in CUSTOMCANCELSLEEP - // 4. terminate the backend as usual pid_t pid = ptcomm->get_backend_pid(); DMSG(ctx, DINFO, "Inform backend about Cancel at PID=%d ...\n", pid) kill(pid, SIGUSR1); - int32_t waitsleep = (CUSTOMCANCELSLEEP == 0) * 5 + CUSTOMCANCELSLEEP; - bmicrosleep(waitsleep, 1); - DMSG(ctx, DINFO, "Terminate backend at PID=%d\n", pid); - ptcomm->terminate(ctx); + return bRC_OK; } @@ -2620,6 +2615,47 @@ bRC METAPLUGIN::checkFile(bpContext * ctx, char *fname) return bRC_OK; } +/** + * @brief Unconditionally terminates backend + * This callback is used on cancel event handling. + * + * @param ptcomm the backend communication object + * @param cp a bpContext - for Bacula debug and jobinfo messages + * @return bRC bRC_OK when success + */ +bRC backendctx_termination_func(PTCOMM *ptcomm, void *cp) +{ + bpContext * ctx = (bpContext*)cp; + + // terminate procedure + // 1. wait default 5 sec or defined in CUSTOMCANCELSLEEP + // 2. terminate the backend as usual + + pid_t pid = ptcomm->get_backend_pid(); + DMSG(ctx, DINFO, "Preparing the backend termination on Cancel at PID=%d ...\n", pid) + int32_t waitsleep = (CUSTOMCANCELSLEEP == 0) * 5 + CUSTOMCANCELSLEEP; + bmicrosleep(waitsleep, 1); + DMSG(ctx, DINFO, "Terminate backend at PID=%d\n", pid); + ptcomm->terminate(ctx); + + return bRC_OK; +} + +/** + * @brief Conditionally terminate backends for cancelled job + * + * @param ctx a bpContext - for Bacula debug and jobinfo messages + */ +void METAPLUGIN::terminate_backends_oncancel(bpContext *ctx) +{ + smart_lock lg(&mutex); + if (job_cancelled) { + DMSG0(ctx, DINFO, "Ensure backend termination on cancelled job\n"); + backend.foreach_command_status(backendctx_termination_func, ctx); + job_cancelled = false; + } +} + /* * Called here to make a new instance of the plugin -- i.e. when * a new Job is started. There can be multiple instances of @@ -2668,7 +2704,9 @@ static bRC freePlugin(bpContext *ctx) if (!self){ return bRC_Error; } + self->terminate_backends_oncancel(ctx); delete self; + return bRC_OK; } diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.h b/bacula/src/plugins/fd/pluginlib/metaplugin.h index 842446b86..cd6b89ea0 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.h +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.h @@ -125,45 +125,45 @@ public: bRC queryParameter(bpContext *ctx, struct query_pkt *qp); bRC metadataRestore(bpContext *ctx, struct meta_pkt *mp); void setup_backend_command(bpContext *ctx, POOL_MEM &exepath); - METAPLUGIN() : - backend_cmd(PM_FNAME), - job_cancelled(false), - backend_available(false), - backend_error(PM_MESSAGE), - mode(NONE), - JobId(0), - JobName(NULL), - since(0), - where(NULL), - regexwhere(NULL), - replace(0), - robjsent(false), - estimate(false), - listing(None), - nodata(false), - nextfile(false), - openerror(false), - pluginobject(false), - pluginobjectsent(false), - readacl(false), - readxattr(false), - skipextract(false), - last_type(0), - fname(PM_FNAME), - lname(PM_FNAME), - robjbuf(PM_MESSAGE), - plugin_obj_cat(PM_FNAME), - plugin_obj_type(PM_FNAME), - plugin_obj_name(PM_FNAME), - plugin_obj_src(PM_FNAME), - plugin_obj_uuid(PM_FNAME), - plugin_obj_size(PM_FNAME), - acldatalen(0), - acldata(PM_MESSAGE), - xattrdatalen(0), - xattrdata(PM_MESSAGE), - metadatas_list(10, true), - prevjobname(NULL) + void terminate_backends_oncancel(bpContext *ctx); + METAPLUGIN() : backend_cmd(PM_FNAME), + job_cancelled(false), + backend_available(false), + backend_error(PM_MESSAGE), + mode(NONE), + JobId(0), + JobName(NULL), + since(0), + where(NULL), + regexwhere(NULL), + replace(0), + robjsent(false), + estimate(false), + listing(None), + nodata(false), + nextfile(false), + openerror(false), + pluginobject(false), + pluginobjectsent(false), + readacl(false), + readxattr(false), + skipextract(false), + last_type(0), + fname(PM_FNAME), + lname(PM_FNAME), + robjbuf(PM_MESSAGE), + plugin_obj_cat(PM_FNAME), + plugin_obj_type(PM_FNAME), + plugin_obj_name(PM_FNAME), + plugin_obj_src(PM_FNAME), + plugin_obj_uuid(PM_FNAME), + plugin_obj_size(PM_FNAME), + acldatalen(0), + acldata(PM_MESSAGE), + xattrdatalen(0), + xattrdata(PM_MESSAGE), + metadatas_list(10, true), + prevjobname(NULL) {} #if __cplusplus > 201103L METAPLUGIN(METAPLUGIN&) = delete; diff --git a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp index 3723236e0..4c5cfce89 100644 --- a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp +++ b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp @@ -66,44 +66,41 @@ bool PTCOMM::close_extpipe(bpContext *ctx) return true; } -/* - * Terminate the connection represented by BPIPE object. +/** + * @brief Terminate the connection represented by BPIPE object. * it shows a debug and job messages when connection close is unsuccessful * and when ctx is available only. * - * in: - * bpContext - Bacula Plugin context required for debug/job messages to show, - * it could be NULL in this case no messages will be shown - * out: - * none + * @param ctx bpContext - Bacula Plugin context required for debug/job messages to show, + * it could be NULL in this case no messages will be shown */ void PTCOMM::terminate(bpContext *ctx) { - if (is_closed()) + if (is_closed()) { return; + } pid_t worker_pid = bpipe->worker_pid; int status = close_bpipe(bpipe); - bpipe = NULL; // indicte closed bpipe + bpipe = NULL; // indicate closed bpipe - if (status && ctx) - { + if (status && ctx) { /* error during close */ berrno be; DMSG(ctx, DERROR, "Error closing backend. Err=%s\n", be.bstrerror(status)); JMSG(ctx, M_ERROR, "Error closing backend. Err=%s\n", be.bstrerror(status)); } - if (worker_pid) - { + if (worker_pid) { /* terminate the backend */ kill(worker_pid, SIGTERM); } - if (extpipe > 0) + if (extpipe > 0) { close_extpipe(ctx); -}; + } +} /** * @brief Reads `nbytes` of data from backend into a buffer `buf`.