[Top] [Prev] [Next] [Bottom]


4 - Requesting Data and Event Reports

All agents have their own permanent RPC program numbers compiled in. Managers, however, do not know (and should not assume) the agent's RPC numbers. They need to look up the RPC program numbers with a call to getrpcbyname(3n). When the manager sends the request to the agent, the agent is instructed where to send the resulting data or event reports. For data reports, usually the manager making the request will ask for the reports, so it uses the transient RPC program number it got when it first registered as a callback. A manager application usually asks for event reports to be sent to the local event dispatcher, so it needs to call getrpcbyname (3n) again to get the RPC program number of the event dispatcher before it can tell the agent where to send the reports.


4.1 Formulating a Request

The first call a manager makes in formulating an agent request is to netmgt_set_instance(3n). This allows the manager to set the name of the <target>, <group>, and optional <key> of the request. The <target> is the name of the object that contains the information the agent can obtain. It does not have to be a name the manager understands, since it is used only by the agent. For example, an agent that gets statistics from individual serial ports in a terminal controller might want a <target> name of "port17," which means nothing to the manager.

The <group> name is the logical collection of attributes the agent provides to the manager. When a manager application specifies the <group> name, all attributes in the group are returned. If a <key> is specified, it is also agent-specific. Each agent's documentation will describe what attributes inside a table it uses for keys, and the method for selecting them. Again, keys mean nothing to the manager, so anything is fair game here.


NOTE - If your application will be using the netmgt_kill_request2(3n) function, you need to call netmgt_set_manager_id (3n) right after calling netmgt_set_instance(3n). See
Section 4.7, "Stopping Requests," on page 4-8 , for more information about netmgt_kill_request2(3n).


4.2 Optional Arguments

Sometimes the standard request mechanism isn't enough to get all needed information to an agent. The Manager Services library allows an "option" string to be specified. The definition of this field is up to the agent. For example, the ping agent uses the optional request arguments to set packet size, time to wait for echo replies, and so on, because it is not possible to specify these parameters through the "standard" request mechanism.

You can also use the option string for SNMP requests. You can specify certain options that you want the SNMP proxy agent to use when sending an SNMP request to a target device. The optional arguments are:

If any optional arguments are to be specified, the manager should call netmgt_set_argument(3n).

The following code fragment shows how to specify an SNMP read community, timeout, and get-list as optional arguments in a request. The complete program example from which this fragment is taken is included in the product structure in the file request.c in the API_examples directory.




bool_t
set_snmp_args()
{
        /* argument for setting options */
        Netmgt_arg      option;
        /* read community string */
        char    *community= "community string";
        /* SNMP retry interval (in seconds) */
        int     retry = 10;
        /* OID list for instances (sysObjectID and sysUpTime) */
        char    *get_list = "1.3.6.1.2.1.1.2.0 1.3.6.1.2.1.1.3.0";
        NETMGT_DBG("setting snmp arguments \n");
        /* send SNMP read community */
        /*      not needed if read access is free
        strcpy(option.name, "na.snmp-read-community");
        option.type = NETMGT_STRING;
        option.length = strlen(community) + 1;
        option.value = community;
        if  (!netmgt_set_argument(&option)) {
                NETMGT_DBG ("netmgt_set_argument failed: %s \n",
                    netmgt_sperror());
                return (FALSE);
        }
        */
        /* send SNMP retry interval */
        strcpy(option.name, "na.snmp.retry");
        option.type = NETMGT_INT;
        option.length = sizeof (int);
        option.value = (char *) &retry;
        if  (!netmgt_set_argument(&option)) {
                NETMGT_DBG ("netmgt_set_argument failed: %s \n",
                    netmgt_sperror());
                return (FALSE);
        }
 




        /* send OID list to request data only for certain attributes 
*/
        strcpy(option.name, "na.snmp-get-list");
        option.type = NETMGT_STRING;
        option.length = strlen(get_list) + 1;
        option.value = get_list;
        if  (!netmgt_set_argument(&option)) {
                NETMGT_DBG ("netmgt_set_argument failed: %s \n",
                    netmgt_sperror());
                return (FALSE);
        }
}
 


