From cf2e3068e5bdeb2f4faf9699036be64a6ebf6093 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 4 Oct 2008 15:38:04 +0000 Subject: [PATCH] kes Refactor restore code to create a close_previous_stream(). This This may destabilize the source. kes Implement planned startRestoreFile() plugin call. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7702 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/filed/fd_plugins.c | 36 ++++-- bacula/src/filed/fd_plugins.h | 2 +- bacula/src/filed/restore.c | 207 ++++++++++++++----------------- bacula/src/findlib/bfile.c | 12 +- bacula/src/plugins/fd/bpipe-fd.c | 8 ++ bacula/src/version.h | 2 +- bacula/technotes-2.5 | 5 +- 7 files changed, 144 insertions(+), 128 deletions(-) diff --git a/bacula/src/filed/fd_plugins.c b/bacula/src/filed/fd_plugins.c index 0d52728ddd..d88960c5b3 100644 --- a/bacula/src/filed/fd_plugins.c +++ b/bacula/src/filed/fd_plugins.c @@ -226,7 +226,7 @@ bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start) sd->bstrerror()); return false; } - Dmsg1(000, "send: %s\n", sd->msg); + Dmsg1(50, "send: %s\n", sd->msg); if (start) { /* Send data -- not much */ @@ -248,8 +248,11 @@ bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start) /* * Plugin name stream found during restore. The record passed in * argument name was generated in send_plugin_name() above. + * + * Returns: true if start of stream + * false if end of steam */ -void plugin_name_stream(JCR *jcr, char *name) +bool plugin_name_stream(JCR *jcr, char *name) { char *p = name; char *cmd; @@ -258,9 +261,6 @@ void plugin_name_stream(JCR *jcr, char *name) int len; int i = 0; bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list; - if (!plugin_ctx_list) { - goto bail_out; - } Dmsg1(dbglvl, "Read plugin stream string=%s\n", name); skip_nonspaces(&p); /* skip over jcr->JobFiles */ @@ -287,6 +287,9 @@ void plugin_name_stream(JCR *jcr, char *name) jcr->plugin = NULL; goto bail_out; } + if (!plugin_ctx_list) { + goto bail_out; + } /* * After this point, we are dealing with a restore start @@ -321,10 +324,11 @@ void plugin_name_stream(JCR *jcr, char *name) } jcr->plugin_ctx = &plugin_ctx_list[i]; jcr->plugin = plugin; + plug_func(plugin)->startRestoreFile((bpContext *)jcr->plugin_ctx, cmd); goto bail_out; } bail_out: - return; + return start; } /* @@ -379,16 +383,23 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) if (rp.create_status == CF_CREATED) { return rp.create_status; /* yes, no need to bopen */ } + flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; Dmsg0(dbglvl, "call bopen\n"); - if ((bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR)) < 0) { + int stat = bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR); + Dmsg1(50, "bopen status=%d\n", stat); + if (stat < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, be.bstrerror()); - Dmsg2(dbglvl,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror()); + Dmsg2(dbglvl,"Could not bopen file %s: ERR=%s\n", attr->ofname, be.bstrerror()); return CF_ERROR; } + + if (!is_bopen(bfd)) { + Dmsg0(000, "===== BFD is not open!!!!\n"); + } return CF_EXTRACT; } @@ -400,6 +411,10 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { Dmsg0(dbglvl, "plugin_set_attributes\n"); + if (is_bopen(ofd)) { + bclose(ofd); + } + pm_strcpy(attr->ofname, "*none*"); return true; } @@ -502,7 +517,7 @@ static int my_plugin_bopen(BFILE *bfd, const char *fname, int flags, mode_t mode Plugin *plugin = (Plugin *)jcr->plugin; bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; struct io_pkt io; - Dmsg0(dbglvl, "plugin_bopen\n"); + Dmsg1(dbglvl, "plugin_bopen flags=%x\n", flags); io.pkt_size = sizeof(io); io.pkt_end = sizeof(io); io.func = IO_OPEN; @@ -521,6 +536,7 @@ static int my_plugin_bopen(BFILE *bfd, const char *fname, int flags, mode_t mode errno = io.io_errno; bfd->lerror = io.lerror; } + Dmsg1(50, "Return from plugin open status=%d\n", io.status); return io.status; } @@ -530,7 +546,7 @@ static int my_plugin_bclose(BFILE *bfd) Plugin *plugin = (Plugin *)jcr->plugin; bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; struct io_pkt io; - Dmsg0(dbglvl, "plugin_bclose\n"); + Dmsg0(dbglvl, "===== plugin_bclose\n"); io.pkt_size = sizeof(io); io.pkt_end = sizeof(io); io.func = IO_CLOSE; diff --git a/bacula/src/filed/fd_plugins.h b/bacula/src/filed/fd_plugins.h index ad203e979e..35a5378e86 100644 --- a/bacula/src/filed/fd_plugins.h +++ b/bacula/src/filed/fd_plugins.h @@ -181,7 +181,7 @@ void new_plugins(JCR *jcr); void free_plugins(JCR *jcr); void generate_plugin_event(JCR *jcr, bEventType event, void *value=NULL); bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start); -void plugin_name_stream(JCR *jcr, char *name); +bool plugin_name_stream(JCR *jcr, char *name); int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace); bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd); int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level); diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 52b304f3d0..2fcf113baf 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -88,6 +88,8 @@ struct r_ctx { intmax_t fork_size; /* Size of alternate stream */ int fork_flags; /* Options for extract_data() */ int32_t type; /* file type FT_ */ + ATTR *attr; /* Pointer to attributes */ + bool extract; /* set when extracting */ SIGNATURE *sig; /* Cryptographic signature (if any) for file */ CRYPTO_SESSION *cs; /* Cryptographic session data (if any) for file */ @@ -108,11 +110,12 @@ static void deallocate_cipher(r_ctx &rctx); static void deallocate_fork_cipher(r_ctx &rctx); static void free_signature(r_ctx &rctx); static void free_session(r_ctx &rctx); +static void close_previous_stream(r_ctx &rctx); static bool verify_signature(JCR *jcr, r_ctx &rctx); -int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, +int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx); bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx); @@ -147,14 +150,13 @@ void do_restore(JCR *jcr) { BSOCK *sd; uint32_t VolSessionId, VolSessionTime; - bool extract = false; int32_t file_index; char ec1[50]; /* Buffer printing huge values */ uint32_t buf_size; /* client buffer size */ int stat; - ATTR *attr; intmax_t rsrc_len = 0; /* Original length of resource fork */ r_ctx rctx; + ATTR *attr; /* ***FIXME*** make configurable */ crypto_digest_t signing_algorithm = have_sha2 ? CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1; @@ -240,7 +242,7 @@ void do_restore(JCR *jcr) */ binit(&rctx.bfd); binit(&rctx.forkbfd); - attr = new_attr(jcr); + attr = rctx.attr = new_attr(jcr); jcr->acl_text = get_pool_memory(PM_MESSAGE); @@ -255,8 +257,8 @@ void do_restore(JCR *jcr) Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg); goto bail_out; } - Dmsg4(130, "Got hdr: Files=%d FilInx=%d Stream=%d, %s.\n", - jcr->JobFiles, file_index, rctx.stream, stream_to_ascii(rctx.stream)); + Dmsg5(50, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n", + jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream)); /* * Now we expect the Stream Data */ if (bget_msg(sd) < 0) { @@ -266,10 +268,12 @@ void do_restore(JCR *jcr) if (rctx.size != (uint32_t)sd->msglen) { Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, rctx.size); + Dmsg2(50, "Actual data size %d not same as header %d\n", + sd->msglen, rctx.size); goto bail_out; } Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream), - sd->msglen, extract); + sd->msglen, rctx.extract); /* If we change streams, close and reset alternate data streams */ if (rctx.prev_stream != rctx.stream) { @@ -285,40 +289,8 @@ void do_restore(JCR *jcr) switch (rctx.stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: - /* - * If extracting, it was from previous stream, so - * close the output file and validate the signature. - */ - if (extract) { - if (rctx.size > 0 && !is_bopen(&rctx.bfd)) { - Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n")); - } - - if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) { - deallocate_cipher(rctx); - deallocate_fork_cipher(rctx); - } - - if (jcr->plugin) { - plugin_set_attributes(jcr, attr, &rctx.bfd); - } else { - set_attributes(jcr, attr, &rctx.bfd); - } - extract = false; - - /* Verify the cryptographic signature, if any */ - rctx.type = attr->type; - verify_signature(jcr, rctx); + close_previous_stream(rctx); /* if any previous stream open, close it */ - /* Free Signature */ - free_signature(rctx); - free_session(rctx); - jcr->ff->flags = 0; - Dmsg0(130, "Stop extracting.\n"); - } else if (is_bopen(&rctx.bfd)) { - Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n")); - bclose(&rctx.bfd); - } /* TODO: manage deleted files */ if (rctx.type == FT_DELETED) { /* deleted file */ @@ -360,7 +332,7 @@ void do_restore(JCR *jcr) * us if we need to extract or not. */ jcr->num_files_examined++; - extract = false; + rctx.extract = false; if (jcr->plugin) { stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace); } else { @@ -376,7 +348,7 @@ void do_restore(JCR *jcr) case CF_SKIP: break; case CF_EXTRACT: /* File created and we expect file data */ - extract = true; + rctx.extract = true; /* FALLTHROUGH */ case CF_CREATED: /* File created, but there is no content */ jcr->JobFiles++; @@ -387,10 +359,10 @@ void do_restore(JCR *jcr) /* Only restore the resource fork for regular files */ from_base64(&rsrc_len, attr->attrEx); if (attr->type == FT_REG && rsrc_len > 0) { - extract = true; + rctx.extract = true; } } - if (!extract) { + if (!rctx.extract) { /* set attributes now because file will not be extracted */ if (jcr->plugin) { plugin_set_attributes(jcr, attr, &rctx.bfd); @@ -409,7 +381,7 @@ void do_restore(JCR *jcr) /* Is this an unexpected session data entry? */ if (rctx.cs) { Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n")); - extract = false; + rctx.extract = false; bclose(&rctx.bfd); continue; } @@ -417,7 +389,7 @@ void do_restore(JCR *jcr) /* Do we have any keys at all? */ if (!jcr->crypto.pki_recipients) { Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n")); - extract = false; + rctx.extract = false; bclose(&rctx.bfd); break; } @@ -428,7 +400,7 @@ void do_restore(JCR *jcr) jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm); if (!jcr->crypto.digest) { Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n")); - extract = false; + rctx.extract = false; bclose(&rctx.bfd); break; } @@ -453,7 +425,7 @@ void do_restore(JCR *jcr) } if (cryptoerr != CRYPTO_ERROR_NONE) { - extract = false; + rctx.extract = false; bclose(&rctx.bfd); continue; } @@ -471,7 +443,7 @@ void do_restore(JCR *jcr) case STREAM_ENCRYPTED_FILE_GZIP_DATA: case STREAM_ENCRYPTED_WIN32_GZIP_DATA: /* Force an expected, consistent stream type here */ - if (extract && (rctx.prev_stream == rctx.stream + if (rctx.extract && (rctx.prev_stream == rctx.stream || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) { @@ -498,7 +470,7 @@ void do_restore(JCR *jcr) if (!rctx.cipher_ctx.cipher) { if (!rctx.cs) { Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname); - extract = false; + rctx.extract = false; bclose(&rctx.bfd); continue; } @@ -507,7 +479,7 @@ void do_restore(JCR *jcr) &rctx.cipher_ctx.block_size)) == NULL) { Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname); free_session(rctx); - extract = false; + rctx.extract = false; bclose(&rctx.bfd); continue; } @@ -520,9 +492,8 @@ void do_restore(JCR *jcr) rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */ } - if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr, + if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx) < 0) { - extract = false; bclose(&rctx.bfd); continue; } @@ -541,10 +512,10 @@ void do_restore(JCR *jcr) rctx.fork_flags |= FO_ENCRYPT; /* Set up a decryption context */ - if (extract && !rctx.fork_cipher_ctx.cipher) { + if (rctx.extract && !rctx.fork_cipher_ctx.cipher) { if (!rctx.cs) { Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname); - extract = false; + rctx.extract = false; bclose(&rctx.bfd); continue; } @@ -552,18 +523,18 @@ void do_restore(JCR *jcr) if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) { Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname); free_session(rctx); - extract = false; + rctx.extract = false; bclose(&rctx.bfd); continue; } } } - if (extract) { + if (rctx.extract) { if (rctx.prev_stream != rctx.stream) { if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) { Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname); - extract = false; + rctx.extract = false; continue; } @@ -571,9 +542,8 @@ void do_restore(JCR *jcr) Dmsg0(130, "Restoring resource fork\n"); } - if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags, + if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx) < 0) { - extract = false; bclose(&rctx.forkbfd); continue; } @@ -632,7 +602,7 @@ void do_restore(JCR *jcr) continue; } /* Save signature. */ - if (extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) { + if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) { Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname); } break; @@ -652,35 +622,13 @@ void do_restore(JCR *jcr) break; case STREAM_PLUGIN_NAME: - Dmsg1(000, "restore stream_plugin_name=%s\n", sd->msg); + close_previous_stream(rctx); + Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg); plugin_name_stream(jcr, sd->msg); break; default: - /* If extracting, weird stream (not 1 or 2), close output file anyway */ - if (extract) { - Dmsg1(130, "Found weird stream %d\n", rctx.stream); - if (rctx.size > 0 && !is_bopen(&rctx.bfd)) { - Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n")); - } - /* Flush and deallocate cipher context */ - deallocate_cipher(rctx); - deallocate_fork_cipher(rctx); - - if (jcr->plugin) { - plugin_set_attributes(jcr, attr, &rctx.bfd); - } else { - set_attributes(jcr, attr, &rctx.bfd); - } - - /* Verify the cryptographic signature if any */ - rctx.type = attr->type; - verify_signature(jcr, rctx); - extract = false; - } else if (is_bopen(&rctx.bfd)) { - Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n")); - bclose(&rctx.bfd); - } + close_previous_stream(rctx); Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), rctx.stream); Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg); @@ -689,32 +637,15 @@ void do_restore(JCR *jcr) } /* end while get_msg() */ - /* If output file is still open, it was the last one in the + /* + * If output file is still open, it was the last one in the * archive since we just hit an end of file, so close the file. */ if (is_bopen(&rctx.forkbfd)) { bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size); } - if (extract) { - /* Flush and deallocate cipher context */ - deallocate_cipher(rctx); - deallocate_fork_cipher(rctx); - - if (jcr->plugin) { - plugin_set_attributes(jcr, attr, &rctx.bfd); - } else { - set_attributes(jcr, attr, &rctx.bfd); - } - - /* Verify the cryptographic signature on the last file, if any */ - rctx.type = attr->type; - verify_signature(jcr, rctx); - } - - if (is_bopen(&rctx.bfd)) { - bclose(&rctx.bfd); - } + close_previous_stream(rctx); set_jcr_job_status(jcr, JS_Terminated); goto ok_out; @@ -757,7 +688,7 @@ ok_out: } bclose(&rctx.forkbfd); bclose(&rctx.bfd); - free_attr(attr); + free_attr(rctx.attr); free_pool_memory(jcr->acl_text); Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1)); @@ -1017,9 +948,10 @@ bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win * The flags specify whether to use sparse files or compression. * Return value is the number of bytes written, or -1 on errors. */ -int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, +int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx) { + BFILE *bfd = &rctx.bfd; char *wbuf; /* write buffer */ uint32_t wsize; /* write size */ uint32_t rsize; /* read size */ @@ -1053,7 +985,7 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, &decrypted_len)) { /* Decryption failed. Shouldn't happen. */ Jmsg(jcr, M_FATAL, 0, _("Decryption error\n")); - return -1; + goto bail_out; } if (decrypted_len == 0) { @@ -1087,18 +1019,18 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, if (flags & FO_SPARSE) { if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) { - return -1; + goto bail_out; } } if (flags & FO_GZIP) { if (!decompress_data(jcr, &wbuf, &wsize)) { - return -1; + goto bail_out; } } if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) { - return -1; + goto bail_out; } jcr->JobBytes += wsize; *addr += wsize; @@ -1117,8 +1049,59 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, cipher_ctx->packet_len = 0; } return wsize; + +bail_out: + rctx.extract = false; + return -1; + } + +/* + * If extracting, close any previous stream + */ +static void close_previous_stream(r_ctx &rctx) +{ + /* + * If extracting, it was from previous stream, so + * close the output file and validate the signature. + */ + if (rctx.extract) { + if (rctx.size > 0 && !is_bopen(&rctx.bfd)) { + Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n")); + Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size, + is_bopen(&rctx.bfd)); + } + + if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) { + deallocate_cipher(rctx); + deallocate_fork_cipher(rctx); + } + + if (rctx.jcr->plugin) { + plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd); + } else { + set_attributes(rctx.jcr, rctx.attr, &rctx.bfd); + } + rctx.extract = false; + + /* Verify the cryptographic signature, if any */ + rctx.type = rctx.attr->type; + verify_signature(rctx.jcr, rctx); + + /* Free Signature */ + free_signature(rctx); + free_session(rctx); + rctx.jcr->ff->flags = 0; + Dmsg0(130, "Stop extracting.\n"); + } else if (is_bopen(&rctx.bfd)) { + Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n")); + Dmsg0(000, "=== logic error !open\n"); + bclose(&rctx.bfd); + } +} + + /* * In the context of jcr, flush any remaining data from the cipher context, * writing it to bfd. diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index 778f49149e..c9dba67d09 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -422,6 +422,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) int rtnstat; Dmsg1(50, "call plugin_bopen fname=%s\n", fname); rtnstat = plugin_bopen(bfd, fname, flags, mode); + Dmsg1(50, "return from plugin_bopen status=%d\n", rtnstat); if (rtnstat >= 0) { if (flags & O_CREAT || flags & O_WRONLY) { /* Open existing for write */ Dmsg1(50, "plugin_open for write OK file=%s.\n", fname); @@ -432,12 +433,13 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) } } else { bfd->mode = BF_CLOSED; - Dmsg1(000, "plugin_bopen returned bad status=%d\n", rtnstat); + Dmsg1(000, "==== plugin_bopen returned bad status=%d\n", rtnstat); } free_pool_memory(win32_fname_wchar); free_pool_memory(win32_fname); return bfd->mode == BF_CLOSED ? -1 : 1; } + Dmsg0(50, "=== NOT plugin\n"); if (!(p_CreateFileA || p_CreateFileW)) return 0; @@ -571,11 +573,13 @@ int bclose(BFILE *bfd) bfd->errmsg = NULL; } if (bfd->mode == BF_CLOSED) { + Dmsg0(50, "=== BFD already closed.\n"); return 0; } if (bfd->cmd_plugin && plugin_bclose) { stat = plugin_bclose(bfd); + Dmsg0(50, "==== BFD closed!!!\n"); goto all_done; } @@ -839,8 +843,10 @@ bool is_restore_stream_supported(int stream) int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) { if (bfd->cmd_plugin && plugin_bopen) { - Dmsg1(000, "call plugin_bopen fname=%s\n", fname); - return plugin_bopen(bfd, fname, flags, mode); + Dmsg1(50, "call plugin_bopen fname=%s\n", fname); + bfd->fid = plugin_bopen(bfd, fname, flags, mode); + Dmsg1(50, "Plugin bopen stat=%d\n", bfd->fid); + return bfd->fid; } /* Normal file open */ diff --git a/bacula/src/plugins/fd/bpipe-fd.c b/bacula/src/plugins/fd/bpipe-fd.c index 8f14decd63..6058655c67 100644 --- a/bacula/src/plugins/fd/bpipe-fd.c +++ b/bacula/src/plugins/fd/bpipe-fd.c @@ -400,12 +400,20 @@ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) return bRC_OK; } +/* + * Bacula is notifying us that a plugin name string was found, and + * passing us the plugin command, so we can prepare for a restore. + */ static bRC startRestoreFile(bpContext *ctx, const char *cmd) { // printf("bpipe-fd: startRestoreFile cmd=%s\n", cmd); return bRC_OK; } +/* + * Bacula is notifying us that the plugin data has terminated, so + * the restore for this particular file is done. + */ static bRC endRestoreFile(bpContext *ctx) { // printf("bpipe-fd: endRestoreFile\n"); diff --git a/bacula/src/version.h b/bacula/src/version.h index bc4628c36e..d431a7ab0f 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -3,7 +3,7 @@ */ #undef VERSION -#define VERSION "2.5.10" +#define VERSION "2.5.11" #define BDATE "04 October 2008" #define LSMDATE "04Oct08" diff --git a/bacula/technotes-2.5 b/bacula/technotes-2.5 index c0443aa3dc..935b1455e1 100644 --- a/bacula/technotes-2.5 +++ b/bacula/technotes-2.5 @@ -18,8 +18,11 @@ remove reader/writer in FOPTS???? General: 04Oct08 +kes Refactor restore code to create a close_previous_stream(). This + This may destabilize the source. +kes Implement planned startRestoreFile() plugin call. ebl Remove missing Loaded information from status slots storage command. -ebl Fix Console command problem that cancel the job +ebl Fix Console command problem that cancels the job kes Add more plugin restore debug code. 03Oct08 kes Fix plugin_bwrite - plugin-blseek mixup pointed out by James. -- 2.39.5