From mboxrd@z Thu Jan 1 00:00:00 1970 MIME-Version: 1.0 From: Ole-Hjalmar Kristensen Date: Tue, 12 Dec 2017 10:33:55 +0100 Message-ID: To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> Content-Type: multipart/alternative; boundary="94eb2c19c6389003cf056021598b" Subject: [9fans] A potentially useful venti client Topicbox-Message-UUID: c5fa7a88-ead9-11e9-9d60-3106f5b1d025 --94eb2c19c6389003cf056021598b Content-Type: text/plain; charset="UTF-8" Based on copy.c and readlist.c, I have cobbled together a venti client to copy a list of venti blocks from one venti server to another. I am thinking of using it to incrementally replicate the contents on one site site to another. It could even be used for two-way replication, since the CAS and deduplicating properties of venti ensures that you will never have write conflicts at a block level. I have tried it out by feeding it with the output from printarenas, and it seems to work reasonably well. Does anyone have any good ideas about how to incrementally extract the set of scores that has been added to a venti server? You could extract the whole set of scores and do a diff with an old set of course, but that's rather inefficient. Ole-Hj. #include #include #include #include #include enum { // XXX What to do here? VtMaxLumpSize = 65535, }; char *srchost; char *dsthost; Biobuf b; VtConn *zsrc; VtConn *zdst; uchar *buf; void run(Biobuf*); int nn; void usage(void) { fprint(2, "usage: copylist srchost dsthost list\n"); threadexitsall("usage"); } int parsescore(uchar *score, char *buf, int n) { int i, c; memset(score, 0, VtScoreSize); if(n != VtScoreSize*2){ werrstr("score wrong length %d", n); return -1; } for(i=0; i= '0' && buf[i] <= '9') c = buf[i] - '0'; else if(buf[i] >= 'a' && buf[i] <= 'f') c = buf[i] - 'a' + 10; else if(buf[i] >= 'A' && buf[i] <= 'F') c = buf[i] - 'A' + 10; else { c = buf[i]; werrstr("bad score char %d '%c'", c, c); return -1; } if((i & 1) == 0) c <<= 4; score[i>>1] |= c; } return 0; } void threadmain(int argc, char *argv[]) { int fd, i; ARGBEGIN{ default: usage(); break; }ARGEND if(argc < 2) usage(); fmtinstall('V', vtscorefmt); buf = vtmallocz(VtMaxLumpSize); srchost = argv[0]; zsrc = vtdial(srchost); if(zsrc == nil) sysfatal("could not dial src server: %r"); if(vtconnect(zsrc) < 0) sysfatal("vtconnect src: %r"); dsthost = argv[1]; zdst = vtdial(dsthost); if(zdst == nil) sysfatal("could not dial dst server: %r"); if(vtconnect(zdst) < 0) sysfatal("vtconnect dst: %r"); if(argc == 2){ Binit(&b, 0, OREAD); run(&b); }else{ for(i=2; i