Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#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;