diff --git a/TODO b/TODO index 18a8a086..c831948a 100644 --- a/TODO +++ b/TODO @@ -1,98 +1,97 @@ -------------------------------------------------------- The Corosync Cluster Engine Topic Branches and Backlog -------------------------------------------------------- ---------------------------- Last Updated: May 2012 ---------------------------- -------------------------------------- Current priority list for Needle 2.1 -------------------------------------- * disallow binding to localhost (Honza) * don't rely on mcast loop (Honza) * Add support for LOG_TRACE and log received messages in this level (Honza) * Proper support for DNS (always return one address even if function is called multiple times) (Honza) * porting of qdisk to votequorum and eventually finalize qdevice API in votequorum. (Fabio) * Cleaner shutdown process -> free memory (Fabio) -* Merge init and systemd stuff (Fabio) -------------------------------------- Current priority list for Needle 2.X -------------------------------------- * logsys glue layer removal * harden and finish ykd algorithm * implement topic-xmlschema * Modify totemsrp to allow dynamic definitions of the ring counts to allow a larger number of redundant rings then 2. * Investigate always-on flight recorder * support more encryption methods (other than none/aes256) from nss * implement topic-rdmaud -------------------------------- Ideas for future releases (3.0+) -------------------------------- * topic-netmalloc * doxygenize include and lib directories. * re-evaluate using libtool to link libraries. * Support for clang as compiler (depends on libtool) * reorganize library/headers/code in the tree * change and simplify build defaults * libtotem cleanup/rewrite * Rewrite totem fragmentation layer * rewrite top level totempg interface * Split fragmentation layer in totem (ie: totempg talks to totemfrg talks to totemsrp) * Add a getopt and setopt feature to top level interface to allow runtime configuration of the interface * Improve cpg - opaque data in callbacks (client stores data about itself, every node can access them), permissions (read only/read write/ some application may disable listeners) - Probably implemented as extra user space library on top of normal cpg * Better statistic - histogram * totem multiring * load balancing over different speed links in RRP We use topic branches in our git repository to develop new disruptive features that define our future roadmap. This file describes the topic branches the developers have interest in investigating further. targets can be: needle2.1, needle2.X, or future (3.0). Once in a shipped version, please remove from the topic list. ------------------------------------------------------------------------------ topic-xmlschema ------------------------------------------------------------------------------ XML configuration for corosync exists, but imput file is not checked against XML schema. This topic is about implementing preferably RelaxNG schema of corosync configuration. ------------------------------------------------------------------------------ topic-onecrypt ------------------------------------------------------------------------------ Currently encryption code is located in totemudp.c, totemudpu.c, and iba has no encryption support. This topic merges the encryption code into a new file such as totemcrp.c and provides a mechanism for totemnet.c to register encrypt and decrypt functions with totem[udp|iba|udpu] and use them as requested by the configuration. ------------------------------------------------------------------------------ topic-netmalloc ------------------------------------------------------------------------------ The totemiba.c driver must allocate memory and assign it to a protection domain in order for an infiniband driver to transmit memory. In the current implementation, totemsrp.c also allocates these same frames. This results in an extra memcpy when transmitting with libibverbs technology. Memory copies are to be avoided. The simple solution is to have each network driver provide a memory allocation function. When totemsrp wants a free frame, it requests it from the network driver. ------------------------------------------------------------------------------ topic-rdmaud ------------------------------------------------------------------------------ Currently our RDMA code uses librdmacm to setup connections. We are not certain this extra library is needed, and may be able to use only ibverbs. If this is possible, the totem code may be more reliable, especially around failure conditions. diff --git a/configure.ac b/configure.ac index f2222b2c..7ce168f0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,657 +1,666 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. # bootstrap / init AC_PREREQ([2.61]) AC_INIT([corosync], m4_esyscmd([build-aux/git-version-gen .tarball-version]), [discuss@lists.corosync.org]) AM_INIT_AUTOMAKE([-Wno-portability]) AM_SILENT_RULES([yes]) AC_CONFIG_SRCDIR([lib/cpg.c]) AC_CONFIG_HEADER([include/corosync/config.h]) AC_CANONICAL_HOST AC_LANG([C]) dnl Fix default variables - "prefix" variable if not specified if test "$prefix" = "NONE"; then prefix="/usr" dnl Fix "localstatedir" variable if not specified if test "$localstatedir" = "\${prefix}/var"; then localstatedir="/var" fi dnl Fix "sysconfdir" variable if not specified if test "$sysconfdir" = "\${prefix}/etc"; then sysconfdir="/etc" fi dnl Fix "libdir" variable if not specified if test "$libdir" = "\${exec_prefix}/lib"; then if test -e /usr/lib64; then libdir="/usr/lib64" else libdir="/usr/lib" fi fi fi if test "$srcdir" = "."; then AC_MSG_NOTICE([building in place srcdir:$srcdir]) AC_DEFINE([BUILDING_IN_PLACE], 1, [building in place]) else AC_MSG_NOTICE([building out of tree srcdir:$srcdir]) fi # Checks for programs. # check stolen from gnulib/m4/gnu-make.m4 if ! ${MAKE-make} --version /cannot/make/this >/dev/null 2>&1; then AC_MSG_ERROR([you don't seem to have GNU make; it is required]) fi sinclude(coroysync-default.m4) AC_PROG_CC AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_RANLIB AC_CHECK_PROGS([GROFF], [groff]) AC_CHECK_PROGS([PKGCONFIG], [pkg-config]) AC_CHECK_PROGS([AUGTOOL], [augtool]) AC_CHECK_PROGS([DOT], [dot]) AC_CHECK_PROGS([DOXYGEN], [doxygen]) AC_CHECK_PROGS([AWK], [awk]) # Checks for libraries. AC_CHECK_LIB([dl], [dlopen]) AC_CHECK_LIB([pthread], [pthread_create]) AC_CHECK_LIB([socket], [socket]) AC_CHECK_LIB([nsl], [t_open]) AC_CHECK_LIB([rt], [sched_getscheduler]) PKG_CHECK_MODULES([LIBQB], [libqb]) AC_CHECK_LIB([qb], [qb_log_thread_priority_set], \ have_qb_log_thread_priority_set="yes", \ have_qb_log_thread_priority_set="no") if test "x${have_qb_log_thread_priority_set}" = xyes; then AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], 1, [have qb_log_thread_priority_set]) fi PKG_CHECK_MODULES([nss],[nss]) # Checks for header files. AC_FUNC_ALLOCA AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdint.h \ stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h \ sys/time.h syslog.h unistd.h sys/types.h getopt.h malloc.h \ sys/sockio.h utmpx.h ifaddrs.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_UID_T AC_C_INLINE AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_INT64_T AC_TYPE_INT8_T AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_HEADER_TIME AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T AC_C_VOLATILE # Checks for library functions. AC_FUNC_CLOSEDIR_VOID AC_FUNC_ERROR_AT_LINE AC_REPLACE_FNMATCH AC_FUNC_FORK AC_PROG_GCC_TRADITIONAL AC_FUNC_MALLOC AC_FUNC_MEMCMP AC_FUNC_REALLOC AC_FUNC_SELECT_ARGTYPES AC_TYPE_SIGNAL AC_FUNC_VPRINTF AC_CHECK_FUNCS([alarm alphasort atexit bzero dup2 endgrent endpwent fcntl \ getcwd getpeerucred getpeereid gettimeofday inet_ntoa memmove \ memset mkdir scandir select socket strcasecmp strchr strdup \ strerror strrchr strspn strstr pthread_setschedparam \ sched_get_priority_max sched_setscheduler getifaddrs]) AC_CONFIG_FILES([Makefile exec/Makefile include/Makefile init/Makefile lib/Makefile common_lib/Makefile man/Makefile pkgconfig/Makefile test/Makefile cts/Makefile cts/agents/Makefile cts/CTSvars.py tools/Makefile conf/Makefile Doxyfile]) ### Local business dnl =============================================== dnl Functions / global M4 variables dnl =============================================== dnl Global list of LIB names m4_define([local_soname_list], [])dnl dnl Upcase parameter m4_define([local_upcase], [translit([$*], [a-z], [A-Z])])dnl dnl M4 macro for include lib/lib$1.soname and subst that m4_define([LIB_SONAME_IMPORT],[dnl m4_define([local_libname], local_upcase($1)[_SONAME])dnl m4_define([local_soname], translit(m4_sinclude(lib/lib$1.verso), [ ], []))dnl local_libname="local_soname"dnl m4_define([local_soname_list], m4_defn([local_soname_list])[,]local_libname[,]local_upcase($1))dnl AC_SUBST(local_libname)dnl ])dnl dnl M4 macro for print padspaces (used in LIB_MSG_RESULT). It takes 2 arguments, length of string to pad and desired dnl (padded) length m4_define([m4_printpadspace],[ifelse(m4_eval([$2 - $1 < 1]),[1],,[ ][m4_printpadspace([$1],m4_eval([$2 - 1]))])])dnl dnl Show AC_MSG_RESULT for specific libraries m4_define([LIB_MSG_RESULT], [ifelse([$#], [1], ,[dnl AC_MSG_RESULT([ $2 Library SONAME m4_printpadspace(len($2),8) = ${$1}]) LIB_MSG_RESULT(m4_shift(m4_shift($@)))dnl ])])dnl # =============================================== # Helpers # =============================================== ## helper for CC stuff cc_supports_flag() { local CPPFLAGS="$CPPFLAGS $@" AC_MSG_CHECKING([whether $CC supports "$@"]) AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])], [RC=0; AC_MSG_RESULT([yes])], [RC=1; AC_MSG_RESULT([no])]) return $RC } ## cleanup AC_MSG_NOTICE(Sanitizing prefix: ${prefix}) case $prefix in NONE) prefix=/usr/local;; esac AC_MSG_NOTICE(Sanitizing exec_prefix: ${exec_prefix}) case $exec_prefix in dnl For consistency with Corosync, map NONE->$prefix NONE) exec_prefix=$prefix;; prefix) exec_prefix=$prefix;; esac ## local defines PACKAGE_FEATURES="" LINT_FLAGS="-weak -unrecog +posixlib +ignoresigns -fcnuse \ -badflag -D__gnuc_va_list=va_list -D__attribute\(x\)=" # default libraries SONAME SOMAJOR="5" SOMINOR="0" SOMICRO="0" SONAME="${SOMAJOR}.${SOMINOR}.${SOMICRO}" # specific libraries SONAME LIB_SONAME_IMPORT([cfg]) LIB_SONAME_IMPORT([cpg]) LIB_SONAME_IMPORT([quorum]) LIB_SONAME_IMPORT([sam]) LIB_SONAME_IMPORT([votequorum]) LIB_SONAME_IMPORT([cmap]) # local options AC_ARG_ENABLE([ansi], [ --enable-ansi : force to build with ANSI standards. ], [ default="no" ]) AC_ARG_ENABLE([fatal-warnings], [ --enable-fatal-warnings : enable fatal warnings. ], [ default="no" ]) AC_ARG_ENABLE([debug], [ --enable-debug : enable debug build. ], [ default="no" ]) AC_ARG_ENABLE([user-flags], [ --enable-user-flags : rely on user environment. ], [ default="no" ]) AC_ARG_ENABLE([coverage], [ --enable-coverage : coverage analysis of the codebase. ], [ default="no" ]) AC_ARG_ENABLE([small-memory-footprint], [ --enable-small-memory-footprint : Use small message queues and small messages sizes. ], [ default="no" ]) AC_ARG_ENABLE([dbus], [ --enable-dbus : dbus events. ],, [ enable_dbus="no" ]) AC_ARG_ENABLE([testagents], [ --enable-testagents : Install Test Agents. ],, [ default="no" ]) AC_ARG_ENABLE([rdma], [ --enable-rdma : Infiniband RDMA transport support ],, [ enable_rdma="no" ]) AM_CONDITIONAL(BUILD_RDMA, test x$enable_rdma = xyes) AC_ARG_ENABLE([monitoring], [ --enable-monitoring : resource monitoring ],, [ default="no" ]) AM_CONDITIONAL(BUILD_MONITORING, test x$enable_monitoring = xyes) AC_ARG_ENABLE([watchdog], [ --enable-watchdog : Watchdog support ],, [ default="no" ]) AM_CONDITIONAL(BUILD_WATCHDOG, test x$enable_watchdog = xyes) AC_ARG_ENABLE([augeas], [ --enable-augeas : Install the augeas lens for corosync.conf ],, [ enable_augeas="no" ]) AM_CONDITIONAL(INSTALL_AUGEAS, test x$enable_augeas = xyes) AC_ARG_ENABLE([systemd], [ --enable-systemd : Install systemd service files],, [ enable_systemd="no" ]) AM_CONDITIONAL(INSTALL_SYSTEMD, test x$enable_systemd = xyes) AC_ARG_WITH([initddir], [ --with-initddir=DIR : path to init script directory. ], [ INITDDIR="$withval" ], [ INITDDIR="$sysconfdir/init.d" ]) AC_ARG_WITH([systemddir], [ --with-systemddir=DIR : path to systemd unit files directory. ], [ SYSTEMDDIR="$withval" ], [ SYSTEMDDIR="/lib/systemd/system" ]) +AC_ARG_WITH([initwrappersdir], + [ --with-initwrappersdir=DIR : path to init wrappers files directory. ], + [ INITWRAPPERSDIR="$withval" ], + [ INITWRAPPERSDIR="$datarootdir/corosync" ]) + AC_ARG_ENABLE([snmp], [ --enable-snmp : SNMP protocol support ], [ default="no" ]) AC_ARG_ENABLE([xmlconf], [ --enable-xmlconf : XML configuration support ],, [ enable_xmlconf="no" ]) AM_CONDITIONAL(INSTALL_XMLCONF, test x$enable_xmlconf = xyes) # OS detection # THIS SECTION MUST DIE! CP=cp OS_LDL="-ldl" have_linux="no" case "$host_os" in *linux*) AC_DEFINE_UNQUOTED([COROSYNC_LINUX], [1], [Compiling for Linux platform]) OS_CFLAGS="" OS_CPPFLAGS="-D_GNU_SOURCE" OS_LDFLAGS="" OS_DYFLAGS="-rdynamic" DARWIN_OPTS="" have_linux="yes" ;; darwin*) AC_DEFINE_UNQUOTED([COROSYNC_DARWIN], [1], [Compiling for Darwin platform]) CP=rsync OS_CFLAGS="" OS_CPPFLAGS="" OS_LDFLAGS="" OS_DYFLAGS="" DARWIN_OPTS="-dynamiclib -bind_at_load \ -current_version ${SONAME} \ -compatibility_version ${SONAME} -install_name \$(libdir)/\$(@)" AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON], [Shared memory define for Darwin platform]) AC_DEFINE_UNQUOTED([PATH_MAX], [4096], [Number of chars in a path name including nul]) AC_DEFINE_UNQUOTED([NAME_MAX], [255], [Number of chars in a file name]) ;; *bsd*) AC_DEFINE_UNQUOTED([COROSYNC_BSD], [1], [Compiling for BSD platform]) AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON], [Shared memory define for Darwin platform]) OS_CFLAGS="" OS_CPPFLAGS="-I/usr/local/include" OS_LDFLAGS="-L/usr/local/lib" OS_DYFLAGS="-export-dynamic" DARWIN_OPTS="" OS_LDL="" case "$host_os" in *freebsd[[234567]]*) ;; *freebsd*) AC_DEFINE_UNQUOTED([COROSYNC_FREEBSD_GE_8], [1], [Compiling for FreeBSD >= 8 platform]) ;; esac ;; *solaris*) AC_DEFINE_UNQUOTED([COROSYNC_SOLARIS], [1], [Compiling for Solaris platform]) AC_DEFINE_UNQUOTED([TS_CLASS], [1], [Prevent being scheduled RR]) AC_DEFINE_UNQUOTED([_SEM_SEMUN_UNDEFINED], [1], [The semun structure is undefined]) CP=rsync OS_CFLAGS="" OS_CPPFLAGS="-D_REENTRANT" OS_LDFLAGS="" OS_DYFLAGS="-Wl,-z,lazyload" DARWIN_OPTS="" SOLARIS_OPTS=" " ;; *) AC_MSG_ERROR([Unsupported OS? hmmmm]) ;; esac AC_SUBST(CP) # *FLAGS handling goes here ENV_CFLAGS="$CFLAGS" ENV_CPPFLAGS="$CPPFLAGS" ENV_LDFLAGS="$LDFLAGS" # debug build stuff if test "x${enable_debug}" = xyes; then AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code]) OPT_CFLAGS="-O0" PACKAGE_FEATURES="$PACKAGE_FEATURES debug" else OPT_CFLAGS="-O3" fi # gdb flags if test "x${GCC}" = xyes; then GDB_FLAGS="-ggdb3" else GDB_FLAGS="-g" fi # Look for dbus-1 if test "x${enable_dbus}" = xyes; then PKG_CHECK_MODULES([DBUS],[dbus-1]) AC_DEFINE_UNQUOTED([HAVE_DBUS], 1, [have dbus]) PACKAGE_FEATURES="$PACKAGE_FEATURES dbus" fi if test "x${enable_testagents}" = xyes; then AC_DEFINE_UNQUOTED([HAVE_TESTAGENTS], 1, [have testagents]) PACKAGE_FEATURES="$PACKAGE_FEATURES testagents" fi if test "x${enable_rdma}" = xyes; then PKG_CHECK_MODULES([rdmacm],[rdmacm]) PKG_CHECK_MODULES([ibverbs],[ibverbs]) AC_DEFINE_UNQUOTED([HAVE_RDMA], 1, [have rdmacm]) PACKAGE_FEATURES="$PACKAGE_FEATURES rdma" fi if test "x${enable_monitoring}" = xyes; then AC_CHECK_LIB([statgrab], [sg_get_mem_stats], have_libstatgrab="yes", have_libstatgrab="no") if test "x${have_libstatgrab}" = xyes; then AC_DEFINE_UNQUOTED([HAVE_LIBSTATGRAB], 1, [have libstatgrab]) statgrab_LIBS="-lstatgrab" else if test "x${have_linux}" = xno; then AC_MSG_ERROR(monitoring requires libstatgrab on non-linux systems) fi fi AC_SUBST([statgrab_LIBS]) AC_DEFINE_UNQUOTED([HAVE_MONITORING], 1, [have resource monitoring]) PACKAGE_FEATURES="$PACKAGE_FEATURES monitoring" fi if test "x${enable_watchdog}" = xyes; then AC_CHECK_HEADER(linux/watchdog.h,,AC_MSG_ERROR(watchdog requires linux/watchdog.h)) AC_CHECK_HEADER(linux/reboot.h,,AC_MSG_ERROR(watchdog requires linux/reboot.h)) AC_DEFINE_UNQUOTED([HAVE_WATCHDOG], 1, [have watchdog]) PACKAGE_FEATURES="$PACKAGE_FEATURES watchdog" fi if test "x${enable_augeas}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES augeas" fi if test "x${enable_systemd}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES systemd" fi if test "x${enable_xmlconf}" = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES xmlconf" fi if test "x${enable_snmp}" = xyes; then SNMPCONFIG="" AC_CHECK_HEADERS(net-snmp/net-snmp-config.h) if test "x${ac_cv_header_net_snmp_net_snmp_config_h}" != "xyes"; then enable_snmp=no fi if test $enable_snmp != no; then AC_PATH_PROGS(SNMPCONFIG, net-snmp-config) if test "X${SNMPCONFIG}" = "X"; then AC_MSG_RESULT(You need the net_snmp development package to continue.) enable_snmp=no fi fi if test $enable_snmp != no; then AC_MSG_CHECKING(for special snmp libraries) SNMPLIBS=`$SNMPCONFIG --libs` AC_MSG_RESULT($SNMPLIBS) fi if test $enable_snmp != no; then savedLibs=$LIBS LIBS="$LIBS $SNMPLIBS" AC_CHECK_FUNCS(netsnmp_transport_open_client) if test $ac_cv_func_netsnmp_transport_open_client != yes; then AC_CHECK_FUNCS(netsnmp_tdomain_transport) if test $ac_cv_func_netsnmp_tdomain_transport != yes; then enable_snmp=no fi else AC_DEFINE_UNQUOTED([NETSNMPV54], $NETSNMP_NEW_SUPPORT, [have net-snmp5.4 over]) fi LIBS=$savedLibs fi AC_MSG_CHECKING(for snmp) AC_MSG_RESULT($enable_snmp) if test $enable_snmp = no; then enable_snmp=0 AC_MSG_ERROR(Unable to support SNMP) else enable_snmp=1 PACKAGE_FEATURES="$PACKAGE_FEATURES snmp" AC_DEFINE_UNQUOTED([ENABLE_SNMP], $enable_snmp, [Build in support for sending SNMP traps]) fi else enable_snmp=0 fi AC_SUBST([SNMPLIBS]) AM_CONDITIONAL(BUILD_SNMP, test "${enable_snmp}" = "1") # extra warnings EXTRA_WARNINGS="" WARNLIST=" all shadow missing-prototypes missing-declarations strict-prototypes declaration-after-statement pointer-arith write-strings cast-align bad-function-cast missing-format-attribute format=2 format-security format-nonliteral no-long-long unsigned-char gnu89-inline no-strict-aliasing " for j in $WARNLIST; do if cc_supports_flag -W$j; then EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j"; fi done if test "x${enable_coverage}" = xyes && \ cc_supports_flag -ftest-coverage && \ cc_supports_flag -fprofile-arcs ; then AC_MSG_NOTICE([Enabling Coverage (enable -O0 by default)]) OPT_CFLAGS="-O0" COVERAGE_CFLAGS="-ftest-coverage -fprofile-arcs" COVERAGE_LDFLAGS="-ftest-coverage -fprofile-arcs" PACKAGE_FEATURES="$PACKAGE_FEATURES coverage" else COVERAGE_CFLAGS="" COVERAGE_LDFLAGS="" fi if test "x${enable_small_memory_footprint}" = xyes ; then AC_DEFINE_UNQUOTED([HAVE_SMALL_MEMORY_FOOTPRINT], 1, [have small_memory_footprint]) PACKAGE_FEATURES="$PACKAGE_FEATURES small-memory-footprint" fi if test "x${enable_ansi}" = xyes && \ cc_supports_flag -std=iso9899:199409 ; then AC_MSG_NOTICE([Enabling ANSI Compatibility]) ANSI_CPPFLAGS="-ansi -D_GNU_SOURCE -DANSI_ONLY" PACKAGE_FEATURES="$PACKAGE_FEATURES ansi" else ANSI_CPPFLAGS="" fi if test "x${enable_fatal_warnings}" = xyes && \ cc_supports_flag -Werror ; then AC_MSG_NOTICE([Enabling Fatal Warnings (-Werror)]) WERROR_CFLAGS="-Werror" PACKAGE_FEATURES="$PACKAGE_FEATURES fatal-warnings" else WERROR_CFLAGS="" fi # don't add addtional cflags if test "x${enable_user_flags}" = xyes; then OPT_CFLAGS="" GDB_FLAGS="" EXTRA_WARNINGS="" fi # final build of *FLAGS CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS $OS_CFLAGS \ $COVERAGE_CFLAGS $EXTRA_WARNINGS $WERROR_CFLAGS $NSS_CFLAGS" CPPFLAGS="$ENV_CPPFLAGS $ANSI_CPPFLAGS $OS_CPPFLAGS" LDFLAGS="$ENV_LDFLAGS $COVERAGE_LDFLAGS $OS_LDFLAGS" # substitute what we need: AC_SUBST([INITDDIR]) AC_SUBST([SYSTEMDDIR]) +INITWRAPPERSDIR=$(eval echo ${INITWRAPPERSDIR}) +AC_SUBST([INITWRAPPERSDIR]) AC_SUBST([SOMAJOR]) AC_SUBST([SOMINOR]) AC_SUBST([SOMICRO]) AC_SUBST([SONAME]) AC_SUBST([OS_DYFLAGS]) AC_SUBST([OS_LDL]) AM_CONDITIONAL(INSTALL_TESTAGENTS, test -n "${enable_testagents}") AM_CONDITIONAL(INSTALL_MIB, test "${enable_snmp}" = "1") AM_CONDITIONAL(INSTALL_DBUSCONF, test "${enable_dbus}" = "1") AM_CONDITIONAL(AUGTOOL, test -n "${AUGTOOL}") AC_SUBST([NSS_LDFLAGS]) AM_CONDITIONAL(BUILD_DARWIN, test -n "${DARWIN_OPTS}") AM_CONDITIONAL(BUILD_SOLARIS, test -n "${SOLARIS_OPTS}") AC_SUBST([DARWIN_OPTS]) AC_SUBST([SOLARIS_OPTS]) AM_CONDITIONAL(BUILD_HTML_DOCS, test -n "${GROFF}") AC_SUBST([LINT_FLAGS]) AC_DEFINE_UNQUOTED([LOCALSTATEDIR], "$(eval echo ${localstatedir})", [localstate directory]) COROSYSCONFDIR=${sysconfdir}/corosync AC_SUBST([COROSYSCONFDIR]) AC_DEFINE_UNQUOTED([COROSYSCONFDIR], "$(eval echo ${COROSYSCONFDIR})", [corosync config directory]) AC_DEFINE_UNQUOTED([PACKAGE_FEATURES], "${PACKAGE_FEATURES}", [corosync built-in features]) AC_OUTPUT AC_MSG_RESULT([]) AC_MSG_RESULT([$PACKAGE configuration:]) AC_MSG_RESULT([ Version = ${VERSION}]) AC_MSG_RESULT([ Prefix = ${prefix}]) AC_MSG_RESULT([ Executables = ${sbindir}]) AC_MSG_RESULT([ Man pages = ${mandir}]) AC_MSG_RESULT([ Doc dir = ${docdir}]) AC_MSG_RESULT([ Libraries = ${libdir}]) AC_MSG_RESULT([ Header files = ${includedir}]) AC_MSG_RESULT([ Arch-independent files = ${datadir}]) AC_MSG_RESULT([ State information = ${localstatedir}]) AC_MSG_RESULT([ System configuration = ${sysconfdir}]) AC_MSG_RESULT([ System init.d directory = ${INITDDIR}]) +AC_MSG_RESULT([ System systemd directory = ${SYSTEMDDIR}]) +AC_MSG_RESULT([ System init wraps dir = ${INITWRAPPERSDIR}]) AC_MSG_RESULT([ corosync config dir = ${COROSYSCONFDIR}]) AC_MSG_RESULT([ Features =${PACKAGE_FEATURES}]) AC_MSG_RESULT([]) AC_MSG_RESULT([$PACKAGE build info:]) AC_MSG_RESULT([ Library SONAME = ${SONAME}]) LIB_MSG_RESULT(m4_shift(local_soname_list))dnl AC_MSG_RESULT([ Default optimization = ${OPT_CFLAGS}]) AC_MSG_RESULT([ Default debug options = ${GDB_CFLAGS}]) AC_MSG_RESULT([ Extra compiler warnings = ${EXTRA_WARNING}]) AC_MSG_RESULT([ Env. defined CFLAG = ${ENV_CFLAGS}]) AC_MSG_RESULT([ Env. defined CPPFLAGS = ${ENV_CPPFLAGS}]) AC_MSG_RESULT([ Env. defined LDFLAGS = ${ENV_LDFLAGS}]) AC_MSG_RESULT([ OS defined CFLAGS = ${OS_CFLAGS}]) AC_MSG_RESULT([ OS defined CPPFLAGS = ${OS_CPPFLAGS}]) AC_MSG_RESULT([ OS defined LDFLAGS = ${OS_LDFLAGS}]) AC_MSG_RESULT([ OS defined LDL = ${OS_LDL}]) AC_MSG_RESULT([ OS defined DYFLAGS = ${OS_DYFLAGS}]) AC_MSG_RESULT([ ANSI defined CPPFLAGS = ${ANSI_CPPFLAGS}]) AC_MSG_RESULT([ Coverage CFLAGS = ${COVERAGE_CFLAGS}]) AC_MSG_RESULT([ Coverage LDFLAGS = ${COVERAGE_LDFLAGS}]) AC_MSG_RESULT([ Fatal War. CFLAGS = ${WERROR_CFLAGS}]) AC_MSG_RESULT([ Final CFLAGS = ${CFLAGS}]) AC_MSG_RESULT([ Final CPPFLAGS = ${CPPFLAGS}]) AC_MSG_RESULT([ Final LDFLAGS = ${LDFLAGS}]) diff --git a/corosync.spec.in b/corosync.spec.in index 40623512..1c99d20a 100644 --- a/corosync.spec.in +++ b/corosync.spec.in @@ -1,293 +1,296 @@ %global alphatag @alphatag@ %global numcomm @numcomm@ %global dirty @dirty@ # Conditionals # Invoke "rpmbuild --without " or "rpmbuild --with " # to disable or enable specific features %bcond_with testagents %bcond_with watchdog %bcond_with monitoring %bcond_with snmp %bcond_with dbus %bcond_with rdma %bcond_with systemd %bcond_with xmlconf Name: corosync Summary: The Corosync Cluster Engine and Application Programming Interfaces Version: @version@ Release: 1%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist} License: BSD Group: System Environment/Base URL: http://ftp.corosync.org Source0: ftp://ftp:user@ftp.corosync.org/downloads/%{name}-%{version}/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz # Runtime bits Requires: corosynclib = %{version}-%{release} Requires(pre): /usr/sbin/useradd Requires(post): /sbin/chkconfig Requires(preun): /sbin/chkconfig Conflicts: openais <= 0.89, openais-devel <= 0.89 # Build bits %define buildtrunk 0 %{?_with_buildtrunk: %define buildtrunk 1} BuildRequires: libqb-devel BuildRequires: nss-devel %if %{buildtrunk} BuildRequires: autoconf automake %endif %if %{with rdma} BuildRequires: libibverbs-devel librdmacm-devel %endif %if %{with snmp} BuildRequires: net-snmp-devel %endif %if %{with dbus} BuildRequires: dbus-devel %endif %if %{with systemd} BuildRequires: systemd-units %endif %if %{with xmlconf} Requires: libxslt %endif BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) %prep %setup -q -n %{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}} %build %if %{buildtrunk} ./autogen.sh %endif %if %{with rdma} export ibverbs_CFLAGS=-I/usr/include/infiniband \ export ibverbs_LIBS=-libverbs \ export rdmacm_CFLAGS=-I/usr/include/rdma \ export rdmacm_LIBS=-lrdmacm \ %endif %{configure} \ %if %{with testagents} --enable-testagents \ %endif %if %{with watchdog} --enable-watchdog \ %endif %if %{with monitoring} --enable-monitoring \ %endif %if %{with snmp} --enable-snmp \ %endif %if %{with dbus} --enable-dbus \ %endif %if %{with rdma} --enable-rdma \ %endif %if %{with systemd} --enable-systemd \ %endif %if %{with xmlconf} --enable-xmlconf \ %endif --with-initddir=%{_initrddir} \ --with-systemddir=%{_unitdir} make %{_smp_mflags} %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} %if %{with dbus} mkdir -p -m 0700 %{buildroot}/%{_sysconfdir}/dbus-1/system.d install -m 644 %{_builddir}/%{name}-%{version}/conf/corosync-signals.conf %{buildroot}/%{_sysconfdir}/dbus-1/system.d/corosync-signals.conf %endif ## tree fixup # drop static libs rm -f %{buildroot}%{_libdir}/*.a # drop docs and html docs for now rm -rf %{buildroot}%{_docdir}/* %clean rm -rf %{buildroot} %description This package contains the Corosync Cluster Engine Executive, several default APIs and libraries, default configuration files, and an init script. %post if [ $1 -eq 1 ]; then /sbin/chkconfig --add corosync || : fi %preun if [ $1 -eq 0 ]; then /sbin/service corosync stop &>/dev/null || : /sbin/chkconfig --del corosync || : fi %files %defattr(-,root,root,-) %doc LICENSE SECURITY %{_sbindir}/corosync %{_sbindir}/corosync-keygen %{_sbindir}/corosync-cmapctl %{_sbindir}/corosync-cfgtool %{_sbindir}/corosync-fplay %{_sbindir}/corosync-cpgtool %{_sbindir}/corosync-quorumtool %{_sbindir}/corosync-notifyd %{_bindir}/corosync-blackbox %if %{with xmlconf} %{_bindir}/corosync-xmlproc %config(noreplace) %{_sysconfdir}/corosync/corosync.xml.example %dir %{_datadir}/corosync %dir %{_datadir}/corosync/xml2conf.xsl %{_mandir}/man8/corosync-xmlproc.8* %{_mandir}/man5/corosync.xml.5* %endif %dir %{_sysconfdir}/corosync %dir %{_sysconfdir}/corosync/uidgid.d %config(noreplace) %{_sysconfdir}/corosync/corosync.conf.example %config(noreplace) %{_sysconfdir}/corosync/corosync.conf.example.udpu %if %{with dbus} %{_sysconfdir}/dbus-1/system.d/corosync-signals.conf %endif %if %{with snmp} %{_datadir}/snmp/mibs/COROSYNC-MIB.txt %endif %if %{with systemd} %{_unitdir}/corosync.service %{_unitdir}/corosync-notifyd.service +%dir %{_datadir}/corosync +%{_datadir}/corosync/corosync +%{_datadir}/corosync/corosync-notifyd %else %{_initrddir}/corosync %{_initrddir}/corosync-notifyd %endif %dir %{_localstatedir}/lib/corosync %dir %{_localstatedir}/log/cluster %{_mandir}/man8/corosync_overview.8* %{_mandir}/man8/corosync.8* %{_mandir}/man8/corosync-blackbox.8* %{_mandir}/man8/corosync-cmapctl.8* %{_mandir}/man8/corosync-keygen.8* %{_mandir}/man8/corosync-cfgtool.8* %{_mandir}/man8/corosync-cpgtool.8* %{_mandir}/man8/corosync-fplay.8* %{_mandir}/man8/corosync-notifyd.8* %{_mandir}/man8/corosync-quorumtool.8* %{_mandir}/man5/corosync.conf.5* %{_mandir}/man5/votequorum.5* %{_mandir}/man8/cmap_keys.8* # optional testagent rpm # %if %{with testagents} %package -n corosync-testagents Summary: The Corosync Cluster Engine Test Agents Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description -n corosync-testagents This package contains corosync test agents. %files -n corosync-testagents %defattr(755,root,root,-) %{_datadir}/corosync/tests/mem_leak_test.sh %{_datadir}/corosync/tests/net_breaker.sh %{_datadir}/corosync/tests/cmap-dispatch-deadlock.sh %{_datadir}/corosync/tests/shm_leak_audit.sh %{_bindir}/cpg_test_agent %{_bindir}/sam_test_agent %{_bindir}/votequorum_test_agent %endif # library # %package -n corosynclib Summary: The Corosync Cluster Engine Libraries Group: System Environment/Libraries Requires: %{name} = %{version}-%{release} %description -n corosynclib This package contains corosync libraries. %files -n corosynclib %defattr(-,root,root,-) %doc LICENSE %{_libdir}/libcfg.so.* %{_libdir}/libcpg.so.* %{_libdir}/libcmap.so.* %{_libdir}/libtotem_pg.so.* %{_libdir}/libquorum.so.* %{_libdir}/libvotequorum.so.* %{_libdir}/libsam.so.* %{_libdir}/libcorosync_common.so.* %post -n corosynclib -p /sbin/ldconfig %postun -n corosynclib -p /sbin/ldconfig %package -n corosynclib-devel Summary: The Corosync Cluster Engine Development Kit Group: Development/Libraries Requires: corosynclib = %{version}-%{release} Requires: pkgconfig Provides: corosync-devel = %{version} Obsoletes: corosync-devel < 0.92-7 %description -n corosynclib-devel This package contains include files and man pages used to develop using The Corosync Cluster Engine APIs. %files -n corosynclib-devel %defattr(-,root,root,-) %doc LICENSE %dir %{_includedir}/corosync/ %{_includedir}/corosync/corodefs.h %{_includedir}/corosync/cfg.h %{_includedir}/corosync/cmap.h %{_includedir}/corosync/corotypes.h %{_includedir}/corosync/cpg.h %{_includedir}/corosync/hdb.h %{_includedir}/corosync/sam.h %{_includedir}/corosync/quorum.h %{_includedir}/corosync/votequorum.h %dir %{_includedir}/corosync/totem/ %{_includedir}/corosync/totem/totem.h %{_includedir}/corosync/totem/totemip.h %{_includedir}/corosync/totem/totempg.h %{_libdir}/libcfg.so %{_libdir}/libcpg.so %{_libdir}/libcmap.so %{_libdir}/libtotem_pg.so %{_libdir}/libquorum.so %{_libdir}/libvotequorum.so %{_libdir}/libsam.so %{_libdir}/libcorosync_common.so %{_libdir}/pkgconfig/*.pc %{_mandir}/man3/cpg_*3* %{_mandir}/man3/quorum_*3* %{_mandir}/man3/votequorum_*3* %{_mandir}/man3/sam_*3* %{_mandir}/man8/cpg_overview.8* %{_mandir}/man8/votequorum_overview.8* %{_mandir}/man8/sam_overview.8* %{_mandir}/man3/cmap_*3* %{_mandir}/man8/cmap_overview.8* %{_mandir}/man8/quorum_overview.8* %changelog * @date@ Autotools generated version - @version@-1-@numcomm@.@alphatag@.@dirty@ - Autotools generated version diff --git a/init/Makefile.am b/init/Makefile.am index 00d56d41..8e4d4c7c 100644 --- a/init/Makefile.am +++ b/init/Makefile.am @@ -1,71 +1,63 @@ # Copyright (c) 2004 MontaVista Software, Inc. # Copyright (c) 2009 Red Hat, Inc. # # Authors: Steven Dake (sdake@redhat.com) # Fabio M. Di Nitto (fdinitto@redhat.com) # # All rights reserved. # # This software licensed under BSD license, the text of which follows: # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # - Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # - Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # - Neither the name of the MontaVista Software, Inc. nor the names of its # contributors may be used to endorse or promote products derived from this # software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGE. MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = generic.in notifyd.in corosync.service.in corosync-notifyd.service.in +EXTRA_DIST = corosync.in corosync-notifyd.in corosync.service.in corosync-notifyd.service.in if INSTALL_SYSTEMD -systemdconfdir = $(SYSTEMDDIR) -systemdconf_DATA = corosync.service corosync-notifyd.service +systemdconfdir = $(SYSTEMDDIR) +systemdconf_DATA = corosync.service corosync-notifyd.service +initscriptdir = $(INITWRAPPERSDIR) else -target_INIT = generic notifyd +initscriptdir = $(INITDDIR) endif +initscript_SCRIPTS = corosync corosync-notifyd %: %.in Makefile rm -f $@-t $@ - sed \ + cp $< $@-t + sed -i \ -e 's#@''SBINDIR@#$(sbindir)#g' \ -e 's#@''SYSCONFDIR@#$(sysconfdir)#g' \ -e 's#@''INITDDIR@#$(INITDDIR)#g' \ + -e 's#@''INITWRAPPERSDIR@#$(INITWRAPPERSDIR)#g' \ -e 's#@''LOCALSTATEDIR@#$(localstatedir)#g' \ - $< > $@-t + $@-t mv $@-t $@ -all-local: $(target_INIT) $(systemdconf_DATA) +all-local: $(initscript_SCRIPTS) $(systemdconf_DATA) clean-local: - rm -rf $(target_INIT) $(systemdconf_DATA) - -if INSTALL_SYSTEMD -else -install-exec-local: - $(INSTALL) -d $(DESTDIR)/$(INITDDIR) - $(INSTALL) -m 755 generic $(DESTDIR)/$(INITDDIR)/corosync - $(INSTALL) -m 755 notifyd $(DESTDIR)/$(INITDDIR)/corosync-notifyd - -uninstall-local: - cd $(DESTDIR)/$(INITDDIR) && \ - rm -f corosync corosync-notifyd -endif + rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA) diff --git a/init/notifyd.in b/init/corosync-notifyd.in similarity index 100% rename from init/notifyd.in rename to init/corosync-notifyd.in diff --git a/init/corosync-notifyd.service.in b/init/corosync-notifyd.service.in index 26a278a2..172653cf 100644 --- a/init/corosync-notifyd.service.in +++ b/init/corosync-notifyd.service.in @@ -1,11 +1,12 @@ [Unit] Description=Corosync Dbus and snmp notifier Wants=corosync.service +After=corosync.service [Service] EnvironmentFile=@SYSCONFIGDIR@/corosync-notifyd ExecStart=@SBINDIR@/corosync-notifyd -f $OPTIONS Type=simple [Install] WantedBy=multi-user.target diff --git a/init/generic.in b/init/corosync.in similarity index 88% rename from init/generic.in rename to init/corosync.in index 1ce26f0d..a9840bd9 100755 --- a/init/generic.in +++ b/init/corosync.in @@ -1,184 +1,178 @@ #!/bin/bash # Authors: # Andrew Beekhof # Fabio M. Di Nitto # # License: Revised BSD # chkconfig: - 20 80 # description: Corosync Cluster Engine # processname: corosync # ### BEGIN INIT INFO # Provides: corosync # Required-Start: $network $syslog # Required-Stop: $network $syslog # Default-Start: # Default-Stop: # Short-Description: Starts and stops Corosync Cluster Engine. # Description: Starts and stops Corosync Cluster Engine. ### END INIT INFO desc="Corosync Cluster Engine" prog="corosync" # set secure PATH PATH="/sbin:/bin:/usr/sbin:/usr/bin:@SBINDIR@" success() { echo -ne "[ OK ]\r" } failure() { echo -ne "[FAILED]\r" } status() { pid=$(pidof $1 2>/dev/null) rtrn=$? if [ $rtrn -ne 0 ]; then echo "$1 is stopped" else echo "$1 (pid $pid) is running..." fi return $rtrn } # rpm based distros if [ -d @SYSCONFDIR@/sysconfig ]; then [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions [ -f @SYSCONFDIR@/sysconfig/$prog ] && . @SYSCONFDIR@/sysconfig/$prog [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/subsys/$prog" fi # deb based distros if [ -d @SYSCONFDIR@/default ]; then [ -f @SYSCONFDIR@/default/$prog ] && . @SYSCONFDIR@/default/$prog [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/$prog" fi # The version of __pids_pidof in /etc/init.d/functions calls pidof with -x # This means it matches scripts, including this one. # Redefine it here so that status (from the same file) works. # Otherwise simultaneous calls to stop() will loop forever __pids_pidof() { pidof -c -o $$ -o $PPID -o %PPID "$1" || \ pidof -c -o $$ -o $PPID -o %PPID "${1##*/}" } cluster_disabled_at_boot() { if grep -q nocluster /proc/cmdline && \ [ "$(tty)" = "/dev/console" ]; then echo -e "not configured to run at boot" failure return 1 fi return 0 } +wait_for_ipc() +{ + try=0 + while [ "$try" -le "20" ]; do + if corosync-cfgtool -s > /dev/null 2>&1; then + return 0 + fi + sleep 0.5 + try=$((try + 1)) + done + + return 1 +} + start() { echo -n "Starting $desc ($prog): " ! cluster_disabled_at_boot && return # most recent distributions use tmpfs for @LOCALSTATEDIR@/run # to avoid to clean it up on every boot. # they also assume that init scripts will create # required subdirectories for proper operations mkdir -p @LOCALSTATEDIR@/run if status $prog > /dev/null 2>&1; then success else $prog > /dev/null 2>&1 - # give it time to fail - sleep 2 - if status $prog > /dev/null 2>&1; then - touch $LOCK_FILE - success - else + if ! wait_for_ipc; then failure rtrn=1 fi + touch $LOCK_FILE + success fi echo } -executed_by_cman() -{ - [ -f @LOCALSTATEDIR@/run/cman.pid ] || return 0 - - read cman_pid foo < @LOCALSTATEDIR@/run/cman.pid - if [ "$(pidof $prog)" == "$cman_pid" ];then - echo -n "$desc was executed by cman" - failure - echo - return 1 - fi - - return 0 -} - stop() { ! status $prog > /dev/null 2>&1 && return - ! executed_by_cman && return - echo -n "Signaling $desc ($prog) to terminate: " kill -TERM $(pidof $prog) > /dev/null 2>&1 success echo echo -n "Waiting for $prog services to unload:" while status $prog > /dev/null 2>&1; do sleep 1 echo -n "." done rm -f $LOCK_FILE success echo } restart() { stop start } rtrn=0 case "$1" in start) start ;; restart|reload|force-reload) restart ;; condrestart|try-restart) if status $prog > /dev/null 2>&1; then restart fi ;; status) status $prog rtrn=$? ;; stop) stop ;; *) echo "usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}" rtrn=2 ;; esac exit $rtrn diff --git a/init/corosync.service.in b/init/corosync.service.in index 8cc692be..8a43ccf1 100644 --- a/init/corosync.service.in +++ b/init/corosync.service.in @@ -1,12 +1,13 @@ [Unit] Description=Corosync Cluster Engine ConditionKernelCommandLine=!nocluster -#Conflicts=cman.service +Requires=network.target +After=network.target [Service] -ExecStart=@SBINDIR@/corosync +ExecStart=@INITWRAPPERSDIR@/corosync start +ExecStop=@INITWRAPPERSDIR@/corosync stop Type=forking -#RestartSec=90s [Install] WantedBy=multi-user.target