Product SiteDocumentation Site

2.6.3. Daemon Initialization

In addition to the initialization function that can be shared by a DSO and a daemon PMDA, a daemon PMDA must also meet the following requirements:
  • Create the pmdaInterface structure that is passed to the initialization function
  • Parse any command-line arguments
  • Open a log file (a DSO PMDA uses PMCD's log file)
  • Set up the IPC connection between the PMDA and the PMCD process
  • Handle incoming PDUs
All these requirements can be handled by default initialization functions in the pcp_pmda library; see the pmdaDaemon(3), pmdaGetOptions(3), pmdaOpenLog(3), pmdaConnect(3), and pmdaMain(3) man pages.

Note

Optionally, a daemon PMDA may wish to reduce or change its privilege level, as seen in Example 2.33, “Initialization in the Trivial PMDA” and Example 2.34, “Initialization in the Simple PMDA”. Some performance domains require the extraction process to run as a specific user in order to access the instrumentation. Many domains require the default root level of access for a daemon PMDA.
The simple PMDA specifies the command-line arguments it accepts using pmdaGetOptions, as shown in Example 2.35, “ main in the Simple PMDA”. For additional information, see the pmdaGetOptions(3) man page.

Example 2.35.  main in the Simple PMDA

static pmLongOptions longopts[] = {
    PMDA_OPTIONS_HEADER(“Options”),
    PMOPT_DEBUG,
    PMDAOPT_DOMAIN,
    PMDAOPT_LOGFILE,
    PMDAOPT_USERNAME,
    PMOPT_HELP,
    PMDA_OPTIONS_TEXT(“\nExactly one of the following options may appear:”),
    PMDAOPT_INET,
    PMDAOPT_PIPE,
    PMDAOPT_UNIX,
    PMDAOPT_IPV6,
    PMDA_OPTIONS_END
};
static pmdaOptions opts = {
    .short_options = “D:d:i:l:pu:U:6:?”,
    .long_options = longopts,
};

int
main(int argc, char **argv)
{
    pmdaInterface       dispatch;

    isDSO = 0;
    pmSetProgname(argv[0]);
    pmGetUsername(&username);
    pmdaDaemon(&dispatch, PMDA_INTERFACE_7, pmGetProgname(), SIMPLE,
               “simple.log”, “${PCP_PMDAS_DIR}/simple/help”);

    pmdaGetOptions(argc, argv, &opts, &dispatch);
    if (opts.errors) {
        pmdaUsageMessage(&opts);
        exit(1);
    }
    if (opts.username)
        username = opts.username;

    pmdaOpenLog(&dispatch);
    simple_init(&dispatch);
    simple_timenow_check();
    pmdaConnect(&dispatch);
    pmdaMain(&dispatch);

    exit(0);
}
The conditions under which pmdaMain will return are either unexpected error conditions (often from failed initialisation, which would already have been logged), or when PMCD closes the connection to the PMDA. In all cases the correct action to take is simply to exit cleanly, possibly after any final cleanup the PMDA may need to perform.