Skip to content

Commit

Permalink
Merge pull request linux-rdma#176 from jgunthorpe/ibacm
Browse files Browse the repository at this point in the history
Sytemd integration for ibacm
  • Loading branch information
dledford authored Aug 3, 2017
2 parents d779dd9 + fb34370 commit 3bc3cee
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 44 deletions.
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,10 @@ CHECK_C_SOURCE_COMPILES("
int main(int argc,const char *argv[]) {return 0;}"
HAVE_COHERENT_DMA)

find_package(Systemd)
include_directories(${SYSTEMD_INCLUDE_DIRS})
RDMA_DoFixup("${SYSTEMD_FOUND}" "systemd/sd-daemon.h")

#-------------------------
# Apply fixups

Expand Down Expand Up @@ -478,6 +482,9 @@ else()
message(STATUS " netlink/route/link.h and net/if.h NOT co-includable (old headers)")
endif()
endif()
if (NOT SYSTEMD_FOUND)
message(STATUS " libsystemd NOT found (disabling features)")
endif()
if (NOT UDEV_FOUND)
message(STATUS " libudev NOT found (disabling features)")
endif()
Expand Down
30 changes: 30 additions & 0 deletions buildlib/FindSystemd.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# COPYRIGHT (c) 2015 Obsidian Research Corporation.
# Licensed under BSD (MIT variant) or GPLv2. See COPYING.

find_path(LIBSYSTEMD_INCLUDE_DIRS "systemd/sd-journal.h")

if (LIBSYSTEMD_INCLUDE_DIRS)
set(SYSTEMD_INCLUDE_DIRS ${LIBSYSTEMD_INCLUDE_DIRS})
find_library(LIBSYSTEMD_LIBRARY NAMES systemd libsystemd)
# Older systemd uses a split library
if (NOT LIBSYSTEMD_LIBRARY)
find_library(LIBSYSTEMD_JOURNAL_LIBRARY NAMES systemd-journal libsystemd-journal)
find_library(LIBSYSTEMD_ID128_LIBRARY NAMES systemd-id128 libsystemd-id128)
find_library(LIBSYSTEMD_DAEMON_LIBRARY NAMES systemd-daemon libsystemd-daemon)

if (LIBSYSTEMD_JOURNAL_LIBRARY AND LIBSYSTEMD_ID128_LIBRARY AND LIBSYSTEMD_DAEMON_LIBRARY)
set(SYSTEMD_LIBRARIES
${LIBSYSTEMD_JOURNAL_LIBRARY}
${LIBSYSTEMD_ID128_LIBRARY}
${LIBSYSTEMD_DAEMON_LIBRARY})
endif()
else()
set(SYSTEMD_LIBRARIES ${LIBSYSTEMD_LIBRARY})
endif()
set(SYSTEMD_INCLUDE_DIRS)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Systemd REQUIRED_VARS SYSTEMD_LIBRARIES LIBSYSTEMD_INCLUDE_DIRS)

mark_as_advanced(LIBSYSTEMD_LIBRARY LIBSYSTEMD_JOURNAL_LIBRARY LIBSYSTEMD_ID128_LIBRARY LIBSYSTEMD_DAEMON_LIBRARY)
18 changes: 12 additions & 6 deletions buildlib/cbuild
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class centos6(YumEnvironment):

class centos7(YumEnvironment):
docker_parent = "centos:7";
pkgs = centos6.pkgs;
pkgs = centos6.pkgs | {'systemd-devel'};
name = "centos7";
use_make = True;
specfile = "redhat/rdma-core.spec";
Expand Down Expand Up @@ -152,7 +152,7 @@ class APTEnvironment(Environment):

class trusty(APTEnvironment):
docker_parent = "ubuntu:14.04";
pkgs = {
common_pkgs = {
'build-essential',
'cmake',
'debhelper',
Expand All @@ -167,30 +167,35 @@ class trusty(APTEnvironment):
'python',
'valgrind',
};
pkgs = common_pkgs | {
'libsystemd-daemon-dev',
'libsystemd-id128-dev',
'libsystemd-journal-dev',
};
name = "ubuntu-14.04";
aliases = {"trusty"};

class xenial(APTEnvironment):
docker_parent = "ubuntu:16.04"
pkgs = trusty.pkgs;
pkgs = trusty.common_pkgs | {"libsystemd-dev"};
name = "ubuntu-16.04";
aliases = {"xenial"};

class jessie(APTEnvironment):
docker_parent = "debian:8"
pkgs = trusty.pkgs;
pkgs = xenial.pkgs;
name = "debian-8";
aliases = {"jessie"};

class stretch(APTEnvironment):
docker_parent = "debian:9"
pkgs = trusty.pkgs;
pkgs = jessie.pkgs;
name = "debian-9";
aliases = {"stretch"};

class debian_experimental(APTEnvironment):
docker_parent = "debian:experimental"
pkgs = (trusty.pkgs ^ {"gcc"}) | {"gcc-7"};
pkgs = (stretch.pkgs ^ {"gcc"}) | {"gcc-7"};
name = "debian-experimental";

def get_docker_file(self):
Expand Down Expand Up @@ -299,6 +304,7 @@ class harlequin(ZypperEnvironment):
'pkg-config',
'python',
'rpm-build',
'systemd-devel',
'valgrind-devel',
};
name = "opensuse-13.2";
Expand Down
11 changes: 11 additions & 0 deletions buildlib/fixup-include/systemd-sd-daemon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#define SD_LISTEN_FDS_START 3

