Coverage Report

Created: 2026-10-17 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/compat/simple-ipc/ipc-unix-socket.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "gettext.h"
3
#include "simple-ipc.h"
4
#include "strbuf.h"
5
#include "thread-utils.h"
6
#include "trace2.h"
7
#include "unix-socket.h"
8
#include "unix-stream-server.h"
9
10
#ifndef SUPPORTS_SIMPLE_IPC
11
/*
12
 * This source file should only be compiled when Simple IPC is supported.
13
 * See the top-level Makefile.
14
 */
15
#error SUPPORTS_SIMPLE_IPC not defined
16
#endif
17
18
enum ipc_active_state ipc_get_active_state(const char *path)
19
0
{
20
0
  enum ipc_active_state state = IPC_STATE__OTHER_ERROR;
21
0
  struct ipc_client_connect_options options
22
0
    = IPC_CLIENT_CONNECT_OPTIONS_INIT;
23
0
  struct stat st;
24
0
  struct ipc_client_connection *connection_test = NULL;
25
26
0
  options.wait_if_busy = 0;
27
0
  options.wait_if_not_found = 0;
28
29
0
  if (lstat(path, &st) == -1) {
30
0
    switch (errno) {
31
0
    case ENOENT:
32
0
    case ENOTDIR:
33
0
      return IPC_STATE__NOT_LISTENING;
34
0
    default:
35
0
      return IPC_STATE__INVALID_PATH;
36
0
    }
37
0
  }
38
39
#ifdef __CYGWIN__
40
  /*
41
   * Cygwin emulates Unix sockets by writing special-crafted files whose
42
   * `system` bit is set.
43
   *
44
   * If we are too fast, Cygwin might still be in the process of marking
45
   * the underlying file as a system file. Until then, we will not see a
46
   * Unix socket here, but a plain file instead. Just in case that this
47
   * is happening, wait a little and try again.
48
   */
49
  {
50
    static const int delay[] = { 1, 10, 20, 40, -1 };
51
    int i;
52
53
    for (i = 0; S_ISREG(st.st_mode) && delay[i] > 0; i++) {
54
      sleep_millisec(delay[i]);
55
      if (lstat(path, &st) == -1)
56
        return IPC_STATE__INVALID_PATH;
57
    }
58
  }
59
#endif
60
61
  /* also complain if a plain file is in the way */
62
0
  if ((st.st_mode & S_IFMT) != S_IFSOCK)
63
0
    return IPC_STATE__INVALID_PATH;
64
65
  /*
66
   * Just because the filesystem has a S_IFSOCK type inode
67
   * at `path`, doesn't mean it that there is a server listening.
68
   * Ping it to be sure.
69
   */
70
0
  state = ipc_client_try_connect(path, &options, &connection_test);
71
0
  ipc_client_close_connection(connection_test);
72
73
0
  return state;
74
0
}
75
76
/*
77
 * Retry frequency when trying to connect to a server.
78
 *
79
 * This value should be short enough that we don't seriously delay our
80
 * caller, but not fast enough that our spinning puts pressure on the
81
 * system.
82
 */
83
0
#define WAIT_STEP_MS (50)
84
85
/*
86
 * Try to connect to the server.  If the server is just starting up or
87
 * is very busy, we may not get a connection the first time.
88
 */
89
static enum ipc_active_state connect_to_server(
90
  const char *path,
91
  int timeout_ms,
92
  const struct ipc_client_connect_options *options,
93
  int *pfd)
94
0
{
95
0
  int k;
96
97
0
  *pfd = -1;
98
99
0
  for (k = 0; k < timeout_ms; k += WAIT_STEP_MS) {
100
0
    int fd = unix_stream_connect(path, options->uds_disallow_chdir);
101
102
0
    if (fd != -1) {
103
0
      *pfd = fd;
104
0
      return IPC_STATE__LISTENING;
105
0
    }
106
107
0
    if (errno == ENOENT) {
108
0
      if (!options->wait_if_not_found)
109
0
        return IPC_STATE__PATH_NOT_FOUND;
110
111
0
      goto sleep_and_try_again;
112
0
    }
113
114
0
    if (errno == ETIMEDOUT) {
115
0
      if (!options->wait_if_busy)
116
0
        return IPC_STATE__NOT_LISTENING;
117
118
0
      goto sleep_and_try_again;
119
0
    }
120
121
0
    if (errno == ECONNREFUSED) {
122
0
      if (!options->wait_if_busy)
123
0
        return IPC_STATE__NOT_LISTENING;
124
125
0
      goto sleep_and_try_again;
126
0
    }
127
128
0
    return IPC_STATE__OTHER_ERROR;
129
130
0
  sleep_and_try_again:
131
0
    sleep_millisec(WAIT_STEP_MS);
132
0
  }
133
134
0
  return IPC_STATE__NOT_LISTENING;
135
0
}
136
137
/*
138
 * The total amount of time that we are willing to wait when trying to
139
 * connect to a server.
140
 *
141
 * When the server is first started, it might take a little while for
142
 * it to become ready to service requests.  Likewise, the server may
143
 * be very (temporarily) busy and not respond to our connections.
144
 *
145
 * We should gracefully and silently handle those conditions and try
146
 * again for a reasonable time period.
147
 *
148
 * The value chosen here should be long enough for the server
149
 * to reliably heal from the above conditions.
150
 */
