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