4.3 Count and Interval

Reports are sent according to a schedule the manager application sets. When the request is started, two parameters are specified to instruct the agent how often to report and how long to report. The two parameters, <count> and interval, will be interpreted by the agent according to this chart:

Table  4-1 Count/Interval Interpretations
Count
Interval
Interpretation

0  

0  

Send reports forever at an agent-specific interval  

0  

< i>  

Send reports forever, every < i> seconds  

1  

0  

Quick Dump -- send one report  

1  

< i>  

Quick Dump -- send one report  

<c>  

0  

Send <c> reports at an agent-specific interval  

<c>  

i  

Send <c> reports every i seconds  


For data reporting, agents report, sleep for <interval> and then report again, <count> times (or forever if <count> is zero). For event reporting, agents act the same way, but the Agent Services library prevents the report from getting back to the manager application if an event was not detected during the <interval> . Thus, it is possible for an agent to "send" <count> reports and exit without the manager application ever seeing an event report, because no events have occurred. (However, the manager application will get a special event report with the NETMGT_NO_EVENTS flag set when the agent finishes processing the request.)


4.4 Request Flags

Managers can vary the behavior of agents via a special <flags> parameter at the time the request is sent. Two of these <flags>, NETMGT_RESTART and NETMGT_DO_DEFERRED , pertain to both data and event reports, while one of them, NETMGT_SEND_ONCE only pertains to event reports. By default, these <flags> are not set.

NETMGT_RESTART

restarts the request if the agent abnormally terminates and is restarted. Otherwise this request is forgotten when the agent restarts.

This flag is advisory; request restart is not guaranteed. The restart is not attempted until the agent parent is started (asked to start another request, or asked what requests it is working on) when all requests marked for restart will be restarted if possible.
NETMGT_DO_DEFERRED
have the agent collect the report information but don't send it just yet.

Often an agent collects useful information for debugging problems, but the information isn't useful under normal conditions. If the manager started the request only after the error condition started, it would have been started after the fact and valuable data would have been lost. On the other hand, if the request was started and the reports were continually streaming back to the manager before the error condition occurred, an unnecessary traffic and CPU load would be caused from many uninteresting reports coming back.

With this flag, reports can be held on the agent's system until the manager is ready (if ever) to ask for them. When the manager asks via a call to netmgt_request_deferred(3n) for the collected reports, the "old" reports will be sent.

This option (as well as netmgt_request_deferred (3n), described in its man page) is handled for the agent by the Agent Services library. The library keeps only the last 32 reports the agent "sent", memory permitting.

This option does not defer error reports.
NETMGT_SEND_ONCE
have the agent terminate after one event report has been sent. If this flag is not set, the agent continues to conditionally send event reports until otherwise directed.
To send more than one of these flags, OR them together.


4.5 Setting Thresholds

If you are about to send a request for an event report, you need to tell the agent what attributes you are interested in, and what constitutes an event. You do this by calling netmgt_set_threshold (3n) with a pointer to a Netmgt_thresh buffer, specifying the attribute name, a threshold value and the relational operator to be applied between the two. You can specify more than one relationship by making repeated calls to this function before you send the request.

Agents cannot compute inter-attribute relationships; they are only capable of reporting the attributes defined in their agent schema. While some of these attributes are derived values, the formulas for deriving them are hard-coded into the agent.


4.6 Sending the Request

You're now ready to send the request. If you are sending a request for a data report, call netmgt_request_data (3n). Otherwise, call netmgt_request_events(3n). The parameters are identical--they specify where to send the request (the host name, and RPC program and version number of the agent), where to send the reply (the host name, and RPC program and version number of the rendezvous, usually the manager making the request), the number of reports to send and how often to send them, the RPC <timeout> and any request <flags> (discussed above).


