X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fqueue.c;h=bb75c99cd13c393006327958057d01b162ce91ab;hb=46d2a5e6f6e7709d172903b13945d23fc0a2c888;hp=8c9f5cb2ac37e49c0dfba3c0973802b1aa08e93c;hpb=45907b9dd8939da28facc8032ff2df8549c22c7f;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/queue.c b/src/src/queue.c index 8c9f5cb2a..bb75c99cd 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -353,6 +353,7 @@ uschar *log_detail = NULL; int subcount = 0; uschar subdirs[64]; pid_t qpid[4] = {0}; /* Parallelism factor for q2stage 1st phase */ +BOOL single_id = FALSE; #ifdef MEASURE_TIMING report_time_since(×tamp_startup, US"queue_run start"); @@ -405,6 +406,9 @@ if (!recurse) queue_name, log_detail); else log_write(L_queue_run, LOG_MAIN, "Start queue run: %s", log_detail); + + single_id = start_id && stop_id && !f.queue_2stage + && Ustrcmp(start_id, stop_id) == 0; } /* If deliver_selectstring is a regex, compile it. */ @@ -483,18 +487,17 @@ for (int i = queue_run_in_order ? -1 : 0; int i; if (qpid[f.running_in_test_harness ? 0 : nelem(qpid) - 1]) { - DEBUG(D_queue_run) debug_printf("q2stage waiting for child\n"); + DEBUG(D_queue_run) debug_printf("q2stage waiting for child %d\n", (int)qpid[0]); waitpid(qpid[0], NULL, 0); DEBUG(D_queue_run) debug_printf("q2stage reaped child %d\n", (int)qpid[0]); - for (i = 0; i < nelem(qpid) - 1; i++) qpid[i] = qpid[i+1]; + if (f.running_in_test_harness) i = 0; + else for (i = 0; i < nelem(qpid) - 1; i++) qpid[i] = qpid[i+1]; qpid[i] = 0; } else for (i = 0; qpid[i]; ) i++; - DEBUG(D_queue_run) debug_printf("q2stage forking\n"); - if ((qpid[i] = fork())) + if ((qpid[i] = exim_fork(US"qrun-phase-one"))) continue; /* parent loops around */ - DEBUG(D_queue_run) debug_printf("q2stage child\n"); } /* Skip this message unless it's within the ID limits */ @@ -645,13 +648,14 @@ for (int i = queue_run_in_order ? -1 : 0; report_time_since(×tamp_startup, US"queue msg selected"); #endif - if ((pid = fork()) == 0) +single_item_retry: + if ((pid = exim_fork(US"qrun-delivery")) == 0) { int rc; - testharness_pause_ms(100); (void)close(pfd[pipe_read]); rc = deliver_message(fq->text, force_delivery, FALSE); - exim_underbar_exit(rc == DELIVER_NOT_ATTEMPTED); + exim_underbar_exit(rc == DELIVER_NOT_ATTEMPTED + ? EXIT_FAILURE : EXIT_SUCCESS); } if (pid < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork of delivery process from " @@ -676,6 +680,18 @@ for (int i = queue_run_in_order ? -1 : 0; "queue run: process %d crashed with signal %d while delivering %s", (int)pid, status & 0x00ff, fq->text); + /* If single-item delivery was untried (likely due to locking) + retry once after a delay */ + + if (status & 0xff00 && single_id) + { + single_id = FALSE; + DEBUG(D_queue_run) debug_printf("qrun single-item pause before retry\n"); + millisleep(500); + DEBUG(D_queue_run) debug_printf("qrun single-item retry after pause\n"); + goto single_item_retry; + } + /* Before continuing, wait till the pipe gets closed at the far end. This tells us that any children created by the delivery to re-use any SMTP channels have all finished. Since no process actually writes to the pipe, @@ -691,7 +707,7 @@ for (int i = queue_run_in_order ? -1 : 0; /* If initial of a 2-phase run, we are a child - so just exit */ if (f.queue_2stage && !queue_run_in_order) - exim_exit(EXIT_SUCCESS, US"2-phase child"); + exim_exit(EXIT_SUCCESS); /* If we are in the test harness, and this is not the first of a 2-stage queue run, update fudged queue times. */ @@ -708,7 +724,7 @@ for (int i = queue_run_in_order ? -1 : 0; go_around: /* If initial of a 2-phase run, we are a child - so just exit */ if (f.queue_2stage && !queue_run_in_order) - exim_exit(EXIT_SUCCESS, US"2-phase child"); + exim_exit(EXIT_SUCCESS); } /* End loop for list of messages */ tree_nonrecipients = NULL; @@ -1394,13 +1410,13 @@ switch(action) parse_extract_address(argv[recipients_arg], &errmess, &start, &end, &domain, (action == MSG_EDIT_SENDER)); - if (recipient == NULL) + if (!recipient) { yield = FALSE; printf("- error while %s:\n bad address %s: %s\n", doing, argv[recipients_arg], errmess); } - else if (recipient[0] != 0 && domain == 0) + else if (*recipient && domain == 0) { yield = FALSE; printf("- error while %s:\n bad address %s: " @@ -1530,17 +1546,16 @@ memcpy(buf+1, msgid, MESSAGE_ID_LENGTH+1); if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) >= 0) { struct sockaddr_un sa_un = {.sun_family = AF_UNIX}; - int slen; #ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS int len = offsetof(struct sockaddr_un, sun_path) + 1 + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s", - NOTIFIER_SOCKET_NAME); + expand_string(notifier_socket)); sa_un.sun_path[0] = 0; #else int len = offsetof(struct sockaddr_un, sun_path) - + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s/%s", - spool_directory, NOTIFIER_SOCKET_NAME); + + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s", + expand_string(notifier_socket)); #endif if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sa_un, len) < 0)