Skip to content

Source · fairmq/shmem/

runMonitor.cxxsource

Described in Test your devices, Monitor and clean up, fairmq-shmmonitor.

fairmq/shmem/runMonitor.cxx198 lines · C++GitHub ↗
1/********************************************************************************2 *    Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH    *3 *                                                                              *4 *              This software is distributed under the terms of the             *5 *              GNU Lesser General Public Licence (LGPL) version 3,             *6 *                  copied verbatim in the file "LICENSE"                       *7 ********************************************************************************/8#include "Monitor.h"9#include "Common.h"10 11#include <boost/program_options.hpp>12 13#include <cstdio>14#include <cstdlib>15#include <unistd.h>16#include <sys/types.h>17#include <sys/stat.h>18 19#include <iostream>20#include <string>21 22using namespace std;23using namespace boost::program_options;24using namespace fair::mq::shmem;25 26static void daemonize()27{28    // already a daemon?29    if (getppid() == 1) {30        return;31    }32 33    // Fork34    pid_t pid = fork();35    if (pid < 0) {36        exit(1);37    }38 39    // If we got a good PID, then we can exit the parent process.40    if (pid > 0) {41        exit(0);42    }43 44    // Change the file mode mask45    umask(0);46 47    // Create a new session with the calling process as its leader.48    if (setsid() < 0) {49        exit(1);50    }51 52    // Change the current working directory. This prevents the current directory from being locked; hence not being able to remove it.53    if ((chdir("/")) < 0) {54        exit(1);55    }56 57    // Redirect standard files to /dev/null58    if (!freopen("/dev/null", "r", stdin)) {59        cout << "could not redirect stdin to /dev/null" << endl;60    }61    if (!freopen("/dev/null", "w", stdout)) {62        cout << "could not redirect stdout to /dev/null" << endl;63    }64    if (!freopen("/dev/null", "w", stderr)) {65        cout << "could not redirect stderr to /dev/null" << endl;66    }67}68 69int main(int argc, char** argv)70{71    try {72        fair::Logger::SetConsoleColor(false);73        fair::Logger::DefineVerbosity(fair::Verbosity::user1, fair::VerbositySpec::Make(fair::VerbositySpec::Info::timestamp_us));74        fair::Logger::SetVerbosity(fair::Verbosity::verylow);75 76        string sessionName;77        string shmId;78        bool cleanup = false;79        bool resetContent = false;80        bool selfDestruct = false;81        bool interactive = false;82        bool viewOnly = false;83        unsigned int timeoutInMS = 5000;84        unsigned int intervalInMS = 100;85        bool runAsDaemon = false;86        bool monitor = false;87        bool debug = false;88        bool cleanOnExit = false;89        bool getShmId = false;90        bool listAll = false;91        string listAllPath;92        bool verbose = false;93        string severity;94        int userId = -1;95 96        options_description desc("Options");97        desc.add_options()98            ("session,s"      , value<string>(&sessionName)->default_value("default"),  "Session id")99            ("shmid"          , value<string>(&shmId)->default_value(""),               "Shmem id (if not provided, it is generated out of session id and user id)")100            ("cleanup,c"      , value<bool>(&cleanup)->implicit_value(true),            "Perform cleanup and quit")101            ("reset-content,r", value<bool>(&resetContent)->implicit_value(true),       "[EXPERIMENTAL] Reset content of the segments (only call this when segment is not in use)")102            ("self-destruct,x", value<bool>(&selfDestruct)->implicit_value(true),       "Quit after first closing of the memory")103            ("interactive,i"  , value<bool>(&interactive)->implicit_value(true),        "Interactive run")104            ("view,v"         , value<bool>(&viewOnly)->implicit_value(true),           "Run in view only mode")105            ("timeout,t"      , value<unsigned int>(&timeoutInMS)->default_value(5000), "Heartbeat timeout in milliseconds")106            ("daemonize,d"    , value<bool>(&runAsDaemon)->implicit_value(true),        "Daemonize the monitor process (only in monitoring mode)")107            ("monitor,m"      , value<bool>(&monitor)->implicit_value(true),            "Run in monitoring mode")108            ("debug,b"        , value<bool>(&debug)->implicit_value(true),              "Debug - Print a list of messages)")109            ("clean-on-exit,e", value<bool>(&cleanOnExit)->implicit_value(true),        "Perform cleanup on exit")110            ("interval"       , value<unsigned int>(&intervalInMS)->default_value(1000),"Output interval for interactive mode")111            ("get-shmid"      , value<bool>(&getShmId)->implicit_value(true),           "Translate given session id and user id to a shmem id (uses current user id if none provided)")112            ("list-all"       , value<bool>(&listAll)->implicit_value(true),            "List all sessions & segments")113            ("list-all-path"  , value<string>(&listAllPath)->default_value("/dev/shm/"),"Path for the --list-all command to search segments in")114            ("verbose"        , value<bool>(&verbose)->implicit_value(true),            "Verbose mode (daemon will output to a file 'fairmq-shmmonitor_<timestamp>')")115            ("severity"       , value<string>(&severity)->default_value("info"),        "Log severity")116            ("user-id"        , value<int>(&userId)->default_value(-1),                 "User id (used with --get-shmid)")117            ("help,h",                                                                  "Print help");118 119        variables_map vm;120        store(parse_command_line(argc, argv, desc), vm);121 122        if (vm.count("help")) {123            LOG(info) << "FairMQ Shared Memory Monitor" << "\n" << desc;124            return 0;125        }126 127        notify(vm);128 129        fair::Logger::SetConsoleSeverity(severity);130 131        if (getShmId) {132            if (userId == -1) {133                LOG(info) << "shmem id for session '" << sessionName << "' and current user id " << geteuid()134                          << " is: " << makeShmIdStr(sessionName);135            } else {136                LOG(info) << "shmem id for session '" << sessionName << "' and user id " << userId137                          << " is: " << makeShmIdStr(sessionName, to_string(userId));138            }139            return 0;140        }141 142        if (shmId.empty()) {143            shmId = makeShmIdStr(sessionName);144        }145 146        if (cleanup) {147            Monitor::CleanupFull(ShmId{shmId});148            return 0;149        }150 151        if (resetContent) {152            Monitor::ResetContent(ShmId{shmId});153            return 0;154        }155 156        if (debug) {157            Monitor::PrintDebugInfo(ShmId{shmId});158            return 0;159        }160 161        if (listAll) {162            Monitor::ListAll(listAllPath);163            return 0;164        }165 166        if (!viewOnly && !interactive && !monitor) {167            // if neither of the run modes are selected, use view only mode.168            viewOnly = true;169        }170 171        if (viewOnly && !interactive) {172            if (!Monitor::PrintShm(ShmId{shmId})) {173                LOG(info) << "No segments found.";174            }175            return 0;176        }177 178        if (runAsDaemon && monitor) {179            if (verbose) {180                fair::Logger::InitFileSink("trace", "fairmq-shmmonitor");181            }182            daemonize();183        }184 185        LOG(info) << "Starting shared memory monitor for session: \"" << sessionName << "\" (shm id: " << shmId << ")...";186 187        Monitor shmmonitor(shmId, selfDestruct, interactive, viewOnly, timeoutInMS, intervalInMS, monitor, cleanOnExit);188        shmmonitor.CatchSignals();189        shmmonitor.Run();190    } catch (Monitor::DaemonPresent& dp) {191        return 0;192    } catch (exception& e) {193        LOG(error) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit";194        return 2;195    }196 197    return 0;198}