NOTE - Requests are identified by the agent host's IP address and the timestamp of the request.
When you send the request, you will get a reply from the Manager Services library indicating the status of the request. If the request was accepted by the agent, you will get a UNIX timestamp you can use to identify the request when you get reports or want to kill the request. If the request timestamp was NULL, either the agent didn't accept the request or there was an error sending the message to the agent. You can call netmgt_fetch_error(3n), discussed below, for more information on handling errors.


4.7 Stopping Requests

For manager applications created with the manager services libraries, there are two basic ways of killing requests:
If you don't specify <manager> , requests started by any manager will be terminated. If you specify {0,0} for the <timestamp>, requests started at any time will be terminated.

NOTE - You cannot use netmgt_kill_request2(3n) to kill requests started by an agent created with Site/SunNet/Domain Manager version 1.x agent services libraries. Upon receiving a netmgt_kill_request2(3n) call, SunNet Manager 1.x agents will return FALSE and set the service error to NETMGT_UNKNOWNREQUEST. To work properly with 1.x agents, your application should call netmgt_kill_requests(3n), which is understood by all versions of Site/SunNet/Domain Manager agents.
To stop requests, you call netmgt_kill_request2(3n), specifying the host name, program and version number where the request is running, and a timeout value. Additionally, you must specify a manager identification that uniquely identifies the manager application running on a particular host. (The manager identification is set by calling netmgt_set_manager_id(3n) right after calling netmgt_set_instance(3n), and before calling netmgt_request_data (3n) or netmgt_request_events(3n).)

4.8 Summary

Sending requests is not as complicated as it may seem. It can be summarized as follows:

1. Call netmgt_set_instance (3n).


2. Call netmgt_set_manager_id (3n) if you will be using netmgt_kill_request2(3n) to terminate requests.


3. Call netmgt_set_argument (3n) if you have optional arguments.


4. Call netmgt_set_threshold(3n) if you are requesting event reports.


5. Call netmgt_request_data (3n) or netmgt_request_events(3n) to start the request.


6. Call netmgt_kill_request(3n) or netmgt_kill_request2 (3n) to terminate the request.
Most of the flags and options listed are not normally used; they are presented here rather than referring you to the man pages so you can get a more complete picture.


4.9 Sample Code

The following code fragment is an example of how to request an event report and a data report. The complete program example from which this fragment is taken is included in the product structure in the file request.c in the API_examples directory.




/*
 *  request_event - send event report request to agent
 *      returns request timestamp if successful; otherwise NULL
 */
struct timeval *
request_event(count, interval, timeout, threshold, group, optstring, key, flags)
    u_int count;                /* report count */
    struct timeval interval;    /* reporting interval */
    struct timeval timeout;     /* rpc timeout */
    Netmgt_thresh *threshold;   /* event threshold */
    char *group;                /* group of statistics */
    char *optstring;            /* optstring to the  agent */
    char *key;                  /* key for table group */
    u_int flags;                /* restart */
{
        Netmgt_arg      arg;
        struct rpcent   *agent_rpc;     /* rpc entry for the agent */
        struct timeval  *timestamp;     /* request timestamp */
        u_long          agent_prog;     /* agent's RPC program number */
        u_long          rendez_prog;    /* rendez vous RPC program number */
        NETMGT_DBG("requesting events \n");
         
        /* declare managed object instance */
        if (!netmgt_set_instance(target, group, key)) {
                NETMGT_DBG("set_instance failed for %s: %s\n",
                    target, netmgt_sperror());
                return (struct timeval *) NULL;
        }
 
#ifndef SNMP_AGENT
        /* get the agent's RPC info */
        agent_rpc = getrpcbyname(agentname);
        if (!agent_rpc) {
                NETMGT_DBG("can't get RPC program number for %s\n", agentname);
                return (struct timeval *) NULL;
        }
             agent_prog = agent_rpc->r_number;   
 




#else
        agent_prog = SNMP_RPC_NUM;
        /* set SNMP arguments */
        set_snmp_args();
#endif
 
 
        /* pass optional arguments */
        if (optstring) {
                (void) strcpy(arg.name, NETMGT_OPTSTRING);
                arg.type = NETMGT_STRING;
                arg.length = strlen(optstring) + 1;
                arg.value = optstring;
                if (!netmgt_set_argument(&arg)) {
                        NETMGT_DBG ("netmgt_set_argument failed: %s \n",
                            netmgt_sperror());
                        return (struct timeval *) NULL;
                }
        }
 
        /* set threshold */
        if (!netmgt_set_threshold(threshold)) {
                NETMGT_DBG("netmgt_set_threshold failed: %s\n",
                    netmgt_sperror());
                return (struct timeval *) NULL;
        }
 
        /* send the event report to the event dispatcher */
        rendez_prog = NETMGT_EVENT_PROG;
 
        /* start the event report request */
        timestamp = netmgt_request_events(agent_host, agent_prog,
            NETMGT_VERS, event_host, rendez_prog, NETMGT_VERS,
            count, interval, timeout, flags);
 
        if (!timestamp)
                NETMGT_DBG("Can't request event report: %s\n",netmgt_sperror()); 
        return timestamp;
 
}
 
 