151
0
#define MY_CONNECTION_TIMEOUT_MS (1000)
152
153
enum ipc_active_state ipc_client_try_connect(
154
  const char *path,
155
  const struct ipc_client_connect_options *options,
156
  struct ipc_client_connection **p_connection)
157
0
{
158
0
  enum ipc_active_state state = IPC_STATE__OTHER_ERROR;
159
0
  int fd = -1;
160
161
0
  *p_connection = NULL;
162
163
0
  trace2_region_enter("ipc-client", "try-connect", NULL);
164
0
  trace2_data_string("ipc-client", NULL, "try-connect/path", path);
165
166
0
  state = connect_to_server(path, MY_CONNECTION_TIMEOUT_MS,
167
0
          options, &fd);
168
169
0
  trace2_data_intmax("ipc-client", NULL, "try-connect/state",
170
0
         (intmax_t)state);
171
0
  trace2_region_leave("ipc-client", "try-connect", NULL);
172
173
0
  if (state == IPC_STATE__LISTENING) {
174
0
    (*p_connection) = xcalloc(1, sizeof(struct ipc_client_connection));
175
0
    (*p_connection)->fd = fd;
176
0
  }
177
178
0
  return state;
179
0
}
180
181
void ipc_client_close_connection(struct ipc_client_connection *connection)
182
0
{
183
0
  if (!connection)
184
0
    return;
185
186
0
  if (connection->fd != -1)
187
0
    close(connection->fd);
188
189
0
  free(connection);
190
0
}
191
192
int ipc_client_send_command_to_connection(
193
  struct ipc_client_connection *connection,
194
  const char *message, size_t message_len,
195
  struct strbuf *answer)
196
0
{
197
0
  int ret = 0;
198
199
0
  strbuf_setlen(answer, 0);
200
201
0
  trace2_region_enter("ipc-client", "send-command", NULL);
202
203
0
  if (write_packetized_from_buf_no_flush(message, message_len,
204
0
                 connection->fd) < 0 ||
205
0
      packet_flush_gently(connection->fd) < 0) {
206
0
    ret = error(_("could not send IPC command"));
207
0
    goto done;
208
0
  }
209
210
0
  if (read_packetized_to_strbuf(
211
0
        connection->fd, answer,
212
0
        PACKET_READ_GENTLE_ON_EOF | PACKET_READ_GENTLE_ON_READ_ERROR) < 0) {
213
0
    ret = error(_("could not read IPC response"));
214
0
    goto done;
215
0
  }
216
217
0
done:
218
0
  trace2_region_leave("ipc-client", "send-command", NULL);
219
0
  return ret;
220
0
}
221
222
int ipc_client_send_command(const char *path,
223
          const struct ipc_client_connect_options *options,
224
          const char *message, size_t message_len,
225
          struct strbuf *answer)
226
0
{
227
0
  int ret = -1;
228
0
  enum ipc_active_state state;
229
0
  struct ipc_client_connection *connection = NULL;
230
231
0
  state = ipc_client_try_connect(path, options, &connection);
232
233
0
  if (state != IPC_STATE__LISTENING)
234
0
    return ret;
235
236
0
  ret = ipc_client_send_command_to_connection(connection,
237
0
                message, message_len,
238
0
                answer);
239
240
0
  ipc_client_close_connection(connection);
241
242
0
  return ret;
243
0
}
244
245
static int set_socket_blocking_flag(int fd, int make_nonblocking)
246
0
{
247
0
  int flags;
248
249
0
  flags = fcntl(fd, F_GETFL, NULL);
250
251
0
  if (flags < 0)
252
0
    return -1;
253
254
0
  if (make_nonblocking)
255
0
    flags |= O_NONBLOCK;
256
0
  else
257
0
    flags &= ~O_NONBLOCK;
258
259
0
  return fcntl(fd, F_SETFL, flags);
260
0
}
261
262
/*
263
 * Magic numbers used to annotate callback instance data.
264
 * These are used to help guard against accidentally passing the
265
 * wrong instance data across multiple levels of callbacks (which
266
 * is easy to do if there are `void*` arguments).
267
 */
