From: Radosław Korzeniewski Date: Tue, 13 Apr 2021 13:07:29 +0000 (+0200) Subject: metaplugin: Add proper skip handling to Bacula. X-Git-Tag: Release-11.3.2~587 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b79855a10b0b35ac40ceb6e00f479938dc134e7;p=thirdparty%2Fbacula.git metaplugin: Add proper skip handling to Bacula. This extends a metaplugin protocol with a SKIP command in metadta streams handling, so backend can decide later if the file should be skipped or extracted. It update metaplugin and Bacula for a proper SKIP command handling, so both xacl's and metadata's will be properly skipped for backend. --- diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 44f4b2fe4..1899e623e 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -896,6 +896,7 @@ void do_restore(JCR *jcr) case STREAM_XACL_HURD_DEFAULT: case STREAM_XACL_HURD_ACCESS: case STREAM_XACL_PLUGIN_ACL: + // here we can simply skip this stream if rctx.extract is false, right? case STREAM_XACL_GPFS_ACL_DEFAULT: case STREAM_XACL_GPFS_ACL_ACCESS: /* @@ -929,6 +930,7 @@ void do_restore(JCR *jcr) break; case STREAM_XACL_PLUGIN_XATTR: + // here we can simply skip this stream if rctx.extract is false, right? case STREAM_XACL_HURD_XATTR: case STREAM_XACL_IRIX_XATTR: case STREAM_XACL_TRU64_XATTR: @@ -1031,6 +1033,7 @@ void do_restore(JCR *jcr) case STREAM_PLUGIN_META_BLOB: case STREAM_PLUGIN_META_CATALOG: { + // here we can simply skip this stream if rctx.extract is false, right? if (!jcr->plugin) { Dmsg0(10, "No plugin related to metadata packet found, metadata restore failed!\n"); goto get_out; @@ -1050,11 +1053,19 @@ void do_restore(JCR *jcr) } int rc = plug_func(jcr->plugin)->metadataRestore(jcr->plugin_ctx, &mp); - if (rc != bRC_OK) { + switch (rc) + { + case bRC_Skip: + Dmsg0(200, "metadata:rctx.extract = false\n"); + rctx.extract = false; + bclose(&rctx.bfd); + break; + case bRC_OK: + break; + default: Jmsg(jcr, M_ERROR, 0, _("Plugin metadataRestore call failed, err: %d\n"), rc); goto get_out; } - break; } diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index 23445c7ac..47273a78f 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -152,10 +152,6 @@ const char *stream_to_ascii(int stream) return _("Restore Object"); case STREAM_PLUGIN_OBJECT: return _("Plugin Object"); - case STREAM_PLUGIN_META_BLOB: - return _("Plugin metadata (binary)"); - case STREAM_PLUGIN_META_CATALOG: - return _("Plugin metadata (catalog)"); case STREAM_XACL_AIX_TEXT: return _("AIX ACL attribs"); case STREAM_XACL_DARWIN_ACCESS: @@ -216,6 +212,10 @@ const char *stream_to_ascii(int stream) return _("Linux Extended attribs"); case STREAM_XACL_NETBSD_XATTR: return _("NetBSD Extended attribs"); + case STREAM_PLUGIN_META_BLOB: + return _("Plugin Metadata Blob"); + case STREAM_PLUGIN_META_CATALOG: + return _("Plugin Metadata Catalog"); default: sprintf(buf, "%d", stream); return (const char *)buf; diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp index ce3175a64..467877a2a 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp @@ -165,6 +165,7 @@ METAPLUGIN::METAPLUGIN(bpContext *bpctx) : pluginobjectsent(false), readacl(false), readxattr(false), + skipextract(false), fname(PM_FNAME), lname(PM_FNAME), robjbuf(NULL), @@ -2180,6 +2181,7 @@ bRC METAPLUGIN::createFile(bpContext *ctx, struct restore_pkt *rp) POOL_MEM cmd(PM_FNAME); char type; + skipextract = false; if (CORELOCALRESTORE && islocalpath(where)){ DMSG0(ctx, DDEBUG, "createFile:Forwarding restore to Core\n"); rp->create_status = CF_CORE; @@ -2234,6 +2236,7 @@ bRC METAPLUGIN::createFile(bpContext *ctx, struct restore_pkt *rp) } else if (strcmp(cmd.c_str(), "SKIP") == 0){ rp->create_status = CF_SKIP; + skipextract = true; } else if (strcmp(cmd.c_str(), "CORE") == 0){ rp->create_status = CF_CORE; @@ -2296,33 +2299,40 @@ void METAPLUGIN::setup_backend_command(bpContext *ctx, POOL_MEM &exepath) */ bRC METAPLUGIN::handleXACLdata(bpContext *ctx, struct xacl_pkt *xacl) { - switch (xacl->func){ - case BACL_BACKUP: - if (readacl){ - DMSG0(ctx, DINFO, "bacl_backup\n"); - xacl->count = acldatalen; - xacl->content = acldata.c_str(); - readacl= false; - } else { - xacl->count = 0; - } - break; - case BACL_RESTORE: - DMSG0(ctx, DINFO, "bacl_restore\n"); - return perform_write_acl(ctx, xacl); - case BXATTR_BACKUP: - if (readxattr){ - DMSG0(ctx, DINFO, "bxattr_backup\n"); - xacl->count = xattrdatalen; - xacl->content = xattrdata.c_str(); - readxattr= false; - } else { - xacl->count = 0; + switch (xacl->func) + { + case BACL_BACKUP: + if (readacl){ + DMSG0(ctx, DINFO, "bacl_backup\n"); + xacl->count = acldatalen; + xacl->content = acldata.c_str(); + readacl= false; + } else { + xacl->count = 0; + } + break; + case BACL_RESTORE: + DMSG0(ctx, DINFO, "bacl_restore\n"); + if (!skipextract){ + return perform_write_acl(ctx, xacl); } break; - case BXATTR_RESTORE: - DMSG0(ctx, DINFO, "bxattr_restore\n"); + case BXATTR_BACKUP: + if (readxattr){ + DMSG0(ctx, DINFO, "bxattr_backup\n"); + xacl->count = xattrdatalen; + xacl->content = xattrdata.c_str(); + readxattr= false; + } else { + xacl->count = 0; + } + break; + case BXATTR_RESTORE: + DMSG0(ctx, DINFO, "bxattr_restore\n"); + if (!skipextract){ return perform_write_xattr(ctx, xacl); + } + break; } return bRC_OK; @@ -2427,25 +2437,45 @@ bRC METAPLUGIN::queryParameter(bpContext *ctx, struct query_pkt *qp) */ bRC METAPLUGIN::metadataRestore(bpContext *ctx, struct meta_pkt *mp) { - POOL_MEM cmd(PM_FNAME); + if (!skipextract){ + POOL_MEM cmd(PM_FNAME); - if (mp->buf != NULL && mp->buf_len > 0){ - /* send command METADATA */ - pm_strcpy(cmd, prepare_metadata_type(mp->type)); - backend.ctx->write_command(ctx, cmd.c_str()); - /* send metadata stream data */ - DMSG1(ctx, DINFO, "writeMetadata: %i\n", mp->buf_len); - int rc = backend.ctx->write_data(ctx, (char*)mp->buf, mp->buf_len); - if (rc < 0){ - /* got some error */ - return bRC_Error; - } - /* signal end of metadata stream to restore and get ack */ - if (!backend.ctx->send_ack(ctx)){ - return bRC_Error; + if (mp->buf != NULL && mp->buf_len > 0){ + /* send command METADATA */ + pm_strcpy(cmd, prepare_metadata_type(mp->type)); + backend.ctx->write_command(ctx, cmd.c_str()); + /* send metadata stream data */ + DMSG1(ctx, DINFO, "writeMetadata: %i\n", mp->buf_len); + int rc = backend.ctx->write_data(ctx, (char*)mp->buf, mp->buf_len); + if (rc < 0){ + /* got some error */ + return bRC_Error; + } + + // signal end of metadata stream to restore and get ack + backend.ctx->signal_eod(ctx); + + // check if backend accepted the file + if (backend.ctx->read_command(ctx, cmd) > 0) { + DMSG(ctx, DINFO, "metadataRestore:resp: %s\n", cmd.c_str()); + if (bstrcmp(cmd.c_str(), "SKIP")) { + // SKIP! + skipextract = true; + return bRC_Skip; + } + if (!bstrcmp(cmd.c_str(), "OK")) { + DMSG(ctx, DERROR, "Wrong backend response to metadataRestore, got: %s\n", cmd.c_str()); + JMSG(ctx, backend.ctx->jmsg_err_level(), "Wrong backend response to metadataRestore, got: %s\n", cmd.c_str()); + return bRC_Error; + } + } else { + if (backend.ctx->is_error()) { + // raise up error from backend + return bRC_Error; + } + } } } - return bRC_OK; } diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.h b/bacula/src/plugins/fd/pluginlib/metaplugin.h index 6ebeff31a..a91bf7a3b 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.h +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.h @@ -154,6 +154,7 @@ private: bool pluginobjectsent; // set when startBackupFile handled plugin object and endBackupFile has to check for nextfile bool readacl; // got ACL data from backend bool readxattr; // got XATTR data from backend + bool skipextract; // got SKIP response from backend, so we should artificially skip it for backend COMMCTX backend; // the backend context list for multiple backend execution for a single job POOL_MEM fname; // current file name to backup (grabbed from backend) POOL_MEM lname; // current LSTAT data if any diff --git a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp index 010966240..88f1cad59 100644 --- a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp +++ b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp @@ -791,7 +791,7 @@ bool PTCOMM::send_ack(bpContext *ctx) // check if backend response with OK if (bstrcmp(buf.c_str(), "OK")){ - // great ACk confirmed + // great ACK confirmed return true; }