/*
 *  request_data - send data report request to agent
 *      returns request timestamp if successful; otherwise NULL
 */
struct timeval *
request_data(count, interval, timeout, group, optstring, key, flags)
    u_int count;                /* report count */
    struct timeval interval;    /* reporting interval */
    struct timeval timeout;     /* rpc timeout */
    char *group;                /* group of statistics */
    char *optstring;            /* optstring to the  agent */
    char *key;                  /* key for table group */
    u_int flags;                /* restart */
{
 
        Netmgt_arg      arg;
        struct rpcent   *agent_rpc;     /* rpc entry for the agent */
        struct timeval  *timestamp;     /* request timestamp */
 
        u_long          agent_prog;     /* agent's RPC program number */
        u_long          rendez_prog;    /* rendez vous RPC program number */
 
        NETMGT_DBG("requesting data \n");
 
 
        /* declare managed object instance */
        if (!netmgt_set_instance(target, group, key)) {
                NETMGT_DBG("set_instance failed for %s: %s\n",
                    target, netmgt_sperror());
                return (struct timeval *) NULL;
        }
 
#ifndef SNMP_AGENT
        /* get the agent's RPC info */
        agent_rpc = getrpcbyname(agentname);
        if (!agent_rpc) {
                NETMGT_DBG("can't get RPC program number for %s\n", agentname);
                return (struct timeval *) NULL;
        }
        agent_prog = agent_rpc->r_number;
 





#else
        agent_prog = SNMP_RPC_NUM;
        /* set SNMP arguments */
        set_snmp_args();
#endif
 
        /* pass optional arguments */
        if (optstring) {
                (void) strcpy(arg.name, NETMGT_OPTSTRING);
                arg.type = NETMGT_STRING;
                arg.length = strlen(optstring) + 1;
                arg.value = optstring;
                if (!netmgt_set_argument(&arg)) {
                        NETMGT_DBG ("netmgt_set_argument failed: %s \n",
                            netmgt_sperror());
                        return (struct timeval *) NULL;
                }
        }
 
 
        /* send the data report to the logger */
        rendez_prog = NETMGT_LOGGER_PROG;
 
        /* start the event report request */
        timestamp = netmgt_request_data(agent_host, agent_prog,
            NETMGT_VERS, event_host, rendez_prog, NETMGT_VERS,
            count, interval, timeout, flags);
 
        if (!timestamp)
                NETMGT_DBG("Can't request event report: %s\n",netmgt_sperror()); 
        return timestamp;
 
}
 



 


[Top] [Prev] [Next] [Bottom]

Copyright 1996 Sun Microsystems, Inc., 2550 Garcia Ave., Mtn. View, CA 94043-1100 USA. All Rights Reserved