268
enum magic {
269
  MAGIC_SERVER_REPLY_DATA,
270
  MAGIC_WORKER_THREAD_DATA,
271
  MAGIC_ACCEPT_THREAD_DATA,
272
  MAGIC_SERVER_DATA,
273
};
274
275
struct ipc_server_reply_data {
276
  enum magic magic;
277
  int fd;
278
  struct ipc_worker_thread_data *worker_thread_data;
279
};
280
281
struct ipc_worker_thread_data {
282
  enum magic magic;
283
  struct ipc_worker_thread_data *next_thread;
284
  struct ipc_server_data *server_data;
285
  pthread_t pthread_id;
286
};
287
288
struct ipc_accept_thread_data {
289
  enum magic magic;
290
  struct ipc_server_data *server_data;
291
292
  struct unix_ss_socket *server_socket;
293
294
  int fd_send_shutdown;
295
  int fd_wait_shutdown;
296
  pthread_t pthread_id;
297
};
298
299
/*
300
 * With unix-sockets, the conceptual "ipc-server" is implemented as a single
301
 * controller "accept-thread" thread and a pool of "worker-thread" threads.
302
 * The former does the usual `accept()` loop and dispatches connections
303
 * to an idle worker thread.  The worker threads wait in an idle loop for
304
 * a new connection, communicate with the client and relay data to/from
305
 * the `application_cb` and then wait for another connection from the
306
 * server thread.  This avoids the overhead of constantly creating and
307
 * destroying threads.
308
 */
309
struct ipc_server_data {
310
  enum magic magic;
311
  ipc_server_application_cb *application_cb;
312
  void *application_data;
313
  struct strbuf buf_path;
314
315
  struct ipc_accept_thread_data *accept_thread;
316
  struct ipc_worker_thread_data *worker_thread_list;
317
318
  pthread_mutex_t work_available_mutex;
319
  pthread_cond_t work_available_cond;
320
321
  /*
322
   * Accepted but not yet processed client connections are kept
323
   * in a circular buffer FIFO.  The queue is empty when the
324
   * positions are equal.
325
   */
326
  int *fifo_fds;
327
  int queue_size;
328
  int back_pos;
329
  int front_pos;
330
331
  int started;
332
  int shutdown_requested;
333
  int is_stopped;
334
};
335
336
/*
337
 * Remove and return the oldest queued connection.
338
 *
339
 * Returns -1 if empty.
340
 */
341
static int fifo_dequeue(struct ipc_server_data *server_data)
342
0
{
343
  /* ASSERT holding mutex */
344
345
0
  int fd;
346
347
0
  if (server_data->back_pos == server_data->front_pos)
348
0
    return -1;
349
350
0
  fd = server_data->fifo_fds[server_data->front_pos];
351
0
  server_data->fifo_fds[server_data->front_pos] = -1;
352
353
0
  server_data->front_pos++;
354
0
  if (server_data->front_pos == server_data->queue_size)
355
0
    server_data->front_pos = 0;
356
357
0
  return fd;
358
0
}
359
360
/*
361
 * Push a new fd onto the back of the queue.
362
 *
363
 * Drop it and return -1 if queue is already full.
364
 */
365
static int fifo_enqueue(struct ipc_server_data *server_data, int fd)
366
0
{
367
  /* ASSERT holding mutex */
368
369
0
  int next_back_pos;
370
371
0
  next_back_pos = server_data->back_pos + 1;
372
0
  if (next_back_pos == server_data->queue_size)
373
0
    next_back_pos = 0;
374
375
0
  if (next_back_pos == server_data->front_pos) {
376
    /* Queue is full. Just drop it. */
377
0
    close(fd);
378
0
    return -1;
379
0
  }
380
381
0
  server_data->fifo_fds[server_data->back_pos] = fd;
382
0
  server_data->back_pos = next_back_pos;
383
384
0
  return fd;
385
0
}
386
387
/*
388
 * Wait for a connection to be queued to the FIFO and return it.
389
 *
390
 * Returns -1 if someone has already requested a shutdown.
391
 */
392
static int worker_thread__wait_for_connection(
393
  struct ipc_worker_thread_data *worker_thread_data)
394
0
{
395
  /* ASSERT NOT holding mutex */
396
397
0
  struct ipc_server_data *server_data = worker_thread_data->server_data;
398
0
  int fd = -1;
399
400
0
  pthread_mutex_lock(&server_data->work_available_mutex);
401
0
  for (;;) {
402
0
    if (server_data->shutdown_requested)
403
0
      break;
404
405
0
    fd = fifo_dequeue(server_data);
406
0
    if (fd >= 0)
407
0
      break;
408
409
0
    pthread_cond_wait(&server_data->work_available_cond,
410
0
          &server_data->work_available_mutex);
411
0
  }
412
0
  pthread_mutex_unlock(&server_data->work_available_mutex);
413
414
0
  return fd;
415
0
}
416
417
/*
418
 * Forward declare our reply callback function so that any compiler
419
 * errors are reported when we actually define the function (in addition
420
 * to any errors reported when we try to pass this callback function as
421
 * a parameter in a function call).  The former are easier to understand.
422
 */
