Implement a string_printf utility function.
[cumulus.git] / main.cc
diff --git a/main.cc b/main.cc
index ef8f2d7..5ac0f8c 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -292,9 +292,8 @@ int64_t dumpfile(int fd, dictionary &file_info, const string &path,
                     if (object_group == 0) {
                         o->set_group("data");
                     } else {
-                        char group[32];
-                        sprintf(group, "compacted-%d", object_group);
-                        o->set_group(group);
+                        o->set_group(string_printf("compacted-%d",
+                                                   object_group));
                     }
                     if (status == NULL)
                         status = "partial";
@@ -860,8 +859,12 @@ int main(int argc, char *argv[])
     std::set<string> segment_list = db->GetUsedSegments();
     for (std::set<string>::iterator i = segment_list.begin();
          i != segment_list.end(); ++i) {
-        string seg_path, seg_csum;
-        if (db->GetSegmentMetadata(*i, &seg_path, &seg_csum)) {
+        map<string, string> segment_metadata = db->GetSegmentMetadata(*i);
+        if (segment_metadata.count("path")
+            && segment_metadata.count("checksum"))
+        {
+            string seg_path = segment_metadata["path"];
+            string seg_csum = segment_metadata["checksum"];
             const char *raw_checksum = NULL;
             if (strncmp(seg_csum.c_str(), csum_type,
                         strlen(csum_type)) == 0) {
@@ -888,6 +891,36 @@ int main(int argc, char *argv[])
 
     checksum_file->send();
 
+    /* Write out a summary file with metadata for all the segments in this
+     * snapshot (can be used to reconstruct database contents if needed). */
+    string dbmeta_filename = "snapshot-";
+    if (backup_scheme.size() > 0)
+        dbmeta_filename += backup_scheme + "-";
+    dbmeta_filename += timestamp + ".meta";
+    RemoteFile *dbmeta_file = remote->alloc_file(dbmeta_filename,
+                                                   "meta");
+    FILE *dbmeta = fdopen(dbmeta_file->get_fd(), "w");
+
+    for (std::set<string>::iterator i = segment_list.begin();
+         i != segment_list.end(); ++i) {
+        map<string, string> segment_metadata = db->GetSegmentMetadata(*i);
+        if (segment_metadata.size() > 0) {
+            map<string, string>::const_iterator j;
+            for (j = segment_metadata.begin();
+                 j != segment_metadata.end(); ++j)
+            {
+                fprintf(dbmeta, "%s: %s\n",
+                        j->first.c_str(), j->second.c_str());
+            }
+            fprintf(dbmeta, "\n");
+        }
+    }
+    fclose(dbmeta);
+
+    string dbmeta_csum
+        = Hash::hash_file(dbmeta_file->get_local_path().c_str());
+    dbmeta_file->send();
+
     db->Close();
 
     /* All other files should be flushed to remote storage before writing the
@@ -930,6 +963,10 @@ int main(int argc, char *argv[])
         fprintf(descriptor, "Scheme: %s\n", backup_scheme.c_str());
     fprintf(descriptor, "Root: %s\n", backup_root.c_str());
 
+    if (dbmeta_csum.size() > 0) {
+        fprintf(descriptor, "Database-state: %s\n", dbmeta_csum.c_str());
+    }
+
     if (csum.size() > 0) {
         fprintf(descriptor, "Checksums: %s\n", csum.c_str());
     }