Blame tools/fpgad/fpgad.c

Packit 6639f8
// Copyright(c) 2018-2020, Intel Corporation
Packit 6639f8
//
Packit 6639f8
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 6639f8
// modification, are permitted provided that the following conditions are met:
Packit 6639f8
//
Packit 6639f8
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 6639f8
//   this list of conditions and the following disclaimer.
Packit 6639f8
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 6639f8
//   this list of conditions and the following disclaimer in the documentation
Packit 6639f8
//   and/or other materials provided with the distribution.
Packit 6639f8
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 6639f8
//   may be used to  endorse or promote  products derived  from this  software
Packit 6639f8
//   without specific prior written permission.
Packit 6639f8
//
Packit 6639f8
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 6639f8
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 6639f8
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 6639f8
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 6639f8
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 6639f8
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 6639f8
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 6639f8
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 6639f8
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 6639f8
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 6639f8
// POSSIBILITY OF SUCH DAMAGE.
Packit 6639f8
Packit 6639f8
#ifdef HAVE_CONFIG_H
Packit 6639f8
#include <config.h>
Packit 6639f8
#endif // HAVE_CONFIG_H
Packit 6639f8
Packit 6639f8
#include <signal.h>
Packit 6639f8
#include "fpgad.h"
Packit 6639f8
#include "monitor_thread.h"
Packit 6639f8
#include "event_dispatcher_thread.h"
Packit 6639f8
#include "events_api_thread.h"
Packit 6639f8
Packit 6639f8
#ifdef LOG
Packit 6639f8
#undef LOG
Packit 6639f8
#endif
Packit 6639f8
#define LOG(format, ...) \
Packit 6639f8
log_printf("main: " format, ##__VA_ARGS__)
Packit 6639f8
Packit 6639f8
struct fpgad_config global_config;
Packit 6639f8
Packit 6639f8
void sig_handler(int sig, siginfo_t *info, void *unused)
Packit 6639f8
{
Packit 6639f8
	UNUSED_PARAM(info);
Packit 6639f8
	UNUSED_PARAM(unused);
Packit 6639f8
	switch (sig) {
Packit 6639f8
	case SIGINT:
Packit 6639f8
		// Process interrupted.
Packit 6639f8
		LOG("Got SIGINT. Exiting.\n");
Packit 6639f8
		global_config.running = false;
Packit 6639f8
		break;
Packit 6639f8
	case SIGTERM:
Packit 6639f8
		// Process terminated.
Packit 6639f8
		LOG("Got SIGTERM. Exiting.\n");
Packit 6639f8
		global_config.running = false;
Packit 6639f8
		break;
Packit 6639f8
	}
Packit 6639f8
}
Packit 6639f8
Packit 6639f8
int main(int argc, char *argv[])
Packit 6639f8
{
Packit 6639f8
	int res;
Packit 6639f8
	FILE *fp;
Packit 6639f8
Packit 6639f8
	memset(&global_config, 0, sizeof(global_config));
Packit 6639f8
Packit 6639f8
	global_config.poll_interval_usec = 100 * 1000;
Packit 6639f8
	global_config.running = true;
Packit 6639f8
	global_config.api_socket = "/tmp/fpga_event_socket";
Packit 6639f8
	global_config.num_null_gbs = 0;
Packit 6639f8
Packit 6639f8
	log_set(stdout);
Packit 6639f8
Packit 6639f8
	res = cmd_parse_args(&global_config, argc, argv);
Packit 6639f8
	if (res != 0) {
Packit 6639f8
		if (res == -2)
Packit 6639f8
			res = 0;
Packit 6639f8
		else
Packit 6639f8
			LOG("error parsing command line.\n");
Packit 6639f8
		goto out_destroy;
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	if (cmd_canonicalize_paths(&global_config)) {
Packit 6639f8
		LOG("error with paths.\n");
Packit 6639f8
		goto out_destroy;
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	if (global_config.daemon) {
Packit 6639f8
Packit 6639f8
		res = daemonize(sig_handler,
Packit 6639f8
				global_config.filemode,
Packit 6639f8
				global_config.directory);
Packit 6639f8
		if (res != 0) {
Packit 6639f8
			LOG("daemonize failed: %s\n", strerror(res));
Packit 6639f8
			goto out_destroy;
Packit 6639f8
		}
Packit 6639f8
Packit 6639f8
Packit 6639f8
	} else {
Packit 6639f8
		struct sigaction sa;
Packit 6639f8
Packit 6639f8
		memset(&sa, 0, sizeof(sa));
Packit 6639f8
		sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
Packit 6639f8
		sa.sa_sigaction = sig_handler;
Packit 6639f8
Packit 6639f8
		res = sigaction(SIGINT, &sa, NULL);
Packit 6639f8
		if (res < 0) {
Packit 6639f8
			LOG("failed to register SIGINT handler.\n");
Packit 6639f8
			goto out_destroy;
Packit 6639f8
		}
Packit 6639f8
Packit 6639f8
		res = sigaction(SIGTERM, &sa, NULL);
Packit 6639f8
		if (res < 0) {
Packit 6639f8
			LOG("failed to register SIGTERM handler.\n");
Packit 6639f8
			goto out_destroy;
Packit 6639f8
		}
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	if (log_open(global_config.logfile) < 0) {
Packit 6639f8
		LOG("failed to open log file\n");
Packit 6639f8
		res = 1;
Packit 6639f8
		goto out_destroy;
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	fp = fopen(global_config.pidfile, "w");
Packit 6639f8
	if (NULL == fp) {
Packit 6639f8
		LOG("failed to open pid file\n");
Packit 6639f8
		res = 1;
Packit 6639f8
		goto out_destroy;
Packit 6639f8
	}
Packit 6639f8
	fprintf(fp, "%d\n", getpid());
Packit 6639f8
	fclose(fp);
Packit 6639f8
Packit 6639f8
	res = mon_enumerate(&global_config);
Packit 6639f8
	if (res) {
Packit 6639f8
		LOG("OPAE device enumeration failed\n");
Packit 6639f8
		goto out_destroy;
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	res = pthread_create(&global_config.event_dispatcher_thr,
Packit 6639f8
			     NULL,
Packit 6639f8
			     event_dispatcher_thread,
Packit 6639f8
			     &event_dispatcher_config);
Packit 6639f8
	if (res) {
Packit 6639f8
		LOG("failed to create event_dispatcher_thread\n");
Packit 6639f8
		global_config.running = false;
Packit 6639f8
		goto out_destroy;
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	while (!evt_dispatcher_is_ready())
Packit 6639f8
		usleep(1);
Packit 6639f8
Packit 6639f8
	res = pthread_create(&global_config.monitor_thr,
Packit 6639f8
			     NULL,
Packit 6639f8
			     monitor_thread,
Packit 6639f8
			     &monitor_config);
Packit 6639f8
	if (res) {
Packit 6639f8
		LOG("failed to create monitor_thread\n");
Packit 6639f8
		global_config.running = false;
Packit 6639f8
		goto out_stop_event_dispatcher;
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	res = pthread_create(&global_config.events_api_thr,
Packit 6639f8
			     NULL,
Packit 6639f8
			     events_api_thread,
Packit 6639f8
			     &events_api_config);
Packit 6639f8
	if (res) {
Packit 6639f8
		LOG("failed to create events_api_thread\n");
Packit 6639f8
		global_config.running = false;
Packit 6639f8
		goto out_stop_monitor;
Packit 6639f8
	}
Packit 6639f8
Packit 6639f8
	if (pthread_join(global_config.events_api_thr, NULL)) {
Packit 6639f8
		LOG("failed to join events_api_thread\n");
Packit 6639f8
	}
Packit 6639f8
out_stop_monitor:
Packit 6639f8
	if (pthread_join(global_config.monitor_thr, NULL)) {
Packit 6639f8
		LOG("failed to join monitor_thread\n");
Packit 6639f8
	}
Packit 6639f8
out_stop_event_dispatcher:
Packit 6639f8
	if (pthread_join(global_config.event_dispatcher_thr, NULL)) {
Packit 6639f8
		LOG("failed to join event_dispatcher_thread\n");
Packit 6639f8
	}
Packit 6639f8
out_destroy:
Packit 6639f8
	mon_destroy(&global_config);
Packit 6639f8
	cmd_destroy(&global_config);
Packit 6639f8
	log_close();
Packit 6639f8
	return res;
Packit 6639f8
}