#pragma lib "libventi.a" #pragma src "/sys/src/libventi" /* XXX should be own library? */ /* * Packets */ enum { MaxFragSize = 9*1024 }; typedef struct Packet Packet; #pragma incomplete Packet Packet* packetalloc(void); void packetappend(Packet*, uchar *buf, int n); uint packetasize(Packet*); int packetcmp(Packet*, Packet*); int packetcompact(Packet*); void packetconcat(Packet*, Packet*); int packetconsume(Packet*, uchar *buf, int n); int packetcopy(Packet*, uchar *buf, int offset, int n); Packet* packetdup(Packet*, int offset, int n); Packet* packetforeign(uchar *buf, int n, void (*free)(void *a), void *a); int packetfragments(Packet*, IOchunk*, int nio, int offset); void packetfree(Packet*); uchar* packetheader(Packet*, int n); uchar* packetpeek(Packet*, uchar *buf, int offset, int n); void packetprefix(Packet*, uchar *buf, int n); void packetsha1(Packet*, uchar sha1[20]); uint packetsize(Packet*); Packet* packetsplit(Packet*, int n); void packetstats(void); uchar* packettrailer(Packet*, int n); int packettrim(Packet*, int offset, int n); /* XXX should be own library? */ /* * Logging */ typedef struct VtLog VtLog; typedef struct VtLogChunk VtLogChunk; struct VtLog { VtLog *next; /* in hash table */ char *name; VtLogChunk *chunk; uint nchunk; VtLogChunk *w; QLock lk; int ref; }; struct VtLogChunk { char *p; char *ep; char *wp; }; VtLog* vtlogopen(char *name, uint size); void vtlogprint(VtLog *log, char *fmt, ...); void vtlog(char *name, char *fmt, ...); void vtlogclose(VtLog*); void vtlogremove(char *name); char** vtlognames(int*); void vtlogdump(int fd, VtLog*); /* XXX begin actual venti.h */ typedef struct VtFcall VtFcall; typedef struct VtConn VtConn; typedef struct VtEntry VtEntry; typedef struct VtRoot VtRoot; /* * Fundamental constants. */ enum { VtScoreSize = 20, VtMaxStringSize = 1024, VtMaxLumpSize = 56*1024, VtPointerDepth = 7 }; #define VtMaxFileSize ((1ULL<<48)-1) /* * Strings in packets. */ int vtputstring(Packet*, char*); int vtgetstring(Packet*, char**); /* * Block types. * * The initial Venti protocol had a much * less regular list of block types. * VtToDiskType converts from new to old. */ enum { VtDataType = 0<<3, /* VtDataType+1, ... */ VtDirType = 1<<3, /* VtDirType+1, ... */ VtRootType = 2<<3, VtMaxType, VtCorruptType = 0xFF, VtTypeDepthMask = 7, VtTypeBaseMask = ~VtTypeDepthMask }; /* convert to/from on-disk type numbers */ uint vttodisktype(uint); uint vtfromdisktype(uint); /* * VtEntry describes a Venti stream * * The _ enums are only used on the wire. * They are not present in the VtEntry structure * and should not be used by client programs. * (The info is in the type field.) */ enum { VtEntryActive = 1<<0, /* entry is in use */ _VtEntryDir = 1<<1, /* a directory */ _VtEntryDepthShift = 2, /* shift for pointer depth */ _VtEntryDepthMask = 7<<2, /* mask for pointer depth */ VtEntryLocal = 1<<5 /* for local storage only */ }; enum { VtEntrySize = 40 }; struct VtEntry { ulong gen; /* generation number */ ushort psize; /* pointer block size */ ushort dsize; /* data block size */ uchar type; uchar flags; uvlong size; uchar score[VtScoreSize]; }; void vtentrypack(VtEntry*, uchar*, int index); int vtentryunpack(VtEntry*, uchar*, int index); struct VtRoot { char name[128]; char type[128]; uchar score[VtScoreSize]; /* to a Dir block */ ushort blocksize; /* maximum block size */ uchar prev[VtScoreSize]; /* last root block */ }; enum { VtRootSize = 300, VtRootVersion = 2 }; void vtrootpack(VtRoot*, uchar*); int vtrootunpack(VtRoot*, uchar*); /* * score of zero length block */ extern uchar vtzeroscore[VtScoreSize]; /* * zero extend and truncate blocks */ void vtzeroextend(int type, uchar *buf, uint n, uint nn); uint vtzerotruncate(int type, uchar *buf, uint n); /* * parse score: mungs s */ int vtparsescore(char *s, char **prefix, uchar[VtScoreSize]); /* * formatting * other than noted, these formats all ignore * the width and precision arguments, and all flags * * V a venti score */ #pragma varargck type "V" uchar* #pragma varargck type "F" VtFcall* #pragma varargck type "T" void #pragma varargck type "lT" void int vtscorefmt(Fmt*); /* * error-checking malloc et al. */ void vtfree(void *); void* vtmalloc(int); void* vtmallocz(int); void* vtrealloc(void *p, int); void* vtbrk(int n); char* vtstrdup(char *); /* * Venti protocol */ /* * Crypto strengths */ enum { VtCryptoStrengthNone, VtCryptoStrengthAuth, VtCryptoStrengthWeak, VtCryptoStrengthStrong }; /* * Crypto suites */ enum { VtCryptoNone, VtCryptoSSL3, VtCryptoTLS1, VtCryptoMax }; /* * Codecs */ enum { VtCodecNone, VtCodecDeflate, VtCodecThwack, VtCodecMax }; enum { VtRerror = 1, VtTping = 2, VtRping, VtThello = 4, VtRhello, VtTgoodbye = 6, VtRgoodbye, /* not used */ VtTauth0 = 8, VtRauth0, VtTauth1 = 10, VtRauth1, VtTread = 12, VtRread, VtTwrite = 14, VtRwrite, VtTsync = 16, VtRsync, VtTmax }; struct VtFcall { uchar msgtype; uchar tag; char *error; /* Rerror */ char *version; /* Thello */ char *uid; /* Thello */ uchar strength; /* Thello */ uchar *crypto; /* Thello */ uint ncrypto; /* Thello */ uchar *codec; /* Thello */ uint ncodec; /* Thello */ char *sid; /* Rhello */ uchar rcrypto; /* Rhello */ uchar rcodec; /* Rhello */ uchar *auth; /* TauthX, RauthX */ uint nauth; /* TauthX, RauthX */ uchar score[VtScoreSize]; /* Tread, Rwrite */ uchar blocktype; /* Tread, Twrite */ ushort count; /* Tread */ Packet *data; /* Rread, Twrite */ }; Packet* vtfcallpack(VtFcall*); int vtfcallunpack(VtFcall*, Packet*); void vtfcallclear(VtFcall*); int vtfcallfmt(Fmt*); enum { VtStateAlloc, VtStateConnected, VtStateClosed }; struct VtConn { QLock lk; QLock inlk; QLock outlk; int debug; int infd; int outfd; int muxer; void *writeq; void *readq; int state; void *wait[256]; uint ntag; uint nsleep; Packet *part; Rendez tagrend; Rendez rpcfork; char *version; char *uid; char *sid; char addr[256]; /* address of other side */ }; VtConn* vtconn(int infd, int outfd); VtConn* vtdial(char*); void vtfreeconn(VtConn*); int vtsend(VtConn*, Packet*); Packet* vtrecv(VtConn*); int vtversion(VtConn* z); void vtdebug(VtConn* z, char*, ...); void vthangup(VtConn* z); int vtgoodbye(VtConn* z); /* #pragma varargck argpos vtdebug 2 */ /* server */ typedef struct VtSrv VtSrv; #pragma incomplete VtSrv typedef struct VtReq VtReq; struct VtReq { VtFcall tx; VtFcall rx; /* private */ VtSrv *srv; void *sc; }; int vtsrvhello(VtConn*); VtSrv* vtlisten(char *addr); VtReq* vtgetreq(VtSrv*); void vtrespond(VtReq*); /* client */ Packet* vtrpc(VtConn*, Packet*); Packet* _vtrpc(VtConn*, Packet*, VtFcall*); void vtrecvproc(void*); /* VtConn */ void vtsendproc(void*); /* VtConn */ int vtconnect(VtConn*); int vthello(VtConn*); int vtread(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n); int vtwrite(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n); Packet* vtreadpacket(VtConn*, uchar score[VtScoreSize], uint type, int n); int vtwritepacket(VtConn*, uchar score[VtScoreSize], uint type, Packet *p); int vtsync(VtConn*); int vtping(VtConn*); /* * Data blocks and block cache. */ enum { NilBlock = ~0 }; typedef struct VtBlock VtBlock; typedef struct VtCache VtCache; #pragma incomplete VtCache struct VtBlock { VtCache *c; QLock lk; uchar *data; uchar score[VtScoreSize]; uchar type; /* BtXXX */ /* internal to cache */ int nlock; int iostate; int ref; u32int heap; VtBlock *next; VtBlock **prev; u32int used; u32int used2; u32int addr; uintptr pc; }; u32int vtglobaltolocal(uchar[VtScoreSize]); void vtlocaltoglobal(u32int, uchar[VtScoreSize]); VtCache*vtcachealloc(VtConn*, int blocksize, ulong nblocks); void vtcachefree(VtCache*); VtBlock*vtcachelocal(VtCache*, u32int addr, int type); VtBlock*vtcacheglobal(VtCache*, uchar[VtScoreSize], int type); VtBlock*vtcacheallocblock(VtCache*, int type); void vtcachesetwrite(VtCache*, int(*)(VtConn*, uchar[VtScoreSize], uint, uchar*, int)); void vtblockput(VtBlock*); u32int vtcacheblocksize(VtCache*); int vtblockwrite(VtBlock*); VtBlock*vtblockcopy(VtBlock*); void vtblockduplock(VtBlock*); extern int vtcachencopy, vtcachenread, vtcachenwrite; extern int vttracelevel; /* * Hash tree file tree. */ typedef struct VtFile VtFile; struct VtFile { QLock lk; int ref; int local; VtBlock *b; /* block containing this file */ uchar score[VtScoreSize]; /* score of block containing this file */ /* immutable */ VtCache *c; int mode; u32int gen; int dsize; int psize; int dir; VtFile *parent; int epb; /* entries per block in parent */ u32int offset; /* entry offset in parent */ }; enum { VtOREAD, VtOWRITE, VtORDWR }; VtBlock*vtfileblock(VtFile*, u32int, int mode); int vtfileblockscore(VtFile*, u32int, uchar[VtScoreSize]); void vtfileclose(VtFile*); VtFile* _vtfilecreate(VtFile*, int offset, int psize, int dsize, int dir); VtFile* vtfilecreate(VtFile*, int psize, int dsize, int dir); VtFile* vtfilecreateroot(VtCache*, int psize, int dsize, int type); int vtfileflush(VtFile*); int vtfileflushbefore(VtFile*, u64int); u32int vtfilegetdirsize(VtFile*); int vtfilegetentry(VtFile*, VtEntry*); uvlong vtfilegetsize(VtFile*); void vtfileincref(VtFile*); int vtfilelock2(VtFile*, VtFile*, int); int vtfilelock(VtFile*, int); VtFile* vtfileopen(VtFile*, u32int, int); VtFile* vtfileopenroot(VtCache*, VtEntry*); long vtfileread(VtFile*, void*, long, vlong); int vtfileremove(VtFile*); int vtfilesetdirsize(VtFile*, u32int); int vtfilesetentry(VtFile*, VtEntry*); int vtfilesetsize(VtFile*, u64int); int vtfiletruncate(VtFile*); void vtfileunlock(VtFile*); long vtfilewrite(VtFile*, void*, long, vlong); int vttimefmt(Fmt*); extern int chattyventi; extern int ventidoublechecksha1; extern int ventilogging; extern char *VtServerLog;