Fossil SCM

Add the test-integrity command for verifying repository integrity. Also add an "all" version of this command.

drh 2010-12-23 18:18 trunk
Commit d56734549a258b3f70d5430801f8216683f93d8b
--- src/allrepo.c
+++ src/allrepo.c
@@ -103,10 +103,12 @@
103103
zCmd = "pull -autourl -R";
104104
}else if( strncmp(zCmd, "rebuild", n)==0 ){
105105
zCmd = "rebuild";
106106
}else if( strncmp(zCmd, "sync", n)==0 ){
107107
zCmd = "sync -autourl -R";
108
+ }else if( strncmp(zCmd, "test-integrity", n)==0 ){
109
+ zCmd = "test-integrity";
108110
}else if( strncmp(zCmd, "ignore", n)==0 ){
109111
int j;
110112
db_begin_transaction();
111113
for(j=3; j<g.argc; j++){
112114
db_multi_exec("DELETE FROM global_config WHERE name GLOB 'repo:%q'",
113115
--- src/allrepo.c
+++ src/allrepo.c
@@ -103,10 +103,12 @@
103 zCmd = "pull -autourl -R";
104 }else if( strncmp(zCmd, "rebuild", n)==0 ){
105 zCmd = "rebuild";
106 }else if( strncmp(zCmd, "sync", n)==0 ){
107 zCmd = "sync -autourl -R";
 
 
108 }else if( strncmp(zCmd, "ignore", n)==0 ){
109 int j;
110 db_begin_transaction();
111 for(j=3; j<g.argc; j++){
112 db_multi_exec("DELETE FROM global_config WHERE name GLOB 'repo:%q'",
113
--- src/allrepo.c
+++ src/allrepo.c
@@ -103,10 +103,12 @@
103 zCmd = "pull -autourl -R";
104 }else if( strncmp(zCmd, "rebuild", n)==0 ){
105 zCmd = "rebuild";
106 }else if( strncmp(zCmd, "sync", n)==0 ){
107 zCmd = "sync -autourl -R";
108 }else if( strncmp(zCmd, "test-integrity", n)==0 ){
109 zCmd = "test-integrity";
110 }else if( strncmp(zCmd, "ignore", n)==0 ){
111 int j;
112 db_begin_transaction();
113 for(j=3; j<g.argc; j++){
114 db_multi_exec("DELETE FROM global_config WHERE name GLOB 'repo:%q'",
115
--- src/content.c
+++ src/content.c
@@ -746,5 +746,47 @@
746746
void test_content_deltify_cmd(void){
747747
if( g.argc!=5 ) usage("RID SRCID FORCE");
748748
db_must_be_within_tree();
749749
content_deltify(atoi(g.argv[2]), atoi(g.argv[3]), atoi(g.argv[4]));
750750
}
751
+
752
+/*
753
+** COMMAND: test-integrity
754
+**
755
+** Verify that all content can be extracted from the BLOB table correctly.
756
+** If the BLOB table is correct, then the repository can always be
757
+** successfully reconstructed using "fossil rebuild".
758
+*/
759
+void test_integrity(void){
760
+ Stmt q;
761
+ Blob content;
762
+ Blob cksum;
763
+ int n1 = 0;
764
+ int n2 = 0;
765
+ db_find_and_open_repository(OPEN_ANY_SCHEMA, 2);
766
+ db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid");
767
+ while( db_step(&q)==SQLITE_ROW ){
768
+ int rid = db_column_int(&q, 0);
769
+ const char *zUuid = db_column_text(&q, 1);
770
+ int size = db_column_int(&q, 2);
771
+ n1++;
772
+ if( size<0 ){
773
+ printf("skip phantom %d %s\n", rid, zUuid);
774
+ continue; /* Ignore phantoms */
775
+ }
776
+ content_get(rid, &content);
777
+ if( blob_size(&content)!=size ){
778
+ fossil_fatal("size mismatch on blob rid=%d: %d vs %d",
779
+ rid, blob_size(&content), size);
780
+ }
781
+ sha1sum_blob(&content, &cksum);
782
+ if( strcmp(blob_str(&cksum), zUuid)!=0 ){
783
+ fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s",
784
+ rid, blob_str(&cksum), zUuid);
785
+ }
786
+ blob_reset(&cksum);
787
+ blob_reset(&content);
788
+ n2++;
789
+ }
790
+ db_finalize(&q);
791
+ printf("%d non-phantom blobs (out of %d total) verified\n", n2, n1);
792
+}
751793
--- src/content.c
+++ src/content.c
@@ -746,5 +746,47 @@
746 void test_content_deltify_cmd(void){
747 if( g.argc!=5 ) usage("RID SRCID FORCE");
748 db_must_be_within_tree();
749 content_deltify(atoi(g.argv[2]), atoi(g.argv[3]), atoi(g.argv[4]));
750 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
751
--- src/content.c
+++ src/content.c
@@ -746,5 +746,47 @@
746 void test_content_deltify_cmd(void){
747 if( g.argc!=5 ) usage("RID SRCID FORCE");
748 db_must_be_within_tree();
749 content_deltify(atoi(g.argv[2]), atoi(g.argv[3]), atoi(g.argv[4]));
750 }
751
752 /*
753 ** COMMAND: test-integrity
754 **
755 ** Verify that all content can be extracted from the BLOB table correctly.
756 ** If the BLOB table is correct, then the repository can always be
757 ** successfully reconstructed using "fossil rebuild".
758 */
759 void test_integrity(void){
760 Stmt q;
761 Blob content;
762 Blob cksum;
763 int n1 = 0;
764 int n2 = 0;
765 db_find_and_open_repository(OPEN_ANY_SCHEMA, 2);
766 db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid");
767 while( db_step(&q)==SQLITE_ROW ){
768 int rid = db_column_int(&q, 0);
769 const char *zUuid = db_column_text(&q, 1);
770 int size = db_column_int(&q, 2);
771 n1++;
772 if( size<0 ){
773 printf("skip phantom %d %s\n", rid, zUuid);
774 continue; /* Ignore phantoms */
775 }
776 content_get(rid, &content);
777 if( blob_size(&content)!=size ){
778 fossil_fatal("size mismatch on blob rid=%d: %d vs %d",
779 rid, blob_size(&content), size);
780 }
781 sha1sum_blob(&content, &cksum);
782 if( strcmp(blob_str(&cksum), zUuid)!=0 ){
783 fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s",
784 rid, blob_str(&cksum), zUuid);
785 }
786 blob_reset(&cksum);
787 blob_reset(&content);
788 n2++;
789 }
790 db_finalize(&q);
791 printf("%d non-phantom blobs (out of %d total) verified\n", n2, n1);
792 }
793

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button