From dde9fb431bc41e5334f416ebc0fa1d7da0b70e5a Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Sun, 16 Aug 2026 16:43:26 +0900 Subject: [PATCH] test: probe the dead IBus address in-process rejectold forked and re-execed the test binary with --reject-address just to call dbus_connection_open_private once against the crashed daemon's abstract address, then waited on the helper, drained its stderr pipe and checked its exit status. An abstract socket with no listener refuses the connection immediately, so the call cannot block and needs no separate process. Open the address in-process and require a null connection with the D-Bus error set, freeing the error afterwards. This drops the helper process, its stderr capture, the Test.helper fields and the argv dispatch in main. killdaemon stays; the daemons still need it. --- tests/daemon_restart_test.c | 124 ++++-------------------------------- 1 file changed, 12 insertions(+), 112 deletions(-) diff --git a/tests/daemon_restart_test.c b/tests/daemon_restart_test.c index edfd4ae..d4080c4 100644 --- a/tests/daemon_restart_test.c +++ b/tests/daemon_restart_test.c @@ -1,7 +1,5 @@ #define _GNU_SOURCE #include -#include -#include #include #include #include @@ -29,7 +27,6 @@ struct Test Live l; Daemon first; Daemon second; - Daemon helper; pid_t firstpid; int ipcfirst; int ipcnew; @@ -48,7 +45,6 @@ setup(Test *t) memset(t, 0, sizeof *t); daemoninit(&t->first, "first daemon"); daemoninit(&t->second, "second daemon"); - daemoninit(&t->helper, "old-address helper"); t->firstpid = -1; t->ipcfirst = -1; t->ipcnew = -1; @@ -245,114 +241,25 @@ checkstale(Test *t) return 1; } +/* The dead daemon's abstract socket has no listener, so this must fail. */ static int -helpermain(char *address) +rejectold(Test *t, char *where) { DBusConnection *conn; DBusError err; + int ok; dbus_error_init(&err); - conn = dbus_connection_open_private(address, &err); + conn = dbus_connection_open_private(t->firstaddress, &err); if(conn != NULL){ dbus_connection_set_exit_on_disconnect(conn, FALSE); closebus(&conn); - dbus_error_free(&err); - fprintf(stderr, "old private address unexpectedly accepted a connection\n"); - return 1; - } - if(!dbus_error_is_set(&err)){ - fprintf(stderr, "old private address failed without a D-Bus error\n"); - dbus_error_free(&err); - return 2; - } + ok = fail("old private address accepted a connection %s", where); + }else + ok = dbus_error_is_set(&err) || + fail("old private address failed without a D-Bus error %s", where); dbus_error_free(&err); - return 0; -} - -static int -rejectold(Test *t, char *self, char *where) -{ - struct pollfd pfd; - int errpipe[2], fd, n, status, timeout; - long maxfd; - pid_t pid; - int64_t deadline; - - if(pipe2(errpipe, O_CLOEXEC|O_NONBLOCK) < 0) - return fail("pipe old-address helper: %s", strerror(errno)); - pid = fork(); - if(pid < 0){ - close(errpipe[0]); - close(errpipe[1]); - return fail("fork old-address helper: %s", strerror(errno)); - } - if(pid == 0){ - close(errpipe[0]); - if(dup2(errpipe[1], STDERR_FILENO) < 0) - _exit(126); - close(errpipe[1]); - if(close_range(3, UINT_MAX, 0) < 0){ - maxfd = sysconf(_SC_OPEN_MAX); - if(maxfd < 0) - maxfd = 1024; - for(fd = 3; fd < maxfd; fd++) - close(fd); - } - execl(self, self, "--reject-address", t->firstaddress, (char*)0); - dprintf(STDERR_FILENO, "exec %s: %s\n", self, strerror(errno)); - _exit(127); - } - close(errpipe[1]); - t->helper.pid = pid; - t->helper.errfd = errpipe[0]; - deadline = nowms() + Calltimeout; - for(;;){ - do - n = waitpid(pid, &status, WNOHANG); - while(n < 0 && errno == EINTR); - if(n == pid){ - t->helper.pid = -1; - break; - } - if(n < 0){ - fail("wait old-address helper %ld: %s", (long)pid, strerror(errno)); - if(errno == ECHILD) - t->helper.pid = -1; - else - killdaemon(&t->helper, NULL); - return 0; - } - timeout = leftms(deadline); - if(timeout == 0){ - fail("old private address open did not fail promptly %s", where); - killdaemon(&t->helper, NULL); - return 0; - } - pfd.fd = t->helper.errfd; - pfd.events = POLLIN|POLLHUP; - pfd.revents = 0; - n = poll(&pfd, 1, timeout); - if(n < 0 && errno == EINTR) - continue; - if(n < 0){ - fail("poll old-address helper: %s", strerror(errno)); - killdaemon(&t->helper, NULL); - return 0; - } - if(pfd.revents & (POLLERR|POLLNVAL)){ - fail("old-address helper pipe became unusable: %#x", pfd.revents); - killdaemon(&t->helper, NULL); - return 0; - } - if(pfd.revents & (POLLIN|POLLHUP)) - readerrors(&t->helper); - } - if(!closeerrors(&t->helper)) - return 0; - if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) - return fail("old private address helper failed %s with status %#x", - where, status); - return 1; + return ok; } static int @@ -400,8 +307,6 @@ cleanup(Test *t) ok = fail("close persistent IPC client: %s", strerror(errno)); t->ipcfirst = -1; } - if(!killdaemon(&t->helper, NULL)) - ok = 0; if(!killdaemon(&t->first, NULL)) ok = 0; if(!stopdaemon(&t->second)) @@ -410,15 +315,13 @@ cleanup(Test *t) ok = 0; if(!closeerrors(&t->second)) ok = 0; - if(!closeerrors(&t->helper)) - ok = 0; if(!liveclean(&t->l)) ok = 0; return ok; } static int -runrestart(Test *t, char *self, char *program, char *mapdir) +runrestart(Test *t, char *program, char *mapdir) { if(!startdaemon(&t->l, &t->first, program, mapdir)) return 0; @@ -427,7 +330,7 @@ runrestart(Test *t, char *self, char *program, char *mapdir) !privateaddress(t->firstaddress, t->firstpid) || !openpersistent(t)) return 0; if(!hardcrash(t) || !waitipcclosed(t) || !waitbusclosed(t) || - !checkstale(t) || !rejectold(t, self, "after hard crash")) + !checkstale(t) || !rejectold(t, "after hard crash")) return 0; closebus(&t->busfirst); if(close(t->ipcfirst) < 0) @@ -450,21 +353,18 @@ main(int argc, char **argv) int ok; testname = "daemon_restart_test"; - if(argc == 3 && strcmp(argv[1], "--reject-address") == 0) - return helpermain(argv[2]); if(argc != 3){ fprintf(stderr, "usage: daemon_restart_test strans mapdir\n"); return 2; } ok = setup(&test); if(ok) - ok = runrestart(&test, argv[0], argv[1], argv[2]); + ok = runrestart(&test, argv[1], argv[2]); if(!cleanup(&test)) ok = 0; if(!ok){ showerrors(&test.first); showerrors(&test.second); - showerrors(&test.helper); return 1; } printf("daemon hard-crash endpoint recovery: ok\n");