From a2b27097dd2575af9af7035d2450e57e9232b3b0 Mon Sep 17 00:00:00 2001 From: Jorgen Lundman Date: Thu, 21 Nov 2024 14:46:55 +0900 Subject: [PATCH] Add support to zed to be a Windows Service Signed-off-by: Jorgen Lundman --- cmd/zed/os/windows/zed_exec.c | 53 +++++++++++++++++++ cmd/zed/zed.c | 98 +++++++++++++++++++++-------------- 2 files changed, 112 insertions(+), 39 deletions(-) diff --git a/cmd/zed/os/windows/zed_exec.c b/cmd/zed/os/windows/zed_exec.c index b7dc48bfb47a..2a407e4d62be 100644 --- a/cmd/zed/os/windows/zed_exec.c +++ b/cmd/zed/os/windows/zed_exec.c @@ -510,3 +510,56 @@ zed_exec_process(uint64_t eid, const char *class, const char *subclass, free(e); return (0); } + +void main_loop(void); + +static SERVICE_STATUS ServiceStatus; +static SERVICE_STATUS_HANDLE hStatus; + +// Service Control Handler +static void WINAPI +ServiceControlHandler(DWORD controlCode) +{ + switch (controlCode) { + case SERVICE_CONTROL_STOP: + ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + // Perform cleanup + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(hStatus, &ServiceStatus); + break; + default: + break; + } +} + +static void WINAPI +ServiceMain(DWORD argc, LPTSTR *argv) +{ + ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + hStatus = RegisterServiceCtrlHandler(TEXT("OpenZFS_zed"), + ServiceControlHandler); + if (!hStatus) + return; + + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus(hStatus, &ServiceStatus); + + // Service logic here, e.g., initializing zed's main functionality + // while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) { + main_loop(); + // } +} + +void +win_run_loop(void) +{ + SERVICE_TABLE_ENTRY ServiceTable[] = { + { TEXT("OpenZFS_zed"), (LPSERVICE_MAIN_FUNCTION) ServiceMain }, + { NULL, NULL } + }; + /* Blocks until Service is stopped */ + StartServiceCtrlDispatcher(ServiceTable); + exit(EXIT_SUCCESS); +} diff --git a/cmd/zed/zed.c b/cmd/zed/zed.c index 4a413af6f927..a37113aa7c71 100644 --- a/cmd/zed/zed.c +++ b/cmd/zed/zed.c @@ -210,53 +210,22 @@ _finish_daemonize(void) /* Notify parent that daemonization is complete. */ zed_log_pipe_close_writes(); + +#ifdef _WIN32 + void win_run_loop(void); + win_run_loop(); +#endif } /* - * ZFS Event Daemon (ZED). + * Main loop for ZED. */ -int -main(int argc, char *argv[]) +void +main_loop(void) { struct zed_conf zcp; uint64_t saved_eid; int64_t saved_etime[2]; - - zed_log_init(argv[0]); - zed_log_stderr_open(LOG_NOTICE); - zed_conf_init(&zcp); - zed_conf_parse_opts(&zcp, argc, argv); - if (zcp.do_verbose) - zed_log_stderr_open(LOG_INFO); - - if (geteuid() != 0) - zed_log_die("Must be run as root"); - - zed_file_close_from(STDERR_FILENO + 1); - - (void) umask(0); - - if (chdir("/") < 0) - zed_log_die("Failed to change to root directory"); - - if (zed_conf_scan_dir(&zcp) < 0) - exit(EXIT_FAILURE); - - if (!zcp.do_foreground) { - _start_daemonize(); - zed_log_syslog_open(LOG_DAEMON); - } - _setup_sig_handlers(); - - if (zcp.do_memlock) - _lock_memory(); - - if ((zed_conf_write_pid(&zcp) < 0) && (!zcp.do_force)) - exit(EXIT_FAILURE); - - if (!zcp.do_foreground) - _finish_daemonize(); - zed_log_msg(LOG_NOTICE, "ZFS Event Daemon %s-%s (PID %d)", ZFS_META_VERSION, ZFS_META_RELEASE, (int)getpid()); @@ -306,5 +275,56 @@ main(int argc, char *argv[]) out: zed_conf_destroy(&zcp); zed_log_fini(); +} + +/* + * ZFS Event Daemon (ZED). + */ +int +main(int argc, char *argv[]) +{ + struct zed_conf zcp; + uint64_t saved_eid; + int64_t saved_etime[2]; + + zed_log_init(argv[0]); + zed_log_stderr_open(LOG_NOTICE); + zed_conf_init(&zcp); + zed_conf_parse_opts(&zcp, argc, argv); + if (zcp.do_verbose) + zed_log_stderr_open(LOG_INFO); + + if (geteuid() != 0) + zed_log_die("Must be run as root"); + + zed_file_close_from(STDERR_FILENO + 1); + + (void) umask(0); + + if (chdir("/") < 0) + zed_log_die("Failed to change to root directory"); + + if (zed_conf_scan_dir(&zcp) < 0) + exit(EXIT_FAILURE); + + if (!zcp.do_foreground) { + _start_daemonize(); + zed_log_syslog_open(LOG_DAEMON); + } + _setup_sig_handlers(); + + if (zcp.do_memlock) + _lock_memory(); + + if ((zed_conf_write_pid(&zcp) < 0) && (!zcp.do_force)) + exit(EXIT_FAILURE); + + if (!zcp.do_foreground) + _finish_daemonize(); + + /* Windows daemonize needs to specify function for thread */ + + main_loop(); + exit(EXIT_SUCCESS); }