Update arguments passed to upload script.
[cumulus.git] / metadata.cc
index a3323a1..2b5f12a 100644 (file)
@@ -12,6 +12,7 @@
 #include <map>
 
 #include "metadata.h"
+#include "localdb.h"
 #include "ref.h"
 #include "store.h"
 #include "util.h"
@@ -24,7 +25,12 @@ using std::ostringstream;
 
 static const size_t LBS_METADATA_BLOCK_SIZE = 65536;
 
+// If true, forces a full write of metadata: will not include pointers to
+// metadata in old snapshots.
+bool flag_full_metadata = false;
+
 /* TODO: Move to header file */
+extern LocalDb *db;
 void add_segment(const string& segment);
 
 /* Like strcmp, but sorts in the order that files will be visited in the
@@ -198,12 +204,13 @@ bool MetadataWriter::find(const string& path)
 }
 
 /* Does a file appear to be unchanged from the previous time it was backed up,
- * based on stat information?
- *
- * TODO: Notice files that were modified as they were being backed up the last
- * time. */
+ * based on stat information? */
 bool MetadataWriter::is_unchanged(const struct stat *stat_buf)
 {
+    if (old_metadata.find("volatile") != old_metadata.end()
+        && parse_int(old_metadata["volatile"]) != 0)
+        return false;
+
     if (old_metadata.find("ctime") == old_metadata.end())
         return false;
     if (stat_buf->st_ctime != parse_int(old_metadata["ctime"]))
@@ -268,6 +275,13 @@ void MetadataWriter::metadata_flush()
     ObjectReference indirect;
     for (list<MetadataItem>::iterator i = items.begin();
          i != items.end(); ++i) {
+        // If indirectly referencing any other metadata logs, be sure those
+        // segments are properly referenced.
+        if (i->reused) {
+            add_segment(i->ref.get_segment());
+            db->UseSegment(i->ref.get_segment(), 1.0);
+        }
+
         // Write out an indirect reference to any previous objects which could
         // be reused
         if (!i->reused || !indirect.merge(i->ref)) {
@@ -314,6 +328,7 @@ void MetadataWriter::metadata_flush()
     ObjectReference ref = meta->get_ref();
     metadata_root << "@" << ref.to_string() << "\n";
     add_segment(ref.get_segment());
+    db->UseSegment(ref.get_segment(), 1.0);
 
     delete meta;
 
@@ -342,7 +357,7 @@ void MetadataWriter::add(dictionary info)
     item.reused = false;
     item.text += encode_dict(info) + "\n";
 
-    if (info == old_metadata) {
+    if (info == old_metadata && !flag_full_metadata) {
         ObjectReference ref = ObjectReference::parse(old_metadata_loc);
         if (!ref.is_null()) {
             item.reused = true;
@@ -368,6 +383,7 @@ ObjectReference MetadataWriter::close()
     root->write(store);
     root->checksum();
     add_segment(root->get_ref().get_segment());
+    db->UseSegment(root->get_ref().get_segment(), 1.0);
 
     ObjectReference ref = root->get_ref();
     delete root;