423
static ipc_server_reply_cb do_io_reply_callback;
424
425
/*
426
 * Relay application's response message to the client process.
427
 * (We do not flush at this point because we allow the caller
428
 * to chunk data to the client thru us.)
429
 */
430
static int do_io_reply_callback(struct ipc_server_reply_data *reply_data,
431
           const char *response, size_t response_len)
432
0
{
433
0
  if (reply_data->magic != MAGIC_SERVER_REPLY_DATA)
434
0
    BUG("reply_cb called with wrong instance data");
435
436
0
  return write_packetized_from_buf_no_flush(response, response_len,
437
0
              reply_data->fd);
438
0
}
439
440
/* A randomly chosen value. */
441
0
#define MY_WAIT_POLL_TIMEOUT_MS (10)
442
443
/*
444
 * If the client hangs up without sending any data on the wire, just
445
 * quietly close the socket and ignore this client.
446
 *
447
 * This worker thread is committed to reading the IPC request data
448
 * from the client at the other end of this fd.  Wait here for the
449
 * client to actually put something on the wire -- because if the
450
 * client just does a ping (connect and hangup without sending any
451
 * data), our use of the pkt-line read routines will spew an error
452
 * message.
453
 *
454
 * Return -1 if the client hung up.
455
 * Return 0 if data (possibly incomplete) is ready.
456
 */
457
static int worker_thread__wait_for_io_start(
458
  struct ipc_worker_thread_data *worker_thread_data,
459
  int fd)
460
0
{
461
0
  struct ipc_server_data *server_data = worker_thread_data->server_data;
462
0
  struct pollfd pollfd[1];
463
0
  int result;
464
465
0
  for (;;) {
466
0
    pollfd[0].fd = fd;
467
0
    pollfd[0].events = POLLIN;
468
469
0
    result = poll(pollfd, 1, MY_WAIT_POLL_TIMEOUT_MS);
470
0
    if (result < 0) {
471
0
      if (errno == EINTR)
472
0
        continue;
473
0
      goto cleanup;
474
0
    }
475
476
0
    if (result == 0) {
477
      /* a timeout */
478
479
0
      int in_shutdown;
480
481
0
      pthread_mutex_lock(&server_data->work_available_mutex);
482
0
      in_shutdown = server_data->shutdown_requested;
483
0
      pthread_mutex_unlock(&server_data->work_available_mutex);
484
485
      /*
486
       * If a shutdown is already in progress and this
487
       * client has not started talking yet, just drop it.
488
       */
489
0
      if (in_shutdown)
490
0
        goto cleanup;
491
0
      continue;
492
0
    }
493
494
0
    if (pollfd[0].revents & POLLHUP)
495
0
      goto cleanup;
496
497
0
    if (pollfd[0].revents & POLLIN)
498
0
      return 0;
499
500
0
    goto cleanup;
501
0
  }
502
503
0
cleanup:
504
0
  close(fd);
505
0
  return -1;
506
0
}
507
508
/*
509
 * Receive the request/command from the client and pass it to the
510
 * registered request-callback.  The request-callback will compose
511
 * a response and call our reply-callback to send it to the client.
512
 */
513
static int worker_thread__do_io(
514
  struct ipc_worker_thread_data *worker_thread_data,
515
  int fd)
516
0
{
517
  /* ASSERT NOT holding lock */
518
519
0
  struct strbuf buf = STRBUF_INIT;
520
0
  struct ipc_server_reply_data reply_data;
521
0
  int ret = 0;
522
523
0
  reply_data.magic = MAGIC_SERVER_REPLY_DATA;
524
0
  reply_data.worker_thread_data = worker_thread_data;
525
526
0
  reply_data.fd = fd;
527
528
0
  ret = read_packetized_to_strbuf(
529
0
    reply_data.fd, &buf,
530
0
    PACKET_READ_GENTLE_ON_EOF | PACKET_READ_GENTLE_ON_READ_ERROR);
531
0
  if (ret >= 0) {
532
0
    ret = worker_thread_data->server_data->application_cb(
533
0
      worker_thread_data->server_data->application_data,
534
0
      buf.buf, buf.len, do_io_reply_callback, &reply_data);
535
536
0
    packet_flush_gently(reply_data.fd);
537
0
  }
538
0
  else {
539
    /*
540
     * The client probably disconnected/shutdown before it
541
     * could send a well-formed message.  Ignore it.
542
     */
543
0
  }
544
545
0
  strbuf_release(&buf);
546
0
  close(reply_data.fd);
547
548
0
  return ret;
549
0
}
550
551
/*
552
 * Block SIGPIPE on the current thread (so that we get EPIPE from
553
 * write() rather than an actual signal).
554
 *
555
 * Note that using sigchain_push() and _pop() to control SIGPIPE
556
 * around our IO calls is not thread safe:
557
 * [] It uses a global stack of handler frames.
558
 * [] It uses ALLOC_GROW() to resize it.
559
 * [] Finally, according to the `signal(2)` man-page:
560
 *    "The effects of `signal()` in a multithreaded process are unspecified."
561
 */
