chiark / gitweb /
Commit 2.4.5-5 as unpacked
[innduct.git] / storage / ovdb / ovdb-private.h
1 #ifdef USE_BERKELEY_DB
2
3 #include <db.h>
4
5 #if DB_VERSION_MAJOR == 2
6 #if DB_VERSION_MINOR < 6
7 #error "Need BerkeleyDB 2.6.x, 2.7.x, 3.x or 4.x"
8 #endif
9 #else
10 #if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR > 4
11 #error "Need BerkeleyDB 2.6.x, 2.7.x, 3.x or 4.x"
12 #endif
13 #endif
14
15 /*
16  * How data is stored:
17  *
18  * Each group is assigned an integer ID.  The mapping between a group name
19  * and its ID is stored in the groupinfo DB.  Overview data itself
20  * is stored in one or more btree DBs.  The specific DB file that is used
21  * to store data for a certain group is chosen by taking the hash of the
22  * group name, copying the first bytes of the hash into an int, and then
23  * modding the int value to the number of DBs.
24  *
25  * Each group has one groupinfo structure in the groupinfo DB, whose key
26  * is the newsgroup name.  The overview records for the group have a
27  * 'struct datakey' as their keys, which consists of the group ID (in
28  * native byteorder) followed by the article number in network byteorder.
29  * The reason for storing the article number in net byte order (big-endian)
30  * is that the keys will sort correctly using BerkeleyDB's default sort
31  * function (basically, a memcmp).
32  *
33  * The overview records consist of a 'struct ovdata' followed by the actual
34  * overview data.  The struct ovdata contains the token and arrival time.
35  */ 
36
37 struct ovdb_conf {
38     char *home;         /* path to directory where db files are stored */
39     int  txn_nosync;    /* whether to pass DB_TXN_NOSYNC to db_appinit */
40     int  numdbfiles;
41     size_t cachesize;
42     size_t pagesize;
43     int minkey;
44     int maxlocks;
45     int nocompact;
46     int readserver;
47     int numrsprocs;
48     int maxrsconn;
49     int useshm;
50     int shmkey;
51 };
52
53 typedef u_int32_t group_id_t;
54
55 struct groupinfo {
56     ARTNUM     low;
57     ARTNUM     high;
58     int        count;
59     int        flag;
60     time_t     expired;         /* when this group was last touched by expiregroup */
61     group_id_t current_gid;     /* group ID */
62     group_id_t new_gid;         /* pending ID (expireover) */
63     int        current_db;      /* which DB file the records are in */
64     int        new_db;          /* pending DB file */
65     pid_t      expiregrouppid;  /* PID of expireover process */
66     int        status;
67 };
68 #define GROUPINFO_DELETED    1
69 #define GROUPINFO_EXPIRING   (1<<1)
70 #define GROUPINFO_MOVING     (1<<2)
71 #define GROUPINFO_MOVE_REQUESTED (1<<3) /*NYI*/
72
73 struct datakey {
74     group_id_t groupnum;        /* must be the first member of this struct */
75     u_int32_t artnum;
76 };
77
78 struct ovdata {
79     TOKEN token;
80     time_t arrived;
81     time_t expires;
82 };
83
84
85 #define DATA_VERSION 2
86
87 extern struct ovdb_conf ovdb_conf;
88 extern DB_ENV *OVDBenv;
89
90 #define OVDB_ERR_NONE   0
91 #define OVDB_ERR_SYSLOG 1       /* default */
92 #define OVDB_ERR_STDERR 2
93 extern int ovdb_errmode;
94
95 void read_ovdb_conf(void);
96 int ovdb_open_berkeleydb(int mode, int flags);
97 void ovdb_close_berkeleydb(void);
98 int ovdb_getgroupinfo(char *group, struct groupinfo *gi, int ignoredeleted, DB_TXN *tid, int getflags);
99
100 #define OVDB_RECOVER    1
101 #define OVDB_UPGRADE    2
102
103 #define OVDB_LOCK_NORMAL 0
104 #define OVDB_LOCK_ADMIN 1
105 #define OVDB_LOCK_EXCLUSIVE 2
106
107 bool ovdb_getlock(int mode);
108 bool ovdb_releaselock(void);
109 bool ovdb_check_pidfile(char *file);
110 bool ovdb_check_user(void);
111
112 #define OVDB_LOCKFN "ovdb.sem"
113 #define OVDB_MONITOR_PIDFILE "ovdb_monitor.pid"
114 #define OVDB_SERVER_PIDFILE "ovdb_server.pid"
115 #define SPACES "                "
116
117 /* read server stuff */
118 #define CMD_QUIT        0x01
119 #define CMD_GROUPSTATS  0x02
120 #define CMD_OPENSRCH    0x03
121 #define CMD_SRCH        0x04
122 #define CMD_CLOSESRCH   0x05
123 #define CMD_ARTINFO     0x06
124 #define CMD_MASK        0x0F
125 #define RPLY_OK         0x00
126 #define RPLY_ERROR      0x10
127 #define OVDB_SERVER     (1<<4)
128 #define OVDB_SERVER_BANNER "ovdb read protocol 1"
129 #define OVDB_SERVER_PORT 32323  /* only used if don't have unix domain sockets */
130 #define OVDB_SERVER_SOCKET "ovdb.server"
131
132 struct rs_cmd {
133     uint32_t    what;
134     uint32_t    grouplen;
135     uint32_t    artlo;
136     uint32_t    arthi;
137     void *      handle;
138 };
139
140 struct rs_groupstats {
141     uint32_t    status;
142     int         lo;
143     int         hi;
144     int         count;
145     int         flag;
146     uint32_t    aliaslen;
147     /* char alias */
148 };
149
150 struct rs_opensrch {
151     uint32_t    status;
152     void *      handle;
153 };
154
155 struct rs_srch {
156     uint32_t    status;
157     ARTNUM      artnum;
158     TOKEN       token;
159     time_t      arrived;
160     int         len;
161     /* char data */
162 };
163
164 struct rs_artinfo {
165     uint32_t    status;
166     TOKEN       token;
167 };
168
169
170 #if DB_VERSION_MAJOR == 2
171 char *db_strerror(int err);
172
173 #define TXN_START(label, tid) \
174 label: { \
175   int txn_ret; \
176   txn_ret = txn_begin(OVDBenv->tx_info, NULL, &tid); \
177   if (txn_ret != 0) { \
178     syslog(L_ERROR, "OVDB: " #label " txn_begin: %s", db_strerror(ret)); \
179     tid = NULL; \
180   } \
181 }
182
183 #define TXN_RETRY(label, tid) \
184 { txn_abort(tid); goto label; }
185
186 #define TXN_ABORT(label, tid) txn_abort(tid)
187 #define TXN_COMMIT(label, tid) txn_commit(tid)
188
189 #define TRYAGAIN EAGAIN
190
191 #elif DB_VERSION_MAJOR == 3
192
193 #define TXN_START(label, tid) \
194 label: { \
195   int txn_ret; \
196   txn_ret = txn_begin(OVDBenv, NULL, &tid, 0); \
197   if (txn_ret != 0) { \
198     syslog(L_ERROR, "OVDB: " #label " txn_begin: %s", db_strerror(ret)); \
199     tid = NULL; \
200   } \
201 }
202
203 #define TXN_RETRY(label, tid) \
204 { txn_abort(tid); goto label; }
205
206 #define TXN_ABORT(label, tid) txn_abort(tid)
207 #define TXN_COMMIT(label, tid) txn_commit(tid, 0)
208
209 #define TRYAGAIN DB_LOCK_DEADLOCK
210
211 #else /* DB_VERSION_MAJOR == 4 */
212
213 #define TXN_START(label, tid) \
214 label: { \
215   int txn_ret; \
216   txn_ret = OVDBenv->txn_begin(OVDBenv, NULL, &tid, 0); \
217   if (txn_ret != 0) { \
218     syslog(L_ERROR, "OVDB: " #label " txn_begin: %s", db_strerror(ret)); \
219     tid = NULL; \
220   } \
221 }
222
223 #define TXN_RETRY(label, tid) \
224 { (tid)->abort(tid); goto label; }
225
226 #define TXN_ABORT(label, tid) (tid)->abort(tid)
227 #define TXN_COMMIT(label, tid) (tid)->commit(tid, 0)
228
229 #define TRYAGAIN DB_LOCK_DEADLOCK
230
231 #endif /* DB_VERSION_MAJOR == 4 */
232
233 #endif /* USE_BERKELEY_DB */