void writethread(void *v) { WriteReq wr; char err[ERRMAX]; USED(v); while(recv(writechan, &wr) == 1){ nrecv++; if(wr.p == nil) break; if(fastwrites && vtread(z, wr.score, wr.type, nil, 0) < 0){ rerrstr(err, sizeof err); if(strstr(err, "read too small")){ /* already exists */ nskip++; packetfree(wr.p); continue; } } if(vtwritepacket(z, wr.score, wr.type, wr.p) < 0) sysfatal("vtwritepacket: %r"); packetfree(wr.p); } }
void threadmain(int argc, char *argv[]) { int i, n; unsigned char score[VtScoreSize]; unsigned char *buf; VtConn *z; char *host; VtRoot root; fmtinstall('F', vtfcallfmt); fmtinstall('V', vtscorefmt); quotefmtinstall(); host = nil; ARGBEGIN{ case 'h': host = EARGF(usage()); break; default: usage(); break; }ARGEND if(argc == 0) usage(); buf = vtmallocz(VtMaxLumpSize); z = vtdial(host); if(z == nil) sysfatal("could not connect to server: %r"); if(vtconnect(z) < 0) sysfatal("vtconnect: %r"); for(i=0; i<argc; i++){ if(vtparsescore(argv[i], nil, score) < 0){ fprint(2, "cannot parse score '%s': %r\n", argv[i]); continue; } n = vtread(z, score, VtRootType, buf, VtMaxLumpSize); if(n < 0){ fprint(2, "could not read block %V: %r\n", score); continue; } if(n != VtRootSize){ fprint(2, "block %V is wrong size %d != 300\n", score, n); continue; } if(vtrootunpack(&root, buf) < 0){ fprint(2, "unpacking block %V: %r\n", score); continue; } print("%V: %q %q %V %d %V\n", score, root.name, root.type, root.score, root.blocksize, root.prev); } vthangup(z); threadexitsall(0); }
void rd(char *buf, char *buf2) { uint8_t score[VtScoreSize]; DigestState ds; memset(&ds, 0, sizeof ds); sha1((uint8_t*)buf, blocksize, score, &ds); if(vtread(z, score, VtDataType, (uint8_t*)buf2, blocksize) < 0) sysfatal("vtread %V at %,lld: %r", score, cur); if(memcmp(buf, buf2, blocksize) != 0) sysfatal("bad data read! %V", score); }
Tnode* initxvacroot(uchar score[VtScoreSize]) { Tnode *t; uchar buf[VtRootSize]; int n; if((n = vtread(z, score, VtRootType, buf, VtRootSize)) < 0) return stringnode("reading root %V: %r", score); if(vtrootunpack(&vac, buf) < 0) return stringnode("unpack %d-byte root: %r", n); h.blockSize = vac.blocksize; t = stringnode("vac version=%#ux name=%s type=%s blocksize=%lud score=%V prev=%V", VtRootVersion, vac.name, vac.type, vac.blocksize, vac.score, vac.prev); t->expand = xvacrootexpand; return t; }
Block* ventiBlock(uchar score[VtScoreSize], uint type) { int n; Block *b; b = allocBlock(); memmove(b->score, score, VtScoreSize); b->addr = NilBlock; n = vtread(z, b->score, vtType[type], b->data, h.blockSize); if(n < 0) { fprint(2, "vtread returns %d: %r\n", n); blockPut(b); return nil; } vtzeroextend(vtType[type], b->data, n, h.blockSize); b->l.type = type; b->l.state = 0; b->l.tag = 0; b->l.epoch = 0; return b; }
void walk(uint8_t score[VtScoreSize], uint type, int base) { int i, n; uint8_t *buf; uint8_t nscore[VtScoreSize]; VtEntry e; VtRoot root; if(memcmp(score, vtzeroscore, VtScoreSize) == 0 || memcmp(score, zeroscore, VtScoreSize) == 0) return; if(havevisited(score, type)){ nskip++; return; } buf = vtmallocz(VtMaxLumpSize); if(fast && vtread(zdst, score, type, buf, VtMaxLumpSize) >= 0){ if(verbose) fprint(2, "skip %V\n", score); free(buf); return; } n = vtread(zsrc, score, type, buf, VtMaxLumpSize); if(n < 0){ if(rewrite){ changes++; memmove(score, vtzeroscore, VtScoreSize); }else if(!ignoreerrors) sysfatal("reading block %V (type %d): %r", score, type); return; } switch(type){ case VtRootType: if(vtrootunpack(&root, buf) < 0){ fprint(2, "warning: could not unpack root in %V %d\n", score, type); break; } walk(root.prev, VtRootType, 0); walk(root.score, VtDirType, 0); if(rewrite) vtrootpack(&root, buf); /* walk might have changed score */ break; case VtDirType: for(i=0; i*VtEntrySize<n; i++){ if(vtentryunpack(&e, buf, i) < 0){ fprint(2, "warning: could not unpack entry #%d in %V %d\n", i, score, type); continue; } if(!(e.flags & VtEntryActive)) continue; walk(e.score, e.type, e.type&VtTypeBaseMask); /* * Don't repack unless we're rewriting -- some old * vac files have psize==0 and dsize==0, and these * get rewritten by vtentryunpack to have less strange * block sizes. So vtentryunpack; vtentrypack does not * guarantee to preserve the exact bytes in buf. */ if(rewrite) vtentrypack(&e, buf, i); } break; case VtDataType: break; default: /* pointers */ for(i=0; i<n; i+=VtScoreSize) if(memcmp(buf+i, vtzeroscore, VtScoreSize) != 0) walk(buf+i, type-1, base); break; } nwrite++; if(vtwrite(zdst, nscore, type, buf, n) < 0){ /* figure out score for better error message */ /* can't use input argument - might have changed contents */ n = vtzerotruncate(type, buf, n); sha1(buf, n, score, nil); sysfatal("writing block %V (type %d): %r", score, type); } if(!rewrite && memcmp(score, nscore, VtScoreSize) != 0){ fprint(2, "not rewriting: wrote %V got %V\n", score, nscore); abort(); sysfatal("not rewriting: wrote %V got %V", score, nscore); } markvisited(score, type); free(buf); }
void main(int argc, char *argv[]) { int type, n; unsigned char score[VtScoreSize]; unsigned char *buf; char *prefix; fmtinstall('F', vtfcallfmt); fmtinstall('V', vtscorefmt); type = -1; ARGBEGIN{ case 'V': chattyventi++; break; case 'f': fast = 1; break; case 'i': if(rewrite) usage(); ignoreerrors = 1; break; case 'm': scoretree = mkavltree(scoretreecmp); break; case 'r': if(ignoreerrors) usage(); rewrite = 1; break; case 't': type = atoi(EARGF(usage())); break; case 'v': verbose = 1; break; default: usage(); break; }ARGEND if(argc != 3) usage(); if(vtparsescore(argv[2], &prefix, score) < 0) sysfatal("could not parse score: %r"); buf = vtmallocz(VtMaxLumpSize); zsrc = vtdial(argv[0]); if(zsrc == nil) sysfatal("could not dial src server: %r"); if(vtconnect(zsrc) < 0) sysfatal("vtconnect src: %r"); zdst = vtdial(argv[1]); if(zdst == nil) sysfatal("could not dial dst server: %r"); if(vtconnect(zdst) < 0) sysfatal("vtconnect dst: %r"); if(type != -1){ n = vtread(zsrc, score, type, buf, VtMaxLumpSize); if(n < 0) sysfatal("could not read block: %r"); }else{ for(type=0; type<VtMaxType; type++){ n = vtread(zsrc, score, type, buf, VtMaxLumpSize); if(n >= 0) break; } if(type == VtMaxType) sysfatal("could not find block %V of any type", score); } walk(score, type, VtDirType); if(changes) print("%s:%V (%d pointers rewritten)\n", prefix, score, changes); if(verbose) print("%d skipped, %d written\n", nskip, nwrite); if(vtsync(zdst) < 0) sysfatal("could not sync dst server: %r"); exits(0); }
void threadmain(int argc, char *argv[]) { int type, n; uchar score[VtScoreSize]; uchar *buf; VtConn *z; char *host; fmtinstall('F', vtfcallfmt); fmtinstall('V', vtscorefmt); host = nil; type = -1; ARGBEGIN{ case 'h': host = EARGF(usage()); break; case 't': type = atoi(EARGF(usage())); break; default: usage(); break; }ARGEND if(argc != 1) usage(); if(vtparsescore(argv[0], nil, score) < 0) sysfatal("could not parse score '%s': %r", argv[0]); buf = vtmallocz(VtMaxLumpSize); z = vtdial(host); if(z == nil) sysfatal("could not connect to server: %r"); if(vtconnect(z) < 0) sysfatal("vtconnect: %r"); if(type == -1){ n = -1; for(type=0; type<VtMaxType; type++){ n = vtread(z, score, type, buf, VtMaxLumpSize); if(n >= 0){ fprint(2, "venti/read%s%s %V %d\n", host ? " -h" : "", host ? host : "", score, type); break; } } }else n = vtread(z, score, type, buf, VtMaxLumpSize); vthangup(z); if(n < 0) sysfatal("could not read block: %r"); if(write(1, buf, n) != n) sysfatal("write: %r"); threadexitsall(0); }
void threadmain(int argc, char *argv[]) { int n; uchar score[VtScoreSize]; uchar *buf; char *host, *type; vlong off; VtEntry e; VtRoot root; VtCache *c; VtConn *z; VtFile *f; quotefmtinstall(); fmtinstall('F', vtfcallfmt); fmtinstall('V', vtscorefmt); host = nil; ARGBEGIN{ case 'V': chattyventi++; break; case 'h': host = EARGF(usage()); break; case 'v': chatty++; break; default: usage(); break; }ARGEND if(argc != 1) usage(); type = nil; if(vtparsescore(argv[0], &type, score) < 0) sysfatal("could not parse score '%s': %r", argv[0]); if(type == nil || strcmp(type, "file") != 0) sysfatal("bad score - not file:..."); buf = vtmallocz(VtMaxLumpSize); z = vtdial(host); if(z == nil) sysfatal("could not connect to server: %r"); if(vtconnect(z) < 0) sysfatal("vtconnect: %r"); // root block ... n = vtread(z, score, VtRootType, buf, VtMaxLumpSize); if(n < 0) sysfatal("could not read root %V: %r", score); if(n != VtRootSize) sysfatal("root block %V is wrong size %d != %d", score, n, VtRootSize); if(vtrootunpack(&root, buf) < 0) sysfatal("unpacking root block %V: %r", score); if(strcmp(root.type, "file") != 0) sysfatal("bad root type %q (not 'file')", root.type); if(chatty) fprint(2, "%V: %q %q %V %d %V\n", score, root.name, root.type, root.score, root.blocksize, root.prev); // ... points at entry block n = vtread(z, root.score, VtDirType, buf, VtMaxLumpSize); if(n < 0) sysfatal("could not read entry %V: %r", root.score); if(n != VtEntrySize) sysfatal("dir block %V is wrong size %d != %d", root.score, n, VtEntrySize); if(vtentryunpack(&e, buf, 0) < 0) sysfatal("unpacking dir block %V: %r", root.score); if((e.type&VtTypeBaseMask) != VtDataType) sysfatal("not a single file"); // open and read file c = vtcachealloc(z, root.blocksize*32); if(c == nil) sysfatal("vtcachealloc: %r"); f = vtfileopenroot(c, &e); if(f == nil) sysfatal("vtfileopenroot: %r"); off = 0; vtfilelock(f, VtOREAD); while((n = vtfileread(f, buf, VtMaxLumpSize, off)) > 0){ write(1, buf, n); off += n; } threadexitsall(0); }