]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskDaemon/diskd.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / DiskIO / DiskDaemon / diskd.cc
CommitLineData
b95b6efb 1/*
262a0e14 2 * $Id$
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.
26ac0430 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.
26ac0430 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
f7f3304a 35#include "squid.h"
8cab55b3
AJ
36#include "DiskIO/DiskDaemon/diomsg.h"
37#include "hash.h"
cd748f27 38
cec4754f
AJ
39#if HAVE_ERRNO_H
40#include <errno.h>
41#endif
cd748f27 42#include <sys/ipc.h>
43#include <sys/msg.h>
44#include <sys/shm.h>
cec4754f
AJ
45#if HAVE_IOSTREAM
46#include <iostream>
47#endif
cd748f27 48
137a13ea 49void
50xassert(const char *msg, const char *file, int line)
51{
52 fprintf(stderr,"assertion failed: %s:%d: \"%s\"\n", file, line, msg);
cd748f27 53
137a13ea 54 abort();
55}
cd748f27 56
b9ae18aa 57const int diomsg::msg_snd_rcv_sz = sizeof(diomsg) - sizeof(mtyp_t);
58#define DEBUG(LEVEL) if ((LEVEL) <= DebugLevel)
cd748f27 59
60typedef struct _file_state file_state;
61
26ac0430 62struct _file_state {
cd748f27 63 void *key;
64 file_state *next;
65 int id;
66 int fd;
67 off_t offset;
68};
69
70static hash_table *hash = NULL;
71static pid_t mypid;
72static char *shmbuf;
46069294 73static int DebugLevel = 0;
cd748f27 74
75static int
76do_open(diomsg * r, int len, const char *buf)
77{
78 int fd;
79 file_state *fs;
80 /*
81 * note r->offset holds open() flags
82 */
83 fd = open(buf, r->offset, 0600);
62e76326 84
cd748f27 85 if (fd < 0) {
62e76326 86 DEBUG(1) {
87 fprintf(stderr, "%d %s: ", (int) mypid, buf);
88 perror("open");
89 }
90
91 return -errno;
cd748f27 92 }
62e76326 93
e6ccf245 94 fs = (file_state *)xcalloc(1, sizeof(*fs));
cd748f27 95 fs->id = r->id;
6ca34f6f 96 fs->key = &fs->id; /* gack */
cd748f27 97 fs->fd = fd;
98 hash_join(hash, (hash_link *) fs);
6ca34f6f
HN
99 DEBUG(2) {
100 fprintf(stderr, "%d OPEN id %d, FD %d, fs %p\n",
101 (int) mypid,
102 fs->id,
103 fs->fd,
104 fs);
105 }
cd748f27 106 return fd;
107}
108
109static int
110do_close(diomsg * r, int len)
111{
112 int fd;
113 file_state *fs;
114 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 115
cd748f27 116 if (NULL == fs) {
62e76326 117 errno = EBADF;
118 DEBUG(1) {
119 fprintf(stderr, "%d CLOSE id %d: ", (int) mypid, r->id);
120 perror("do_close");
121 }
122
123 return -errno;
cd748f27 124 }
62e76326 125
cd748f27 126 fd = fs->fd;
127 hash_remove_link(hash, (hash_link *) fs);
6ca34f6f
HN
128 DEBUG(2) {
129 fprintf(stderr, "%d CLOSE id %d, FD %d, fs %p\n",
130 (int) mypid,
131 r->id,
132 fs->fd,
133 fs);
134 }
cd748f27 135 xfree(fs);
136 return close(fd);
137}
138
139static int
140do_read(diomsg * r, int len, char *buf)
141{
142 int x;
143 int readlen = r->size;
144 file_state *fs;
145 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 146
cd748f27 147 if (NULL == fs) {
62e76326 148 errno = EBADF;
149 DEBUG(1) {
150 fprintf(stderr, "%d READ id %d: ", (int) mypid, r->id);
151 perror("do_read");
152 }
153
154 return -errno;
cd748f27 155 }
62e76326 156
cd748f27 157 if (r->offset > -1 && r->offset != fs->offset) {
6ca34f6f
HN
158 DEBUG(2) {
159 fprintf(stderr, "seeking to %"PRId64"\n", (int64_t)r->offset);
160 }
62e76326 161
162 if (lseek(fs->fd, r->offset, SEEK_SET) < 0) {
163 DEBUG(1) {
ee139403 164 fprintf(stderr, "%d FD %d, offset %"PRId64": ", (int) mypid, fs->fd, (int64_t)r->offset);
62e76326 165 perror("lseek");
166 }
167 }
cd748f27 168 }
62e76326 169
cd748f27 170 x = read(fs->fd, buf, readlen);
6ca34f6f
HN
171 DEBUG(2) {
172 fprintf(stderr, "%d READ %d,%d,%"PRId64" ret %d\n", (int) mypid,
173 fs->fd, readlen, (int64_t)r->offset, x);
174 }
62e76326 175
cd748f27 176 if (x < 0) {
62e76326 177 DEBUG(1) {
178 fprintf(stderr, "%d FD %d: ", (int) mypid, fs->fd);
179 perror("read");
180 }
181
182 return -errno;
cd748f27 183 }
62e76326 184
cd748f27 185 fs->offset = r->offset + x;
186 return x;
187}
188
189static int
190do_write(diomsg * r, int len, const char *buf)
191{
192 int wrtlen = r->size;
193 int x;
194 file_state *fs;
195 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 196
cd748f27 197 if (NULL == fs) {
62e76326 198 errno = EBADF;
199 DEBUG(1) {
200 fprintf(stderr, "%d WRITE id %d: ", (int) mypid, r->id);
201 perror("do_write");
202 }
203
204 return -errno;
cd748f27 205 }
62e76326 206
cd748f27 207 if (r->offset > -1 && r->offset != fs->offset) {
62e76326 208 if (lseek(fs->fd, r->offset, SEEK_SET) < 0) {
209 DEBUG(1) {
ee139403 210 fprintf(stderr, "%d FD %d, offset %"PRId64": ", (int) mypid, fs->fd, (int64_t)r->offset);
62e76326 211 perror("lseek");
212 }
213 }
cd748f27 214 }
62e76326 215
6ca34f6f
HN
216 DEBUG(2) {
217 fprintf(stderr, "%d WRITE %d,%d,%"PRId64"\n", (int) mypid,
218 fs->fd, wrtlen, (int64_t)r->offset);
219 }
cd748f27 220 x = write(fs->fd, buf, wrtlen);
62e76326 221
cd748f27 222 if (x < 0) {
62e76326 223 DEBUG(1) {
224 fprintf(stderr, "%d FD %d: ", (int) mypid, fs->fd);
225 perror("write");
226 }
227
228 return -errno;
cd748f27 229 }
62e76326 230
cd748f27 231 fs->offset = r->offset + x;
232 return x;
233}
234
235static int
236do_unlink(diomsg * r, int len, const char *buf)
237{
b3fb9070 238 if (unlink(buf) < 0) {
62e76326 239 DEBUG(1) {
240 fprintf(stderr, "%d UNLNK id %d %s: ", (int) mypid, r->id, buf);
6af23c85 241 perror("unlink");
62e76326 242 }
243
244 return -errno;
cd748f27 245 }
62e76326 246
6ca34f6f
HN
247 DEBUG(2) {
248 fprintf(stderr, "%d UNLNK %s\n", (int) mypid, buf);
249 }
cd748f27 250 return 0;
251}
252
253static void
254msg_handle(diomsg * r, int rl, diomsg * s)
255{
256 char *buf = NULL;
257 s->mtype = r->mtype;
a1ad81aa 258 s->id = r->id;
6ca34f6f 259 s->seq_no = r->seq_no; /* optional, debugging */
cd748f27 260 s->callback_data = r->callback_data;
b9ae18aa 261 s->requestor = r->requestor;
6ca34f6f
HN
262 s->size = 0; /* optional, debugging */
263 s->offset = 0; /* optional, debugging */
cd748f27 264 s->shm_offset = r->shm_offset;
d3b3ab85 265 s->newstyle = r->newstyle;
62e76326 266
cd748f27 267 if (s->shm_offset > -1)
62e76326 268 buf = shmbuf + s->shm_offset;
269
cd748f27 270 switch (r->mtype) {
62e76326 271
cd748f27 272 case _MQD_OPEN:
62e76326 273
d3b3ab85 274 case _MQD_CREATE:
62e76326 275 s->status = do_open(r, rl, buf);
276 break;
277
cd748f27 278 case _MQD_CLOSE:
62e76326 279 s->status = do_close(r, rl);
280 break;
281
cd748f27 282 case _MQD_READ:
62e76326 283 s->status = do_read(r, rl, buf);
284 break;
285
cd748f27 286 case _MQD_WRITE:
62e76326 287 s->status = do_write(r, rl, buf);
288 break;
289
cd748f27 290 case _MQD_UNLINK:
62e76326 291 s->status = do_unlink(r, rl, buf);
292 break;
293
cd748f27 294 default:
62e76326 295 assert(0);
296 break;
cd748f27 297 }
298}
299
2d72d4fd 300static int
cd748f27 301fsCmp(const void *a, const void *b)
302{
e6ccf245 303 const int *A = (const int *)a;
304 const int *B = (const int *)b;
cd748f27 305 return *A != *B;
306}
307
2d72d4fd 308static unsigned int
cd748f27 309fsHash(const void *key, unsigned int n)
310{
311 /* note, n must be a power of 2! */
e6ccf245 312 const int *k = (const int *)key;
cd748f27 313 return (*k & (--n));
314}
315
e4ae841b 316SQUIDCEXTERN {
9853f3b5
A
317 static void
318 alarm_handler(int sig) {
319 (void) 0;
320 }
e4ae841b 321};
cd748f27 322
323int
324main(int argc, char *argv[])
325{
326 int key;
327 int rmsgid;
328 int smsgid;
329 int shmid;
330 diomsg rmsg;
331 diomsg smsg;
332 int rlen;
333 char rbuf[512];
62e76326 334
cd748f27 335 struct sigaction sa;
336 setbuf(stdout, NULL);
337 setbuf(stderr, NULL);
338 mypid = getpid();
339 assert(4 == argc);
340 key = atoi(argv[1]);
341 rmsgid = msgget(key, 0600);
62e76326 342
cd748f27 343 if (rmsgid < 0) {
62e76326 344 perror("msgget");
345 return 1;
cd748f27 346 }
62e76326 347
cd748f27 348 key = atoi(argv[2]);
349 smsgid = msgget(key, 0600);
62e76326 350
cd748f27 351 if (smsgid < 0) {
62e76326 352 perror("msgget");
353 return 1;
cd748f27 354 }
62e76326 355
cd748f27 356 key = atoi(argv[3]);
357 shmid = shmget(key, 0, 0600);
62e76326 358
cd748f27 359 if (shmid < 0) {
62e76326 360 perror("shmget");
361 return 1;
cd748f27 362 }
62e76326 363
e6ccf245 364 shmbuf = (char *)shmat(shmid, NULL, 0);
62e76326 365
cd748f27 366 if (shmbuf == (void *) -1) {
62e76326 367 perror("shmat");
368 return 1;
cd748f27 369 }
62e76326 370
cd748f27 371 hash = hash_create(fsCmp, 1 << 4, fsHash);
372 assert(hash);
373 fcntl(0, F_SETFL, SQUID_NONBLOCK);
374 memset(&sa, '\0', sizeof(sa));
375 sa.sa_handler = alarm_handler;
376 sa.sa_flags = SA_RESTART;
377 sigaction(SIGALRM, &sa, NULL);
62e76326 378
cd748f27 379 for (;;) {
62e76326 380 alarm(1);
381 memset(&rmsg, '\0', sizeof(rmsg));
6ca34f6f
HN
382 DEBUG(2) {
383 std::cerr << "msgrcv: " << rmsgid << ", "
384 << &rmsg << ", " << diomsg::msg_snd_rcv_sz
385 << ", " << 0 << ", " << 0 << std::endl;
386 }
b9ae18aa 387 rlen = msgrcv(rmsgid, &rmsg, diomsg::msg_snd_rcv_sz, 0, 0);
62e76326 388
389 if (rlen < 0) {
390 if (EINTR == errno) {
391 if (read(0, rbuf, 512) <= 0) {
392 if (EWOULDBLOCK == errno)
393 (void) 0;
394 else if (EAGAIN == errno)
395 (void) 0;
396 else
397 break;
398 }
399 }
400
401 if (EAGAIN == errno) {
402 continue;
403 }
404
405 perror("msgrcv");
406 break;
407 }
408
409 alarm(0);
410 msg_handle(&rmsg, rlen, &smsg);
411
b9ae18aa 412 if (msgsnd(smsgid, &smsg, diomsg::msg_snd_rcv_sz, 0) < 0) {
62e76326 413 perror("msgsnd");
414 break;
415 }
cd748f27 416 }
62e76326 417
6ca34f6f
HN
418 DEBUG(2) {
419 fprintf(stderr, "%d diskd exiting\n", (int) mypid);
420 }
62e76326 421
cd748f27 422 if (msgctl(rmsgid, IPC_RMID, 0) < 0)
62e76326 423 perror("msgctl IPC_RMID");
424
cd748f27 425 if (msgctl(smsgid, IPC_RMID, 0) < 0)
62e76326 426 perror("msgctl IPC_RMID");
427
cd748f27 428 if (shmdt(shmbuf) < 0)
62e76326 429 perror("shmdt");
430
cd748f27 431 if (shmctl(shmid, IPC_RMID, 0) < 0)
62e76326 432 perror("shmctl IPC_RMID");
433
cd748f27 434 return 0;
435}