// 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;
}
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<smart_mutex> 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
if (!self){
return bRC_Error;
}
+ self->terminate_backends_oncancel(ctx);
delete self;
+
return bRC_OK;
}
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;
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`.