From dbceb68d5b5aa2bf2d5af556c9f8b0d28bb4d369 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 21 Apr 2005 17:20:38 +0000 Subject: [PATCH] Get FD Python running -- design Python backup interface. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1946 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/examples/python/DirStartUp.py | 2 +- bacula/examples/python/FDStartUp.py | 23 +- bacula/examples/python/SDStartUp.py | 43 +-- bacula/kernstodo | 1 + bacula/src/dird/job.c | 4 +- bacula/src/dird/python.c | 20 +- bacula/src/filed/filed.c | 2 + bacula/src/filed/filed_conf.c | 3 + bacula/src/filed/job.c | 504 ++++++++++++++------------- bacula/src/filed/python.c | 127 ++++--- bacula/src/findlib/bfile.c | 9 +- bacula/src/lib/jcr.c | 7 - bacula/src/lib/pythonlib.c | 8 +- bacula/src/stored/bls.c | 2 +- bacula/src/stored/bscan.c | 2 +- bacula/src/stored/python.c | 2 + bacula/src/tools/dbcheck.c | 6 +- bacula/src/tools/testfind.c | 2 + bacula/src/tools/testls.c | 2 + 19 files changed, 383 insertions(+), 386 deletions(-) diff --git a/bacula/examples/python/DirStartUp.py b/bacula/examples/python/DirStartUp.py index 2a810f4bc7..230f307c09 100644 --- a/bacula/examples/python/DirStartUp.py +++ b/bacula/examples/python/DirStartUp.py @@ -1,5 +1,5 @@ # -# Bacula Python interface script +# Bacula Python interface script for the Director # # You must import both sys and bacula diff --git a/bacula/examples/python/FDStartUp.py b/bacula/examples/python/FDStartUp.py index 2fe0fb27ee..0ef8ea993b 100644 --- a/bacula/examples/python/FDStartUp.py +++ b/bacula/examples/python/FDStartUp.py @@ -1,7 +1,6 @@ # -# Bacula Python interface script +# Bacula Python interface script for the File Daemon # - # You must import both sys and bacula import sys, bacula @@ -26,18 +25,14 @@ class BaculaEvents: sys.stdout = events # send stdout to Bacula jobid = job.get("JobId") client = job.get("Client") - numvols = job.get("NumVols") - job.set(JobReport="Python StartJob: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols)) + job.set(JobReport="Python FD StartJob: JobId=%d Client=%s \n" % (jobid,client)) return 1 # Bacula Job is going to terminate def JobEnd(self, job): jobid = job.get("JobId") client = job.get("Client") - job.set(JobReport="Python EndJob output: JobId=%d Client=%s.\n" % (jobid, client)) - if (jobid < 2) : - startid = job.run("run kernsave") - print "Python started new Job: jobid=", startid + job.set(JobReport="Python FD EndJob output: JobId=%d Client=%s.\n" % (jobid, client)) return 1 # Called here when the Bacula daemon is going to exit @@ -55,18 +50,6 @@ class JobEvents: # normally used noop = 1 - def NewVolume(self, job): - jobid = job.get("JobId") - print "JobId=", jobid - client = job.get("Client") - print "Client=" + client - numvol = job.get("NumVols"); - print "NumVols=", numvol - job.set(JobReport="Python New Volume set for Job.\n") - job.set(VolumeName="TestA-001") - return 1 - - # Pass output back to Bacula def write(self, text): self.job.write(text) diff --git a/bacula/examples/python/SDStartUp.py b/bacula/examples/python/SDStartUp.py index 2fe0fb27ee..480f7fb287 100644 --- a/bacula/examples/python/SDStartUp.py +++ b/bacula/examples/python/SDStartUp.py @@ -1,7 +1,6 @@ # -# Bacula Python interface script +# Bacula Python interface script for the Storage Daemon # - # You must import both sys and bacula import sys, bacula @@ -26,18 +25,15 @@ class BaculaEvents: sys.stdout = events # send stdout to Bacula jobid = job.get("JobId") client = job.get("Client") - numvols = job.get("NumVols") - job.set(JobReport="Python StartJob: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols)) + job.set(JobReport="Python SD StartJob: JobId=%d Client=%s \n" % (jobid,client)) return 1 # Bacula Job is going to terminate def JobEnd(self, job): jobid = job.get("JobId") client = job.get("Client") - job.set(JobReport="Python EndJob output: JobId=%d Client=%s.\n" % (jobid, client)) - if (jobid < 2) : - startid = job.run("run kernsave") - print "Python started new Job: jobid=", startid + job.set(JobReport="Python SD EndJob output: JobId=%d Client=%s.\n" % (jobid, client)) + print "Python SD JobEnd\n" return 1 # Called here when the Bacula daemon is going to exit @@ -55,38 +51,7 @@ class JobEvents: # normally used noop = 1 - def NewVolume(self, job): - jobid = job.get("JobId") - print "JobId=", jobid - client = job.get("Client") - print "Client=" + client - numvol = job.get("NumVols"); - print "NumVols=", numvol - job.set(JobReport="Python New Volume set for Job.\n") - job.set(VolumeName="TestA-001") - return 1 - - # Pass output back to Bacula def write(self, text): self.job.write(text) - # Open file to be backed up. file is the filename - def open(self, file): - print "Open %s called" % file - self.fd = open('m.py', 'rb') - jobid = self.job.get("JobId") - print "Open: JobId=%d" % jobid - print "name=%s" % bacula.name - - # Read file data into Bacula memory buffer (mem) - # return length read. 0 => EOF, -1 => error - def read(self, mem): - print "Read called\n" - len = self.fd.readinto(mem) - print "Read %s bytes into mem.\n" % len - return len - - # Close file - def close(self): - self.fd.close() diff --git a/bacula/kernstodo b/bacula/kernstodo index fb19aef22f..e8d0299ea4 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -28,6 +28,7 @@ Autochangers: all Volumes from other drives. "update slots all-drives"? For 1.37: +- Fix FD JobType to be set before RunBeforeJob in FD. - SD crashes after a tape restore then doing a backup. - Look at dird_conf.c:1000: warning: `int size' might be used uninitialized in this function diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index a42b66bc24..5569fb6358 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -190,13 +190,13 @@ JobId_t run_job(JCR *jcr) return JobId; bail_out: + generate_daemon_event(jcr, "JobEnd"); if (jcr->fname) { free_memory(jcr->fname); jcr->fname = NULL; } V(jcr->mutex); return JobId; - } @@ -335,7 +335,7 @@ static void *job_thread(void *arg) bail_out: break; } - + generate_daemon_event(jcr, "JobEnd"); Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus); sm_check(__FILE__, __LINE__, true); return NULL; diff --git a/bacula/src/dird/python.c b/bacula/src/dird/python.c index f5445366e8..09dfaebe6b 100644 --- a/bacula/src/dird/python.c +++ b/bacula/src/dird/python.c @@ -40,18 +40,18 @@ extern PyObject *find_method(PyObject *eventsObject, PyObject *method, const char *name); static PyObject *job_get(PyObject *self, PyObject *args); -static PyObject *jcr_write(PyObject *self, PyObject *args); -static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw); +static PyObject *job_write(PyObject *self, PyObject *args); +static PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw); static PyObject *set_job_events(PyObject *self, PyObject *args); static PyObject *jcr_run(PyObject *self, PyObject *args); /* Define Job entry points */ PyMethodDef JobMethods[] = { {"get", job_get, METH_VARARGS, "Get Job variables."}, - {"set", (PyCFunction)jcr_set, METH_VARARGS|METH_KEYWORDS, + {"set", (PyCFunction)job_set, METH_VARARGS|METH_KEYWORDS, "Set Job variables."}, {"set_events", set_job_events, METH_VARARGS, "Define Job events."}, - {"write", jcr_write, METH_VARARGS, "Write output."}, + {"write", job_write, METH_VARARGS, "Write output."}, {"run", (PyCFunction)jcr_run, METH_VARARGS, "Run a Bacula command."}, {NULL, NULL, 0, NULL} /* last item */ }; @@ -90,7 +90,7 @@ static PyObject *job_get(PyObject *self, PyObject *args) int i; char buf[10]; - Dmsg0(100, "In jcr_get.\n"); + Dmsg0(100, "In job_get.\n"); if (!PyArg_ParseTuple(args, "s:get", &item)) { return NULL; } @@ -138,14 +138,14 @@ static PyObject *job_get(PyObject *self, PyObject *args) } /* Set Job variables */ -static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw) +static PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw) { JCR *jcr; char *msg = NULL; char *VolumeName = NULL; static char *kwlist[] = {"JobReport", "VolumeName", NULL}; - Dmsg0(100, "In jcr_set.\n"); + Dmsg0(100, "In job_set.\n"); if (!PyArg_ParseTupleAndKeywords(args, keyw, "|ss:set", kwlist, &msg, &VolumeName)) { return NULL; @@ -180,7 +180,7 @@ static PyObject *set_job_events(PyObject *self, PyObject *args) JCR *jcr; Dmsg0(100, "In set_job_events.\n"); - if (!PyArg_ParseTuple(args, "O:set_events_hook", &eObject)) { + if (!PyArg_ParseTuple(args, "O:set_events", &eObject)) { return NULL; } jcr = get_jcr_from_PyObject(self); @@ -193,7 +193,7 @@ static PyObject *set_job_events(PyObject *self, PyObject *args) } /* Write text to job output */ -static PyObject *jcr_write(PyObject *self, PyObject *args) +static PyObject *job_write(PyObject *self, PyObject *args) { char *text; @@ -267,6 +267,8 @@ bail_out: return stat; } +bool python_set_prog(JCR*, char const*) { return false; } + #else /* Dummy if Python not configured */ diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index bcfa65c5ed..fdc181e1eb 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -267,8 +267,10 @@ int main (int argc, char *argv[]) void terminate_filed(int sig) { bnet_stop_thread_server(server_tid); + generate_daemon_event(NULL, "Exit"); write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs)); delete_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs)); + if (configfile != NULL) { free(configfile); } diff --git a/bacula/src/filed/filed_conf.c b/bacula/src/filed/filed_conf.c index b856e3fc42..9e95e8e6cc 100644 --- a/bacula/src/filed/filed_conf.c +++ b/bacula/src/filed/filed_conf.c @@ -206,6 +206,9 @@ void free_resource(RES *sres, int type) if (res->res_client.subsys_directory) { free(res->res_client.subsys_directory); } + if (res->res_client.scripts_directory) { + free(res->res_client.scripts_directory); + } if (res->res_client.FDaddrs) { free_addresses(res->res_client.FDaddrs); } diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index a228d29e92..9f9e6ac3ab 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -30,7 +30,7 @@ #include "filed.h" extern char my_name[]; -extern CLIENT *me; /* our client resource */ +extern CLIENT *me; /* our client resource */ /* Imported functions */ extern int status_cmd(JCR *jcr); @@ -89,7 +89,7 @@ static struct s_cmds cmds[] = { {"bootstrap", bootstrap_cmd, 0}, {"RunBeforeJob", runbefore_cmd, 0}, {"RunAfterJob", runafter_cmd, 0}, - {NULL, NULL} /* list terminator */ + {NULL, NULL} /* list terminator */ }; /* Commands received from director that need scanning */ @@ -182,37 +182,37 @@ void *handle_client_request(void *dirp) /* Read command */ if (bnet_recv(dir) < 0) { - break; /* connection terminated */ + break; /* connection terminated */ } dir->msg[dir->msglen] = 0; Dmsg1(100, "msg); found = false; for (i=0; cmds[i].cmd; i++) { - if (strncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd)) == 0) { - found = true; /* indicate command found */ - if (!jcr->authenticated && cmds[i].func != hello_cmd) { - bnet_fsend(dir, no_auth); - bnet_sig(dir, BNET_EOD); - break; - } - if ((jcr->authenticated) && (!cmds[i].monitoraccess) && (jcr->director->monitor)) { + if (strncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd)) == 0) { + found = true; /* indicate command found */ + if (!jcr->authenticated && cmds[i].func != hello_cmd) { + bnet_fsend(dir, no_auth); + bnet_sig(dir, BNET_EOD); + break; + } + if ((jcr->authenticated) && (!cmds[i].monitoraccess) && (jcr->director->monitor)) { Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd); - bnet_fsend(dir, illegal_cmd); - bnet_sig(dir, BNET_EOD); - break; - } + bnet_fsend(dir, illegal_cmd); + bnet_sig(dir, BNET_EOD); + break; + } Dmsg1(100, "Executing %s command.\n", cmds[i].cmd); - if (!cmds[i].func(jcr)) { /* do command */ - quit = true; /* error or fully terminated, get out */ + if (!cmds[i].func(jcr)) { /* do command */ + quit = true; /* error or fully terminated, get out */ Dmsg0(20, "Quit command loop due to command error or Job done.\n"); - } - break; - } + } + break; + } } - if (!found) { /* command not found */ - bnet_fsend(dir, errmsg); - quit = true; - break; + if (!found) { /* command not found */ + bnet_fsend(dir, errmsg); + quit = true; + break; } } @@ -224,7 +224,9 @@ void *handle_client_request(void *dirp) if (jcr->RunAfterJob && !job_canceled(jcr)) { run_cmd(jcr, jcr->RunAfterJob, "ClientRunAfterJob"); } - dequeue_messages(jcr); /* send any queued messages */ + generate_daemon_event(jcr, "JobEnd"); + + dequeue_messages(jcr); /* send any queued messages */ /* Inform Director that we are done */ bnet_sig(dir, BNET_TERMINATE); @@ -236,48 +238,48 @@ void *handle_client_request(void *dirp) int i, j, k; /* Delete FileSet Include lists */ for (i=0; iinclude_list.size(); i++) { - findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); - for (j=0; jopts_list.size(); j++) { - findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); - for (k=0; kregex.size(); k++) { - regfree((regex_t *)fo->regex.get(k)); - } - fo->regex.destroy(); - fo->regexdir.destroy(); - fo->regexfile.destroy(); - fo->wild.destroy(); - fo->wilddir.destroy(); - fo->wildfile.destroy(); - fo->base.destroy(); - fo->fstype.destroy(); - if (fo->reader) { - free(fo->reader); - } - if (fo->writer) { - free(fo->writer); - } - } - incexe->opts_list.destroy(); - incexe->name_list.destroy(); + findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); + for (j=0; jopts_list.size(); j++) { + findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); + for (k=0; kregex.size(); k++) { + regfree((regex_t *)fo->regex.get(k)); + } + fo->regex.destroy(); + fo->regexdir.destroy(); + fo->regexfile.destroy(); + fo->wild.destroy(); + fo->wilddir.destroy(); + fo->wildfile.destroy(); + fo->base.destroy(); + fo->fstype.destroy(); + if (fo->reader) { + free(fo->reader); + } + if (fo->writer) { + free(fo->writer); + } + } + incexe->opts_list.destroy(); + incexe->name_list.destroy(); } fileset->include_list.destroy(); /* Delete FileSet Exclude lists */ for (i=0; iexclude_list.size(); i++) { - findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); - for (j=0; jopts_list.size(); j++) { - findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); - fo->regex.destroy(); - fo->regexdir.destroy(); - fo->regexfile.destroy(); - fo->wild.destroy(); - fo->wilddir.destroy(); - fo->wildfile.destroy(); - fo->base.destroy(); - fo->fstype.destroy(); - } - incexe->opts_list.destroy(); - incexe->name_list.destroy(); + findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); + for (j=0; jopts_list.size(); j++) { + findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); + fo->regex.destroy(); + fo->regexdir.destroy(); + fo->regexfile.destroy(); + fo->wild.destroy(); + fo->wilddir.destroy(); + fo->wildfile.destroy(); + fo->base.destroy(); + fo->fstype.destroy(); + } + incexe->opts_list.destroy(); + incexe->name_list.destroy(); } fileset->exclude_list.destroy(); free(fileset); @@ -287,7 +289,7 @@ void *handle_client_request(void *dirp) term_find_files((FF_PKT *)jcr->ff); jcr->ff = NULL; Dmsg0(100, "Done with term_find_files\n"); - free_jcr(jcr); /* destroy JCR record */ + free_jcr(jcr); /* destroy JCR record */ Dmsg0(100, "Done with free_jcr\n"); return NULL; } @@ -320,20 +322,20 @@ static int cancel_cmd(JCR *jcr) if (!(cjcr=get_jcr_by_full_name(Job))) { bnet_fsend(dir, "2901 Job %s not found.\n", Job); } else { - if (cjcr->store_bsock) { - P(cjcr->mutex); - cjcr->store_bsock->timed_out = 1; - cjcr->store_bsock->terminated = 1; + if (cjcr->store_bsock) { + P(cjcr->mutex); + cjcr->store_bsock->timed_out = 1; + cjcr->store_bsock->terminated = 1; /* * #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32) */ #if !defined(HAVE_CYGWIN) - pthread_kill(cjcr->my_thread_id, TIMEOUT_SIGNAL); + pthread_kill(cjcr->my_thread_id, TIMEOUT_SIGNAL); #endif - V(cjcr->mutex); - } - set_jcr_job_status(cjcr, JS_Canceled); - free_jcr(cjcr); + V(cjcr->mutex); + } + set_jcr_job_status(cjcr, JS_Canceled); + free_jcr(cjcr); bnet_fsend(dir, _("2001 Job %s marked to be canceled.\n"), Job); } } else { @@ -393,8 +395,8 @@ static int job_cmd(JCR *jcr) sd_auth_key = get_memory(dir->msglen); if (sscanf(dir->msg, jobcmd, &jcr->JobId, jcr->Job, - &jcr->VolSessionId, &jcr->VolSessionTime, - sd_auth_key) != 5) { + &jcr->VolSessionId, &jcr->VolSessionTime, + sd_auth_key) != 5) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad Job Command: %s"), jcr->errmsg); bnet_fsend(dir, BADjob); @@ -471,13 +473,13 @@ static bool run_cmd(JCR *jcr, char *cmd, const char *name) if (bpipe == NULL) { berrno be; Jmsg(jcr, M_FATAL, 0, _("%s could not execute. ERR=%s\n"), name, - be.strerror()); + be.strerror()); return false; } while (fgets(line, sizeof(line), bpipe->rfd)) { int len = strlen(line); if (len > 0 && line[len-1] == '\n') { - line[len-1] = 0; + line[len-1] = 0; } Jmsg(jcr, M_INFO, 0, _("%s: %s\n"), name, line); } @@ -485,7 +487,7 @@ static bool run_cmd(JCR *jcr, char *cmd, const char *name) if (status != 0) { berrno be; Jmsg(jcr, M_FATAL, 0, _("%s returned non-zero status=%d. ERR=%s\n"), name, - status, be.strerror(status)); + status, be.strerror(status)); return false; } return true; @@ -552,39 +554,39 @@ static void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *filese p = (char *)fname; switch (*p) { case '|': - p++; /* skip over | */ + p++; /* skip over | */ fn = get_pool_memory(PM_FNAME); fn = edit_job_codes(jcr, fn, p, ""); bpipe = open_bpipe(fn, 0, "r"); free_pool_memory(fn); if (!bpipe) { Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"), - p, strerror(errno)); - return; + p, strerror(errno)); + return; } while (fgets(buf, sizeof(buf), bpipe->rfd)) { - strip_trailing_junk(buf); - fileset->incexe->name_list.append(bstrdup(buf)); + strip_trailing_junk(buf); + fileset->incexe->name_list.append(bstrdup(buf)); } if ((stat=close_bpipe(bpipe)) != 0) { Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. RtnStat=%d ERR=%s\n"), - p, stat, strerror(errno)); - return; + p, stat, strerror(errno)); + return; } break; case '<': Dmsg0(100, "Doing < include on client.\n"); - p++; /* skip over < */ + p++; /* skip over < */ if ((ffd = fopen(p, "r")) == NULL) { - berrno be; + berrno be; Jmsg(jcr, M_FATAL, 0, _("Cannot open FileSet input file: %s. ERR=%s\n"), - p, be.strerror()); - return; + p, be.strerror()); + return; } while (fgets(buf, sizeof(buf), ffd)) { - strip_trailing_junk(buf); + strip_trailing_junk(buf); Dmsg1(100, "%s\n", buf); - fileset->incexe->name_list.append(bstrdup(buf)); + fileset->incexe->name_list.append(bstrdup(buf)); } fclose(ffd); break; @@ -663,27 +665,27 @@ static void add_fileset(JCR *jcr, const char *item) char prbuf[500]; preg = (regex_t *)malloc(sizeof(regex_t)); if (current_opts->flags & FO_IGNORECASE) { - rc = regcomp(preg, item, REG_EXTENDED|REG_ICASE); + rc = regcomp(preg, item, REG_EXTENDED|REG_ICASE); } else { - rc = regcomp(preg, item, REG_EXTENDED); + rc = regcomp(preg, item, REG_EXTENDED); } if (rc != 0) { - regerror(rc, preg, prbuf, sizeof(prbuf)); - regfree(preg); - free(preg); + regerror(rc, preg, prbuf, sizeof(prbuf)); + regfree(preg); + free(preg); Jmsg(jcr, M_FATAL, 0, "REGEX %s compile error. ERR=%s\n", item, prbuf); - state = state_error; - break; + state = state_error; + break; } state = state_options; if (subcode == ' ') { - current_opts->regex.append(preg); + current_opts->regex.append(preg); } else if (subcode == 'D') { - current_opts->regexdir.append(preg); + current_opts->regexdir.append(preg); } else if (subcode == 'F') { - current_opts->regexfile.append(preg); + current_opts->regexfile.append(preg); } else { - state = state_error; + state = state_error; } break; case 'B': @@ -700,13 +702,13 @@ static void add_fileset(JCR *jcr, const char *item) current_opts = start_options(ff); state = state_options; if (subcode == ' ') { - current_opts->wild.append(bstrdup(item)); + current_opts->wild.append(bstrdup(item)); } else if (subcode == 'D') { - current_opts->wilddir.append(bstrdup(item)); + current_opts->wilddir.append(bstrdup(item)); } else if (subcode == 'F') { - current_opts->wildfile.append(bstrdup(item)); + current_opts->wildfile.append(bstrdup(item)); } else { - state = state_error; + state = state_error; } break; case 'O': @@ -742,37 +744,37 @@ static bool term_fileset(JCR *jcr) findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); Dmsg0(400, "I\n"); for (j=0; jopts_list.size(); j++) { - findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); - for (k=0; kregex.size(); k++) { + findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); + for (k=0; kregex.size(); k++) { Dmsg1(400, "R %s\n", (char *)fo->regex.get(k)); - } - for (k=0; kregexdir.size(); k++) { + } + for (k=0; kregexdir.size(); k++) { Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k)); - } - for (k=0; kregexfile.size(); k++) { + } + for (k=0; kregexfile.size(); k++) { Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k)); - } - for (k=0; kwild.size(); k++) { + } + for (k=0; kwild.size(); k++) { Dmsg1(400, "W %s\n", (char *)fo->wild.get(k)); - } - for (k=0; kwilddir.size(); k++) { + } + for (k=0; kwilddir.size(); k++) { Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k)); - } - for (k=0; kwildfile.size(); k++) { + } + for (k=0; kwildfile.size(); k++) { Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k)); - } - for (k=0; kbase.size(); k++) { + } + for (k=0; kbase.size(); k++) { Dmsg1(400, "B %s\n", (char *)fo->base.get(k)); - } - for (k=0; kfstype.size(); k++) { + } + for (k=0; kfstype.size(); k++) { Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k)); - } - if (fo->reader) { + } + if (fo->reader) { Dmsg1(400, "D %s\n", fo->reader); - } - if (fo->writer) { + } + if (fo->writer) { Dmsg1(400, "T %s\n", fo->writer); - } + } } for (j=0; jname_list.size(); j++) { Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j)); @@ -782,31 +784,31 @@ static bool term_fileset(JCR *jcr) findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); Dmsg0(400, "E\n"); for (j=0; jopts_list.size(); j++) { - findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); - for (k=0; kregex.size(); k++) { + findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); + for (k=0; kregex.size(); k++) { Dmsg1(400, "R %s\n", (char *)fo->regex.get(k)); - } - for (k=0; kregexdir.size(); k++) { + } + for (k=0; kregexdir.size(); k++) { Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k)); - } - for (k=0; kregexfile.size(); k++) { + } + for (k=0; kregexfile.size(); k++) { Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k)); - } - for (k=0; kwild.size(); k++) { + } + for (k=0; kwild.size(); k++) { Dmsg1(400, "W %s\n", (char *)fo->wild.get(k)); - } - for (k=0; kwilddir.size(); k++) { + } + for (k=0; kwilddir.size(); k++) { Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k)); - } - for (k=0; kwildfile.size(); k++) { + } + for (k=0; kwildfile.size(); k++) { Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k)); - } - for (k=0; kbase.size(); k++) { + } + for (k=0; kbase.size(); k++) { Dmsg1(400, "B %s\n", (char *)fo->base.get(k)); - } - for (k=0; kfstype.size(); k++) { + } + for (k=0; kfstype.size(); k++) { Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k)); - } + } } for (j=0; jname_list.size(); j++) { Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j)); @@ -830,72 +832,72 @@ static void set_options(findFOPTS *fo, const char *opts) switch (*p) { case 'a': /* alway replace */ case '0': /* no option */ - break; + break; case 'e': - fo->flags |= FO_EXCLUDE; - break; + fo->flags |= FO_EXCLUDE; + break; case 'f': - fo->flags |= FO_MULTIFS; - break; + fo->flags |= FO_MULTIFS; + break; case 'h': /* no recursion */ - fo->flags |= FO_NO_RECURSION; - break; + fo->flags |= FO_NO_RECURSION; + break; case 'H': /* no hard link handling */ - fo->flags |= FO_NO_HARDLINK; - break; + fo->flags |= FO_NO_HARDLINK; + break; case 'i': - fo->flags |= FO_IGNORECASE; - break; + fo->flags |= FO_IGNORECASE; + break; case 'M': /* MD5 */ - fo->flags |= FO_MD5; - break; + fo->flags |= FO_MD5; + break; case 'n': - fo->flags |= FO_NOREPLACE; - break; + fo->flags |= FO_NOREPLACE; + break; case 'p': /* use portable data format */ - fo->flags |= FO_PORTABLE; - break; + fo->flags |= FO_PORTABLE; + break; case 'R': /* Resource forks and Finder Info */ - fo->flags |= FO_HFSPLUS; + fo->flags |= FO_HFSPLUS; case 'r': /* read fifo */ - fo->flags |= FO_READFIFO; - break; + fo->flags |= FO_READFIFO; + break; case 'S': - fo->flags |= FO_SHA1; - break; + fo->flags |= FO_SHA1; + break; case 's': - fo->flags |= FO_SPARSE; - break; + fo->flags |= FO_SPARSE; + break; case 'm': - fo->flags |= FO_MTIMEONLY; - break; + fo->flags |= FO_MTIMEONLY; + break; case 'k': - fo->flags |= FO_KEEPATIME; - break; + fo->flags |= FO_KEEPATIME; + break; case 'A': - fo->flags |= FO_ACL; - break; + fo->flags |= FO_ACL; + break; case 'V': /* verify options */ - /* Copy Verify Options */ + /* Copy Verify Options */ for (j=0; *p && *p != ':'; p++) { - fo->VerifyOpts[j] = *p; - if (j < (int)sizeof(fo->VerifyOpts) - 1) { - j++; - } - } - fo->VerifyOpts[j] = 0; - break; + fo->VerifyOpts[j] = *p; + if (j < (int)sizeof(fo->VerifyOpts) - 1) { + j++; + } + } + fo->VerifyOpts[j] = 0; + break; case 'w': - fo->flags |= FO_IF_NEWER; - break; + fo->flags |= FO_IF_NEWER; + break; case 'Z': /* gzip compression */ - fo->flags |= FO_GZIP; + fo->flags |= FO_GZIP; fo->GZIP_level = *++p - '0'; Dmsg1(200, "Compression level=%d\n", fo->GZIP_level); - break; + break; default: Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p); - break; + break; } } } @@ -923,6 +925,10 @@ static int fileset_cmd(JCR *jcr) } +/* + * The Director sends us the bootstrap file, which + * we will in turn pass to the SD. + */ static int bootstrap_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; @@ -945,10 +951,10 @@ static int bootstrap_cmd(JCR *jcr) * read our error message. */ while (bnet_recv(dir) >= 0) - { } + { } Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"), - jcr->RestoreBootstrap, be.strerror()); + jcr->RestoreBootstrap, be.strerror()); free_pool_memory(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; set_jcr_job_status(jcr, JS_ErrorTerminated); @@ -996,54 +1002,54 @@ static int level_cmd(JCR *jcr) return 1; /* * We get his UTC since time, then sync the clocks and correct it - * to agree with our clock. + * to agree with our clock. */ } else if (strcmp(level, "since_utime") == 0) { buf = get_memory(dir->msglen+1); utime_t since_time, adj; btime_t his_time, bt_start, rt=0, bt_adj=0; if (jcr->JobLevel == L_NONE) { - jcr->JobLevel = L_SINCE; /* if no other job level set, do it now */ + jcr->JobLevel = L_SINCE; /* if no other job level set, do it now */ } if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d", - buf, &mtime_only) != 2) { - goto bail_out; + buf, &mtime_only) != 2) { + goto bail_out; } - since_time = str_to_uint64(buf); /* this is the since time */ + since_time = str_to_uint64(buf); /* this is the since time */ char ed1[50], ed2[50]; /* * Sync clocks by polling him for the time. We take * 10 samples of his time throwing out the first two. */ for (int i=0; i<10; i++) { - bt_start = get_current_btime(); - bnet_sig(dir, BNET_BTIME); /* poll for time */ - if (bnet_recv(dir) <= 0) { /* get response */ - goto bail_out; - } + bt_start = get_current_btime(); + bnet_sig(dir, BNET_BTIME); /* poll for time */ + if (bnet_recv(dir) <= 0) { /* get response */ + goto bail_out; + } if (sscanf(dir->msg, "btime %s", buf) != 1) { - goto bail_out; - } - if (i < 2) { /* toss first two results */ - continue; - } - his_time = str_to_uint64(buf); - rt = get_current_btime() - bt_start; /* compute round trip time */ - bt_adj -= his_time - bt_start - rt/2; + goto bail_out; + } + if (i < 2) { /* toss first two results */ + continue; + } + his_time = str_to_uint64(buf); + rt = get_current_btime() - bt_start; /* compute round trip time */ + bt_adj -= his_time - bt_start - rt/2; Dmsg2(200, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2)); } - bt_adj = bt_adj / 8; /* compute average time */ + bt_adj = bt_adj / 8; /* compute average time */ Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2)); adj = btime_to_utime(bt_adj); - since_time += adj; /* adjust for clock difference */ + since_time += adj; /* adjust for clock difference */ if (adj != 0) { Jmsg(jcr, M_INFO, 0, _("DIR and FD clocks differ by %d seconds, FD automatically adjusting.\n"), adj); } bnet_sig(dir, BNET_EOD); Dmsg2(100, "adj = %d since_time=%d\n", (int)adj, (int)since_time); - jcr->incremental = 1; /* set incremental or decremental backup */ + jcr->incremental = 1; /* set incremental or decremental backup */ jcr->mtime = (time_t)since_time; /* set since time */ } else { Jmsg1(jcr, M_FATAL, 0, "Unknown backup level: %s\n", level); @@ -1075,9 +1081,9 @@ static int session_cmd(JCR *jcr) Dmsg1(100, "SessionCmd: %s", dir->msg); if (sscanf(dir->msg, sessioncmd, jcr->VolumeName, - &jcr->VolSessionId, &jcr->VolSessionTime, - &jcr->StartFile, &jcr->EndFile, - &jcr->StartBlock, &jcr->EndBlock) != 7) { + &jcr->VolSessionId, &jcr->VolSessionTime, + &jcr->StartFile, &jcr->EndFile, + &jcr->StartBlock, &jcr->EndBlock) != 7) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, "Bad session command: %s", jcr->errmsg); return 0; @@ -1092,10 +1098,10 @@ static int session_cmd(JCR *jcr) */ static int storage_cmd(JCR *jcr) { - int stored_port; /* storage daemon port */ - int enable_ssl; /* enable ssl to sd */ + int stored_port; /* storage daemon port */ + int enable_ssl; /* enable ssl to sd */ BSOCK *dir = jcr->dir_bsock; - BSOCK *sd; /* storage daemon bsock */ + BSOCK *sd; /* storage daemon bsock */ Dmsg1(100, "StorageCmd: %s", dir->msg); if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port, &enable_ssl) != 3) { @@ -1107,12 +1113,12 @@ static int storage_cmd(JCR *jcr) /* Open command communications with Storage daemon */ /* Try to connect for 1 hour at 10 second intervals */ sd = bnet_connect(jcr, 10, (int)me->SDConnectTimeout, _("Storage daemon"), - jcr->stored_addr, NULL, stored_port, 1); + jcr->stored_addr, NULL, stored_port, 1); if (sd == NULL) { Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"), - jcr->stored_addr, stored_port); + jcr->stored_addr, stored_port); Dmsg2(100, "Failed to connect to Storage daemon: %s:%d\n", - jcr->stored_addr, stored_port); + jcr->stored_addr, stored_port); return 0; } Dmsg0(110, "Connection OK to SD.\n"); @@ -1166,7 +1172,7 @@ static int backup_cmd(JCR *jcr) Dmsg1(110, "msg); if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) { Jmsg(jcr, M_FATAL, 0, _("Bad response to append open: %s\n"), sd->msg); - goto cleanup; + goto cleanup; } Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket); } else { @@ -1188,6 +1194,8 @@ static int backup_cmd(JCR *jcr) goto cleanup; } + generate_daemon_event(jcr, "JobStart"); + /* * Send Files to Storage daemon */ @@ -1199,15 +1207,15 @@ static int backup_cmd(JCR *jcr) } else { set_jcr_job_status(jcr, JS_Terminated); if (jcr->JobStatus != JS_Terminated) { - bnet_suppress_error_messages(sd, 1); - goto cleanup; /* bail out now */ + bnet_suppress_error_messages(sd, 1); + goto cleanup; /* bail out now */ } /* * Expect to get response to append_data from Storage daemon */ if (!response(jcr, sd, OK_append, "Append Data")) { - set_jcr_job_status(jcr, JS_ErrorTerminated); - goto cleanup; + set_jcr_job_status(jcr, JS_ErrorTerminated); + goto cleanup; } /* @@ -1216,8 +1224,8 @@ static int backup_cmd(JCR *jcr) bnet_fsend(sd, append_end, jcr->Ticket); /* Get end OK */ if (!response(jcr, sd, OK_end, "Append End")) { - set_jcr_job_status(jcr, JS_ErrorTerminated); - goto cleanup; + set_jcr_job_status(jcr, JS_ErrorTerminated); + goto cleanup; } /* @@ -1225,18 +1233,18 @@ static int backup_cmd(JCR *jcr) */ bnet_fsend(sd, append_close, jcr->Ticket); while (bget_msg(sd) >= 0) { /* stop on signal or error */ - if (sscanf(sd->msg, OK_close, &SDJobStatus) == 1) { - ok = 1; + if (sscanf(sd->msg, OK_close, &SDJobStatus) == 1) { + ok = 1; Dmsg2(200, "SDJobStatus = %d %c\n", SDJobStatus, (char)SDJobStatus); - } + } } if (!ok) { Jmsg(jcr, M_FATAL, 0, _("Append Close with SD failed.\n")); - goto cleanup; + goto cleanup; } if (SDJobStatus != JS_Terminated) { Jmsg(jcr, M_FATAL, 0, _("Bad status %d returned from Storage Daemon.\n"), - SDJobStatus); + SDJobStatus); } } @@ -1246,7 +1254,7 @@ cleanup: edit_uint64(jcr->JobBytes, ed2), jcr->Errors); Dmsg1(110, "End FD msg: %s\n", dir->msg); - return 0; /* return and stop command loop */ + return 0; /* return and stop command loop */ } /* @@ -1264,6 +1272,7 @@ static int verify_cmd(JCR *jcr) bnet_fsend(dir, "2994 Bad verify command: %s\n", dir->msg); return 0; } + if (strcasecmp(level, "init") == 0) { jcr->JobLevel = L_VERIFY_INIT; } else if (strcasecmp(level, "catalog") == 0){ @@ -1280,6 +1289,9 @@ static int verify_cmd(JCR *jcr) } bnet_fsend(dir, OKverify); + + generate_daemon_event(jcr, "JobStart"); + Dmsg1(110, "bfiled>dird: %s", dir->msg); switch (jcr->JobLevel) { @@ -1289,7 +1301,7 @@ static int verify_cmd(JCR *jcr) break; case L_VERIFY_VOLUME_TO_CATALOG: if (!open_sd_read_session(jcr)) { - return 0; + return 0; } start_dir_heartbeat(jcr); do_verify_volume(jcr); @@ -1301,7 +1313,7 @@ static int verify_cmd(JCR *jcr) Dmsg1(130, "bfiled>stored: %s", sd->msg); /* ****FIXME**** check response */ - bget_msg(sd); /* get OK */ + bget_msg(sd); /* get OK */ /* Inform Storage daemon that we are done */ bnet_sig(sd, BNET_TERMINATE); @@ -1324,7 +1336,7 @@ static int verify_cmd(JCR *jcr) /* Inform Director that we are done */ bnet_sig(dir, BNET_TERMINATE); - return 0; /* return and terminate command loop */ + return 0; /* return and terminate command loop */ } /* @@ -1350,9 +1362,9 @@ static int restore_cmd(JCR *jcr) if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) { if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) { - pm_strcpy(jcr->errmsg, dir->msg); + pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg); - return 0; + return 0; } *where = 0; } @@ -1374,6 +1386,7 @@ static int restore_cmd(JCR *jcr) jcr->JobType = JT_RESTORE; set_jcr_job_status(jcr, JS_Blocked); + if (!open_sd_read_session(jcr)) { set_jcr_job_status(jcr, JS_ErrorTerminated); goto bail_out; @@ -1385,6 +1398,7 @@ static int restore_cmd(JCR *jcr) * Do restore of files and data */ start_dir_heartbeat(jcr); + generate_daemon_event(jcr, "JobStart"); do_restore(jcr); stop_dir_heartbeat(jcr); @@ -1399,7 +1413,7 @@ static int restore_cmd(JCR *jcr) bnet_fsend(sd, read_close, jcr->Ticket); Dmsg1(130, "bfiled>stored: %s", sd->msg); - bget_msg(sd); /* get OK */ + bget_msg(sd); /* get OK */ /* Inform Storage daemon that we are done */ bnet_sig(sd, BNET_TERMINATE); @@ -1418,7 +1432,7 @@ bail_out: bnet_sig(dir, BNET_TERMINATE); Dmsg0(130, "Done in job.c\n"); - return 0; /* return and terminate command loop */ + return 0; /* return and terminate command loop */ } static int open_sd_read_session(JCR *jcr) @@ -1447,7 +1461,7 @@ static int open_sd_read_session(JCR *jcr) Dmsg1(110, "bfiledmsg); if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) { Jmsg(jcr, M_FATAL, 0, _("Bad response to SD read open: %s\n"), sd->msg); - return 0; + return 0; } Dmsg1(110, "bfiled: got Ticket=%d\n", jcr->Ticket); } else { @@ -1504,7 +1518,7 @@ static void filed_free_jcr(JCR *jcr) * sent. Check that the response is OK. * * Returns: 0 on failure - * 1 on success + * 1 on success */ int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd) { @@ -1514,18 +1528,18 @@ int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd) if (bget_msg(sd) > 0) { Dmsg0(110, sd->msg); if (strcmp(sd->msg, resp) == 0) { - return 1; + return 1; } } if (job_canceled(jcr)) { - return 0; /* if canceled avoid useless error messages */ + return 0; /* if canceled avoid useless error messages */ } if (is_bnet_error(sd)) { Jmsg2(jcr, M_FATAL, 0, _("Comm error with SD. bad response to %s. ERR=%s\n"), - cmd, bnet_strerror(sd)); + cmd, bnet_strerror(sd)); } else { Jmsg3(jcr, M_FATAL, 0, _("Bad response to %s command. Wanted %s, got %s\n"), - cmd, resp, sd->msg); + cmd, resp, sd->msg); } return 0; } @@ -1546,7 +1560,7 @@ static int send_bootstrap_file(JCR *jcr) if (!bs) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), - jcr->RestoreBootstrap, be.strerror()); + jcr->RestoreBootstrap, be.strerror()); set_jcr_job_status(jcr, JS_ErrorTerminated); goto bail_out; } diff --git a/bacula/src/filed/python.c b/bacula/src/filed/python.c index e8fdeefc4a..81ce93f9c7 100644 --- a/bacula/src/filed/python.c +++ b/bacula/src/filed/python.c @@ -39,28 +39,22 @@ extern JCR *get_jcr_from_PyObject(PyObject *self); extern PyObject *find_method(PyObject *eventsObject, PyObject *method, const char *name); -static PyObject *jcr_get(PyObject *self, PyObject *args); -static PyObject *jcr_write(PyObject *self, PyObject *args); -static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw); +static PyObject *job_get(PyObject *self, PyObject *args); +static PyObject *job_write(PyObject *self, PyObject *args); +static PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw); static PyObject *set_job_events(PyObject *self, PyObject *args); /* Define Job entry points */ PyMethodDef JobMethods[] = { - {"get", jcr_get, METH_VARARGS, "Get Job variables."}, - {"set", (PyCFunction)jcr_set, METH_VARARGS|METH_KEYWORDS, + {"get", job_get, METH_VARARGS, "Get Job variables."}, + {"set", (PyCFunction)job_set, METH_VARARGS|METH_KEYWORDS, "Set Job variables."}, {"set_events", set_job_events, METH_VARARGS, "Define Job events."}, - {"write", jcr_write, METH_VARARGS, "Write output."}, + {"write", job_write, METH_VARARGS, "Write output."}, {NULL, NULL, 0, NULL} /* last item */ }; - -static PyObject *open_method = NULL; -static PyObject *read_method = NULL; -static PyObject *close_method = NULL; - - struct s_vars { const char *name; char *fmt; @@ -80,7 +74,7 @@ static struct s_vars vars[] = { }; /* Return Job variables */ -PyObject *jcr_get(PyObject *self, PyObject *args) +PyObject *job_get(PyObject *self, PyObject *args) { JCR *jcr; char *item; @@ -123,17 +117,14 @@ PyObject *jcr_get(PyObject *self, PyObject *args) } /* Set Job variables */ -PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw) +PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw) { JCR *jcr; char *msg = NULL; - PyObject *fo = NULL, *fr = NULL, *fc = NULL; - static char *kwlist[] = {"JobReport", - "FileOpen", "FileRead", "FileClose", - NULL}; + static char *kwlist[] = {"JobReport", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keyw, "|sOOO:set", kwlist, - &msg, &fo, &fr, &fc)) { + if (!PyArg_ParseTupleAndKeywords(args, keyw, "|s:set", kwlist, + &msg)) { return NULL; } jcr = get_jcr_from_PyObject(self); @@ -141,29 +132,6 @@ PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw) if (msg) { Jmsg(jcr, M_INFO, 0, "%s", msg); } - if (strcmp("Reader", jcr->event) == 0) { - if (fo) { - if (PyCallable_Check(fo)) { - jcr->ff->bfd.pio.fo = fo; - } else { - Jmsg(jcr, M_ERROR, 0, _("Python FileOpen object not callable.\n")); - } - } - if (fr) { - if (PyCallable_Check(fo)) { - jcr->ff->bfd.pio.fr = fr; - } else { - Jmsg(jcr, M_ERROR, 0, _("Python FileRead object not callable.\n")); - } - } - if (fc) { - if (PyCallable_Check(fc)) { - jcr->ff->bfd.pio.fc = fc; - } else { - Jmsg(jcr, M_ERROR, 0, _("Python FileClose object not callable.\n")); - } - } - } return Py_BuildValue("i", 1); } @@ -172,22 +140,26 @@ static PyObject *set_job_events(PyObject *self, PyObject *args) { PyObject *eObject; JCR *jcr; + + Dmsg0(100, "In set_job_events.\n"); + if (!PyArg_ParseTuple(args, "O:set_events", &eObject)) { return NULL; } - Py_XINCREF(eObject); jcr = get_jcr_from_PyObject(self); - jcr->ff->bfd.pio.fo = find_method(eObject, open_method, "open"); - jcr->ff->bfd.pio.fr = find_method(eObject, read_method, "read"); - jcr->ff->bfd.pio.fc = find_method(eObject, close_method, "close"); + Py_XDECREF((PyObject *)jcr->Python_events); + Py_INCREF(eObject); + jcr->Python_events = (void *)eObject; + Py_INCREF(Py_None); return Py_None; } /* Write text to job output */ -static PyObject *jcr_write(PyObject *self, PyObject *args) +static PyObject *job_write(PyObject *self, PyObject *args) { - char *text; + char *text = NULL; + if (!PyArg_ParseTuple(args, "s:write", &text)) { return NULL; } @@ -202,19 +174,68 @@ static PyObject *jcr_write(PyObject *self, PyObject *args) int generate_job_event(JCR *jcr, const char *event) { + PyObject *method = NULL; + PyObject *Job = (PyObject *)jcr->Python_job; + PyObject *result = NULL; + int stat = 0; + + if (!Job) { + return 0; + } + PyEval_AcquireLock(); - PyObject *result = PyObject_CallFunction(open_method, "s", "m.py"); + PyObject *events = (PyObject *)jcr->Python_events; + method = find_method(events, method, event); + if (!method) { + goto bail_out; + } + + bstrncpy(jcr->event, event, sizeof(jcr->event)); + result = PyObject_CallFunction(method, "O", Job); + jcr->event[0] = 0; /* no event in progress */ if (result == NULL) { - PyErr_Print(); - PyErr_Clear(); + if (PyErr_Occurred()) { + PyErr_Print(); + Dmsg1(000, "Error in Python method %s\n", event); + } + } else { + stat = 1; } Py_XDECREF(result); +bail_out: PyEval_ReleaseLock(); - return 1; + return stat; +} + + +bool python_set_prog(JCR *jcr, const char *prog) +{ + PyObject *events = (PyObject *)jcr->Python_events; + BFILE *bfd = &jcr->ff->bfd; + char method[MAX_NAME_LENGTH]; + + if (!events) { + return false; + } + bstrncpy(method, prog, sizeof(method)); + bstrncat(method, "_", sizeof(method)); + bstrncat(method, "open", sizeof(method)); + bfd->pio.fo = find_method(events, bfd->pio.fo, method); + bstrncpy(method, prog, sizeof(method)); + bstrncat(method, "_", sizeof(method)); + bstrncat(method, "read", sizeof(method)); + bfd->pio.fr = find_method(events, bfd->pio.fr, method); + bstrncpy(method, prog, sizeof(method)); + bstrncat(method, "_", sizeof(method)); + bstrncat(method, "close", sizeof(method)); + bfd->pio.fc = find_method(events, bfd->pio.fc, method); + return bfd->pio.fo && bfd->pio.fr && bfd->pio.fc; } + + #else /* Dummy if Python not configured */ diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index 64231a5594..099e2b1831 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -9,7 +9,7 @@ * */ /* - Copyright (C) 2003-2004 Kern Sibbald and John Walker + Copyright (C) 2003-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -31,7 +31,7 @@ #include "bacula.h" #include "find.h" -extern int generate_job_event(JCR *jcr, const char *event); +extern bool python_set_prog(JCR *jcr, const char *prog); #ifdef HAVE_DARWIN_OS #include @@ -459,13 +459,14 @@ bool set_prog(BFILE *bfd, char *prog, JCR *jcr) return true; /* already setup */ } - int stat = generate_job_event(jcr, "Reader"); - if (stat == 1 && bfd->pio.fo && bfd->pio.fr && bfd->pio.fc) { + if (python_set_prog(jcr, prog)) { + Dmsg1(000, "Set prog=%s\n", prog); bfd->prog = prog; bfd->jcr = jcr; return true; } #endif + Dmsg0(000, "No prog set\n"); bfd->prog = NULL; return false; diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 709a30d9b2..959e329084 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -367,13 +367,6 @@ void free_jcr(JCR *jcr) return; } - /* - * At this point, we are actually releasing the JCR, which - * means that the job is complete. - */ - if (jcr->JobId != 0) { - generate_daemon_event(jcr, "JobEnd"); - } remove_jcr(jcr); /* remove Jcr from chain */ unlock_jcr_chain(); diff --git a/bacula/src/lib/pythonlib.c b/bacula/src/lib/pythonlib.c index 416df8ff0b..b507960a7e 100644 --- a/bacula/src/lib/pythonlib.c +++ b/bacula/src/lib/pythonlib.c @@ -126,8 +126,10 @@ void init_python_interpreter(const char *progname, const char *scripts, char buf[MAXSTRING]; if (!scripts || scripts[0] == 0) { + Dmsg1(100, "No script dir. prog=%s\n", module); return; } + Dmsg2(100, "Script dir=%s prog=%s\n", scripts, module); Py_SetProgramName((char *)progname); Py_Initialize(); @@ -234,9 +236,11 @@ int generate_daemon_event(JCR *jcr, const char *event) PyObject *result = NULL; if (!StartUp_module) { + Dmsg0(100, "No startup module.\n"); return 0; } + Dmsg1(100, "event=%s\n", event); PyEval_AcquireLock(); if (strcmp(event, "JobStart") == 0) { if (!JobStart_method) { @@ -268,11 +272,13 @@ int generate_daemon_event(JCR *jcr, const char *event) goto jobstart_ok; } else if (strcmp(event, "JobEnd") == 0) { - if (!JobEnd_method) { + if (!JobEnd_method || !jcr->Python_job) { + Dmsg0(100, "No JobEnd method\n"); stat = 0; goto bail_out; } bstrncpy(jcr->event, event, sizeof(jcr->event)); + Dmsg1(100, "Call event=%s\n", event); result = PyObject_CallFunction(JobEnd_method, "O", jcr->Python_job); jcr->event[0] = 0; /* no event in progress */ if (result == NULL) { diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 85c6e780a8..5fb318e39f 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -434,7 +434,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} int generate_job_event(JCR *jcr, const char *event) { return 1; } - +bool python_set_prog(JCR*, char const*) { return false; } bool dir_ask_sysop_to_mount_volume(DCR *dcr) { diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index c8d442b13b..9c7dc32211 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -1205,7 +1205,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} int generate_job_event(JCR *jcr, const char *event) { return 1; } - +bool python_set_prog(JCR*, char const*) { return false; } bool dir_ask_sysop_to_mount_volume(DCR *dcr) { diff --git a/bacula/src/stored/python.c b/bacula/src/stored/python.c index aa9e7e86a1..d03982ec55 100644 --- a/bacula/src/stored/python.c +++ b/bacula/src/stored/python.c @@ -198,6 +198,8 @@ int generate_job_event(JCR *jcr, const char *event) return 1; } +bool python_set_prog(JCR*, char const*) { return false; } + #else /* Dummy if Python not configured */ diff --git a/bacula/src/tools/dbcheck.c b/bacula/src/tools/dbcheck.c index 9411818f38..70cb29f3d7 100644 --- a/bacula/src/tools/dbcheck.c +++ b/bacula/src/tools/dbcheck.c @@ -9,7 +9,7 @@ * */ /* - Copyright (C) 2002-2004 Kern Sibbald and John Walker + Copyright (C) 2002-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -1064,8 +1064,6 @@ static void repair_bad_paths() } - - /* * Gen next input command from the terminal */ @@ -1087,3 +1085,5 @@ static int yes_no(const char *prompt) cmd = get_cmd(prompt); return strcasecmp(cmd, "yes") == 0; } + +bool python_set_prog(JCR*, char const*) { return false; } diff --git a/bacula/src/tools/testfind.c b/bacula/src/tools/testfind.c index 23af56784d..18cc25dd71 100644 --- a/bacula/src/tools/testfind.c +++ b/bacula/src/tools/testfind.c @@ -341,3 +341,5 @@ static void count_files(FF_PKT *ar) } } + +bool python_set_prog(JCR*, char const*) { return false; } diff --git a/bacula/src/tools/testls.c b/bacula/src/tools/testls.c index da1a4db131..3fd8d36aa7 100755 --- a/bacula/src/tools/testls.c +++ b/bacula/src/tools/testls.c @@ -247,3 +247,5 @@ static void print_ls_output(char *fname, char *link, int type, struct stat *stat *p = 0; fputs(buf, stdout); } + +bool python_set_prog(JCR*, char const*) { return false; } -- 2.39.5