]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
metaplugin: Add hardlink support to protocol.
authorRadosław Korzeniewski <radoslaw@korzeniewski.net>
Tue, 16 Mar 2021 12:43:32 +0000 (13:43 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:00 +0000 (09:03 +0100)
bacula/src/plugins/fd/pluginlib/metaplugin.cpp
bacula/src/plugins/fd/pluginlib/metaplugin.h
bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c

index 02fef06b1d9c92089aa075e010584aee4514e27f..cdca3120e5347526f05808dc2e5961aae45a9cac 100644 (file)
@@ -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;
 }
 
index 6b895ca1009e5115824981a325611048019314a0..6dd09b38095a0009b4c8627556891b847ef9019f 100644 (file)
@@ -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);
index 456eab2ff51d2ec1154d7effbe976087b33bdd9f..769d226e71cfc2a527beb70212e7374bb5f673d6 100644 (file)
@@ -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();
 }