From 9204714af1fdf503d657f1d31e3c9b52cc8b630f Mon Sep 17 00:00:00 2001 From: Philipp Storz Date: Mon, 6 Jan 2014 11:43:26 +0100 Subject: [PATCH] check return values of spool functions We now check the return values of * begin_data_spool() * begin_attribute_spool() as otherwise the job hangs until eternety if there is a problem with the spool file. Fixes: #265: job hangs and cannot be terminated if spool file is not writable --- src/stored/append.c | 23 +++++++++++++++-------- src/stored/mac.c | 27 +++++++++++++++++++-------- src/stored/ndmp_tape.c | 33 ++++++++++++++++----------------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/stored/append.c b/src/stored/append.c index 51e42131962..92bc5cee488 100644 --- a/src/stored/append.c +++ b/src/stored/append.c @@ -69,19 +69,16 @@ bool do_append_data(JCR *jcr, BSOCK *bs, const char *what) Dmsg1(100, "Start append data. res=%d\n", dev->num_reserved()); if (!bs->set_buffer_size(dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) { - jcr->setJobStatus(JS_ErrorTerminated); Jmsg0(jcr, M_FATAL, 0, _("Unable to set network buffer size.\n")); - return false; + goto bail_out; } if (!acquire_device_for_append(dcr)) { - jcr->setJobStatus(JS_ErrorTerminated); - return false; + goto bail_out; } if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) { - jcr->setJobStatus(JS_ErrorTerminated); - return false; + goto bail_out; } jcr->sendJobStatus(JS_Running); @@ -91,8 +88,14 @@ bool do_append_data(JCR *jcr, BSOCK *bs, const char *what) } Dmsg1(50, "Begin append device=%s\n", dev->print_name()); - begin_data_spool(dcr); - begin_attribute_spool(jcr); + if (!begin_data_spool(dcr) ) { + goto bail_out; + } + + if (!begin_attribute_spool(jcr)) { + discard_data_spool(dcr); + goto bail_out; + } Dmsg0(100, "Just after acquire_device_for_append\n"); if (dev->VolCatInfo.VolCatName[0] == 0) { @@ -339,6 +342,10 @@ bool do_append_data(JCR *jcr, BSOCK *bs, const char *what) Dmsg1(100, "return from do_append_data() ok=%d\n", ok); return ok; + +bail_out: + jcr->setJobStatus(JS_ErrorTerminated); + return false; } /* diff --git a/src/stored/mac.c b/src/stored/mac.c index 0356202bb0c..73893a0acb5 100644 --- a/src/stored/mac.c +++ b/src/stored/mac.c @@ -462,7 +462,7 @@ bool do_mac_run(JCR *jcr) * Ready devices for reading. */ if (!acquire_device_for_read(jcr->read_dcr)) { - jcr->setJobStatus(JS_ErrorTerminated); + ok = false; goto bail_out; } @@ -475,8 +475,8 @@ bool do_mac_run(JCR *jcr) */ sd = jcr->store_bsock; if (!sd->set_buffer_size(me->max_network_buffer_size, BNET_SETBUF_WRITE)) { - jcr->setJobStatus(JS_ErrorTerminated); Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size SD->SD.\n")); + ok = false; goto bail_out; } @@ -511,7 +511,7 @@ bool do_mac_run(JCR *jcr) * Expect to get response to the replicate data cmd from Storage daemon */ if (!response(jcr, sd, OK_data, "replicate data")) { - jcr->setJobStatus(JS_ErrorTerminated); + ok = false; goto bail_out; } @@ -536,7 +536,7 @@ bool do_mac_run(JCR *jcr) * Expect to get response that the replicate data succeeded. */ if (!response(jcr, sd, OK_replicate, "replicate data")) { - jcr->setJobStatus(JS_ErrorTerminated); + ok = false; goto bail_out; } @@ -550,7 +550,7 @@ bool do_mac_run(JCR *jcr) * Expect to get response to the end replicate cmd from Storage daemon */ if (!response(jcr, sd, OK_end_replicate, "end replicate")) { - jcr->setJobStatus(JS_ErrorTerminated); + ok = false; goto bail_out; } @@ -571,7 +571,7 @@ bool do_mac_run(JCR *jcr) */ if (!acquire_device_for_read(jcr->read_dcr) || !acquire_device_for_append(jcr->dcr)) { - jcr->setJobStatus(JS_ErrorTerminated); + ok = false; goto bail_out; } @@ -579,8 +579,15 @@ bool do_mac_run(JCR *jcr) jcr->sendJobStatus(JS_Running); - begin_data_spool(jcr->dcr); - begin_attribute_spool(jcr); + if (!begin_data_spool(jcr->dcr) ) { + ok = false; + goto bail_out; + } + + if (!begin_attribute_spool(jcr)) { + ok = false; + goto bail_out; + } jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0; jcr->run_time = time(NULL); @@ -594,6 +601,10 @@ bool do_mac_run(JCR *jcr) } bail_out: + if (!ok) { + jcr->setJobStatus(JS_ErrorTerminated); + } + if (!jcr->remote_replicate && jcr->dcr) { /* * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits, diff --git a/src/stored/ndmp_tape.c b/src/stored/ndmp_tape.c index 123d675931d..8f45ca0342f 100644 --- a/src/stored/ndmp_tape.c +++ b/src/stored/ndmp_tape.c @@ -626,16 +626,14 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, * Actually acquire the device which we reserved. */ if (!acquire_device_for_append(dcr)) { - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } /* * Let any SD plugin know now its time to setup the record translation infra. */ if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) { - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } /* @@ -655,7 +653,10 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, * set per NDMP backup stream we only setup data spooling and not * attribute spooling. */ - begin_data_spool(dcr); + + if (!begin_data_spool(dcr) ) { + goto bail_out; + } /* * Write Begin Session Record @@ -664,8 +665,7 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"), dcr->dev->bstrerror()); - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } dcr->VolFirstIndex = dcr->VolLastIndex = 0; @@ -696,8 +696,7 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, if (!bndmp_create_virtual_file(jcr, virtual_filename.c_str())) { Jmsg0(jcr, M_FATAL, 0, _("Creating virtual file attributes failed.\n")); - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } } else { bool ok = true; @@ -711,8 +710,7 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, if (jcr->NumReadVolumes == 0) { Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n")); - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } Dmsg2(200, "Found %d volumes names to restore. First=%s\n", @@ -722,16 +720,14 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, * Ready device for reading */ if (!acquire_device_for_read(dcr)) { - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } /* * Let any SD plugin know now its time to setup the record translation infra. */ if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) { - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } /* @@ -763,8 +759,7 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, Jmsg1(jcr, M_FATAL, 0, _("Read session label failed. ERR=%s\n"), dcr->dev->bstrerror()); - jcr->setJobStatus(JS_ErrorTerminated); - return NDMP9_NO_DEVICE_ERR; + goto bail_out; } read_context_set_record(dcr, rctx); @@ -793,6 +788,10 @@ extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, ta->tape_state.space_remain.valid = NDMP9_VALIDITY_INVALID; return NDMP9_NO_ERR; + +bail_out: + jcr->setJobStatus(JS_ErrorTerminated); + return NDMP9_NO_DEVICE_ERR; } extern "C" ndmp9_error bndmp_tape_close(struct ndm_session *sess)