562
static void thread_block_sigpipe(sigset_t *old_set)
563
0
{
564
0
  sigset_t new_set;
565
566
0
  sigemptyset(&new_set);
567
0
  sigaddset(&new_set, SIGPIPE);
568
569
0
  sigemptyset(old_set);
570
0
  pthread_sigmask(SIG_BLOCK, &new_set, old_set);
571
0
}
572
573
/*
574
 * Thread proc for an IPC worker thread.  It handles a series of
575
 * connections from clients.  It pulls the next fd from the queue
576
 * processes it, and then waits for the next client.
577
 *
578
 * Block SIGPIPE in this worker thread for the life of the thread.
579
 * This avoids stray (and sometimes delayed) SIGPIPE signals caused
580
 * by client errors and/or when we are under extremely heavy IO load.
581
 *
582
 * This means that the application callback will have SIGPIPE blocked.
583
 * The callback should not change it.
584
 */
585
static void *worker_thread_proc(void *_worker_thread_data)
586
0
{
587
0
  struct ipc_worker_thread_data *worker_thread_data = _worker_thread_data;
588
0
  struct ipc_server_data *server_data = worker_thread_data->server_data;
589
0
  sigset_t old_set;
590
0
  int fd, io;
591
0
  int ret;
592
593
0
  trace2_thread_start("ipc-worker");
594
595
0
  thread_block_sigpipe(&old_set);
596
597
0
  for (;;) {
598
0
    fd = worker_thread__wait_for_connection(worker_thread_data);
599
0
    if (fd == -1)
600
0
      break; /* in shutdown */
601
602
0
    io = worker_thread__wait_for_io_start(worker_thread_data, fd);
603
0
    if (io == -1)
604
0
      continue; /* client hung up without sending anything */
605
606
0
    ret = worker_thread__do_io(worker_thread_data, fd);
607
608
0
    if (ret == SIMPLE_IPC_QUIT) {
609
0
      trace2_data_string("ipc-worker", NULL, "queue_stop_async",
610
0
             "application_quit");
611
      /*
612
       * The application layer is telling the ipc-server
613
       * layer to shutdown.
614
       *
615
       * We DO NOT have a response to send to the client.
616
       *
617
       * Queue an async stop (to stop the other threads) and
618
       * allow this worker thread to exit now (no sense waiting
619
       * for the thread-pool shutdown signal).
620
       *
621
       * Other non-idle worker threads are allowed to finish
622
       * responding to their current clients.
623
       */
624
0
      ipc_server_stop_async(server_data);
625
0
      break;
626
0
    }
627
0
  }
628
629
0
  trace2_thread_exit();
630
0
  return NULL;
631
0
}
632
633
/* A randomly chosen value. */
634
0
#define MY_ACCEPT_POLL_TIMEOUT_MS (60 * 1000)
635
636
/*
637
 * Accept a new client connection on our socket.  This uses non-blocking
638
 * IO so that we can also wait for shutdown requests on our socket-pair
639
 * without actually spinning on a fast timeout.
640
 */
641
static int accept_thread__wait_for_connection(
642
  struct ipc_accept_thread_data *accept_thread_data)
