]> git.ipfire.org Git - thirdparty/squid.git/blame - src/fs/diskd/diskd.cc
Merge in authentication bugfix for digest.
[thirdparty/squid.git] / src / fs / diskd / diskd.cc
CommitLineData
b95b6efb 1/*
62e76326 2 * $Id: diskd.cc,v 1.15 2003/02/21 22:50:40 robertc Exp $
b95b6efb 3 *
4 * DEBUG: section -- External DISKD process implementation.
5 * AUTHOR: Harvest Derived
6 *
2b6662ba 7 * SQUID Web Proxy Cache http://www.squid-cache.org/
b95b6efb 8 * ----------------------------------------------------------
9 *
2b6662ba 10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
b95b6efb 18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
2b6662ba 23 *
b95b6efb 24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
2b6662ba 28 *
b95b6efb 29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 *
33 */
cd748f27 34
35#include "config.h"
36#include "squid.h"
37
cd748f27 38#include <sys/ipc.h>
39#include <sys/msg.h>
40#include <sys/shm.h>
41
822b78b5 42#include "dio.h"
767e4890 43
cd748f27 44#undef assert
45#include <assert.h>
46
47
0ad82b7a 48#define DEBUG(LEVEL) if (LEVEL <= DebugLevel)
cd748f27 49
50typedef struct _file_state file_state;
51
62e76326 52struct _file_state
53{
cd748f27 54 void *key;
55 file_state *next;
56 int id;
57 int fd;
58 off_t offset;
59};
60
61static hash_table *hash = NULL;
62static pid_t mypid;
63static char *shmbuf;
9a8f2084 64static int DebugLevel = 0;
cd748f27 65
66static int
67do_open(diomsg * r, int len, const char *buf)
68{
69 int fd;
70 file_state *fs;
71 /*
72 * note r->offset holds open() flags
73 */
74 fd = open(buf, r->offset, 0600);
62e76326 75
cd748f27 76 if (fd < 0) {
62e76326 77 DEBUG(1) {
78 fprintf(stderr, "%d %s: ", (int) mypid, buf);
79 perror("open");
80 }
81
82 return -errno;
cd748f27 83 }
62e76326 84
e6ccf245 85 fs = (file_state *)xcalloc(1, sizeof(*fs));
cd748f27 86 fs->id = r->id;
87 fs->key = &fs->id; /* gack */
88 fs->fd = fd;
89 hash_join(hash, (hash_link *) fs);
9a8f2084 90 DEBUG(2)
62e76326 91 fprintf(stderr, "%d OPEN id %d, FD %d, fs %p\n",
92 (int) mypid,
93 fs->id,
94 fs->fd,
95 fs);
cd748f27 96 return fd;
97}
98
99static int
100do_close(diomsg * r, int len)
101{
102 int fd;
103 file_state *fs;
104 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 105
cd748f27 106 if (NULL == fs) {
62e76326 107 errno = EBADF;
108 DEBUG(1) {
109 fprintf(stderr, "%d CLOSE id %d: ", (int) mypid, r->id);
110 perror("do_close");
111 }
112
113 return -errno;
cd748f27 114 }
62e76326 115
cd748f27 116 fd = fs->fd;
117 hash_remove_link(hash, (hash_link *) fs);
9a8f2084 118 DEBUG(2)
62e76326 119 fprintf(stderr, "%d CLOSE id %d, FD %d, fs %p\n",
120 (int) mypid,
121 r->id,
122 fs->fd,
123 fs);
cd748f27 124 xfree(fs);
125 return close(fd);
126}
127
128static int
129do_read(diomsg * r, int len, char *buf)
130{
131 int x;
132 int readlen = r->size;
133 file_state *fs;
134 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 135
cd748f27 136 if (NULL == fs) {
62e76326 137 errno = EBADF;
138 DEBUG(1) {
139 fprintf(stderr, "%d READ id %d: ", (int) mypid, r->id);
140 perror("do_read");
141 }
142
143 return -errno;
cd748f27 144 }
62e76326 145
cd748f27 146 if (r->offset > -1 && r->offset != fs->offset) {
62e76326 147 DEBUG(2)
148 fprintf(stderr, "seeking to %d\n", r->offset);
149
150 if (lseek(fs->fd, r->offset, SEEK_SET) < 0) {
151 DEBUG(1) {
152 fprintf(stderr, "%d FD %d, offset %d: ", (int) mypid, fs->fd, r->offset);
153 perror("lseek");
154 }
155 }
cd748f27 156 }
62e76326 157
cd748f27 158 x = read(fs->fd, buf, readlen);
9a8f2084 159 DEBUG(2)
62e76326 160 fprintf(stderr, "%d READ %d,%d,%d ret %d\n", (int) mypid,
161 fs->fd, readlen, r->offset, x);
162
cd748f27 163 if (x < 0) {
62e76326 164 DEBUG(1) {
165 fprintf(stderr, "%d FD %d: ", (int) mypid, fs->fd);
166 perror("read");
167 }
168
169 return -errno;
cd748f27 170 }
62e76326 171
cd748f27 172 fs->offset = r->offset + x;
173 return x;
174}
175
176static int
177do_write(diomsg * r, int len, const char *buf)
178{
179 int wrtlen = r->size;
180 int x;
181 file_state *fs;
182 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 183
cd748f27 184 if (NULL == fs) {
62e76326 185 errno = EBADF;
186 DEBUG(1) {
187 fprintf(stderr, "%d WRITE id %d: ", (int) mypid, r->id);
188 perror("do_write");
189 }
190
191 return -errno;
cd748f27 192 }
62e76326 193
cd748f27 194 if (r->offset > -1 && r->offset != fs->offset) {
62e76326 195 if (lseek(fs->fd, r->offset, SEEK_SET) < 0) {
196 DEBUG(1) {
197 fprintf(stderr, "%d FD %d, offset %d: ", (int) mypid, fs->fd, r->offset);
198 perror("lseek");
199 }
200 }
cd748f27 201 }
62e76326 202
9a8f2084 203 DEBUG(2)
62e76326 204 fprintf(stderr, "%d WRITE %d,%d,%d\n", (int) mypid,
205 fs->fd, wrtlen, r->offset);
cd748f27 206 x = write(fs->fd, buf, wrtlen);
62e76326 207
cd748f27 208 if (x < 0) {
62e76326 209 DEBUG(1) {
210 fprintf(stderr, "%d FD %d: ", (int) mypid, fs->fd);
211 perror("write");
212 }
213
214 return -errno;
cd748f27 215 }
62e76326 216
cd748f27 217 fs->offset = r->offset + x;
218 return x;
219}
220
221static int
222do_unlink(diomsg * r, int len, const char *buf)
223{
93041634 224#if USE_TRUNCATE
62e76326 225
6d2cd907 226 if (truncate(buf, 0) < 0)
93041634 227#else
62e76326 228
6d2cd907 229 if (unlink(buf) < 0)
93041634 230#endif
62e76326 231
6d2cd907 232 {
62e76326 233 DEBUG(1) {
234 fprintf(stderr, "%d UNLNK id %d %s: ", (int) mypid, r->id, buf);
235 perror("truncate");
236 }
237
238 return -errno;
cd748f27 239 }
62e76326 240
9a8f2084 241 DEBUG(2)
62e76326 242 fprintf(stderr, "%d UNLNK %s\n", (int) mypid, buf);
cd748f27 243 return 0;
244}
245
246static void
247msg_handle(diomsg * r, int rl, diomsg * s)
248{
249 char *buf = NULL;
250 s->mtype = r->mtype;
251 s->callback_data = r->callback_data;
252 s->shm_offset = r->shm_offset;
253 s->id = r->id;
d3b3ab85 254 s->newstyle = r->newstyle;
62e76326 255
cd748f27 256 if (s->shm_offset > -1)
62e76326 257 buf = shmbuf + s->shm_offset;
258
cd748f27 259 switch (r->mtype) {
62e76326 260
cd748f27 261 case _MQD_OPEN:
62e76326 262
d3b3ab85 263 case _MQD_CREATE:
62e76326 264 s->status = do_open(r, rl, buf);
265 break;
266
cd748f27 267 case _MQD_CLOSE:
62e76326 268 s->status = do_close(r, rl);
269 break;
270
cd748f27 271 case _MQD_READ:
62e76326 272 s->status = do_read(r, rl, buf);
273 break;
274
cd748f27 275 case _MQD_WRITE:
62e76326 276 s->status = do_write(r, rl, buf);
277 break;
278
cd748f27 279 case _MQD_UNLINK:
62e76326 280 s->status = do_unlink(r, rl, buf);
281 break;
282
cd748f27 283 default:
62e76326 284 assert(0);
285 break;
cd748f27 286 }
287}
288
2d72d4fd 289static int
cd748f27 290fsCmp(const void *a, const void *b)
291{
e6ccf245 292 const int *A = (const int *)a;
293 const int *B = (const int *)b;
cd748f27 294 return *A != *B;
295}
296
2d72d4fd 297static unsigned int
cd748f27 298fsHash(const void *key, unsigned int n)
299{
300 /* note, n must be a power of 2! */
e6ccf245 301 const int *k = (const int *)key;
cd748f27 302 return (*k & (--n));
303}
304
305static void
306alarm_handler(int sig)
307{
308 (void) 0;
309}
310
311int
312main(int argc, char *argv[])
313{
314 int key;
315 int rmsgid;
316 int smsgid;
317 int shmid;
318 diomsg rmsg;
319 diomsg smsg;
320 int rlen;
321 char rbuf[512];
62e76326 322
cd748f27 323 struct sigaction sa;
324 setbuf(stdout, NULL);
325 setbuf(stderr, NULL);
326 mypid = getpid();
327 assert(4 == argc);
328 key = atoi(argv[1]);
329 rmsgid = msgget(key, 0600);
62e76326 330
cd748f27 331 if (rmsgid < 0) {
62e76326 332 perror("msgget");
333 return 1;
cd748f27 334 }
62e76326 335
cd748f27 336 key = atoi(argv[2]);
337 smsgid = msgget(key, 0600);
62e76326 338
cd748f27 339 if (smsgid < 0) {
62e76326 340 perror("msgget");
341 return 1;
cd748f27 342 }
62e76326 343
cd748f27 344 key = atoi(argv[3]);
345 shmid = shmget(key, 0, 0600);
62e76326 346
cd748f27 347 if (shmid < 0) {
62e76326 348 perror("shmget");
349 return 1;
cd748f27 350 }
62e76326 351
e6ccf245 352 shmbuf = (char *)shmat(shmid, NULL, 0);
62e76326 353
cd748f27 354 if (shmbuf == (void *) -1) {
62e76326 355 perror("shmat");
356 return 1;
cd748f27 357 }
62e76326 358
cd748f27 359 hash = hash_create(fsCmp, 1 << 4, fsHash);
360 assert(hash);
361 fcntl(0, F_SETFL, SQUID_NONBLOCK);
362 memset(&sa, '\0', sizeof(sa));
363 sa.sa_handler = alarm_handler;
364 sa.sa_flags = SA_RESTART;
365 sigaction(SIGALRM, &sa, NULL);
62e76326 366
cd748f27 367 for (;;) {
62e76326 368 alarm(1);
369 memset(&rmsg, '\0', sizeof(rmsg));
370 rlen = msgrcv(rmsgid, &rmsg, msg_snd_rcv_sz, 0, 0);
371
372 if (rlen < 0) {
373 if (EINTR == errno) {
374 if (read(0, rbuf, 512) <= 0) {
375 if (EWOULDBLOCK == errno)
376 (void) 0;
377 else if (EAGAIN == errno)
378 (void) 0;
379 else
380 break;
381 }
382 }
383
384 if (EAGAIN == errno) {
385 continue;
386 }
387
388 perror("msgrcv");
389 break;
390 }
391
392 alarm(0);
393 msg_handle(&rmsg, rlen, &smsg);
394
395 if (msgsnd(smsgid, &smsg, msg_snd_rcv_sz, 0) < 0) {
396 perror("msgsnd");
397 break;
398 }
cd748f27 399 }
62e76326 400
9a8f2084 401 DEBUG(2)
62e76326 402 fprintf(stderr, "%d diskd exiting\n", (int) mypid);
403
cd748f27 404 if (msgctl(rmsgid, IPC_RMID, 0) < 0)
62e76326 405 perror("msgctl IPC_RMID");
406
cd748f27 407 if (msgctl(smsgid, IPC_RMID, 0) < 0)
62e76326 408 perror("msgctl IPC_RMID");
409
cd748f27 410 if (shmdt(shmbuf) < 0)
62e76326 411 perror("shmdt");
412
cd748f27 413 if (shmctl(shmid, IPC_RMID, 0) < 0)
62e76326 414 perror("shmctl IPC_RMID");
415
cd748f27 416 return 0;
417}