Skip to content

Commit

Permalink
Add support to zed to be a Windows Service
Browse files Browse the repository at this point in the history
Signed-off-by: Jorgen Lundman <[email protected]>
  • Loading branch information
lundman committed Nov 21, 2024
1 parent 15ba867 commit a2b2709
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 39 deletions.
53 changes: 53 additions & 0 deletions cmd/zed/os/windows/zed_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
98 changes: 59 additions & 39 deletions cmd/zed/zed.c
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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);
}

0 comments on commit a2b2709

Please sign in to comment.