From: Radosław Korzeniewski Date: Tue, 16 Mar 2021 12:43:32 +0000 (+0100) Subject: metaplugin: Add hardlink support to protocol. X-Git-Tag: Release-11.3.2~676 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c2f01eec2a4c17dc4ae11d02403ac15ad77733f6;p=thirdparty%2Fbacula.git metaplugin: Add hardlink support to protocol. --- diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp index 02fef06b1..cdca3120e 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp @@ -865,14 +865,12 @@ bRC METAPLUGIN::send_startjob(bpContext *ctx, const char *command) POOL_MEM cmd; pm_strcpy(cmd, command); - if (backend.ctx->write_command(ctx, cmd) < 0) - { + if (backend.ctx->write_command(ctx, cmd) < 0){ /* error */ return bRC_Error; } - if (!backend.ctx->read_ack(ctx)) - { + if (!backend.ctx->read_ack(ctx)){ strip_trailing_newline(cmd.c_str()); DMSG(ctx, DERROR, "Wrong backend response to %s command.\n", cmd.c_str()); JMSG(ctx, backend.ctx->jmsg_err_level(), "Wrong backend response to %s command.\n", cmd.c_str()); @@ -1675,6 +1673,11 @@ bRC METAPLUGIN::perform_read_metadata(bpContext *ctx) perform_read_xattr(ctx); continue; } + if (bstrcmp(cmd.c_str(), "FileIndex")){ + /* got FileIndex query */ + perform_file_index_query(ctx); + continue; + } /* error in protocol */ DMSG(ctx, DERROR, "Protocol error, got unknown command: %s\n", cmd.c_str()); JMSG(ctx, M_FATAL, "Protocol error, got unknown command: %s\n", cmd.c_str()); @@ -1695,6 +1698,21 @@ bRC METAPLUGIN::perform_read_metadata(bpContext *ctx) return bRC_Error; } +bRC METAPLUGIN::perform_file_index_query(bpContext *ctx) +{ + POOL_MEM cmd(PM_FNAME); + int32_t fileindex; + + getBaculaVar(bVarFileIndex, (void *)&fileindex); + Mmsg(cmd, "%d\n", fileindex); + if (backend.ctx->write_command(ctx, cmd) < 0){ + /* error */ + return bRC_Error; + } + + return bRC_OK; +} + /** * @brief * @@ -1706,8 +1724,7 @@ bRC METAPLUGIN::perform_read_pluginobject(bpContext *ctx, struct save_pkt *sp) { POOL_MEM cmd(PM_FNAME); - if (strlen(fname.c_str()) == 0) - { + if (strlen(fname.c_str()) == 0){ // input variable is not valid return bRC_Error; } @@ -1899,6 +1916,7 @@ bRC METAPLUGIN::startBackupFile(bpContext *ctx, struct save_pkt *sp) int uid, gid; uint perms; int nlinks; + int32_t nfi; int reqparams = 2; /* The first file in Full backup, is the RestoreObject */ @@ -1948,34 +1966,51 @@ bRC METAPLUGIN::startBackupFile(bpContext *ctx, struct save_pkt *sp) while (backend.ctx->read_command(ctx, cmd) > 0){ DMSG(ctx, DINFO, "read_command(2): %s\n", cmd.c_str()); - if (sscanf(cmd.c_str(), "STAT:%c %ld %d %d %o %d", &type, &size, &uid, &gid, &perms, &nlinks) == 6){ + // int nrscan = sscanf(cmd.c_str(), "STAT:%c %ld %d %d %o %d", &type, &size, &uid, &gid, &perms, &nlinks); + nfi = -1; + int nrscan = sscanf(cmd.c_str(), "STAT:%c %ld %d %d %o %d %d", &type, &size, &uid, &gid, &perms, &nlinks, &nfi); + DMSG1(ctx, DVDEBUG, "read_command-nrscan: %d\n", nrscan); + if (nrscan >= 6) + { sp->statp.st_size = size; sp->statp.st_nlink = nlinks; sp->statp.st_uid = uid; sp->statp.st_gid = gid; sp->statp.st_mode = perms; - switch (type){ - case 'F': - sp->type = FT_REG; - break; - case 'E': - sp->type = FT_REGE; - break; - case 'D': - sp->type = FT_DIREND; - sp->link = sp->fname; - break; - case 'S': - sp->type = FT_LNK; - reqparams++; - break; - default: - /* we need to signal error */ - sp->type = FT_REG; - DMSG2(ctx, DERROR, "Invalid file type: %c for %s\n", type, fname.c_str()); - JMSG2(ctx, M_ERROR, "Invalid file type: %c for %s\n", type, fname.c_str()); + switch (type) + { + case 'F': + sp->type = FT_REG; + break; + case 'E': + sp->type = FT_REGE; + break; + case 'D': + sp->type = FT_DIREND; + sp->link = sp->fname; + break; + case 'S': + sp->type = FT_LNK; + reqparams++; + break; + case 'L': + if (nrscan > 6){ + sp->type = FT_LNKSAVED; + sp->LinkFI = nfi; + } else { + DMSG1(ctx, DERROR, "Invalid stat packet: %s\n", cmd.c_str()); + JMSG1(ctx, backend.ctx->jmsg_err_level(), "Invalid stat packet: %s\n", cmd.c_str()); + return bRC_Error; + } + break; + default: + /* we need to signal error */ + sp->type = FT_REG; + DMSG2(ctx, DERROR, "Invalid file type: %c for %s\n", type, fname.c_str()); + JMSG2(ctx, M_ERROR, "Invalid file type: %c for %s\n", type, fname.c_str()); } - DMSG6(ctx, DINFO, "STAT:%c size:%lld uid:%d gid:%d mode:%06o nl:%d\n", type, size, uid, gid, perms, nlinks); + DMSG4(ctx, DINFO, "STAT:%c size:%lld uid:%d gid:%d\n", type, size, uid, gid); + DMSG3(ctx, DINFO, " mode:%06o nl:%d fi:%d\n", perms, nlinks, nfi); reqparams--; continue; } @@ -2051,6 +2086,8 @@ bRC METAPLUGIN::startBackupFile(bpContext *ctx, struct save_pkt *sp) sp->statp.st_blksize = 4096; sp->statp.st_blocks = size / 4096 + 1; + // DMSG1(ctx, DVDEBUG, "sp->plug_meta = %p\n", sp->plug_meta); + return bRC_OK; } diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.h b/bacula/src/plugins/fd/pluginlib/metaplugin.h index 6b895ca10..6dd09b380 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.h +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.h @@ -186,6 +186,7 @@ private: bRC perform_read_xattr(bpContext *ctx); bRC perform_write_xattr(bpContext *ctx, struct xacl_pkt * xacl); bRC perform_read_metadata_info(bpContext *ctx, metadata_type type, struct save_pkt *sp); + bRC perform_file_index_query(bpContext *ctx); // bRC perform_write_metadata_info(bpContext *ctx, struct meta_pkt *mp); metadata_type scan_metadata_type(const POOL_MEM &cmd); const char *prepare_metadata_type(metadata_type type); diff --git a/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c b/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c index 456eab2ff..769d226e7 100644 --- a/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c +++ b/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c @@ -193,10 +193,23 @@ void signal_term(){ */ void perform_backup() { + // This is a test for FileIndex Query + snprintf(buf, BIGBUFLEN, "FileIndex\n"); + write_plugin('C', buf); + char firesponse[32] = {0}; // well the file index is int32_t so max 11 chars + read_plugin(firesponse); + int fileindex = atoi(firesponse); + snprintf(buf, BIGBUFLEN, "TEST05 - FileIndex query: %d", fileindex); + write_plugin('I', buf); + + // here we store the linked.file origin fname + char fileindex_link[256]; + snprintf(fileindex_link, 256, "%s/bucket/%d/vm1.iso", PLUGINPREFIX, mypid); + // Backup Loop - snprintf(buf, BIGBUFLEN, "FNAME:%s/bucket/%d/vm1.iso\n", PLUGINPREFIX, mypid); + snprintf(buf, BIGBUFLEN, "FNAME:%s\n", fileindex_link); // we use it here write_plugin('C', buf); - write_plugin('C', "STAT:F 1048576 100 100 100640 1\n"); + write_plugin('C', "STAT:F 1048576 100 100 100640 2\n"); // this will be the first file hardlinked write_plugin('C', "TSTAMP:1504271937 1504271937 1504271937\n"); write_plugin('I', "TEST5"); signal_eod(); @@ -215,8 +228,7 @@ void perform_backup() write_plugin('I', "TEST5Acl"); signal_eod(); - if (regress_error_backup_no_files) - { + if (regress_error_backup_no_files) { write_plugin('E', "No files found for pattern container1/otherobject\n"); signal_eod(); return; @@ -454,6 +466,16 @@ void perform_backup() signal_eod(); } + snprintf(buf, BIGBUFLEN, "FNAME:%s/office/%d/linked.file\n", PLUGINPREFIX, mypid); + write_plugin('C', buf); + snprintf(buf, BIGBUFLEN, "STAT:L 10240 100 100 040755 2 %d\n", fileindex); + write_plugin('C', buf); + write_plugin('C', "TSTAMP:1504271937 1504271937 1504271937\n"); + snprintf(buf, BIGBUFLEN, "LSTAT:%s\n", fileindex_link); + write_plugin('C', buf); + signal_eod(); + signal_eod(); + /* this is the end of all data */ signal_eod(); }