From: Kern Sibbald Date: Tue, 10 May 2005 12:56:24 +0000 (+0000) Subject: - Add cancel() to Dir Python scripting. X-Git-Tag: Release-1.38.0~478 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=fec528ba507de4a27ac5430a885f0569360eae59;p=bacula%2Fbacula - Add cancel() to Dir Python scripting. - Re-correct bug in parse-config error handling. - Reorganization of use_command in SD to permit waiting and multiple drive autochanger support. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2020 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index f1a4b364cc..8c493d2ea2 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -54,7 +54,6 @@ Document: For 1.37: - --without-openssl breaks at least on Solaris. -- Move test for max wait time exceeded in job.c up -- Peter's idea. - Python: - Make a callback when Rerun failed levels is called. - Give Python program access to Scheduled jobs. @@ -1323,3 +1322,5 @@ Block Position: 0 then list last 20 backups. - Finish implementation of passing all Storage and Device needs to the SD. +- Move test for max wait time exceeded in job.c up -- Peter's idea. + diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 8d0c3ebe17..45f0a18fda 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -141,7 +141,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) * Request to find specific Volume information */ } else if (sscanf(bs->msg, Get_Vol_Info, &Job, &mr.VolumeName, &writing) == 3) { - Dmsg1(500, "CatReq GetVolInfo Vol=%s\n", mr.VolumeName); + Dmsg1(100, "CatReq GetVolInfo Vol=%s\n", mr.VolumeName); /* * Find the Volume */ @@ -195,7 +195,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) } else { bnet_fsend(bs, "1997 Volume \"%s\" not in catalog.\n", mr.VolumeName); - Dmsg1(400, "1997 Volume \"%s\" not in catalog.\n", mr.VolumeName); + Dmsg1(100, "1997 Volume \"%s\" not in catalog.\n", mr.VolumeName); } /* diff --git a/bacula/src/dird/pythondir.c b/bacula/src/dird/pythondir.c index a3452fd115..77245b07db 100644 --- a/bacula/src/dird/pythondir.c +++ b/bacula/src/dird/pythondir.c @@ -43,11 +43,13 @@ extern PyObject *find_method(PyObject *eventsObject, PyObject *method, static PyObject *set_job_events(PyObject *self, PyObject *arg); static PyObject *job_run(PyObject *self, PyObject *arg); static PyObject *job_write(PyObject *self, PyObject *arg); +static PyObject *job_cancel(PyObject *self, PyObject *arg); PyMethodDef JobMethods[] = { {"set_events", set_job_events, METH_VARARGS, "Set Job events"}, {"run", job_run, METH_VARARGS, "Run a Job"}, {"write", job_write, METH_VARARGS, "Write to output"}, + {"cancel", job_cancel, METH_VARARGS, "Cancel a Job"}, {NULL, NULL, 0, NULL} /* last item */ }; @@ -284,6 +286,46 @@ static PyObject *job_write(PyObject *self, PyObject *args) return Py_None; } +static PyObject *job_cancel(PyObject *self, PyObject *args) +{ + JobId_t JobId = 0; + JCR *jcr; + bool found = false; + + if (!PyArg_ParseTuple(args, "i:cancel", &JobId)) { + Dmsg0(000, "Parse tuple error in job_write\n"); + return NULL; + } + lock_jcr_chain(); + foreach_jcr(jcr) { + if (jcr->JobId == 0) { + free_locked_jcr(jcr); /* OK to free now cuz chain is locked */ + continue; + } + if (jcr->JobId == JobId) { + found = true; + break; + } + } + if (!found) { + unlock_jcr_chain(); + /* ***FIXME*** raise exception */ + return NULL; + } + unlock_jcr_chain(); + PyEval_ReleaseLock(); + UAContext *ua = new_ua_context(jcr); + ua->batch = true; + if (!cancel_job(ua, jcr)) { + /* ***FIXME*** raise exception */ + return NULL; + } + free_ua_context(ua); + free_locked_jcr(jcr); + PyEval_AcquireLock(); + Py_INCREF(Py_None); + return Py_None; +} /* * Generate a Job event, which means look up the event diff --git a/bacula/src/lib/lex.c b/bacula/src/lib/lex.c index 095ce50d37..1adec6015d 100644 --- a/bacula/src/lib/lex.c +++ b/bacula/src/lib/lex.c @@ -61,11 +61,10 @@ int scan_to_next_not_eol(LEX * lc) return token; } - /* * Format a scanner error message */ -void s_err(const char *file, int line, LEX *lc, const char *msg, ...) +static void s_err(const char *file, int line, LEX *lc, const char *msg, ...) { va_list arg_ptr; char buf[MAXSTRING]; @@ -90,6 +89,11 @@ void s_err(const char *file, int line, LEX *lc, const char *msg, ...) } } +void lex_set_default_error_handler(LEX *lf) +{ + lf->scan_error = s_err; +} + /* * Free the current file, and retrieve the contents @@ -152,15 +156,15 @@ LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error) lf = nf; /* start new packet */ memset(lf, 0, sizeof(LEX)); } - lf->fd = fd; - lf->fname = fname; - lf->state = lex_none; - lf->ch = L_EOL; if (scan_error) { lf->scan_error = scan_error; } else { - lf->scan_error = s_err; + lex_set_default_error_handler(lf); } + lf->fd = fd; + lf->fname = fname; + lf->state = lex_none; + lf->ch = L_EOL; Dmsg1(2000, "Return lex=%x\n", lf); return lf; } diff --git a/bacula/src/lib/parse_conf.c b/bacula/src/lib/parse_conf.c index 3f76e4e3e5..9afb58a22c 100755 --- a/bacula/src/lib/parse_conf.c +++ b/bacula/src/lib/parse_conf.c @@ -755,16 +755,17 @@ parse_config(const char *cf, LEX_ERROR_HANDLER *scan_error) for (pass=1; pass <= 2; pass++) { Dmsg1(900, "parse_config pass %d\n", pass); if ((lc = lex_open_file(lc, cf, scan_error)) == NULL) { + berrno be; + /* We must create a lex packet to print the error */ lc = (LEX *)malloc(sizeof(LEX)); memset(lc, 0, sizeof(LEX)); if (scan_error) { lc->scan_error = scan_error; } else { - lc->scan_error = s_err; + lex_set_default_error_handler(lc); } bstrncpy(lc->str, cf, sizeof(lc->str)); lc->fname = lc->str; - berrno be; scan_err2(lc, _("Cannot open config file %s: %s\n"), lc->str, be.strerror()); free(lc); diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index ec9b7e70df..942ac1a4eb 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -150,7 +150,7 @@ int lex_get_char (LEX *lf); void lex_unget_char (LEX *lf); const char * lex_tok_to_str (int token); int lex_get_token (LEX *lf, int expect); -void s_err(const char *file, int line, LEX *lc, const char *msg, ...); +void lex_set_default_error_handler (LEX *lf); /* message.c */ void my_name_is (int argc, char *argv[], const char *name); diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index d0b2e4219a..c4510f1850 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -271,19 +271,19 @@ public: char pool_type[MAX_NAME_LENGTH]; }; +static int search_res_for_device(JCR *jcr, DIRSTORE *store, char *device_name, int append); + static bool use_storage_cmd(JCR *jcr) { POOL_MEM store_name, dev_name, media_type, pool_name, pool_type; BSOCK *dir = jcr->dir_bsock; - DEVRES *device; - AUTOCHANGER *changer; int append; bool ok; int Copy, Stripe; alist *dirstore; DIRSTORE *store; char *device_name; - + DCR *dcr = NULL; /* * If there are multiple devices, the director sends us * use_device for each device that it wants to use. @@ -321,8 +321,9 @@ static bool use_storage_cmd(JCR *jcr) } } while (ok && bnet_recv(dir) >= 0); +#ifdef DEVELOPER /* This loop is debug code and can be removed */ - /* ***FIXME*** turn off in production */ + /* ***FIXME**** remove after 1.38 release */ foreach_alist(store, dirstore) { Dmsg4(100, "Storage=%s media_type=%s pool=%s pool_type=%s\n", store->name, store->media_type, store->pool_name, @@ -331,121 +332,28 @@ static bool use_storage_cmd(JCR *jcr) Dmsg1(100, " Device=%s\n", device_name); } } +#endif - + /* + * At this point, we have a list of all the Director's Storage + * resources indicated for this Job, which include Pool, PoolType, + * storage name, and Media type. + * Then for each of the Storage resources, we have a list of + * device names that were given. + * + * Wiffle through them and find one that can do the backup. + */ if (ok) { -// LockRes(); store = (DIRSTORE *)dirstore->first(); foreach_alist(device_name, store->device) { - foreach_res(device, R_DEVICE) { - /* Find resource, and make sure we were able to open it */ - if (fnmatch(device_name, device->hdr.name, 0) == 0 && - strcmp(device->media_type, store->media_type) == 0) { - const int name_len = MAX_NAME_LENGTH; - DCR *dcr; -// UnlockRes(); - if (!device->dev) { - device->dev = init_dev(jcr, NULL, device); - } - if (!device->dev) { - Jmsg(jcr, M_WARNING, 0, _("\n" - " Device \"%s\" requested by DIR could not be opened or does not exist.\n"), - dev_name.c_str()); - bnet_fsend(dir, NOT_open, dev_name.c_str()); - Dmsg1(100, ">dird: %s\n", dir->msg); - return false; - } - dcr = new_dcr(jcr, device->dev); - if (!dcr) { - bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str()); - Dmsg1(100, ">dird: %s\n", dir->msg); - return false; - } - Dmsg1(100, "Found device %s\n", device->hdr.name); - bstrncpy(dcr->pool_name, store->pool_name, name_len); - bstrncpy(dcr->pool_type, store->pool_type, name_len); - bstrncpy(dcr->media_type, store->media_type, name_len); - bstrncpy(dcr->dev_name, device_name, name_len); - dcr->Copy = Copy; - dcr->Stripe = Stripe; - jcr->dcr = dcr; - if (append == SD_APPEND) { - ok = reserve_device_for_append(dcr); - } else { - ok = reserve_device_for_read(dcr); - } - if (!ok) { - bnet_fsend(dir, _("3927 Could not reserve device: %s\n"), dev_name.c_str()); - Dmsg1(100, ">dird: %s\n", dir->msg); - free_dcr(jcr->dcr); - goto get_out; - } - Dmsg1(220, "Got: %s", dir->msg); - bash_spaces(dev_name); - ok = bnet_fsend(dir, OK_device, dev_name.c_str()); - Dmsg1(100, ">dird: %s\n", dir->msg); - goto get_out; - } - } - foreach_res(changer, R_AUTOCHANGER) { - /* Find resource, and make sure we were able to open it */ - if (fnmatch(device_name, changer->hdr.name, 0) == 0) { - const int name_len = MAX_NAME_LENGTH; - DCR *dcr; - /* Try each device in this AutoChanger */ - foreach_alist(device, changer->device) { - Dmsg1(100, "Try changer device %s\n", device->hdr.name); - if (!device->dev) { - device->dev = init_dev(jcr, NULL, device); - } - if (!device->dev) { - Dmsg1(100, "Device %s could not be opened. Skipped\n", dev_name.c_str()); - Jmsg(jcr, M_WARNING, 0, _("\n" - " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"), - device->hdr.name, dev_name.c_str()); - continue; - } - if (!device->dev->autoselect) { - continue; /* device is not available */ - } - dcr = new_dcr(jcr, device->dev); - if (!dcr) { - bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str()); - Dmsg1(100, ">dird: %s\n", dir->msg); -// UnlockRes(); - ok = false; - goto get_out; - } - Dmsg1(100, "Found changer device %s\n", device->hdr.name); - bstrncpy(dcr->pool_name, store->pool_name, name_len); - bstrncpy(dcr->pool_type, store->pool_type, name_len); - bstrncpy(dcr->media_type, store->media_type, name_len); - bstrncpy(dcr->dev_name, device_name, name_len); - jcr->dcr = dcr; - if (append == SD_APPEND) { - ok = reserve_device_for_append(dcr); - } else { - ok = reserve_device_for_read(dcr); - } - if (!ok) { - Jmsg(jcr, M_WARNING, 0, _("Could not reserve device: %s\n"), dev_name.c_str()); - free_dcr(jcr->dcr); - continue; - } - Dmsg1(100, "Device %s opened.\n", device_name); -// UnlockRes(); - pm_strcpy(dev_name, device->hdr.name); - bash_spaces(dev_name); - ok = bnet_fsend(dir, OK_device, dev_name.c_str()); - Dmsg1(100, ">dird: %s\n", dir->msg); - goto get_out; - } - break; /* we found it but could not open a device */ - } + if (search_res_for_device(jcr, store, device_name, append) == 1) { + dcr = jcr->dcr; + dcr->Copy = Copy; + dcr->Stripe = Stripe; + ok = true; + goto done; } } - -// UnlockRes(); if (verbose) { unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); @@ -469,15 +377,136 @@ static bool use_storage_cmd(JCR *jcr) ok = false; } -get_out: +done: foreach_alist(store, dirstore) { delete store->device; delete store; } delete dirstore; + if (!ok && dcr) { + free_dcr(dcr); + } return ok; } +/* + * Returns: 1 -- OK, have DCR + * 0 -- must wait + * -1 -- fatal error + */ +static int search_res_for_device(JCR *jcr, DIRSTORE *store, char *device_name, int append) +{ + DEVRES *device; + AUTOCHANGER *changer; + BSOCK *dir = jcr->dir_bsock; + bool ok; + DCR *dcr; + + Dmsg1(100, "Search res for %s\n", device_name); + foreach_res(device, R_DEVICE) { + Dmsg1(100, "Try res=%s\n", device->hdr.name); + /* Find resource, and make sure we were able to open it */ + if (fnmatch(device_name, device->hdr.name, 0) == 0 && + strcmp(device->media_type, store->media_type) == 0) { + const int name_len = MAX_NAME_LENGTH; + if (!device->dev) { + device->dev = init_dev(jcr, NULL, device); + } + if (!device->dev) { + Jmsg(jcr, M_WARNING, 0, _("\n" + " Device \"%s\" requested by DIR could not be opened or does not exist.\n"), + device_name); + bnet_fsend(dir, NOT_open, device_name); + Dmsg1(100, ">dird: %s\n", dir->msg); + return -1; + } + Dmsg1(100, "Found device %s\n", device->hdr.name); + dcr = new_dcr(jcr, device->dev); + if (!dcr) { + bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), device_name); + Dmsg1(100, ">dird: %s\n", dir->msg); + return -1; + } + jcr->dcr = dcr; + bstrncpy(dcr->pool_name, store->pool_name, name_len); + bstrncpy(dcr->pool_type, store->pool_type, name_len); + bstrncpy(dcr->media_type, store->media_type, name_len); + bstrncpy(dcr->dev_name, device_name, name_len); + if (append == SD_APPEND) { + ok = reserve_device_for_append(dcr); + } else { + ok = reserve_device_for_read(dcr); + } + if (!ok) { + bnet_fsend(dir, _("3927 Could not reserve device: %s\n"), device_name); + Dmsg1(100, ">dird: %s\n", dir->msg); + free_dcr(jcr->dcr); + return 0; + } + Dmsg1(220, "Got: %s", dir->msg); + bash_spaces(device_name); + ok = bnet_fsend(dir, OK_device, device_name); + Dmsg1(100, ">dird: %s\n", dir->msg); + return ok; + } + } + foreach_res(changer, R_AUTOCHANGER) { + Dmsg1(100, "Try changer res=%s\n", changer->hdr.name); + /* Find resource, and make sure we were able to open it */ + if (fnmatch(device_name, changer->hdr.name, 0) == 0) { + const int name_len = MAX_NAME_LENGTH; + /* Try each device in this AutoChanger */ + foreach_alist(device, changer->device) { + Dmsg1(100, "Try changer device %s\n", device->hdr.name); + if (!device->dev) { + device->dev = init_dev(jcr, NULL, device); + } + if (!device->dev) { + Dmsg1(100, "Device %s could not be opened. Skipped\n", device_name); + Jmsg(jcr, M_WARNING, 0, _("\n" + " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"), + device->hdr.name, device_name); + continue; + } + if (!device->dev->autoselect) { + continue; /* device is not available */ + } + dcr = new_dcr(jcr, device->dev); + if (!dcr) { + bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), device_name); + Dmsg1(100, ">dird: %s\n", dir->msg); + return -1; + } + Dmsg1(100, "Found changer device %s\n", device->hdr.name); + bstrncpy(dcr->pool_name, store->pool_name, name_len); + bstrncpy(dcr->pool_type, store->pool_type, name_len); + bstrncpy(dcr->media_type, store->media_type, name_len); + bstrncpy(dcr->dev_name, device_name, name_len); + jcr->dcr = dcr; + if (append == SD_APPEND) { + ok = reserve_device_for_append(dcr); + } else { + ok = reserve_device_for_read(dcr); + } + if (!ok) { + Jmsg(jcr, M_WARNING, 0, _("Could not reserve device: %s\n"), device_name); + free_dcr(jcr->dcr); + continue; + } + POOL_MEM dev_name; + Dmsg1(100, "Device %s opened.\n", device_name); + pm_strcpy(dev_name, device->hdr.name); + bash_spaces(dev_name); + ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */ + Dmsg1(100, ">dird: %s\n", dir->msg); + return ok; + } + } + } + return 0; +} + + #ifdef needed /* * Query Device command from Director diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index c089b1268a..70f959259c 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -236,10 +236,10 @@ read_volume: memcpy(&VolCatInfo, &dcr->VolCatInfo, sizeof(VolCatInfo)); memcpy(&devVolCatInfo, &dev->VolCatInfo, sizeof(devVolCatInfo)); /* Check if this is a valid Volume in the pool */ - bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName)); if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) { /* Restore desired volume name, note device info out of sync */ /* This gets the info regardless of the Pool */ + bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName)); if (autochanger && dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) { mark_volume_not_inchanger(dcr); } diff --git a/bacula/src/version.h b/bacula/src/version.h index 3e8c5cfc9c..97d8003e37 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION #define VERSION "1.37.18" -#define BDATE "09 May 2005" -#define LSMDATE "09May05" +#define BDATE "10 May 2005" +#define LSMDATE "10May05" /* Debug flags */ #undef DEBUG