diff -Nru mapplauncherd-4.1.21+15.10.20150727/CMakeLists.txt mapplauncherd-4.2.0+15.10.20150805/CMakeLists.txt --- mapplauncherd-4.1.21+15.10.20150727/CMakeLists.txt 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/CMakeLists.txt 2015-08-05 11:55:08.000000000 +0000 @@ -8,12 +8,15 @@ # # Default C++-flags. Sub-builds might alter these. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wextra -g -O3 -Wl,--as-needed") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wextra -g -Wl,--as-needed") # Default C-flags. Sub-builds might alter these. -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wextra -g -O3") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wextra -g") -set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") -set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 ") + +set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_RELEASE "") +set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS_RELEASE "") # Find libdl find_library(LIBDL NAMES dl) @@ -25,6 +28,7 @@ # Set the program name defines. Must be at this level due to unit tests. add_definitions(-DPROG_NAME_INVOKER="invoker") add_definitions(-DPROG_NAME_SINGLE_INSTANCE="single-instance") +add_definitions(-DEXEC_AFTER_FORK) # applauncherd will try to load single-instance using this path add_definitions(-DSINGLE_INSTANCE_PATH="/usr/bin/single-instance") diff -Nru mapplauncherd-4.1.21+15.10.20150727/debian/changelog mapplauncherd-4.2.0+15.10.20150805/debian/changelog --- mapplauncherd-4.1.21+15.10.20150727/debian/changelog 2015-08-05 12:11:14.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/debian/changelog 2015-08-05 12:11:14.000000000 +0000 @@ -1,6 +1,6 @@ -mapplauncherd (4.1.21+15.10.20150727-0ubuntu1) vivid; urgency=medium +mapplauncherd (4.2.0+15.10.20150805-0ubuntu1) vivid; urgency=medium - * Initial packaging + * Initial packaging of the exec solution -- Zoltán Balogh Fri, 24 Jul 2015 12:37:00 +0300 diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/invoker/CMakeLists.txt mapplauncherd-4.2.0+15.10.20150805/src/invoker/CMakeLists.txt --- mapplauncherd-4.1.21+15.10.20150727/src/invoker/CMakeLists.txt 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/invoker/CMakeLists.txt 2015-08-05 11:55:08.000000000 +0000 @@ -19,6 +19,6 @@ target_link_libraries(invoker ${DBUS_LDFLAGS}) # Add install rule -install(PROGRAMS invoker DESTINATION /usr/bin/) +install(TARGETS invoker DESTINATION /usr/bin/) diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/invoker/invoker.c mapplauncherd-4.2.0+15.10.20150805/src/invoker/invoker.c --- mapplauncherd-4.1.21+15.10.20150727/src/invoker/invoker.c 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/invoker/invoker.c 2015-08-05 11:55:08.000000000 +0000 @@ -466,7 +466,7 @@ } else { info("Failed to connect to the DBus session bus: %s", error.message); dbus_error_free(&error); - return 1; + return; } } diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/CMakeLists.txt mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/CMakeLists.txt --- mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/CMakeLists.txt 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/CMakeLists.txt 2015-08-05 11:55:08.000000000 +0000 @@ -14,7 +14,7 @@ # Set libraries to be linked. Shared libraries to be preloaded are not linked in anymore, # but dlopen():ed and listed in src/launcher/preload.h instead. -link_libraries(${LIBDL} "-L/lib -lsystemd-daemon") +link_libraries(${LIBDL} "-L/lib -lsystemd") # Set executable add_library(applauncherd MODULE ${SRC} ${MOC_SRC}) diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/connection.cpp mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/connection.cpp --- mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/connection.cpp 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/connection.cpp 2015-08-05 11:55:08.000000000 +0000 @@ -133,8 +133,8 @@ } else { - Logger::logDebug("Connection: %s: %08x", __FUNCTION__, *msg); *msg = buf; + Logger::logDebug("Connection: %s: %08x", __FUNCTION__, *msg); } return ret != -1; diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/daemon.cpp mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/daemon.cpp --- mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/daemon.cpp 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/daemon.cpp 2015-08-05 11:55:08.000000000 +0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include "coverage.h" @@ -98,21 +99,16 @@ m_singleInstance(new SingleInstance), m_reExec(false), m_notifySystemd(false), +#ifdef EXEC_AFTER_FORK + m_preforkExec(false), + m_boosterInvokerSocket(-1), +#endif m_booster(0) { // Open the log Logger::openLog(argc > 0 ? argv[0] : "booster"); Logger::logDebug("starting.."); - // Install signal handlers. The original handlers are saved - // in the daemon instance so that they can be restored in boosters. - setUnixSignalHandler(SIGCHLD, sigChldHandler); // reap zombies - setUnixSignalHandler(SIGTERM, sigTermHandler); // exit launcher - setUnixSignalHandler(SIGUSR1, sigUsr1Handler); // enter normal mode from boot mode - setUnixSignalHandler(SIGUSR2, sigUsr2Handler); // enter boot mode (same as --boot-mode) - setUnixSignalHandler(SIGPIPE, sigPipeHandler); // broken invoker's pipe - setUnixSignalHandler(SIGHUP, sigHupHandler); // re-exec - if (!Daemon::m_instance) { Daemon::m_instance = this; @@ -125,15 +121,30 @@ // Parse arguments parseArgs(ArgVect(argv, argv + argc)); + // Store arguments list + m_initialArgv = argv; + m_initialArgc = argc; + +#ifdef EXEC_AFTER_FORK + if (m_preforkExec) + return; +#endif + + // Install signal handlers. The original handlers are saved + // in the daemon instance so that they can be restored in boosters. + setUnixSignalHandler(SIGCHLD, sigChldHandler); // reap zombies + setUnixSignalHandler(SIGTERM, sigTermHandler); // exit launcher + setUnixSignalHandler(SIGUSR1, sigUsr1Handler); // enter normal mode from boot mode + setUnixSignalHandler(SIGUSR2, sigUsr2Handler); // enter boot mode (same as --boot-mode) + setUnixSignalHandler(SIGPIPE, sigPipeHandler); // broken invoker's pipe + setUnixSignalHandler(SIGHUP, sigHupHandler); // re-exec + + if (m_reExec) { restoreState(); } - // Store arguments list - m_initialArgv = argv; - m_initialArgc = argc; - if (!m_reExec && socketpair(AF_UNIX, SOCK_DGRAM, 0, m_boosterLauncherSocket) == -1) { throw std::runtime_error("Daemon: Creating a socket pair for boosters failed!\n"); @@ -167,6 +178,12 @@ // dlopen single-instance loadSingleInstancePlugin(); +#ifdef EXEC_AFTER_FORK + if (m_preforkExec) { + return runBooster(); + } +#endif + if (m_reExec) { // Reap dead booster processes and restart them @@ -376,9 +393,6 @@ // Restore used signal handlers restoreUnixSignalHandlers(); - // Will get this signal if applauncherd dies - prctl(PR_SET_PDEATHSIG, SIGHUP); - // Close unused read end of the booster socket close(m_boosterLauncherSocket[0]); @@ -406,29 +420,49 @@ if (!m_bootMode && sleepTime) sleep(sleepTime); - Logger::logDebug("Daemon: Running a new Booster of type '%s'", m_booster->boosterType().c_str()); - - // Initialize and wait for commands from invoker - try { - m_booster->initialize(m_initialArgc, m_initialArgv, m_boosterLauncherSocket[1], - m_socketManager->findSocket(m_booster->boosterType().c_str()), - m_singleInstance, m_bootMode); - } catch (const std::runtime_error &e) { - Logger::logError("Booster: Failed to initialize: %s\n", e.what()); - fprintf(stderr, "Failed to initialize: %s\n", e.what()); - delete m_booster; - _exit(EXIT_FAILURE); - } - - // Run the current Booster - int retval = m_booster->run(m_socketManager); - - // Finish - delete m_booster; - - // _exit() instead of exit() to avoid situation when destructors - // for static objects may be run incorrectly - _exit(retval); +#ifdef EXEC_AFTER_FORK + char *argv[] = { + m_initialArgv[0], + NULL, //debug mode + NULL, //systemd + NULL, //boot-mode + NULL, //exec-booster + NULL, //socket fd + NULL //invoker socket + }; + + int offset = 1; + if (m_debugMode) { + argv[offset] = const_cast("--debug"); + offset++; + } + if (m_notifySystemd) { + argv[offset] = const_cast("--systemd"); + offset++; + } + if (m_bootMode) { + argv[offset] = const_cast("--boot-mode"); + offset++; + } + + char socketFd[20]; + snprintf(socketFd, 20, "%d", m_boosterLauncherSocket[1]); + + char invokerFd[20]; + snprintf(invokerFd, 20, "%d", m_socketManager->findSocket(m_booster->boosterType())); + + argv[offset] = const_cast("--exec-booster"); + argv[offset+1] = socketFd; + argv[offset+2] = invokerFd; + + execve(argv[0],argv,environ); + + // Not reached. + Logger::logDebug("Booster: Failed to execute execve(), exec-after-fork failed, exiting."); + _exit(1); +#else + runBooster(); +#endif } else /* Parent process */ { @@ -441,6 +475,45 @@ } } +void Daemon::runBooster() +{ + if (!m_booster) { + // Critical error unknown booster type. Exiting applauncherd. + _exit(EXIT_FAILURE); + } + +#ifdef EXEC_AFTER_FORK + m_socketManager->addMapping(m_booster->boosterType(), m_boosterInvokerSocket); +#endif + + // Will get this signal if applauncherd dies + prctl(PR_SET_PDEATHSIG, SIGHUP); + + Logger::logDebug("Daemon: Running a new Booster of type '%s'", m_booster->boosterType().c_str()); + + // Initialize and wait for commands from invoker + try { + m_booster->initialize(m_initialArgc, m_initialArgv, m_boosterLauncherSocket[1], + m_socketManager->findSocket(m_booster->boosterType().c_str()), + m_singleInstance, m_bootMode); + } catch (const std::runtime_error &e) { + Logger::logError("Booster: Failed to initialize: %s\n", e.what()); + fprintf(stderr, "Failed to initialize: %s\n", e.what()); + delete m_booster; + _exit(EXIT_FAILURE); + } + + // Run the current Booster + int retval = m_booster->run(m_socketManager); + + // Finish + delete m_booster; + + // _exit() instead of exit() to avoid situation when destructors + // for static objects may be run incorrectly + _exit(retval); +} + void Daemon::reapZombies() { // Loop through all child pid's and wait for them with WNOHANG. @@ -608,6 +681,34 @@ { m_notifySystemd = true; } +#ifdef EXEC_AFTER_FORK + else if ((*i) == "--exec-booster") + { + m_preforkExec = true; + + //read the daemon fd + i++; + int fd = strtol(i->c_str(),NULL,10); + bool fdValid = fd != 0 && (fcntl(fd, F_GETFD) != -1 || errno != EBADF); + if (!fdValid ) { + Logger::logInfo("Booster: Invalid filedescriptor passed after exec."); + _exit(1); + } + + m_boosterLauncherSocket[0] = -1; + m_boosterLauncherSocket[1] = fd; + + //read the invoker fd + i++; + fd = strtol(i->c_str(),NULL,10); + fdValid = fd != 0 && (fcntl(fd, F_GETFD) != -1 || errno != EBADF); + if (!fdValid ) { + Logger::logInfo("Booster: Invalid filedescriptor passed after exec."); + _exit(1); + } + m_boosterInvokerSocket = fd; + } +#endif else { if ((*i).find_first_not_of(' ') != string::npos) diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/daemon.h mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/daemon.h --- mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/daemon.h 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/daemon.h 2015-08-05 11:55:08.000000000 +0000 @@ -101,7 +101,6 @@ * Restore unix signal handlers to their saved values. */ void restoreUnixSignalHandlers(); - private: //! Disable copy-constructor @@ -123,6 +122,9 @@ //! Forks and initializes a new Booster void forkBooster(int sleepTime = 0); + //! executed in the booster process + void runBooster(); + //! Kill given pid with SIGKILL by default void killProcess(pid_t pid, int signal = SIGKILL) const; @@ -214,6 +216,12 @@ //! True if systemd needs to be notified bool m_notifySystemd; +#ifdef EXEC_AFTER_FORK + //! True if exec was called after forking the booster + bool m_preforkExec; + int m_boosterInvokerSocket; +#endif + //! Booster instance Booster * m_booster; diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/logger.cpp mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/logger.cpp --- mapplauncherd-4.1.21+15.10.20150727/src/launcherlib/logger.cpp 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/launcherlib/logger.cpp 2015-08-05 11:55:08.000000000 +0000 @@ -57,8 +57,11 @@ // In debug mode everything is printed also to stdout if (m_debugMode) { - vprintf(format, ap); + va_list va2; + va_copy(va2,ap); + vprintf(format, va2); printf("\n"); + va_end(va2); } // Print to syslog diff -Nru mapplauncherd-4.1.21+15.10.20150727/src/single-instance/CMakeLists.txt mapplauncherd-4.2.0+15.10.20150805/src/single-instance/CMakeLists.txt --- mapplauncherd-4.1.21+15.10.20150727/src/single-instance/CMakeLists.txt 2015-07-01 09:05:44.000000000 +0000 +++ mapplauncherd-4.2.0+15.10.20150805/src/single-instance/CMakeLists.txt 2015-08-05 11:55:08.000000000 +0000 @@ -26,4 +26,4 @@ add_executable(single-instance ${SRC}) # Add install rule -install(PROGRAMS single-instance DESTINATION /usr/bin/) +install(TARGETS single-instance DESTINATION /usr/bin/)