|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* Copyright (c) 2001, Adam Dunkels.
|
|
Packit |
eace71 |
* All rights reserved.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
eace71 |
* modification, are permitted provided that the following conditions
|
|
Packit |
eace71 |
* are met:
|
|
Packit |
eace71 |
* 1. Redistributions of source code must retain the above copyright
|
|
Packit |
eace71 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
eace71 |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
Packit |
eace71 |
* notice, this list of conditions and the following disclaimer in the
|
|
Packit |
eace71 |
* documentation and/or other materials provided with the distribution.
|
|
Packit |
eace71 |
* 3. All advertising materials mentioning features or use of this software
|
|
Packit |
eace71 |
* must display the following acknowledgement:
|
|
Packit |
eace71 |
* This product includes software developed by Adam Dunkels.
|
|
Packit |
eace71 |
* 4. The name of the author may not be used to endorse or promote
|
|
Packit |
eace71 |
* products derived from this software without specific prior
|
|
Packit |
eace71 |
* written permission.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
Packit |
eace71 |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
Packit |
eace71 |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
eace71 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
Packit |
eace71 |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit |
eace71 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
Packit |
eace71 |
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
eace71 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
Packit |
eace71 |
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
Packit |
eace71 |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit |
eace71 |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This file is part of the uIP TCP/IP stack.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include <dlfcn.h>
|
|
Packit |
eace71 |
#include <errno.h>
|
|
Packit |
eace71 |
#include <fcntl.h>
|
|
Packit |
eace71 |
#include <string.h>
|
|
Packit |
eace71 |
#include <signal.h>
|
|
Packit |
eace71 |
#include <stdlib.h>
|
|
Packit |
eace71 |
#include <getopt.h>
|
|
Packit |
eace71 |
#include <unistd.h>
|
|
Packit |
eace71 |
#include <sys/types.h>
|
|
Packit |
eace71 |
#include <sys/stat.h>
|
|
Packit |
eace71 |
#include <sys/utsname.h>
|
|
Packit |
eace71 |
#include <net/ethernet.h>
|
|
Packit |
eace71 |
#include <arpa/inet.h>
|
|
Packit |
eace71 |
#include <sys/mman.h>
|
|
Packit |
eace71 |
#ifndef NO_SYSTEMD
|
|
Packit |
eace71 |
#include <systemd/sd-daemon.h>
|
|
Packit |
eace71 |
#endif
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "uip.h"
|
|
Packit |
eace71 |
#include "uip_arp.h"
|
|
Packit |
eace71 |
#include "uip_eth.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "timer.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "build_date.h"
|
|
Packit |
eace71 |
#include "config.h"
|
|
Packit |
eace71 |
#include "iscsid_ipc.h"
|
|
Packit |
eace71 |
#include "logger.h"
|
|
Packit |
eace71 |
#include "nic.h"
|
|
Packit |
eace71 |
#include "nic_id.h"
|
|
Packit |
eace71 |
#include "nic_nl.h"
|
|
Packit |
eace71 |
#include "nic_utils.h"
|
|
Packit |
eace71 |
#include "options.h"
|
|
Packit |
eace71 |
#include "packet.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "dhcpc.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "iscsid_ipc.h"
|
|
Packit |
eace71 |
#include "brcm_iscsi.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/*******************************************************************************
|
|
Packit |
eace71 |
* Constants
|
|
Packit |
eace71 |
******************************************************************************/
|
|
Packit |
eace71 |
#define PFX "main "
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static const char default_pid_filepath[] = "/run/iscsiuio.pid";
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/*******************************************************************************
|
|
Packit |
eace71 |
* Global Variables
|
|
Packit |
eace71 |
******************************************************************************/
|
|
Packit |
eace71 |
static const struct option long_options[] = {
|
|
Packit |
eace71 |
{"foreground", no_argument, NULL, 'f'},
|
|
Packit |
eace71 |
{"debug", required_argument, NULL, 'd'},
|
|
Packit |
eace71 |
{"pid", required_argument, NULL, 'p'},
|
|
Packit |
eace71 |
{"version", no_argument, NULL, 'v'},
|
|
Packit |
eace71 |
{"help", no_argument, NULL, 'h'},
|
|
Packit |
eace71 |
{NULL, no_argument, NULL, 0}
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
struct options opt = {
|
|
Packit |
eace71 |
.debug = DEBUG_OFF,
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int event_loop_stop;
|
|
Packit |
eace71 |
extern nic_t *nic_list;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
struct utsname cur_utsname;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/**
|
|
Packit |
eace71 |
* cleanup() - This function is called when this program is to be closed
|
|
Packit |
eace71 |
* This function will clean up all the cnic uio interfaces and
|
|
Packit |
eace71 |
* flush/close the logger
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
static void cleanup()
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
iscsid_cleanup();
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
nic_remove_all();
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
unload_all_nic_libraries();
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
LOG_INFO("Done waiting for cnic's/stacks to gracefully close");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
fini_logger(SHUTDOWN_LOGGER);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/**
|
|
Packit |
eace71 |
* signal_handle_thread() - This is the signal handling thread of this program
|
|
Packit |
eace71 |
* This is the only thread which will handle signals.
|
|
Packit |
eace71 |
* All signals are routed here and handled here to
|
|
Packit |
eace71 |
* provide consistant handling.
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
static pthread_t signal_thread;
|
|
Packit |
eace71 |
static void *signal_handle_thread(void *arg)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
sigset_t set;
|
|
Packit |
eace71 |
int rc;
|
|
Packit |
eace71 |
int signal;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
sigfillset(&set);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
LOG_INFO("signal handling thread ready");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
signal_wait:
|
|
Packit |
eace71 |
rc = sigwait(&set, &signal);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
switch (signal) {
|
|
Packit |
eace71 |
case SIGINT:
|
|
Packit |
eace71 |
LOG_INFO("Caught SIGINT signal");
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
case SIGUSR1:
|
|
Packit |
eace71 |
LOG_INFO("Caught SIGUSR1 signal, rotate log");
|
|
Packit |
eace71 |
fini_logger(SHUTDOWN_LOGGER);
|
|
Packit |
eace71 |
rc = init_logger(main_log.log_file);
|
|
Packit |
eace71 |
if (rc != 0)
|
|
Packit |
eace71 |
fprintf(stderr, "WARN: Could not initialize the logger in "
|
|
Packit |
eace71 |
"signal!\n");
|
|
Packit |
eace71 |
goto signal_wait;
|
|
Packit |
eace71 |
default:
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
event_loop_stop = 1;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
LOG_INFO("terminating...");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
cleanup();
|
|
Packit |
eace71 |
exit(EXIT_SUCCESS);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void show_version()
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
printf("%s: Version '%s', Build Date: '%s'\n",
|
|
Packit |
eace71 |
APP_NAME, PACKAGE_VERSION, build_date);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void main_usage()
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
show_version();
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
printf("\nUsage: %s [OPTION]\n", APP_NAME);
|
|
Packit |
eace71 |
printf("iscsiuio daemon.\n"
|
|
Packit |
eace71 |
"-f, --foreground make the program run in the foreground\n"
|
|
Packit |
eace71 |
"-d, --debug debuglevel print debugging information\n"
|
|
Packit |
eace71 |
"-p, --pid pidfile use pid file (default %s).\n"
|
|
Packit |
eace71 |
"-h, --help display this help and exit\n"
|
|
Packit |
eace71 |
"-v, --version display version and exit\n",
|
|
Packit |
eace71 |
default_pid_filepath);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void daemon_init()
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int fd;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
fd = open("/dev/null", O_RDWR);
|
|
Packit |
eace71 |
if (fd == -1)
|
|
Packit |
eace71 |
exit(-1);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
dup2(fd, 0);
|
|
Packit |
eace71 |
dup2(fd, 1);
|
|
Packit |
eace71 |
dup2(fd, 2);
|
|
Packit |
eace71 |
setsid();
|
|
Packit |
eace71 |
chdir("/");
|
|
Packit |
eace71 |
close(fd);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define ISCSI_OOM_PATH_LEN 48
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int oom_adjust(void)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int fd;
|
|
Packit |
eace71 |
char path[ISCSI_OOM_PATH_LEN];
|
|
Packit |
eace71 |
struct stat statb;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (nice(-10) < 0)
|
|
Packit |
eace71 |
LOG_DEBUG("Could not increase process priority: %s",
|
|
Packit |
eace71 |
strerror(errno));
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_score_adj", getpid());
|
|
Packit |
eace71 |
if (stat(path, &statb)) {
|
|
Packit |
eace71 |
/* older kernel so use old oom_adj file */
|
|
Packit |
eace71 |
snprintf(path, ISCSI_OOM_PATH_LEN, "/proc/%d/oom_adj",
|
|
Packit |
eace71 |
getpid());
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
fd = open(path, O_WRONLY);
|
|
Packit |
eace71 |
if (fd < 0)
|
|
Packit |
eace71 |
return -1;
|
|
Packit |
eace71 |
if (write(fd, "-16", 3) < 0) /* for 2.6.11 */
|
|
Packit |
eace71 |
LOG_DEBUG("Could not set oom score to -16: %s",
|
|
Packit |
eace71 |
strerror(errno));
|
|
Packit |
eace71 |
if (write(fd, "-17", 3) < 0) /* for Andrea's patch */
|
|
Packit |
eace71 |
LOG_DEBUG("Could not set oom score to -17: %s",
|
|
Packit |
eace71 |
strerror(errno));
|
|
Packit |
eace71 |
close(fd);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/*******************************************************************************
|
|
Packit |
eace71 |
* Main routine
|
|
Packit |
eace71 |
******************************************************************************/
|
|
Packit |
eace71 |
int main(int argc, char *argv[])
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int rc;
|
|
Packit |
eace71 |
sigset_t set;
|
|
Packit |
eace71 |
const char *pid_file = default_pid_filepath;
|
|
Packit |
eace71 |
int fd;
|
|
Packit |
eace71 |
int foreground = 0;
|
|
Packit |
eace71 |
pid_t pid;
|
|
Packit |
eace71 |
pthread_attr_t attr;
|
|
Packit |
eace71 |
int pipefds[2];
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Record the start time for the user space daemon */
|
|
Packit |
eace71 |
opt.start_time = time(NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* parse the parameters */
|
|
Packit |
eace71 |
while (1) {
|
|
Packit |
eace71 |
int c, option_index;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
c = getopt_long(argc, argv, "fd:p:vh",
|
|
Packit |
eace71 |
long_options, &option_index);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (c == -1)
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
switch (c) {
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
case 'f':
|
|
Packit |
eace71 |
foreground = 1;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Enable debugging mode */
|
|
Packit |
eace71 |
case 'd':
|
|
Packit |
eace71 |
main_log.level = atoi(optarg);
|
|
Packit |
eace71 |
opt.debug = DEBUG_ON;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
case 'p':
|
|
Packit |
eace71 |
pid_file = optarg;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
case 'v':
|
|
Packit |
eace71 |
show_version();
|
|
Packit |
eace71 |
exit(EXIT_SUCCESS);
|
|
Packit |
eace71 |
case 'h':
|
|
Packit |
eace71 |
default:
|
|
Packit |
eace71 |
main_usage();
|
|
Packit |
eace71 |
exit(EXIT_SUCCESS);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (main_log.enabled == LOGGER_ENABLED) {
|
|
Packit |
eace71 |
/* initialize the logger */
|
|
Packit |
eace71 |
rc = init_logger(main_log.log_file);
|
|
Packit |
eace71 |
if (rc != 0 && opt.debug == DEBUG_ON)
|
|
Packit |
eace71 |
fprintf(stderr, "WARN: Could not initialize the logger\n");
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
LOG_INFO("Started iSCSI uio stack: Ver " PACKAGE_VERSION);
|
|
Packit |
eace71 |
LOG_INFO("Build date: %s", build_date);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (opt.debug == DEBUG_ON)
|
|
Packit |
eace71 |
LOG_INFO("Debug mode enabled");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
event_loop_stop = 0;
|
|
Packit |
eace71 |
nic_list = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Determine the current kernel version */
|
|
Packit |
eace71 |
memset(&cur_utsname, 0, sizeof(cur_utsname));
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = uname(&cur_utsname);
|
|
Packit |
eace71 |
if (rc == 0) {
|
|
Packit |
eace71 |
LOG_INFO("Running on sysname: '%s', release: '%s', "
|
|
Packit |
eace71 |
"version '%s' machine: '%s'",
|
|
Packit |
eace71 |
cur_utsname.sysname, cur_utsname.release,
|
|
Packit |
eace71 |
cur_utsname.version, cur_utsname.machine);
|
|
Packit |
eace71 |
} else
|
|
Packit |
eace71 |
LOG_WARN("Could not determine kernel version");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Initialze the iscsid listener */
|
|
Packit |
eace71 |
rc = iscsid_init();
|
|
Packit |
eace71 |
if (rc != 0)
|
|
Packit |
eace71 |
goto error;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!foreground) {
|
|
Packit |
eace71 |
char buf[64];
|
|
Packit |
eace71 |
ssize_t written_bytes;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
fd = open(pid_file, O_WRONLY | O_CREAT, 0644);
|
|
Packit |
eace71 |
if (fd < 0) {
|
|
Packit |
eace71 |
fprintf(stderr, "ERR: Unable to create pid file: %s\n",
|
|
Packit |
eace71 |
pid_file);
|
|
Packit |
eace71 |
exit(1);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (pipe(pipefds) < 0) {
|
|
Packit |
eace71 |
fprintf(stderr, "ERR: Unable to create a PIPE: %s\n",
|
|
Packit |
eace71 |
strerror(errno));
|
|
Packit |
eace71 |
exit(1);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
pid = fork();
|
|
Packit |
eace71 |
if (pid < 0) {
|
|
Packit |
eace71 |
fprintf(stderr, "ERR: Starting daemon failed\n");
|
|
Packit |
eace71 |
exit(1);
|
|
Packit |
eace71 |
} else if (pid) {
|
|
Packit |
eace71 |
char msgbuf[4];
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* parent: wait for child msg then exit */
|
|
Packit |
eace71 |
close(pipefds[1]);
|
|
Packit Service |
83beb6 |
read(pipefds[0], msgbuf, sizeof(msgbuf));
|
|
Packit |
eace71 |
exit(0);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* the child */
|
|
Packit |
eace71 |
rc = chdir("/");
|
|
Packit |
eace71 |
if (rc == -1)
|
|
Packit |
eace71 |
fprintf(stderr, "WARN: Unable to chdir(\") [%s]\n", strerror(errno));
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (lockf(fd, F_TLOCK, 0) < 0) {
|
|
Packit |
eace71 |
fprintf(stderr, "ERR: Unable to lock pid file: %s [%s]\n",
|
|
Packit |
eace71 |
pid_file, strerror(errno));
|
|
Packit |
eace71 |
exit(1);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = ftruncate(fd, 0);
|
|
Packit |
eace71 |
if (rc == -1)
|
|
Packit |
eace71 |
fprintf(stderr, "WARN: ftruncate(%d, 0) failed [%s]\n",
|
|
Packit |
eace71 |
fd, strerror(errno));
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
sprintf(buf, "%d\n", getpid());
|
|
Packit |
eace71 |
written_bytes = write(fd, buf, strlen(buf));
|
|
Packit |
eace71 |
if (written_bytes == -1) {
|
|
Packit |
eace71 |
fprintf(stderr, "ERR: Could not write pid file [%s]\n",
|
|
Packit |
eace71 |
strerror(errno));
|
|
Packit |
eace71 |
exit(1);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
close(fd);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
daemon_init();
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Load the NIC libraries */
|
|
Packit |
eace71 |
rc = load_all_nic_libraries();
|
|
Packit |
eace71 |
if (rc != 0)
|
|
Packit |
eace71 |
goto error;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
brcm_iscsi_init();
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* ensure we don't see any signals */
|
|
Packit |
eace71 |
sigemptyset(&set);
|
|
Packit |
eace71 |
sigaddset(&set, SIGINT);
|
|
Packit |
eace71 |
sigaddset(&set, SIGQUIT);
|
|
Packit |
eace71 |
sigaddset(&set, SIGTERM);
|
|
Packit |
eace71 |
sigaddset(&set, SIGUSR1);
|
|
Packit |
eace71 |
rc = pthread_sigmask(SIG_SETMASK, &set, NULL);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Spin off the signal handling thread */
|
|
Packit |
eace71 |
pthread_attr_init(&attr);
|
|
Packit |
eace71 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
Packit |
eace71 |
rc = pthread_create(&signal_thread, &attr, signal_handle_thread, NULL);
|
|
Packit |
eace71 |
if (rc != 0)
|
|
Packit |
eace71 |
LOG_ERR("Could not create signal handling thread");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Using sysfs to discover iSCSI hosts */
|
|
Packit |
eace71 |
nic_discover_iscsi_hosts();
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* oom-killer will not kill us at the night... */
|
|
Packit |
eace71 |
if (oom_adjust())
|
|
Packit |
eace71 |
LOG_DEBUG("Can not adjust oom-killer's pardon");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* we don't want our active sessions to be paged out... */
|
|
Packit |
eace71 |
if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
|
|
Packit |
eace71 |
LOG_ERR("failed to mlockall, exiting...");
|
|
Packit |
eace71 |
goto error;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Start the iscsid listener */
|
|
Packit |
eace71 |
rc = iscsid_start();
|
|
Packit |
eace71 |
if (rc != 0)
|
|
Packit |
eace71 |
goto error;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!foreground) {
|
|
Packit |
eace71 |
/* signal parent they can go away now */
|
|
Packit |
eace71 |
close(pipefds[0]);
|
|
Packit Service |
83beb6 |
write(pipefds[1], "ok\n", 3);
|
|
Packit |
eace71 |
close(pipefds[1]);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#ifndef NO_SYSTEMD
|
|
Packit |
eace71 |
sd_notify(0, "READY=1\n"
|
|
Packit |
eace71 |
"STATUS=Ready to process requests\n");
|
|
Packit |
eace71 |
#endif
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* NetLink connection to listen to NETLINK_ISCSI private messages */
|
|
Packit |
eace71 |
if (nic_nl_open() != 0)
|
|
Packit |
eace71 |
goto error;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
error:
|
|
Packit |
eace71 |
cleanup();
|
|
Packit |
eace71 |
exit(EXIT_FAILURE);
|
|
Packit |
eace71 |
}
|