]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskDaemon/diskd.cc
Improved some libraries detection logic
[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
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
b9ae18aa 42#include "DiskIO/DiskDaemon/diomsg.h"
767e4890 43
137a13ea 44void
45xassert(const char *msg, const char *file, int line)
46{
47 fprintf(stderr,"assertion failed: %s:%d: \"%s\"\n", file, line, msg);
cd748f27 48
137a13ea 49 abort();
50}
cd748f27 51
b9ae18aa 52const int diomsg::msg_snd_rcv_sz = sizeof(diomsg) - sizeof(mtyp_t);
53#define DEBUG(LEVEL) if ((LEVEL) <= DebugLevel)
cd748f27 54
55typedef struct _file_state file_state;
56
26ac0430 57struct _file_state {
cd748f27 58 void *key;
59 file_state *next;
60 int id;
61 int fd;
62 off_t offset;
63};
64
65static hash_table *hash = NULL;
66static pid_t mypid;
67static char *shmbuf;
46069294 68static int DebugLevel = 0;
cd748f27 69
70static int
71do_open(diomsg * r, int len, const char *buf)
72{
73 int fd;
74 file_state *fs;
75 /*
76 * note r->offset holds open() flags
77 */
78 fd = open(buf, r->offset, 0600);
62e76326 79
cd748f27 80 if (fd < 0) {
62e76326 81 DEBUG(1) {
82 fprintf(stderr, "%d %s: ", (int) mypid, buf);
83 perror("open");
84 }
85
86 return -errno;
cd748f27 87 }
62e76326 88
e6ccf245 89 fs = (file_state *)xcalloc(1, sizeof(*fs));
cd748f27 90 fs->id = r->id;
91 fs->key = &fs->id; /* gack */
92 fs->fd = fd;
93 hash_join(hash, (hash_link *) fs);
9a8f2084 94 DEBUG(2)
62e76326 95 fprintf(stderr, "%d OPEN id %d, FD %d, fs %p\n",
96 (int) mypid,
97 fs->id,
98 fs->fd,
99 fs);
cd748f27 100 return fd;
101}
102
103static int
104do_close(diomsg * r, int len)
105{
106 int fd;
107 file_state *fs;
108 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 109
cd748f27 110 if (NULL == fs) {
62e76326 111 errno = EBADF;
112 DEBUG(1) {
113 fprintf(stderr, "%d CLOSE id %d: ", (int) mypid, r->id);
114 perror("do_close");
115 }
116
117 return -errno;
cd748f27 118 }
62e76326 119
cd748f27 120 fd = fs->fd;
121 hash_remove_link(hash, (hash_link *) fs);
9a8f2084 122 DEBUG(2)
62e76326 123 fprintf(stderr, "%d CLOSE id %d, FD %d, fs %p\n",
124 (int) mypid,
125 r->id,
126 fs->fd,
127 fs);
cd748f27 128 xfree(fs);
129 return close(fd);
130}
131
132static int
133do_read(diomsg * r, int len, char *buf)
134{
135 int x;
136 int readlen = r->size;
137 file_state *fs;
138 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 139
cd748f27 140 if (NULL == fs) {
62e76326 141 errno = EBADF;
142 DEBUG(1) {
143 fprintf(stderr, "%d READ id %d: ", (int) mypid, r->id);
144 perror("do_read");
145 }
146
147 return -errno;
cd748f27 148 }
62e76326 149
cd748f27 150 if (r->offset > -1 && r->offset != fs->offset) {
62e76326 151 DEBUG(2)
ee139403 152 fprintf(stderr, "seeking to %"PRId64"\n", (int64_t)r->offset);
62e76326 153
154 if (lseek(fs->fd, r->offset, SEEK_SET) < 0) {
155 DEBUG(1) {
ee139403 156 fprintf(stderr, "%d FD %d, offset %"PRId64": ", (int) mypid, fs->fd, (int64_t)r->offset);
62e76326 157 perror("lseek");
158 }
159 }
cd748f27 160 }
62e76326 161
cd748f27 162 x = read(fs->fd, buf, readlen);
9a8f2084 163 DEBUG(2)
ee139403 164 fprintf(stderr, "%d READ %d,%d,%"PRId64" ret %d\n", (int) mypid,
165 fs->fd, readlen, (int64_t)r->offset, x);
62e76326 166
cd748f27 167 if (x < 0) {
62e76326 168 DEBUG(1) {
169 fprintf(stderr, "%d FD %d: ", (int) mypid, fs->fd);
170 perror("read");
171 }
172
173 return -errno;
cd748f27 174 }
62e76326 175
cd748f27 176 fs->offset = r->offset + x;
177 return x;
178}
179
180static int
181do_write(diomsg * r, int len, const char *buf)
182{
183 int wrtlen = r->size;
184 int x;
185 file_state *fs;
186 fs = (file_state *) hash_lookup(hash, &r->id);
62e76326 187
cd748f27 188 if (NULL == fs) {
62e76326 189 errno = EBADF;
190 DEBUG(1) {
191 fprintf(stderr, "%d WRITE id %d: ", (int) mypid, r->id);
192 perror("do_write");
193 }
194
195 return -errno;
cd748f27 196 }
62e76326 197
cd748f27 198 if (r->offset > -1 && r->offset != fs->offset) {
62e76326 199 if (lseek(fs->fd, r->offset, SEEK_SET) < 0) {
200 DEBUG(1) {
ee139403 201 fprintf(stderr, "%d FD %d, offset %"PRId64": ", (int) mypid, fs->fd, (int64_t)r->offset);
62e76326 202 perror("lseek");
203 }
204 }
cd748f27 205 }
62e76326 206
9a8f2084 207 DEBUG(2)
ee139403 208 fprintf(stderr, "%d WRITE %d,%d,%"PRId64"\n", (int) mypid,
209 fs->fd, wrtlen, (int64_t)r->offset);
cd748f27 210 x = write(fs->fd, buf, wrtlen);
62e76326 211
cd748f27 212 if (x < 0) {
62e76326 213 DEBUG(1) {
214 fprintf(stderr, "%d FD %d: ", (int) mypid, fs->fd);
215 perror("write");
216 }
217
218 return -errno;
cd748f27 219 }
62e76326 220
cd748f27 221 fs->offset = r->offset + x;
222 return x;
223}
224
225static int
226do_unlink(diomsg * r, int len, const char *buf)
227{
b3fb9070 228 if (unlink(buf) < 0) {
62e76326 229 DEBUG(1) {
230 fprintf(stderr, "%d UNLNK id %d %s: ", (int) mypid, r->id, buf);
6af23c85 231 perror("unlink");
62e76326 232 }
233
234 return -errno;
cd748f27 235 }
62e76326 236
9a8f2084 237 DEBUG(2)
62e76326 238 fprintf(stderr, "%d UNLNK %s\n", (int) mypid, buf);
cd748f27 239 return 0;
240}
241
242static void
243msg_handle(diomsg * r, int rl, diomsg * s)
244{
245 char *buf = NULL;
246 s->mtype = r->mtype;
a1ad81aa 247 s->id = r->id;
248 s->seq_no = r->seq_no; /* optional, debugging */
cd748f27 249 s->callback_data = r->callback_data;
b9ae18aa 250 s->requestor = r->requestor;
a1ad81aa 251 s->size = 0; /* optional, debugging */
252 s->offset = 0; /* optional, debugging */
cd748f27 253 s->shm_offset = r->shm_offset;
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));
b9ae18aa 370 DEBUG(2)
1d8e65c4 371 std::cerr << "msgrcv: " << rmsgid << ", "
26ac0430
AJ
372 << &rmsg << ", " << diomsg::msg_snd_rcv_sz
373 << ", " << 0 << ", " << 0 << std::endl;
b9ae18aa 374 rlen = msgrcv(rmsgid, &rmsg, diomsg::msg_snd_rcv_sz, 0, 0);
62e76326 375
376 if (rlen < 0) {
377 if (EINTR == errno) {
378 if (read(0, rbuf, 512) <= 0) {
379 if (EWOULDBLOCK == errno)
380 (void) 0;
381 else if (EAGAIN == errno)
382 (void) 0;
383 else
384 break;
385 }
386 }
387
388 if (EAGAIN == errno) {
389 continue;
390 }
391
392 perror("msgrcv");
393 break;
394 }
395
396 alarm(0);
397 msg_handle(&rmsg, rlen, &smsg);
398
b9ae18aa 399 if (msgsnd(smsgid, &smsg, diomsg::msg_snd_rcv_sz, 0) < 0) {
62e76326 400 perror("msgsnd");
401 break;
402 }
cd748f27 403 }
62e76326 404
9a8f2084 405 DEBUG(2)
62e76326 406 fprintf(stderr, "%d diskd exiting\n", (int) mypid);
407
cd748f27 408 if (msgctl(rmsgid, IPC_RMID, 0) < 0)
62e76326 409 perror("msgctl IPC_RMID");
410
cd748f27 411 if (msgctl(smsgid, IPC_RMID, 0) < 0)
62e76326 412 perror("msgctl IPC_RMID");
413
cd748f27 414 if (shmdt(shmbuf) < 0)
62e76326 415 perror("shmdt");
416
cd748f27 417 if (shmctl(shmid, IPC_RMID, 0) < 0)
62e76326 418 perror("shmctl IPC_RMID");
419
cd748f27 420 return 0;
421}