|
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 |
#define _GNU_SOURCE
|
|
Packit |
6639f8 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
6639f8 |
#include <config.h>
|
|
Packit |
6639f8 |
#endif // HAVE_CONFIG_H
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#include <getopt.h>
|
|
Packit |
6639f8 |
#include <fcntl.h>
|
|
Packit |
6639f8 |
#include <sys/stat.h>
|
|
Packit |
6639f8 |
#include <sys/types.h>
|
|
Packit |
6639f8 |
#include <pwd.h>
|
|
Packit |
6639f8 |
#include "command_line.h"
|
|
Packit |
6639f8 |
#include "config_file.h"
|
|
Packit |
6639f8 |
#include "monitored_device.h"
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#ifdef LOG
|
|
Packit |
6639f8 |
#undef LOG
|
|
Packit |
6639f8 |
#endif
|
|
Packit |
6639f8 |
#define LOG(format, ...) \
|
|
Packit |
6639f8 |
log_printf("args: " format, ##__VA_ARGS__)
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
extern fpgad_supported_device default_supported_devices_table[];
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#define OPT_STR ":hdl:p:s:n:c:v"
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC struct option longopts[] = {
|
|
Packit |
6639f8 |
{ "help", no_argument, NULL, 'h' },
|
|
Packit |
6639f8 |
{ "daemon", no_argument, NULL, 'd' },
|
|
Packit |
6639f8 |
{ "logfile", required_argument, NULL, 'l' },
|
|
Packit |
6639f8 |
{ "pidfile", required_argument, NULL, 'p' },
|
|
Packit |
6639f8 |
{ "socket", required_argument, NULL, 's' },
|
|
Packit |
6639f8 |
{ "null-bitstream", required_argument, NULL, 'n' },
|
|
Packit |
6639f8 |
{ "config", required_argument, NULL, 'c' },
|
|
Packit |
6639f8 |
{ "version", no_argument, NULL, 'v' },
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
{ 0, 0, 0, 0 }
|
|
Packit |
6639f8 |
};
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#define DEFAULT_DIR_ROOT "/var/lib/opae"
|
|
Packit |
6639f8 |
#define DEFAULT_DIR_ROOT_SIZE 13
|
|
Packit |
6639f8 |
#define DEFAULT_LOG "fpgad.log"
|
|
Packit |
6639f8 |
#define DEFAULT_PID "fpgad.pid"
|
|
Packit |
6639f8 |
#define DEFAULT_CFG "fpgad.cfg"
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
void cmd_show_help(FILE *fptr)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
fprintf(fptr, "Usage: fpgad <options>\n");
|
|
Packit |
6639f8 |
fprintf(fptr, "\n");
|
|
Packit |
6639f8 |
fprintf(fptr, "\t-d,--daemon run as daemon process.\n");
|
|
Packit |
6639f8 |
fprintf(fptr, "\t-l,--logfile <file> the log file for daemon mode [%s].\n", DEFAULT_LOG);
|
|
Packit |
6639f8 |
fprintf(fptr, "\t-p,--pidfile <file> the pid file for daemon mode [%s].\n", DEFAULT_PID);
|
|
Packit |
6639f8 |
fprintf(fptr, "\t-s,--socket <sock> the unix domain socket [/tmp/fpga_event_socket].\n");
|
|
Packit |
6639f8 |
fprintf(fptr, "\t-n,--null-bitstream <file> NULL bitstream (for AP6 handling, may be\n"
|
|
Packit |
6639f8 |
"\t given multiple times).\n");
|
|
Packit |
6639f8 |
fprintf(fptr, "\t-c,--config <file> the configuration file [%s].\n", DEFAULT_CFG);
|
|
Packit |
6639f8 |
fprintf(fptr, "\t-v,--version display the version and exit.\n");
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
STATIC bool cmd_register_null_gbs(struct fpgad_config *c, char *null_gbs_path)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
char *canon_path = NULL;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (c->num_null_gbs < (sizeof(c->null_gbs) / sizeof(c->null_gbs[0]))) {
|
|
Packit |
6639f8 |
canon_path = canonicalize_file_name(null_gbs_path);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (canon_path) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
memset(&c->null_gbs[c->num_null_gbs], 0,
|
|
Packit |
6639f8 |
sizeof(opae_bitstream_info));
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (opae_load_bitstream(canon_path,
|
|
Packit |
6639f8 |
&c->null_gbs[c->num_null_gbs])) {
|
|
Packit |
6639f8 |
LOG("failed to load NULL GBS \"%s\"\n", canon_path);
|
|
Packit |
6639f8 |
opae_unload_bitstream(&c->null_gbs[c->num_null_gbs]);
|
|
Packit |
6639f8 |
free(canon_path);
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
c->num_null_gbs++;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
LOG("registering NULL bitstream \"%s\"\n", canon_path);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("error with NULL GBS argument: %s\n", strerror(errno));
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("maximum number of NULL bitstreams exceeded. Ignoring -n option.\n");
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
return true;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
int cmd_parse_args(struct fpgad_config *c, int argc, char *argv[])
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
int getopt_ret;
|
|
Packit |
6639f8 |
int option_index;
|
|
Packit |
6639f8 |
size_t len;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
while (-1 != (getopt_ret = getopt_long(argc, argv, OPT_STR, longopts, &option_index))) {
|
|
Packit |
6639f8 |
const char *tmp_optarg = optarg;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (optarg && ('=' == *tmp_optarg))
|
|
Packit |
6639f8 |
++tmp_optarg;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!optarg && (optind < argc) &&
|
|
Packit |
6639f8 |
(NULL != argv[optind]) &&
|
|
Packit |
6639f8 |
('-' != argv[optind][0]))
|
|
Packit |
6639f8 |
tmp_optarg = argv[optind++];
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
switch (getopt_ret) {
|
|
Packit |
6639f8 |
case 'h':
|
|
Packit |
6639f8 |
cmd_show_help(stdout);
|
|
Packit |
6639f8 |
return -2;
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case 'd':
|
|
Packit |
6639f8 |
c->daemon = 1;
|
|
Packit |
6639f8 |
LOG("daemon requested\n");
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case 'l':
|
|
Packit |
6639f8 |
if (tmp_optarg) {
|
|
Packit |
6639f8 |
len = strnlen(tmp_optarg, PATH_MAX - 1);
|
|
Packit |
6639f8 |
memcpy(c->logfile, tmp_optarg, len);
|
|
Packit |
6639f8 |
c->logfile[len] = '\0';
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("missing logfile parameter.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case 'p':
|
|
Packit |
6639f8 |
if (tmp_optarg) {
|
|
Packit |
6639f8 |
len = strnlen(tmp_optarg, PATH_MAX - 1);
|
|
Packit |
6639f8 |
memcpy(c->pidfile, tmp_optarg, len);
|
|
Packit |
6639f8 |
c->pidfile[len] = '\0';
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("missing pidfile parameter.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case 'n':
|
|
Packit |
6639f8 |
if (tmp_optarg) {
|
|
Packit |
6639f8 |
if (!cmd_register_null_gbs(c, (char *)tmp_optarg)) {
|
|
Packit |
6639f8 |
LOG("invalid null gbs path: \"%s\"\n", tmp_optarg);
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("missing bitstream parameter.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case 's':
|
|
Packit |
6639f8 |
if (tmp_optarg) {
|
|
Packit |
6639f8 |
c->api_socket = tmp_optarg;
|
|
Packit |
6639f8 |
LOG("daemon socket is %s\n", c->api_socket);
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("missing socket parameter.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case 'c':
|
|
Packit |
6639f8 |
if (tmp_optarg) {
|
|
Packit |
6639f8 |
len = strnlen(tmp_optarg, PATH_MAX - 1);
|
|
Packit |
6639f8 |
memcpy(c->cfgfile, tmp_optarg, len);
|
|
Packit |
6639f8 |
c->cfgfile[len] = '\0';
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
LOG("missing cfgfile parameter.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case 'v':
|
|
Packit |
6639f8 |
fprintf(stdout, "fpgad %s %s%s\n",
|
|
Packit |
6639f8 |
OPAE_VERSION,
|
|
Packit |
6639f8 |
OPAE_GIT_COMMIT_HASH,
|
|
Packit |
6639f8 |
OPAE_GIT_SRC_TREE_DIRTY ? "*":"");
|
|
Packit |
6639f8 |
return -2;
|
|
Packit |
6639f8 |
break;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case ':':
|
|
Packit |
6639f8 |
LOG("Missing option argument.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
case '?':
|
|
Packit |
6639f8 |
LOG("Invalid command option.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
default:
|
|
Packit |
6639f8 |
LOG("Invalid command option.\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return 0;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
int cmd_canonicalize_paths(struct fpgad_config *c)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
char *sub;
|
|
Packit |
6639f8 |
bool def;
|
|
Packit |
6639f8 |
mode_t mode;
|
|
Packit |
6639f8 |
struct stat stat_buf;
|
|
Packit |
6639f8 |
bool search = true;
|
|
Packit |
6639f8 |
char buf[PATH_MAX];
|
|
Packit |
6639f8 |
char *canon_path;
|
|
Packit |
6639f8 |
uid_t uid;
|
|
Packit |
6639f8 |
size_t len;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
uid = geteuid();
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!uid) {
|
|
Packit |
6639f8 |
// If we're being run as root, then use DEFAULT_DIR_ROOT
|
|
Packit |
6639f8 |
// as the working directory.
|
|
Packit |
6639f8 |
memcpy(c->directory, DEFAULT_DIR_ROOT, sizeof(DEFAULT_DIR_ROOT));
|
|
Packit |
6639f8 |
c->directory[sizeof(DEFAULT_DIR_ROOT)] = '\0';
|
|
Packit |
6639f8 |
mode = 0755;
|
|
Packit |
6639f8 |
c->filemode = 0026;
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
// We're not root. Try to use ${HOME}/.opae
|
|
Packit |
6639f8 |
struct passwd *passwd;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
passwd = getpwuid(uid);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
canon_path = canonicalize_file_name(passwd->pw_dir);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (canon_path) {
|
|
Packit |
6639f8 |
snprintf(c->directory, sizeof(c->directory),
|
|
Packit |
6639f8 |
"%s/.opae", canon_path);
|
|
Packit |
6639f8 |
free(canon_path);
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
// ${HOME} not found or invalid - use current dir.
|
|
Packit |
6639f8 |
if (getcwd(buf, sizeof(buf))) {
|
|
Packit |
6639f8 |
if (snprintf(c->directory, sizeof(c->directory),
|
|
Packit |
6639f8 |
"%s/.opae", buf) < 0) {
|
|
Packit |
6639f8 |
len = strnlen("./.opae",
|
|
Packit |
6639f8 |
sizeof(c->directory) - 1);
|
|
Packit |
6639f8 |
memcpy(c->directory, "./.opae", len);
|
|
Packit |
6639f8 |
c->directory[len] = '\0';
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
// Current directory not found - use /
|
|
Packit |
6639f8 |
len = strnlen("/.opae", sizeof(c->directory) - 1);
|
|
Packit |
6639f8 |
memcpy(c->directory, "/.opae", len);
|
|
Packit |
6639f8 |
c->directory[len] = '\0';
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
mode = 0775;
|
|
Packit |
6639f8 |
c->filemode = 0022;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (cmd_path_is_symlink(c->directory)) {
|
|
Packit |
6639f8 |
LOG("Aborting - working directory contains a link: %s\n.",
|
|
Packit |
6639f8 |
c->directory);
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
LOG("daemon working directory is %s\n", c->directory);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Create the directory if it doesn't exist.
|
|
Packit |
6639f8 |
if (lstat(c->directory, &stat_buf) && (errno == ENOENT)) {
|
|
Packit |
6639f8 |
if (mkdir(c->directory, mode)) {
|
|
Packit |
6639f8 |
LOG("mkdir failed\n");
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Verify logfile and pidfile do not contain ".."
|
|
Packit |
6639f8 |
// nor "/".
|
|
Packit |
6639f8 |
def = false;
|
|
Packit |
6639f8 |
sub = strstr(c->logfile, "..");
|
|
Packit |
6639f8 |
if (sub)
|
|
Packit |
6639f8 |
def = true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
sub = strstr(c->logfile, "/");
|
|
Packit |
6639f8 |
if (sub)
|
|
Packit |
6639f8 |
def = true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (def || (c->logfile[0] == '\0')) {
|
|
Packit |
6639f8 |
if (snprintf(c->logfile, sizeof(c->logfile),
|
|
Packit |
6639f8 |
"%s/%s", c->directory, DEFAULT_LOG) < 0) {
|
|
Packit |
6639f8 |
len = strnlen("./" DEFAULT_LOG,
|
|
Packit |
6639f8 |
sizeof(c->logfile) - 1);
|
|
Packit |
6639f8 |
memcpy(c->logfile, "./" DEFAULT_LOG, len);
|
|
Packit |
6639f8 |
c->logfile[len] = '\0';
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
len = strnlen(c->logfile, sizeof(buf) - 1);
|
|
Packit |
6639f8 |
memcpy(buf, c->logfile, len);
|
|
Packit |
6639f8 |
buf[len] = '\0';
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (snprintf(c->logfile, sizeof(c->logfile),
|
|
Packit |
6639f8 |
"%s/%s", c->directory, buf) < 0) {
|
|
Packit |
6639f8 |
len = strnlen("./" DEFAULT_LOG,
|
|
Packit |
6639f8 |
sizeof(c->logfile) - 1);
|
|
Packit |
6639f8 |
memcpy(c->logfile, "./" DEFAULT_LOG, len);
|
|
Packit |
6639f8 |
c->logfile[len] = '\0';
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (cmd_path_is_symlink(c->logfile)) {
|
|
Packit |
6639f8 |
LOG("Aborting - log file path contains a link: %s\n.",
|
|
Packit |
6639f8 |
c->logfile);
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
LOG("daemon log file is %s\n", c->logfile);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
def = false;
|
|
Packit |
6639f8 |
sub = strstr(c->pidfile, "..");
|
|
Packit |
6639f8 |
if (sub)
|
|
Packit |
6639f8 |
def = true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
sub = strstr(c->pidfile, "/");
|
|
Packit |
6639f8 |
if (sub)
|
|
Packit |
6639f8 |
def = true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (def || (c->pidfile[0] == '\0')) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (snprintf(c->pidfile, sizeof(c->pidfile),
|
|
Packit |
6639f8 |
"%s/%s", c->directory, DEFAULT_PID) < 0) {
|
|
Packit |
6639f8 |
len = strnlen("./" DEFAULT_PID,
|
|
Packit |
6639f8 |
sizeof(c->pidfile) - 1);
|
|
Packit |
6639f8 |
memcpy(c->pidfile, "./" DEFAULT_PID, len);
|
|
Packit |
6639f8 |
c->pidfile[len] = '\0';
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
len = strnlen(c->pidfile, sizeof(buf) - 1);
|
|
Packit |
6639f8 |
memcpy(buf, c->pidfile, len);
|
|
Packit |
6639f8 |
buf[len] = '\0';
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (snprintf(c->pidfile, sizeof(c->pidfile),
|
|
Packit |
6639f8 |
"%s/%s", c->directory, buf) < 0) {
|
|
Packit |
6639f8 |
len = strnlen("./" DEFAULT_PID,
|
|
Packit |
6639f8 |
sizeof(c->pidfile) - 1);
|
|
Packit |
6639f8 |
memcpy(c->pidfile, "./" DEFAULT_PID, len);
|
|
Packit |
6639f8 |
c->pidfile[len] = '\0';
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (cmd_path_is_symlink(c->pidfile)) {
|
|
Packit |
6639f8 |
LOG("Aborting - pid file path contains a link: %s\n.",
|
|
Packit |
6639f8 |
c->pidfile);
|
|
Packit |
6639f8 |
return 1;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
LOG("daemon pid file is %s\n", c->pidfile);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// Verify cfgfile doesn't contain ".."
|
|
Packit |
6639f8 |
def = false;
|
|
Packit |
6639f8 |
sub = strstr(c->cfgfile, "..");
|
|
Packit |
6639f8 |
if (sub)
|
|
Packit |
6639f8 |
def = true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (def || (c->cfgfile[0] == '\0')) {
|
|
Packit |
6639f8 |
search = true;
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
canon_path = canonicalize_file_name(c->cfgfile);
|
|
Packit |
6639f8 |
if (canon_path) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!cmd_path_is_symlink(c->cfgfile)) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
len = strnlen(canon_path,
|
|
Packit |
6639f8 |
sizeof(c->cfgfile) - 1);
|
|
Packit |
6639f8 |
memcpy(c->cfgfile,
|
|
Packit |
6639f8 |
canon_path,
|
|
Packit |
6639f8 |
len);
|
|
Packit |
6639f8 |
c->cfgfile[len] = '\0';
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!cfg_load_config(c)) {
|
|
Packit |
6639f8 |
LOG("daemon cfg file is %s\n",
|
|
Packit |
6639f8 |
c->cfgfile);
|
|
Packit |
6639f8 |
search = false; // found and loaded it
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
free(canon_path);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (search) {
|
|
Packit |
6639f8 |
c->cfgfile[0] = '\0';
|
|
Packit |
6639f8 |
if (cfg_find_config_file(c))
|
|
Packit |
6639f8 |
LOG("failed to find config file.\n");
|
|
Packit |
6639f8 |
else {
|
|
Packit |
6639f8 |
if (cfg_load_config(c))
|
|
Packit |
6639f8 |
LOG("failed to load config file %s\n",
|
|
Packit |
6639f8 |
c->cfgfile);
|
|
Packit |
6639f8 |
else
|
|
Packit |
6639f8 |
LOG("daemon cfg file is %s\n", c->cfgfile);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (!c->supported_devices) {
|
|
Packit |
6639f8 |
LOG("using default configuration.\n");
|
|
Packit |
6639f8 |
c->cfgfile[0] = '\0';
|
|
Packit |
6639f8 |
c->supported_devices = default_supported_devices_table;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return 0;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
void cmd_destroy(struct fpgad_config *c)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
unsigned i;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (c->daemon)
|
|
Packit |
6639f8 |
unlink(c->pidfile);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ; i < c->num_null_gbs ; ++i) {
|
|
Packit |
6639f8 |
if (c->null_gbs[i].filename)
|
|
Packit |
6639f8 |
free((char *)c->null_gbs[i].filename);
|
|
Packit |
6639f8 |
opae_unload_bitstream(&c->null_gbs[i]);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
c->num_null_gbs = 0;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (c->supported_devices &&
|
|
Packit |
6639f8 |
(c->supported_devices != default_supported_devices_table)) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
for (i = 0 ; c->supported_devices[i].library_path ; ++i) {
|
|
Packit |
6639f8 |
fpgad_supported_device *d = &c->supported_devices[i];
|
|
Packit |
6639f8 |
if (d->library_path)
|
|
Packit |
6639f8 |
free((void *)d->library_path);
|
|
Packit |
6639f8 |
if (d->config)
|
|
Packit |
6639f8 |
free((void *)d->config);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
free(c->supported_devices);
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
c->supported_devices = NULL;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
bool cmd_path_is_symlink(const char *path)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
char component[PATH_MAX];
|
|
Packit |
6639f8 |
struct stat stat_buf;
|
|
Packit |
6639f8 |
size_t len;
|
|
Packit |
6639f8 |
char *pslash;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
len = strnlen(path, PATH_MAX - 1);
|
|
Packit |
6639f8 |
if (!len) // empty path
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
memcpy(component, path, len);
|
|
Packit |
6639f8 |
component[len] = '\0';
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (component[0] == '/') {
|
|
Packit |
6639f8 |
// absolute path
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
pslash = realpath(path, component);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (strcmp(component, path))
|
|
Packit |
6639f8 |
return true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
} else {
|
|
Packit |
6639f8 |
// relative path
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
pslash = strrchr(component, '/');
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
while (pslash) {
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (fstatat(AT_FDCWD, component,
|
|
Packit |
6639f8 |
&stat_buf, AT_SYMLINK_NOFOLLOW)) {
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (S_ISLNK(stat_buf.st_mode))
|
|
Packit |
6639f8 |
return true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
*pslash = '\0';
|
|
Packit |
6639f8 |
pslash = strrchr(component, '/');
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (fstatat(AT_FDCWD, component,
|
|
Packit |
6639f8 |
&stat_buf, AT_SYMLINK_NOFOLLOW)) {
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (S_ISLNK(stat_buf.st_mode))
|
|
Packit |
6639f8 |
return true;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
}
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return false;
|
|
Packit |
6639f8 |
}
|