From: Martin Schwenke Date: Mon, 13 Jan 2020 10:04:54 +0000 (+1100) Subject: ctdb-daemon: Shut down if interactive and stdin is closed X-Git-Tag: ldb-2.1.1~235 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cf460bd9c4ae1e0de871a6c4980a2c365e82550a;p=thirdparty%2Fsamba.git ctdb-daemon: Shut down if interactive and stdin is closed This allows a test environment to simply close its end of a pipe to cleanly shutdown ctdbd. Like in smbd, this is only done if stdin is a pipe or a socket. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c index cc688b07e9c..c4ab2dbc3d3 100644 --- a/ctdb/server/ctdb_daemon.c +++ b/ctdb/server/ctdb_daemon.c @@ -1389,6 +1389,56 @@ static void ctdb_set_my_pnn(struct ctdb_context *ctdb) D_NOTICE("PNN is %u\n", ctdb->pnn); } +static void stdin_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + struct ctdb_context *ctdb = talloc_get_type_abort( + private_data, struct ctdb_context); + ssize_t nread; + char c; + + nread = read(STDIN_FILENO, &c, 1); + if (nread != 1) { + D_ERR("stdin closed, exiting\n"); + talloc_free(fde); + ctdb_shutdown_sequence(ctdb, EPIPE); + } +} + +static int setup_stdin_handler(struct ctdb_context *ctdb) +{ + struct tevent_fd *fde; + struct stat st; + int ret; + + ret = fstat(STDIN_FILENO, &st); + if (ret != 0) { + /* Problem with stdin, ignore... */ + DBG_INFO("Can't fstat() stdin\n"); + return 0; + } + + if (!S_ISFIFO(st.st_mode)) { + DBG_INFO("Not a pipe...\n"); + return 0; + } + + fde = tevent_add_fd(ctdb->ev, + ctdb, + STDIN_FILENO, + TEVENT_FD_READ, + stdin_handler, + ctdb); + if (fde == NULL) { + return ENOMEM; + } + + DBG_INFO("Set up stdin handler\n"); + return 0; +} + /* start the protocol going as a daemon */ @@ -1448,6 +1498,15 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork) ctdb_set_child_logging(ctdb); } + /* Exit if stdin is closed */ + if (!do_fork) { + ret = setup_stdin_handler(ctdb); + if (ret != 0) { + DBG_ERR("Failed to setup stdin handler\n"); + exit(1); + } + } + TALLOC_FREE(ctdb->srv); if (srvid_init(ctdb, &ctdb->srv) != 0) { DEBUG(DEBUG_CRIT,("Failed to setup message srvid context\n"));