643
0
{
644
0
  struct pollfd pollfd[2];
645
0
  int result;
646
647
0
  for (;;) {
648
0
    pollfd[0].fd = accept_thread_data->fd_wait_shutdown;
649
0
    pollfd[0].events = POLLIN;
650
651
0
    pollfd[1].fd = accept_thread_data->server_socket->fd_socket;
652
0
    pollfd[1].events = POLLIN;
653
654
0
    result = poll(pollfd, 2, MY_ACCEPT_POLL_TIMEOUT_MS);
655
0
    if (result < 0) {
656
0
      if (errno == EINTR)
657
0
        continue;
658
0
      return result;
659
0
    }
660
661
0
    if (result == 0) {
662
      /* a timeout */
663
664
      /*
665
       * If someone deletes or force-creates a new unix
666
       * domain socket at our path, all future clients
667
       * will be routed elsewhere and we silently starve.
668
       * If that happens, just queue a shutdown.
669
       */
670
0
      if (unix_ss_was_stolen(
671
0
            accept_thread_data->server_socket)) {
672
0
        trace2_data_string("ipc-accept", NULL,
673
0
               "queue_stop_async",
674
0
               "socket_stolen");
675
0
        ipc_server_stop_async(
676
0
          accept_thread_data->server_data);
677
0
      }
678
0
      continue;
679
0
    }
680
681
0
    if (pollfd[0].revents & POLLIN) {
682
      /* shutdown message queued to socketpair */
683
0
      return -1;
684
0
    }
685
686
0
    if (pollfd[1].revents & POLLIN) {
687
      /* a connection is available on server_socket */
688
689
0
      int client_fd =
690
0
        accept(accept_thread_data->server_socket->fd_socket,
691
0
               NULL, NULL);
692
0
      if (client_fd >= 0)
693
0
        return client_fd;
694
695
      /*
696
       * An error here is unlikely -- it probably
697
       * indicates that the connecting process has
698
       * already dropped the connection.
699
       */
700
0
      continue;
701
0
    }
702
703
0
    BUG("unandled poll result errno=%d r[0]=%d r[1]=%d",
704
0
        errno, pollfd[0].revents, pollfd[1].revents);
705
0
  }
706
0
}
707
708
/*
709
 * Thread proc for the IPC server "accept thread".  This waits for
710
 * an incoming socket connection, appends it to the queue of available
711
 * connections, and notifies a worker thread to process it.
712
 *
713
 * Block SIGPIPE in this thread for the life of the thread.  This
714
 * avoids any stray SIGPIPE signals when closing pipe fds under
715
 * extremely heavy loads (such as when the fifo queue is full and we
716
 * drop incoming connections).
717
 */
718
static void *accept_thread_proc(void *_accept_thread_data)
719
0
{
720
0
  struct ipc_accept_thread_data *accept_thread_data = _accept_thread_data;
721
0
  struct ipc_server_data *server_data = accept_thread_data->server_data;
722
0
  sigset_t old_set;
723
724
0
  trace2_thread_start("ipc-accept");
725
726
0
  thread_block_sigpipe(&old_set);
727
728
0
  for (;;) {
729
0
    int client_fd = accept_thread__wait_for_connection(
730
0
      accept_thread_data);
731
732
0
    pthread_mutex_lock(&server_data->work_available_mutex);
733
0
    if (server_data->shutdown_requested) {
734
0
      pthread_mutex_unlock(&server_data->work_available_mutex);
735
0
      if (client_fd >= 0)
736
0
        close(client_fd);
737
0
      break;
738
0
    }
739
740
0
    if (client_fd < 0) {
741
      /* ignore transient accept() errors */
742
0
    }
743
0
    else {
744
0
      fifo_enqueue(server_data, client_fd);
745
0
      pthread_cond_broadcast(&server_data->work_available_cond);
746
0
    }
747
0
    pthread_mutex_unlock(&server_data->work_available_mutex);
748
0
  }
749
750
0
  trace2_thread_exit();
751
0
  return NULL;
752
0
}
753
754
/*
755
 * We can't predict the connection arrival rate relative to the worker
756
 * processing rate, therefore we allow the "accept-thread" to queue up
757
 * a generous number of connections, since we'd rather have the client
758
 * not unnecessarily timeout if we can avoid it.  (The assumption is
759
 * that this will be used for FSMonitor and a few second wait on a
760
 * connection is better than having the client timeout and do the full
761
 * computation itself.)
762
 *
763
 * The FIFO queue size is set to a multiple of the worker pool size.
764
 * This value chosen at random.
765
 */
766
0
#define FIFO_SCALE (100)
767
768
/*
769
 * The backlog value for `listen(2)`.  This doesn't need to huge,
770
 * rather just large enough for our "accept-thread" to wake up and
771
 * queue incoming connections onto the FIFO without the kernel
772
 * dropping any.
773
 *
774
 * This value chosen at random.
775
 */
776
0
#define LISTEN_BACKLOG (50)
777
778
static int create_listener_socket(
779
  const char *path,
780
  const struct ipc_server_opts *ipc_opts,
781
  struct unix_ss_socket **new_server_socket)
782
0
{
783
0
  struct unix_ss_socket *server_socket = NULL;
784
0
  struct unix_stream_listen_opts uslg_opts = UNIX_STREAM_LISTEN_OPTS_INIT;
785
0
  int ret;
786
787
0
  uslg_opts.listen_backlog_size = LISTEN_BACKLOG;
788
0
  uslg_opts.disallow_chdir = ipc_opts->uds_disallow_chdir;
789
790
0
  ret = unix_ss_create(path, &uslg_opts, -1, &server_socket);
791
0
  if (ret)
792
0
    return ret;
793
794
0
  if (set_socket_blocking_flag(server_socket->fd_socket, 1)) {
795
0
    int saved_errno = errno;
796
0
    unix_ss_free(server_socket);
797
0
    errno = saved_errno;
798
0
    return -1;
799
0
  }
800
801
0
  *new_server_socket = server_socket;
802
803
0
  trace2_data_string("ipc-server", NULL, "listen-with-lock", path);
804
0
  return 0;
805
0
}
806
807
static int setup_listener_socket(
808
  const char *path,
809
  const struct ipc_server_opts *ipc_opts,
810
  struct unix_ss_socket **new_server_socket)