static inline int sd_listen_fds(int unset_environment)
{
return 0;
}

static inline int sd_is_socket(int fd, int family, int type, int listening)
{
return 0;
}
1 change: 1 addition & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Build-Depends: cmake (>= 2.8.11),
dpkg-dev (>= 1.17),
libnl-3-dev,
libnl-route-3-dev,
libsystemd-dev,
libudev-dev,
ninja-build,
pkg-config,
Expand Down
1 change: 1 addition & 0 deletions debian/ibacm.install
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
etc/init.d/ibacm
lib/systemd/system/ibacm.service
lib/systemd/system/ibacm.socket
usr/bin/ib_acme
usr/include/infiniband/acm.h
usr/include/infiniband/acm_prov.h
Expand Down
7 changes: 6 additions & 1 deletion ibacm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ rdma_sbin_executable(ibacm
target_link_libraries(ibacm LINK_PRIVATE
ibverbs
ibumad
${SYSTEMD_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_DL_LIBS}
)
Expand Down Expand Up @@ -59,7 +60,6 @@ rdma_man_pages(

# FIXME: update the .init.in
set(rdmascript "openibd")
set(prefix "${CMAKE_INSTALL_PREFIX}")
rdma_subst_install(FILES "ibacm.init.in"
DESTINATION "${CMAKE_INSTALL_INITDDIR}"
RENAME "ibacm"
Expand All @@ -69,3 +69,8 @@ rdma_subst_install(FILES "ibacm.service.in"
DESTINATION "${CMAKE_INSTALL_SYSTEMD_SERVICEDIR}"
RENAME ibacm.service
PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)

install(FILES "ibacm.socket"
DESTINATION "${CMAKE_INSTALL_SYSTEMD_SERVICEDIR}"
RENAME ibacm.socket
PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
6 changes: 3 additions & 3 deletions ibacm/ibacm.init.in
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,22 @@ elif [ -s /lib/lsb/init-functions ]; then
# SLES / OpenSuSE / Debian
. /lib/lsb/init-functions
_daemon() { start_daemon "$@"; }
_checkpid() { checkproc -p $pidfile @prefix@/sbin/ibacm; }
_checkpid() { checkproc -p $pidfile @CMAKE_INSTALL_FULL_SBINDIR@/ibacm; }
_success() { log_success_msg; }
_failure() { log_failure_msg; }
elif [ -s /etc/rc.status ]; then
# Older SuSE
. /etc/rc.status
_daemon() { /sbin/start_daemon ${1+"$@"}; }
_checkpid() { checkproc -p $pidfile @prefix@/sbin/ibacm; }
_checkpid() { checkproc -p $pidfile @CMAKE_INSTALL_FULL_SBINDIR@/ibacm; }
_success() { rc_status -v; }
_failure() { rc_status -v; }
fi

start()
{
echo -n "Starting ibacm daemon:"
_daemon @prefix@/sbin/ibacm
_daemon @CMAKE_INSTALL_FULL_SBINDIR@/ibacm
if [[ $RETVAL -eq 0 ]]; then
_success
else
Expand Down
7 changes: 4 additions & 3 deletions ibacm/ibacm.service.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[Unit]
Description=Starts the InfiniBand Address Cache Manager daemon
Description=InfiniBand Address Cache Manager Daemon
Documentation=man:ibacm file:@CMAKE_INSTALL_SYSCONFDIR@/rdma/ibacm_opts.cfg
After=opensm.service
Wants=ibacm.socket

[Service]
Type=forking
ExecStart=@prefix@/sbin/ibacm
ExecStart=@CMAKE_INSTALL_FULL_SBINDIR@/ibacm --systemd

[Install]
Also=ibacm.socket
WantedBy=network.target
10 changes: 10 additions & 0 deletions ibacm/ibacm.socket
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Socket for InfiniBand Address Cache Manager Daemon
Documentation=man:ibacm

[Socket]
ListenStream=6125
BindToDevice=lo

[Install]
WantedBy=sockets.target
4 changes: 4 additions & 0 deletions ibacm/man/ibacm.1
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ address configuration file
.TP
\-O option_file
option configuration file
.TP
\--systemd
Enable systemd integration. This includes optional socket activation of the daemon's
listening socket.
.SH "QUICK START GUIDE"
1. Prerequisites: libibverbs and libibumad must be installed.
The IB stack should be running with IPoIB configured.
Expand Down
87 changes: 56 additions & 31 deletions ibacm/src/acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
* SOFTWARE.
*/

#define _GNU_SOURCE

#include <config.h>

#include <stdio.h>
Expand Down Expand Up @@ -57,6 +59,8 @@
#include <rdma/ib_user_sa.h>
#include <poll.h>
#include <inttypes.h>
#include <getopt.h>
#include <systemd/sd-daemon.h>
#include <ccan/list.h>
#include <util/util.h>
#include "acm_mad.h"
Expand Down Expand Up @@ -597,6 +601,35 @@ static int acm_listen(void)
return 0;
}

/* Retrieve the listening socket from systemd. */
static int acm_listen_systemd(void)
{
int rc = sd_listen_fds(1);
if (rc == 0) {
/* We are in systemd mode but no FDs were passed? Fall back to
* normal mode
*/
return acm_listen();
}
if (rc == -1) {
fprintf(stderr, "sd_listen_fds failed %d\n", rc);
return rc;
}

if (rc != 1) {
fprintf(stderr, "sd_listen_fds returned %d fds, expected 1\n", rc);
return -1;
}

if (!sd_is_socket(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, 1)) {
fprintf(stderr, "sd_listen_fds socket is not a SOCK_STREAM listening socket\n");
return -1;
}

listen_socket = SD_LISTEN_FDS_START;
return 0;
}

static void acm_disconnect_client(struct acmc_client *client)
{
pthread_mutex_lock(&client->lock);
Expand Down Expand Up @@ -1667,15 +1700,18 @@ static int acm_init_nl(void)
return 0;
}

static void acm_server(void)
static void acm_server(bool systemd)
{
fd_set readfds;
int i, n, ret;
struct acmc_device *dev;

acm_log(0, "started\n");
acm_init_server();
ret = acm_listen();
if (systemd)
ret = acm_listen_systemd();
else
ret = acm_listen();
if (ret) {
acm_log(0, "ERROR - server listen failed\n");
return;
Expand Down Expand Up @@ -2933,29 +2969,6 @@ static int acm_open_lock_file(void)
return 0;
}

static void daemonize(void)
{
pid_t pid, sid;

pid = fork();
if (pid)
exit(pid < 0);

sid = setsid();
if (sid < 0)
exit(1);

if (chdir("/"))
exit(1);

if(!freopen("/dev/null", "r", stdin))
exit(1);
if(!freopen("/dev/null", "w", stdout))
exit(1);
if(!freopen("/dev/null", "w", stderr))
exit(1);
}

static void show_usage(char *program)
{
printf("usage: %s\n", program);
Expand All @@ -2969,30 +2982,42 @@ static void show_usage(char *program)

int main(int argc, char **argv)
{
int i, op, daemon = 1;
int i, op, as_daemon = 1;
bool systemd = false;

static const struct option long_opts[] = {
{"systemd", 0, NULL, 's'},
{}
};

while ((op = getopt(argc, argv, "DPA:O:")) != -1) {
while ((op = getopt_long(argc, argv, "DPA:O:", long_opts, NULL)) !=
-1) {
switch (op) {
case 'D':
/* option no longer required */
break;
case 'P':
daemon = 0;
as_daemon = 0;
break;
case 'A':
addr_file = optarg;
break;
case 'O':
opts_file = optarg;
break;
case 's':
systemd = true;
break;
default:
show_usage(argv[0]);
exit(1);
}
}

if (daemon)
daemonize();
if (as_daemon && !systemd) {
if (daemon(0, 0))
return EXIT_FAILURE;
}

acm_set_options();
if (acm_open_lock_file())
Expand Down Expand Up @@ -3032,7 +3057,7 @@ int main(int argc, char **argv)
}
acm_activate_devices();
acm_log(1, "starting server\n");
acm_server();
acm_server(systemd);

acm_log(0, "shutting down\n");
if (client_array[NL_CLIENT_INDEX].sock != -1)
Expand Down
Loading

0 comments on commit 3bc3cee

Please sign in to comment.