]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/DiskDaemon/diskd.cc
2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section -- External DISKD process implementation. */
12 #include "DiskIO/DiskDaemon/diomsg.h"
28 xassert(const char *msg
, const char *file
, int line
)
30 fprintf(stderr
,"assertion failed: %s:%d: \"%s\"\n", file
, line
, msg
);
35 const int diomsg::msg_snd_rcv_sz
= sizeof(diomsg
) - sizeof(mtyp_t
);
36 #define DEBUG(LEVEL) if ((LEVEL) <= DebugLevel)
38 typedef struct _file_state file_state
;
48 static hash_table
*hash
= NULL
;
51 static int DebugLevel
= 0;
54 do_open(diomsg
* r
, int, const char *buf
)
59 * note r->offset holds open() flags
61 fd
= open(buf
, r
->offset
, 0600);
65 fprintf(stderr
, "%d %s: ", (int) mypid
, buf
);
72 fs
= (file_state
*)xcalloc(1, sizeof(*fs
));
74 fs
->key
= &fs
->id
; /* gack */
76 hash_join(hash
, (hash_link
*) fs
);
78 fprintf(stderr
, "%d OPEN id %d, FD %d, fs %p\n",
88 do_close(diomsg
* r
, int)
92 fs
= (file_state
*) hash_lookup(hash
, &r
->id
);
97 fprintf(stderr
, "%d CLOSE id %d: ", (int) mypid
, r
->id
);
105 hash_remove_link(hash
, (hash_link
*) fs
);
107 fprintf(stderr
, "%d CLOSE id %d, FD %d, fs %p\n",
118 do_read(diomsg
* r
, int, char *buf
)
121 int readlen
= r
->size
;
123 fs
= (file_state
*) hash_lookup(hash
, &r
->id
);
128 fprintf(stderr
, "%d READ id %d: ", (int) mypid
, r
->id
);
135 if (r
->offset
> -1 && r
->offset
!= fs
->offset
) {
137 fprintf(stderr
, "seeking to %" PRId64
"\n", (int64_t)r
->offset
);
140 if (lseek(fs
->fd
, r
->offset
, SEEK_SET
) < 0) {
142 fprintf(stderr
, "%d FD %d, offset %" PRId64
": ", (int) mypid
, fs
->fd
, (int64_t)r
->offset
);
148 x
= read(fs
->fd
, buf
, readlen
);
150 fprintf(stderr
, "%d READ %d,%d,%" PRId64
" ret %d\n", (int) mypid
,
151 fs
->fd
, readlen
, (int64_t)r
->offset
, x
);
156 fprintf(stderr
, "%d FD %d: ", (int) mypid
, fs
->fd
);
163 fs
->offset
= r
->offset
+ x
;
168 do_write(diomsg
* r
, int, const char *buf
)
170 int wrtlen
= r
->size
;
173 fs
= (file_state
*) hash_lookup(hash
, &r
->id
);
178 fprintf(stderr
, "%d WRITE id %d: ", (int) mypid
, r
->id
);
185 if (r
->offset
> -1 && r
->offset
!= fs
->offset
) {
186 if (lseek(fs
->fd
, r
->offset
, SEEK_SET
) < 0) {
188 fprintf(stderr
, "%d FD %d, offset %" PRId64
": ", (int) mypid
, fs
->fd
, (int64_t)r
->offset
);
195 fprintf(stderr
, "%d WRITE %d,%d,%" PRId64
"\n", (int) mypid
,
196 fs
->fd
, wrtlen
, (int64_t)r
->offset
);
198 x
= write(fs
->fd
, buf
, wrtlen
);
202 fprintf(stderr
, "%d FD %d: ", (int) mypid
, fs
->fd
);
209 fs
->offset
= r
->offset
+ x
;
214 do_unlink(diomsg
* r
, int, const char *buf
)
216 if (unlink(buf
) < 0) {
218 fprintf(stderr
, "%d UNLNK id %d %s: ", (int) mypid
, r
->id
, buf
);
226 fprintf(stderr
, "%d UNLNK %s\n", (int) mypid
, buf
);
232 msg_handle(diomsg
* r
, int rl
, diomsg
* s
)
237 s
->seq_no
= r
->seq_no
; /* optional, debugging */
238 s
->callback_data
= r
->callback_data
;
239 s
->requestor
= r
->requestor
;
240 s
->size
= 0; /* optional, debugging */
241 s
->offset
= 0; /* optional, debugging */
242 s
->shm_offset
= r
->shm_offset
;
243 s
->newstyle
= r
->newstyle
;
245 if (s
->shm_offset
> -1)
246 buf
= shmbuf
+ s
->shm_offset
;
247 else if (r
->mtype
!= _MQD_CLOSE
) {
248 fprintf(stderr
, "%d UNLNK id(%u) Error: no filename in shm buffer\n", (int) mypid
, s
->id
);
257 s
->status
= do_open(r
, rl
, buf
);
261 s
->status
= do_close(r
, rl
);
265 s
->status
= do_read(r
, rl
, buf
);
269 s
->status
= do_write(r
, rl
, buf
);
273 s
->status
= do_unlink(r
, rl
, buf
);
283 fsCmp(const void *a
, const void *b
)
285 const int *A
= (const int *)a
;
286 const int *B
= (const int *)b
;
291 fsHash(const void *key
, unsigned int n
)
293 /* note, n must be a power of 2! */
294 const int *k
= (const int *)key
;
299 static void alarm_handler(int) {}
303 main(int argc
, char *argv
[])
315 setbuf(stdout
, NULL
);
316 setbuf(stderr
, NULL
);
320 rmsgid
= msgget(key
, 0600);
328 smsgid
= msgget(key
, 0600);
336 shmid
= shmget(key
, 0, 0600);
343 shmbuf
= (char *)shmat(shmid
, NULL
, 0);
345 if (shmbuf
== (void *) -1) {
350 hash
= hash_create(fsCmp
, 1 << 4, fsHash
);
352 if (fcntl(0, F_SETFL
, SQUID_NONBLOCK
) < 0) {
353 perror(xstrerr(errno
));
356 memset(&sa
, '\0', sizeof(sa
));
357 sa
.sa_handler
= alarm_handler
;
358 sa
.sa_flags
= SA_RESTART
;
359 sigaction(SIGALRM
, &sa
, NULL
);
363 memset(&rmsg
, '\0', sizeof(rmsg
));
365 std::cerr
<< "msgrcv: " << rmsgid
<< ", "
366 << &rmsg
<< ", " << diomsg::msg_snd_rcv_sz
367 << ", " << 0 << ", " << 0 << std::endl
;
369 rlen
= msgrcv(rmsgid
, &rmsg
, diomsg::msg_snd_rcv_sz
, 0, 0);
372 if (EINTR
== errno
) {
373 if (read(0, rbuf
, 512) <= 0) {
374 if (EWOULDBLOCK
== errno
)
376 else if (EAGAIN
== errno
)
383 if (EAGAIN
== errno
) {
392 msg_handle(&rmsg
, rlen
, &smsg
);
394 if (msgsnd(smsgid
, &smsg
, diomsg::msg_snd_rcv_sz
, 0) < 0) {
401 fprintf(stderr
, "%d diskd exiting\n", (int) mypid
);
404 if (msgctl(rmsgid
, IPC_RMID
, 0) < 0)
405 perror("msgctl IPC_RMID");
407 if (msgctl(smsgid
, IPC_RMID
, 0) < 0)
408 perror("msgctl IPC_RMID");
410 if (shmdt(shmbuf
) < 0)
413 if (shmctl(shmid
, IPC_RMID
, 0) < 0)
414 perror("shmctl IPC_RMID");