811
0
{
812
0
  int ret, saved_errno;
813
814
0
  trace2_region_enter("ipc-server", "create-listener_socket", NULL);
815
816
0
  ret = create_listener_socket(path, ipc_opts, new_server_socket);
817
818
0
  saved_errno = errno;
819
0
  trace2_region_leave("ipc-server", "create-listener_socket", NULL);
820
0
  errno = saved_errno;
821
822
0
  return ret;
823
0
}
824
825
/*
826
 * Start IPC server in a pool of background threads.
827
 */
828
int ipc_server_init_async(struct ipc_server_data **returned_server_data,
829
        const char *path, const struct ipc_server_opts *opts,
830
        ipc_server_application_cb *application_cb,
831
        void *application_data)
832
0
{
833
0
  struct unix_ss_socket *server_socket = NULL;
834
0
  struct ipc_server_data *server_data;
835
0
  int sv[2];
836
0
  int k;
837
0
  int ret;
838
0
  int nr_threads = opts->nr_threads;
839
840
0
  *returned_server_data = NULL;
841
842
  /*
843
   * Create a socketpair and set sv[1] to non-blocking.  This
844
   * will used to send a shutdown message to the accept-thread
845
   * and allows the accept-thread to wait on EITHER a client
846
   * connection or a shutdown request without spinning.
847
   */
848
0
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0)
849
0
    return -1;
850
851
0
  if (set_socket_blocking_flag(sv[1], 1)) {
852
0
    int saved_errno = errno;
853
0
    close(sv[0]);
854
0
    close(sv[1]);
855
0
    errno = saved_errno;
856
0
    return -1;
857
0
  }
858
859
0
  ret = setup_listener_socket(path, opts, &server_socket);
860
0
  if (ret) {
861
0
    int saved_errno = errno;
862
0
    close(sv[0]);
863
0
    close(sv[1]);
864
0
    errno = saved_errno;
865
0
    return ret;
866
0
  }
867
868
0
  server_data = xcalloc(1, sizeof(*server_data));
869
0
  server_data->magic = MAGIC_SERVER_DATA;
870
0
  server_data->application_cb = application_cb;
871
0
  server_data->application_data = application_data;
872
0
  strbuf_init(&server_data->buf_path, 0);
873
0
  strbuf_addstr(&server_data->buf_path, path);
874
875
0
  if (nr_threads < 1)
876
0
    nr_threads = 1;
877
878
0
  pthread_mutex_init(&server_data->work_available_mutex, NULL);
879
0
  pthread_cond_init(&server_data->work_available_cond, NULL);
880
881
0
  server_data->queue_size = nr_threads * FIFO_SCALE;
882
0
  CALLOC_ARRAY(server_data->fifo_fds, server_data->queue_size);
883
884
0
  server_data->accept_thread =
885
0
    xcalloc(1, sizeof(*server_data->accept_thread));
886
0
  server_data->accept_thread->magic = MAGIC_ACCEPT_THREAD_DATA;
887
0
  server_data->accept_thread->server_data = server_data;
888
0
  server_data->accept_thread->server_socket = server_socket;
889
0
  server_data->accept_thread->fd_send_shutdown = sv[0];
890
0
  server_data->accept_thread->fd_wait_shutdown = sv[1];
891
892
  /*
893
   * Hold work-available mutex so that no work can start until
894
   * we unlock it.
895
   */
896
0
  pthread_mutex_lock(&server_data->work_available_mutex);
897
898
0
  if (pthread_create(&server_data->accept_thread->pthread_id, NULL,
899
0
         accept_thread_proc, server_data->accept_thread))
900
0
    die_errno(_("could not start accept_thread '%s'"), path);
901
902
0
  for (k = 0; k < nr_threads; k++) {
903
0
    struct ipc_worker_thread_data *wtd;
904
905
0
    wtd = xcalloc(1, sizeof(*wtd));
906
0
    wtd->magic = MAGIC_WORKER_THREAD_DATA;
907
0
    wtd->server_data = server_data;
908
909
0
    if (pthread_create(&wtd->pthread_id, NULL, worker_thread_proc,
910
0
           wtd)) {
911
0
      if (k == 0)
912
0
        die(_("could not start worker[0] for '%s'"),
913
0
            path);
914
      /*
915
       * Limp along with the thread pool that we have.
916
       */
917
0
      break;
918
0
    }
919
920
0
    wtd->next_thread = server_data->worker_thread_list;
921
0
    server_data->worker_thread_list = wtd;
922
0
  }
923
924
0
  *returned_server_data = server_data;
925
0
  return 0;
926
0
}
927
928
void ipc_server_start_async(struct ipc_server_data *server_data)
929
0
{
930
0
  if (!server_data || server_data->started)
931
0
    return;
932
933
0
  server_data->started = 1;
934
0
  pthread_mutex_unlock(&server_data->work_available_mutex);
935
0
}
936
937
/*
938
 * Gently tell the IPC server treads to shutdown.
939
 * Can be run on any thread.
940
 */
941
int ipc_server_stop_async(struct ipc_server_data *server_data)
942
0
{
943
  /* ASSERT NOT holding mutex */
944
945
0
  int fd;
946
947
0
  if (!server_data)
948
0
    return 0;
949
950
0
  trace2_region_enter("ipc-server", "server-stop-async", NULL);
951
952
  /* If we haven't started yet, we are already holding lock. */
953
0
  if (server_data->started)
954
0
    pthread_mutex_lock(&server_data->work_available_mutex);
955
956
0
  server_data->shutdown_requested = 1;
957
958
  /*
959
   * Write a byte to the shutdown socket pair to wake up the
960
   * accept-thread.
961
   */
962
0
  if (write(server_data->accept_thread->fd_send_shutdown, "Q", 1) < 0)
963
0
    error_errno("could not write to fd_send_shutdown");
964
965
  /*
966
   * Drain the queue of existing connections.
967
   */
968
0
  while ((fd = fifo_dequeue(server_data)) != -1)
969
0
    close(fd);
970
971
  /*
972
   * Gently tell worker threads to stop processing new connections
973
   * and exit.  (This does not abort in-process conversations.)
974
   */
975
0
  pthread_cond_broadcast(&server_data->work_available_cond);
976
977
0
  pthread_mutex_unlock(&server_data->work_available_mutex);
978
979
0
  trace2_region_leave("ipc-server", "server-stop-async", NULL);
980
981
0
  return 0;
982
0
}
983
984
/*
985
 * Wait for all IPC server threads to stop.
986
 */
987
int ipc_server_await(struct ipc_server_data *server_data)
988
0
{
989
0
  pthread_join(server_data->accept_thread->pthread_id, NULL);
990
991
0
  if (!server_data->shutdown_requested)
992
0
    BUG("ipc-server: accept-thread stopped for '%s'",
993
0
        server_data->buf_path.buf);
994
995
0
  while (server_data->worker_thread_list) {
996
0
    struct ipc_worker_thread_data *wtd =
997
0
      server_data->worker_thread_list;
998
999
0
    pthread_join(wtd->pthread_id, NULL);
1000
1001
0
    server_data->worker_thread_list = wtd->next_thread;
1002
0
    free(wtd);
1003
0
  }
1004
1005
0
  server_data->is_stopped = 1;
1006
1007
0
  return 0;
1008
0
}
1009
1010
void ipc_server_free(struct ipc_server_data *server_data)
1011
0
{
1012
0
  struct ipc_accept_thread_data * accept_thread_data;
1013
1014
0
  if (!server_data)
1015
0
    return;
1016
1017
0
  if (!server_data->is_stopped)
1018
0
    BUG("cannot free ipc-server while running for '%s'",
1019
0
        server_data->buf_path.buf);
1020
1021
0
  accept_thread_data = server_data->accept_thread;
1022
0
  if (accept_thread_data) {
1023
0
    unix_ss_free(accept_thread_data->server_socket);
1024
1025
0
    if (accept_thread_data->fd_send_shutdown != -1)
1026
0
      close(accept_thread_data->fd_send_shutdown);
1027
0
    if (accept_thread_data->fd_wait_shutdown != -1)
1028
0
      close(accept_thread_data->fd_wait_shutdown);
1029
1030
0
    free(server_data->accept_thread);
1031
0
  }
1032
1033
0
  while (server_data->worker_thread_list) {
1034
0
    struct ipc_worker_thread_data *wtd =
1035
0
      server_data->worker_thread_list;
1036
1037
0
    server_data->worker_thread_list = wtd->next_thread;
1038
0
    free(wtd);
1039
0
  }
1040
1041
0
  pthread_cond_destroy(&server_data->work_available_cond);
1042
0
  pthread_mutex_destroy(&server_data->work_available_mutex);
1043
1044
0
  strbuf_release(&server_data->buf_path);
1045
1046
0
  free(server_data->fifo_fds);
1047
0
  free(server_data);
1048
0
}