The System Performance Measurement Interface (SPMI) is an application programming interface (API) that provides standardized access to local system resource statistics. By developing SPMI application programs, a user can retrieve information about system performance with minimum system overhead.
Two types of application programs can use the SPMI:
The Application Types figure illustrates the two different application types using the SPMI.
Figure 1. Application Types
The SPMI assists programmers with the following tasks:
The SPMI offers the following features:
Note: Versions earlier than 2.3 of the SPMI in Performance Toolbox for AIX do not allow simultaneous access of SPMI subroutines from multiple threads of a process.
SPMI data is organized in a multilevel hierarchy of contexts. A context may have subordinate contexts, known as subcontexts, as well as statistics. The higher-level context is called a parent context.
The Sample Data Hierarchy figure illustrates a data hierarchy for a multiprocessor system. Each ellipse depicts a context or subcontext, and each rectangle depicts a statistic. The CPU context consists of a subcontext for each of the processors. The Top context serves as an anchor point for all other contexts.
Figure 2. Sample Data Hierarchy
If an SPMI application program, looking for a statistic called %kernel, follows the CPU context shown in the figure, the program finds the following instances:
CPU/cpu_0/%kernel
CPU/cpu_1/%kernel
. . .
CPU/cpu_n/%kernel
When multiple copies of a resource are available, the SPMI uses a base context description as a template. The SPMI creates one instance of that context for each copy of the resource or system object. This process is known as instantiation. The Sample Data Hierarchy figure illustrates instantiation by showing multiple copies of the CPU context used to describe the processors. A context is considered instantiable if at least one of its immediate subcontexts can exist in more than one copy.
The SPMI can generate new instances of the subcontexts of instantiable contexts prior to the execution of API subroutines that traverse the data hierarchy. An application program can also request instantiation explicitly. In either case, instantiation is accomplished by requesting the instantiation for the parent context of the instances. For example, to instantiate all processor contexts in the Sample Data Hierarchy figure, the application would request instantiation at the CPU context.
Some instantiable contexts always generate a fixed number of subcontext instances in a given system, as long as the system configuration remains unchanged. Examples of this type of instantiability are contexts that contain subcontexts for network interface cards or processors.
Some contexts generate a fixed number of subcontexts on one system, but not on another. Using the Disk context as an example, if System A has a fixed number of disks while System B has removable disk drives, the number of subcontexts for the Disk context of System B changes as disk drives are added and removed while the number of subcontexts for System A is constant.
A final type of context is entirely dynamic in that it will add and delete instances as required during operation. For example, process subcontexts are repeatedly added and deleted during normal system operation.
Because an application program can request instantiation for any context, the contexts are defined as having one of three types of instantiability:
The SPMI uses a shared memory segment created from user space. When an SPMI application program starts, the SPMI checks whether another program has already set up the SPMI data structures in shared memory. If the SPMI does not find the shared memory area, it creates one and generates and initializes all data structures. If the SPMI finds the shared memory area, it bypasses the initialization process. A counter, called users, shows the number of processes currently using the SPMI.
When an application program terminates, the SPMI releases all memory allocated for the application and decrements the users counter. If the counter drops below 1, the entire common shared memory area is freed. Subsequent execution of an SPMI application reallocates the common shared memory area.
The sys/Spmidef.h file contains declarations of all the SPMI data structures.
An application program has access to the data hierarchy through the API. The Application Program View of Data Hierarchy figure gives a simplified picture of the underlying data structures. A set of subroutines allows the application program to navigate through the structures, reviewing what data is available. This action is known as traversing the data hierarchy. The traversal process allows a user to find statistics of interest. To extract data from these statistics, an application program must define a set of statistics, called a statset. See "Data Access Structures and Handles" on page A-8 for more information.
Figure 3. Application Program View of Data Hierarchy
To traverse the data hierarchy, an application program uses four data structures, two handles, and a set of subroutines. See the List of SPMI Subroutines for view the subroutines. The structures include:
The SpmiCx structure describes a context node in the data hierarchy. As seen by an application program, an SpmiCx data structure is always an instance of a context. The data structure names and describes the context in the name and description fields, respectively. The structure also contains a symbolic reference, called a handle, for accessing the parent context (this handle is NULL if the parent context is Top) and a field describing the instantiability of the context. The asnno field contains an Abstract Syntax Notation One (ASN.1) number that makes the structure unique. See Making Dynamic Data-Supplier Statistics Unique for more information about ASN.1.
The SpmiCx structure is defined as follows:
#define SI_MAXNAME 32 #define SI_MAXLNAME 64 enum SiInstFreq { SiNoInst, /* Subcontexts never change */ SiCfgInst, /* Subcontext changes are system configuration changes */ SiContInst, /* System operation changes subcontexts continuously */ };
struct SpmiCx { char name[SI_MAXNAME]; /* short name of the context */ char description[SI_MAXLNAME]; /* descriptive name */ SpmiCxHdl parent; /* handle of parent context */ enum SiInstFreq inst_freq; /* instantiability of context */ u_short asnno; /* ASN.1 number */ u_char deleted; /* nonzero if context deleted */ u_char dummy; /* alignment */ };
The SpmiCxHdl handle is a symbolic reference to a context. To access the SpmiCx structure identified by the handle, use the SpmiGetCx subroutine as follows:
struct SpmiCx *spmicx; SpmiCxHdl cxhdl; spmicx = SpmiGetCx(cxhdl);
The SpmiStat structure describes a statistics object. The object always describes a single-field counter or level statistic. Typically, a system component updates these fields and the update process is asynchronous to any requests to read the field. The field itself is not contained in the SpmiStat structure, but SPMI subroutines allow an application program to retrieve the field value.
The SpmiStat structure, like the SpmiCx structure, associates a name and a description with each object. It also defines default scale values by anticipating the low and high ranges of the field. For a counter field, the SpmiStat structure defines the low and high ranges of the change anticipated for a 1-second time period (the event rate per second).
The ValType enum defines the SiCounter and SiQuantity used to describe the data type as either a counter or a level, respectively. The SpmiStat structure also contains the format of the field. Though the enum DataType field defines many field formats, only SiLong and SiFloat are currently supported.
The asnno field contains an abstract syntax notation number that makes the structure unique from other structures. See Making Dynamic Data-Supplier Statistics Unique for more information.
The SpmiStat structure is defined as follows:
#define SI_MAXNAME 32 #define SI_MAXLNAME 64
enum ValType { SiCounter, /* field is always incremented */ SiQuantity, /* field maintains a level */ };
enum DataType { SiULong, SiLong, SiUInt, SiInt, SiUShort, SiShort, SiChar, SiAddr, SiTimeval, SiFloat, SiDouble, SiPtr, SiUnsign, };
struct SpmiStat { char name[SI_MAXNAME]; /* short name of statistic */ char description[SI_MAXLNAME]; /* descriptive name */ long min; /* default low scale value */ long max; /* default high scale value */ enum ValType value_type; /* data type presented to API */ enum DataType data_type; /* data format presented to API*/ u_short asnno; /* ASN.1 number */ u_short dummy; /* alignment */ };
The SpmiFirstCx and SpmiNextCx S subroutines use the SpmiCxLink structure to traverse the subcontexts of a context. The SpmiCxLink structure serves as a handle when passed as a parameter to the SpmiNextCx subroutine. The structure contains both a reserved field and a field that is the handle of the subcontext.
The SpmiCxLink structure is defined as follows:
struct SpmiCxLink { void *reserved; /* reserved field, don't change */ SpmiCxHdl context; /* handle of subcontext */ };
The SpmiFirstStat and SpmiNextStat subroutines use the SpmiStatLink structure to traverse the statistics of a context. This structure serves as a handle when passed as a parameter to the SpmiNextStat subroutine. The structure contains both a reserved field and a field that is the handle of the statistic.
The SpmiStatLink structure is defined as follows:
struct SpmiStatLink { void *reserved; /* reserved field, don't change */ SpmiStatHdl stat; /* handle of statistic */ };
The SpmiStatHdl handle is a symbolic reference to a statistic. To access the SpmiStat structure identified by the handle, use the SpmiGetStat subroutine as follows:
struct SpmiStat *spmistat; SpmiStatHdl stathdl; spmistat = SpmiGetStat(stathdl);
To access data values, the application program must define the data values it needs to the SPMI. For this purpose, the application program defines sets of statistics, or statsets, through the API. A set of statistics is anchored to a data structure defined as an SpmiStatSet structure. The address of a defined SpmiStatSet structure must be passed to the SPMI through the API each time the application program needs to access the actual data values referenced by the structure.
When the SPMI receives a read request for an SpmiStatSet structure, the SPMI returns the latest value for all the statistics in the set of statistics. This action reduces the system overhead caused by access of kernel structures and other system areas, and ensures that all data values for the statistics within a set are read at the same time. The set of statistics may consist of one or many statistics fields.
The SPMI builds internal data structures for the set in response to API calls from the application program. The Data Value Access Structures figure illustrates a simplified look at the way the application views these structures through the API.
Figure 4. Data Value Access Structures
One SpmiStatVals structure is created for each of the data values selected for the set. When the SPMI executes a request from the application program to read the data values for a set, all SpmiStatVals structures in the set are updated. The application program can then either traverse the list of SpmiStatVals structures, by using the SpmiFirstVals and SpmiNextVals subroutines, or retrieve single values by using the SpmiGetValue or SpmiGetNextValue subroutines.
An application program uses the following data structures to create, delete, and access sets of statistics.
This structure is an anchor point for the structures that define a set of statistics. The application program is responsible for creating the SpmiStatSet structure, adding and deleting statistics, and deleting the SpmiStatSet structure when no longer needed. The SPMI depends on the application program to supply the address of an SpmiStatSet structure. The structure holds only the time stamp for the most recent reading of its associated statistics and the elapsed time since the previous reading.
The SpmiStatSet structure is defined as follows:
struct SpmiStatSet { struct timeval time; /* time of current get */ struct timeval time_change; /* elapsed time since last get */ };
The SpmiStatVals structure carries the data values from the SPMI to the application program. It contains handles that allow an application to access the parent context and the SpmiStat structure of the value. The ref_count field indicates the number of times a particular statistic is included in the same set. The ref_count field usually has a value of 1.
The SpmiStatVals structure is defined as follows:
union Value { long l; float f; };
struct SpmiStatVals { void *reserved; /* reserved field */ SpmiStatHdl stat; /* handle of statistic */ SpmiCxHdl context; /* handle of context */ int ref_count; /* count of simultaneous users */ union Value val; /* counter/level data value */ union Value val_change; /* delta change if counter data*/ enum Error error; /* error code */ };
The last three fields actually transfer the data values, as follows:
To access data values, the application program can define a different type of StatSet to the SPMI. It is used to extract data values for the most or least active statistics for a group of peer contexts. For example, it can be used to define that the program wants to receive information about the two highest loaded disks, optionally subject to those values exceeding a specified threshold. For this purpose, the application program defines sets of peer statistics, called hotsets, through the API.
A hotset is anchored to a data structure defined as an SpmiHotSet structure. The address of a defined SpmiHotSet structure must be passed to the SPMI through the API each time the application program needs to access the actual data values referenced by the structure.
When the SPMI receives a read request for an SpmiHotSet structure, the SPMI reads the latest value for all the peer sets of statistics in the hotset in one operation. This action reduces the system overhead caused by access of kernel structures and other system areas, and ensures that all data values for the peer sets of statistics within a hotset are read at the same time. The hotset may consist of one or many sets of peer statistics.
The SPMI builds internal data structures for the set in response to API calls from the application program. The Data Value Access Structures figure illustrates the statset access structures; the structures for the hotset looks exactly the same but the referenced context is now the parent context of all peers to examine. This parent context is what groups the peers together; all of the subcontexts of that parent context are of the same type and are considered peer contexts. By naming a specific statistic for one peer context, you reference the same statistic for each of the peer contexts, hence the term "a set of peer statistics".
One SpmiHotVals structure is created for each set of peer statistics selected for the hotset. When the SPMI executes a request from the application program to read the data values for a hotset, all SpmiHotVals structures in the set are updated. The application program can then either traverse the list of SpmiStatVals structures, by using the SpmiFirstHot and SpmiNextHot subroutines, or retrieve single values by using the SpmiNextHotItem subroutine.
An application program uses the following data structures to create, delete, and access hotsets.
This structure is an anchor point for the structures that define a group of peer statistic sets. The application program is responsible for creating the SpmiHotSet structure, adding and deleting peer sets of statistics, and deleting the SpmiHotSet structure when no longer needed. The SPMI depends on the application program to supply the address of an SpmiHotSet structure. The structure holds only the time stamp for the most recent reading of its associated statistics and the elapsed time since the previous reading.
The SpmiHotSet structure is defined as follows:
struct SpmiHotSet { struct timeval time; /* time of current get */ struct timeval time_change; /* elapsed time since last get */ };
The SpmiHotVals structure carries the data values from the SPMI to the application program. It contains handles that allow an application to access the parent context of the peer contexts and the SpmiStat structure of the peer statistic. The ref_count field indicates the number of times a particular set of peer statistics is included in the same set. The ref_count field usually has a value of 1.
The SpmiHotVals structure is defined as follows:
union Value { long l; float f; };
enum HotExcept { SiHotNoException = 0, SiHotException, SiHotTrap, SiHotBoth };
enum HotFeed { SiHotNoFeed = 0, SiHotThreshold, SiHotAlways };
struct SpmiHotItems { char name[SI_MAXLNAME]; /* name of the peer context */ union Value val; /* counter/level data value */ union Value val_change; /* delta change if counter data*/ };
struct SpmiHotVals { void *reserved; /* reserved field */ SpmiStatHdl stat; /* handle of statistic */ SpmiCxHdl grandpa; /* parent of the peer contexts */ int ref_count; /* count of simultaneous users */ enum Error error; /* error code */ enum HotExcept except_type; /* when to send exceptions */ short trap_no; /* trap number for SNMP traps */ short severity; /* severity for exception pckt */ enum HotFeed feed_type; /* when to send data feeds */ int threshold; /* threshold for what to send */ short frequency; /* max frequency of exceptions */ short max_responses; /* max # of responses to send */ short avail_resp; /* # of available hot readings */ short count; /* # of returned hot readings */ char *path; /* path to grandpa context */ struct SpmiHotItems *items; /* array of returned readings */ };
The data carrying fields are:
An array of this structure is pointed to by the field items in the SpmiHotVals structure. Elements are ordered after the returned data values; ascending if threshold is negative, otherwise descending. Each element in the array has the following fields, used to return the result. Note that each instance of this structure corresponds to one single peek statistic within a set of peer statistics as defined in an instance of an SpmiHotVals structure.
A DDS program can register and supply private statistics to the SPMI by calling SPMI subroutines. The following information describes the program structures used to communicate between a DDS program and the SPMI.
A DDS program initializes the API by using the SpmiDdsInit subroutine. This subroutine allocates the DDS shared memory area, shown in Data-Supplier Shared Memory Layout , based on the two data structures described in:
DDS programs should not directly manipulate the shared memory area, its control information, or its data structures except by using the following fields:
Note: The time stamp is a structure with two integer elements. It is expected to be stored in Big Endian notation. Hosts that use Little Endian notation must convert the integer fields to Big Endian notation before storing them.
The following structure shows the DDS shared memory layout:
typedef struct { short SiShMajor; /* Major version of shm protocol */ short SiShMinor; /* Minor version of shm protocol */ char SiShName[64]; /* Path name for shm allocation */ char SiShId; /* ID for ftok() function */ key_t SiShKey; /* shared memory key (RSi interface)*/ /* creating process ID (Spmi I/F) */ int SiShMemId; /* shared memory identifier */ u_long SiShInetAddr; /* Internet address of owning host */ u_short SiShPortNo; /* port number to talk to daemon */ int SiShAllocLen; /* length of allocated area */ int SiShInstBegun; /* instantiations begun */ int SiShInstDone; /* instantiations completed */ int SiShRefrBegun; /* refreshes begun */ int SiShRefrDone; /* refreshes completed */ boolean SiShGoAway; /* signal supplier to terminate */ boolean SiShAlarmSw; /* switch to indicate alarm is set */ cx_create *SiShCxTab; /* pointer to fixed context table */ int SiShCxCnt; /* count of contexts in above table */ cx_create *SiShInstTab; /* pointer instantiable contexts */ int SiShInstCnt; /* count of contexts in above table */ struct SpmiRawStat *SiShStatTab; /* pointer to consolidated Stats */ int SiShStatCnt; /* count of Stats in above table */ char *SiShArea; /* pointer to statistics area */ int SiShAreaLen; /* length of statistics area */ struct timeval SiShT; /* time of last area update BY US */ struct timeval SiShPost; /* time of update of fields below */ int SiShInterval; /* sample frequency in milliseconds */ int SiShSubscrib; /* current number of values used */ struct SpmiCxLink *SiShAddCx; /* instantiated contexts to add */ struct SpmiCxLink *SiShActCx; /* active instantiated contexts */ struct SpmiCxLink *SiShDelCx; /* contexts to delete */ struct SpmiCxLink *SiShFreeCx; /* freed contexts */ void *SiShAlarm; /* addr of Shm alarm data area */ u_long SiShLock1; /* lock words to serialize access */ u_long SiShLock2; /* .. from multiple threads/CPUs */ u_long SiShRes[4]; /* reserved for future use */ char SiShData; /* start of data area */ } SpmiShare;
To add permanent statistics, a DDS program must describe the statistics in the SpmiRawStat structure. For each context with statistics that the program wants to add, the program must create a table of statistics.
The SpmiRawStat structure is defined as follows:
#define SI_MAXNAME 32 #define SI_MAXLNAME 64
enum ValType { SiCounter, /* field is always incremented */ SiQuantity, /* field maintains a level */ };
enum DataType { SiULong, SiLong, SiUInt, SiInt, SiUShort, SiShort, SiChar, SiAddr, SiTimeval, SiFloat, SiDouble, SiPtr, SiUnsign, };
struct SpmiRawStat { char name[SI_MAXNAME]; /* short name of statistic */ char description[SI_MAXLNAME]; /* descriptive name */ long min; /* default low scale value */ long max; /* default high scale value */ enum ValType value_type; /* data type presented to API */ enum DataType data_type; /* data format presented to API*/ u_short asnno; /* ASN.1 number */ u_short size; /* source data field size */ int offset; /* source data field offset */ enum DataType type; /* source data field format */ int (*get_fun)(); /* data access function pointer*/ #ifdef _SOLARIS int ksnoffs; /* Solaris ksn_struct offset */ char module[SI_MODL]; /* Solaris kstat source module */ char statname[SI_STAL]; /* Solaris kstat stat name */ char fieldname[SI_FLDL];/* Solaris kstat field name */ int datoffs; /* Solaris ksn data offset */ #endif /* _SOLARIS */ };
Application programs should leave the section inside #ifdef _SOLARIS uninitialized, even on Solaris systems. The following example defines the "gadgets" and "widgets" statistics. See Example of an SPMI Dynamic Data-Supplier Program for a sample program that uses this definition.
static CONST struct SpmiRawStat PUStats[] = { { "gadgets", "Fake counter value", 0, 100, SiCounter, SiLong, 1, SZ_OFF(dat, a, SiULong), NULL}, { "widgets", "Another fake counter value", 0, 100, SiCounter, SiLong, 2, SZ_OFF(dat, b, SiULong), NULL}, };
After declaring the statistics, the DDS program must link them to their parent contexts. To do so, the program uses a single table of structures that defines all the contexts as permanent contexts. Each context requires one element of the cx_create type.
The cx_create structure is defined as follows:
#define SI_MAXNAME 32 #define SI_MAXLNAME 64
typedef struct { char path[SI_MAXLNAME]; /* context path name */ char descr[SI_MAXLNAME]; /* context description */ u_short asnno; /* ASN.1 number */ u_short datasize; /* size of context record */ struct SpmiRawStat *stats; /* Stat array pointer for context */ int num_stats; /* element count of Stat array */ struct SpmiRawStat *inst_stats; /* Stat array for multiple */ /* instances of this context */ int num_inst_stats; /* element count for above array */ int (*inst_subs)(); /* function to instantiate context*/ int inst_freq; /* instantiate frequency */ u_long level; /* relative level (work field) */ char *area; /* data area pointer */ u_long arealen; /* length of above data area */ } cx_create;
The following example defines the DDS/IBM and DDS/IBM/sample1 contexts. See Example of an SPMI Dynamic Data-Supplier Program for a sample program that uses this definition.
static CONST cx_create cx_table[] = { {"DDS/IBM", "IBM-defined Dynamic Data Suppliers", 2, 0, NULL, 0, NULL, 0, NULL, SiNoInst}, {"DDS/IBM/sample1", "Bogus Context Number 1", 191, 0, PUStats, STAT_L(PUStats), NULL, 0, NULL, SiNoInst}, };
Some structures contain an asnno field. The SPMI assigns each context and statistic a unique number in Abstract Syntax Notation One (ASN.1) format and stores the number in this field. As a result, the SPMI can export SPMI and DDS statistics to other interfaces, such as the Simple Network Management Protocol (SNMP). ASN.1 identifiers are composed of a series of integers separated by dots. That is, the context called CPU has the ASN.1 identifier of 1. The subcontexts of CPU have ASN.1 identifiers that are numbered starting with 1. The ASN.1 identifiers for statistics belonging to each subcontext of CPU are also numbered starting with 1. For instance, for the CPU/cpu0/idle path name the CPU context has an ASN.1 identifier of 1, the CPU/cpu0 subcontext has an ASN.1 identifier of 1.1, and the CPU/cpu0/idle statistic has an ASN.1 identifier of 1.1.4. This identifier is referred to as the relative dotted-decimal identifier.
The dotted-decimal identifiers of all statistics can be thought of as a substructure or subtree, which can be attached to any point in another network, such as the SNMP Management Information Base (MIB) tree. For example, an SNMP tree has a point defined as:
internet.private.enterprises.ibm.ibmAgents.aix.risc6000.risc6000private
This subtree is graphically illustrated in the following figure titled Hierarchical Organization of Private MIB Subtrees.:
Figure 5. Hierarchical Organization of Private MIB Subtrees
This description corresponds to a dotted-decimal identifier of 1.3.6.1.4.1.2.3.1.2.2 (the numbers 1.3.6.1 correspond to the internet portion of the tree). If the SPMI contexts were attached at this point, the fully qualified dotted-decimal identifier for the CPU/cpu0/idle path name (1.1.4) would be 1.3.6.1.4.1.2.3.1.2.2.1.1.4.
No two contexts or statistics can have the same relative dotted-decimal identifier. The API checks that you do not assign the same ASN.1 number more than once at each level in the subtree defined by your DDS program. This ensures unique relative dotted-decimal identifiers.
In addition, statistics and contexts must have unique names within the parent context. The API checks that DDS programs adhere to this rule so that the full path name of statistics and contexts remains unique.
However, the API can only detect name or ASN.1 number clashes, not resolve them. Therefore, it is recommended that DDS programs use the following naming and numbering scheme. This scheme uses an SPMI-defined context, called DDS, with a relative dotted-decimal identifier of 99. When adding subtrees, DDS programs should use the DDS context as the parent context.
This naming and numbering scheme is graphically illustrated in the following figure titled Extended Set of Statistics.:
Figure 6. Extended Set of Statistics
Vendors of DDS programs should define a private subcontext of the DDS context as the parent context for all DDS subtrees that the program creates. Assign this private subcontext a meaningful name and an ASN.1 number that corresponds to the ASN.1 number assigned to the vendor in the SNMP subtree enterprises. Such a number is called an Assigned Enterprise Number. For example, IBM has an Assigned Enterprise Number of 2. Therefore, the subcontext for the path name DDS/IBM would have a relative dotted-decimal identifier of 99.2.
DDS programs can be loaded in any sequence. However, since all DDS programs depend on the presence of the vendor-specific context (such as DDS/IBM), each program must attempt to add this context to make sure it exists. Once a program has created the vendor-specific context, it remains defined as long as the common shared memory area exists. When other DDS programs attempt to add the same vendor-specific context, they simply use the already created context. Vendor-specific contexts must never have statistics defined. Statistics should be added to subcontexts of the vendor-specific context.
Note: Vendors without SNMP numbers should register for one by contacting the Internet Assigned Numbers Authority at the following address:
Internet Assigned Numbers Authority USC/Information Sciences Institute 4676 Admiralty Way Marina del Rey, California 90202-6695
The Internet address for the Internet Assigned Numbers Authority is iana@isi.edu.
The API supplied with the Agent component is called the System Performance Measurement Interface (SPMI). It allows you to write programs that extend the number of statistics available from a host's xmservd daemon (dynamic data-supplier programs) and to write programs that access statistics on the local host without using the network interface (local data-consumer programs).
This chapter describes how you use this API to create your own dynamic data-supplier program. The sample programs used to explain the API and several additional ones are provided in machine-readable form as part of the Agent component. The sample programs and a Makefile can be found in directory:
/usr/samples/perfagent/server
When you want to extend the set of statistics available from the xmservd daemon on a host, you create a dynamic data-supplier (DDS) program using the SPMI API. When the DDS program executes, it registers its statistics with the SPMI. This makes the new statistics immediately available to the local data-consumer programs and to the xmservd daemon so any program that gets its statistics from the extended xmservd daemon can access the additional statistics provided by the DDS. DDS programs must execute on the same host as the one running the xmservd whose set of statistics is to be extended.
The include files are based upon a number of pre-processor define directives being properly set. They must be defined with the -D preprocessor flag. The following define directives should be in effect for compiling on AIX Version 3 or 4.
A Makefile to build all the sample programs provided could look like the one shown below.
LIBS = -lbsd -lSpmi CC = cc CFLAGS = -D_BSD -D_AIX -D_AIX_41
all:: SpmiDds SpmiSupl SpmiSupl1 SpmiLogger SpmiPeek lchmon lfiltd
SpmiDds: SpmiDds.c $(CC) -o SpmiDds SpmiDds.c $(CFLAGS) $(LIBS)
SpmiSupl: SpmiSupl.c $(CC) -o SpmiSupl SpmiSupl.c $(CFLAGS) $(LIBS)
SpmiSupl1: SpmiSupl1.c $(CC) -o SpmiSupl1 SpmiSupl1.c $(CFLAGS) $(LIBS)
SpmiLogger: SpmiLogger.c $(CC) -o SpmiLogger SpmiLogger.c $(CFLAGS) $(LIBS)
SpmiPeek: SpmiPeek.c $(CC) -o SpmiPeek SpmiPeek.c $(CFLAGS) $(LIBS)
lchmon: lchmon.c $(CC) -o lchmon lchmon.c $(CFLAGS) $(LIBS) -lcurses
lfiltd: lfiltd.c lex.lfiltd.o lfiltd.h $(CC) -o lfiltd lfiltd.c lex.lfiltd.o $(CFLAGS) $(LIBS)
lex.lfiltd.o: lfiltd.lex lfiltd.h lex lfiltd.lex cp lex.yy.c lex.lfiltd.c rm lex.yy.c $(CC) -c lex.lfiltd.c $(CFLAGS)
To compile on non-AIX systems, other flags must be used. A Makefile is included with each non-AIX agent. Please use flags as defined in that Makefile. If the compiler you are using doesn't support ANSI function prototyping, add the flag:
-D_NO_PROTO
A dynamic data-supplier program is intended to extend the set of statistics that data-consumer programs can be supplied with, either from the xmservd daemon of a host or directly from the SPMI repository through local data-consumer programs. A dynamic data-supplier can add statistics as permanent (non-volatile) or dynamic (volatile) contexts with subcontexts and statistics. To illustrate this concept, assume the SPMI has a set of contexts and statistics as pictured in Figure 7.
Figure 7. Start Set of Statistics
Of course, the set of statistics on an IBM RISC System/6000 is much larger than shown, but this will do as an illustration. Now assume that you have access to other statistics and want them added to the set. This is when you want to create a dynamic data-supplier program. For example, you could extend the tree structure of contexts and statistics to look as shown in Figure 8.
Figure 8. Extended Set of Statistics
In Figure 8, two contexts have been added as subcontexts of a context called DDS/IBM and are named Test and Moretest. The first of these contexts has two statistics called gadgets and widgets. The second has no directly descendent statistics but has a subcontext called SubTest, which in turn has two statistics: level and queue.
By convention, DDS programs always add statistics below the context DDS/vendor where vendor is the name of the vendor or customer that develops the DDS program; not the name of the machine type that the programs run on. This convention is established to prevent name clashes between the DDS programs developed by different vendors. Statistics should only be added to subcontexts of the DDS/vendor contexts, never to the DDS/vendor context itself.
The hierarchy shown in figure 8 could be displayed with the program xmpeek. This generates output as shown below:
/birte/Mem/ Memory statistics /birte/Mem/Real/ Physical memory statistics /birte/Mem/Real/size Size of physical memory (4K pages) /birte/Mem/Real/%free % memory which is free /birte/Mem/Real/%comp % memory allocated to computational segments /birte/Mem/Virt/ Virtual memory management statistics /birte/Mem/Virt/pagein 4K pages read by VMM /birte/Mem/Virt/pageout 4K pages written by VMM /birte/Mem/Virt/steal Physical memory 4K frames stolen by VMM /birte/PagSp/ Paging space statistics /birte/PagSp/size Total active paging space size (4K pages) /birte/PagSp/free Total free disk paging space (4K pages) /birte/PagSp/hd6/ Statistics for paging space hd6 /birte/PagSp/hd6/size Size of paging space (4K pages) /birte/PagSp/hd6/%free Free portion of this paging space (percent) /birte/DDS/ Dynamic Data-Supplier Statistics /birte/DDS/IBM/ IBM-defined Dynamic Data-Suppliers /birte/DDS/IBM/Test/ Bogus Context Number 1 /birte/DDS/IBM/Test/gadgets Fake counter value /birte/DDS/IBM/Test/widgets Another fake counter value /birte/DDS/IBM/Moretest/ Bogus Context Number 2 /birte/DDS/IBM/Moretest/SubTest/ Bogus Context Number 3 /birte/DDS/IBM/Moretest/SubTest/level Fake quantity value /birte/DDS/IBM/Moretest/SubTest/queue Another fake quantity value
For this first exercise, it is assumed that the added contexts and statistics are non-volatile and as such can be added as permanent statistics. This requires the use of only one subroutine and the following programming steps:
Statistics are described in a simple structure of type struct SpmiRawStat. For each of the contexts you define that has statistics, you must create a table of statistics. The definition of the statistics gadgets and widgets would look as shown below:
static const struct SpmiRawStat PUStats[] = { { "gadgets", "Fake counter value", 0, 100, SiCounter, SiLong, 1, SZ_OFF(dat, a, SiULong)}, { "widgets", "Another fake counter value", 0, 100, SiCounter, SiLong, 2, SZ_OFF(dat, b, SiULong)}, };
The fields in the structure are the following:
SiCounter Value is incremented continuously. Normally, data-consumer programs show the delta (change) in the value between observations, divided by the elapsed time, representing a rate.
SiQuantity Value represents a level, such as memory used or available disk space.
Since we actually wanted to add two sets of statistics at two different places in the context hierarchy, we also need to declare the second set. The code piece below shows how that can be done:
static const struct SpmiRawStat FakeMemStats[] = { { "level", "Fake quantity value", 0, 100, SiQuantity, SiLong, 1, SZ_OFF(dat, c, SiULong)}, { "queue", "Another fake quantity value", 0, 100, SiQuantity, SiLong, 2, SZ_OFF(dat, d, SiULong)}, };
After you have the statistics declared, you need to link them to their parent contexts. This is also done by defining a table of data structures. You need a single table of structures holding all the contexts you want to define as permanent contexts. Each context requires one element of the type cx_create. To create the three contexts we wanted to add, declare the four contexts as shown in the code segment below:
static const cx_create cx_table[] = { {"DDS/IBM", "IBM-defined Dynamic Data-Suppliers", 2, 0, NULL, 0, NULL, 0, NULL, SiNoInst}, {"DDS/IBM/Test", "Bogus Context Number 1", 220, 0, PUStats, STAT_L(PUStats), NULL, 0, NULL, SiNoInst}, {"DDS/IBM/Moretest", "Bogus Context Number 2", 221, 0, NULL, 0, NULL, 0, NULL, SiNoInst}, {"DDS/IBM/Moretest/SubTest", "Bogus Context Number 3", 222, 0, FakeMemStats, STAT_L(FakeMemStats), NULL, 0, NULL, SiNoInst} };
The first context declared is the vendor context. Since DDS programs from a vendor may be started in any sequence, there is no guarantee that this context exists. All DDS programs, therefore, must attempt to add the vendor context. If the vendor context exists, the attempt is ignored; otherwise the context is added. Note that this is the only type of context that is handled this way. Attempts to add other contexts twice cause the API to return an error to your program.
Each context element must have the following fields:
Your dynamic data-supplier program must define its own data areas as required. We define the structure and fields shown below:
extern char SpmiErrmsg[]; struct dat { u_long a; u_long b; u_long c; u_long d; }; static int CxCount = CX_L(cx_table); /* Count of contexts defined */ static SpmiShare *dataarea = NULL; /* Shared memory pointer */ static struct dat *d = NULL; /* Pointer to stats data area */
The first line declares an external variable used by the SPMI API to return an error text to the invoking program if an error occurs.
The next lines define the data structure where we calculate the raw statistics to present to System Performance Measurement Interface (SPMI) interface. The data area must hold all the data fields referenced by non-volatile statistics.
Then we define a counter, which we use the CX_L macro to initialize with the number of static contexts we want to add. Finally we define a pointer that will, eventually, be initialized to point to the data area we share with the SPMI interface.
The SPMI interface and the DDS use shared memory to communicate between themselves. As always, when programs share memory, conventions must be established and adhered to for the use of the shared memory areas. The shared memory used by the SPMI is divided into two main areas: the shared memory structured fields and the shared memory data area.
The shared memory area is created by subroutines and its control information and generated data structures should (with few exceptions) never be used or manipulated by the DDS program directly. You can see the control information as it is defined in the include file /usr/include/sys/Spmidef.h as the structure SpmiShare. The fields that must be used by the DDS program are:
Note: The time stamp is a structure with two integer elements. It is expected to be stored in Big-Endian notation. Hosts that use Little-Endian notation must convert the integer fields to Big-Endian notation before storing them.
The shared memory data area is where your DDS is supposed to place its statistics values as they are calculated. You can do your calculations directly in the area allocated in shared memory, or you can do the calculations in local data fields and then move the result to shared memory. The important thing is to be aware that the shared memory area is guaranteed to be large enough to contain the last of those fields in your data structure that are referenced in any one of the tables defining statistics, but no larger.
Thus, if the structure dat as defined in the code segment in section Declare Other Data Areas as required had additional data fields, those would not be available in shared memory because no declared statistics reference them. Attempts to access such fields would cause segmentation faults.
With all required declarations in place we can register with the SPMI interface. This is done through a single subroutine called SpmiDdsInit. For specifics, see the SpmiDdsInit subroutine on page . For the purpose of this example, the subroutine is invoked with the statements shown below:
dataarea = SpmiDdsInit(cx_table, CxCount, NULL,0, "/etc/SpmiSupl1SHM"); if (!dataarea) { printf("%s", SpmiErrmsg); exit(-1); } d = (struct dat *) &dataarea->SiShArea[0];
Because a DDS uses shared memory to talk to SPMI, it is very important to make sure the shared memory area is released when your DDS program dies. The best way to make sure this happens is to catch the signals that indicate that your program dies. The same function used to process the signals can conveniently be used for normal program exit. This could be done as shown in this code piece:
void SpmiStopMe() { dataarea = NULL; SpmiExit(); exit(0); } signal(SIGTERM, SpmiStopMe); signal(SIGHUP, SpmiStopMe); signal(SIGINT, SpmiStopMe); signal(SIGSEGV, SpmiStopMe);
The function SpmiStopMe makes sure the shared memory area is freed and then exits. The "signal" lines defining the signal handler should be placed around the place in the DDS program where the program registers with SPMI.
In most cases, statistics values are a combination of the types SiCounter and SiQuantity. Data consumers normally are interested in delta values for the former, so the first thing to do is take the first reading and initialize the statistics fields in shared memory. That way, even the first delta values read by a data consumer are likely to be valid.
Updating data fields always requires updating the time stamp. The lines used to do this and to give the initial field values could follow the scheme shown below. In this example, the fields are updated directly in the shared memory data area.
gettimeofday(&dataarea->SiShT, NULL); d->a = ... ; d->b = ... ; d->c = ... ; d->d = ... ;
The main loop is normally very simple and is conveniently made as a while loop. One of the conditions you should always include in your while loop is a test for the SiShGoAway flag. Your program may have additional conditions added to terminate the program as required by the application. The example main loop below only tests for the flag:
while(!dataarea->SiShGoAway) { usleep(499000); gettimeofday($dataarea->SiShT, NULL); d->a = ... ; d->b = ... ; d->c = ... ; d->d = ... ; } SpmiStopMe();
Although the main loop can be as simple as shown above, such simplicity may cause the DDS program to update the values in the shared memory area more often than required. In situations where the DDS has defined values but no data-consumer program is using any of those, updating the data fields is entirely unnecessary.
Two fields let you add a little more finesse to your dynamic data-supplier program. Both fields are Shared Memory Structured Fields and can be accessed through the pointer returned by SpmiDdsInit. The fields are not updated by every data-consumer program; only by the xmservd daemon. Therefore, your DDS program must be able to cope with the situation that the two fields are not updated. The fields are:
Obviously, if SiShSubscrib is zero, nobody is requesting continuous supply of data values and you can reduce the update frequency in your DDS accordingly. It is recommended that you do not stop the updating of the data fields but that you do so with intervals of, say, five seconds.
If SiShSubscrib is nonzero, somebody is requesting continuous supply of data values and you should adjust the update frequency to match the request frequency as given in SiShInterval.
A main loop that uses these principles could look as shown here:
while(!dataarea->SiShGoAway) { if (datarea->SiShSubscrib) usleep(dataarea->SiShInterval * 1000); else sleep(5); gettimeofday(&dataarea->SiShT, NULL); d->a = ... ; d->b = ... ; d->c = ... ; d->d = ... ; } SpmiStopMe();
The SiShSubscrib field normally holds a count of all data-consumer programs written to the RSi API (see RSi Programming Guide ) that are currently subscribing to data values in the shared memory area. However, in order to allow a program that acts both as a data consumer and a dynamic data supplier, you can move the port number of the port assigned to the data consumer side of the program to the field SiShPortNo, which is another shared memory structured field. A data-consumer/dynamic data-supplier program could use a statement like the following to insert the port number:
dataarea->SiShPortNo = rsh->portno;
where rsh is the RSiHandle for the host. The field portno in the RSiHandle structure is updated by the subroutine RSiOpen.
When the port number is inserted in the shared memory area, the xmservd does not count subscriptions for data values in the shared memory area that originate at that port number on the local host.
The above program segments are combined into a working DDS program below. Source code for the program can be found in /usr/samples/perfagent/server/SpmiSupl1.c:
#include <stdio.h> #include <sys/signal.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/Spmidef.h>
extern char SpmiErrmsg[]; struct dat { u_long a; u_long b; u_long c; u_long d; }; static const struct SpmiRawStat PUStats[] = { { "gadgets", "Fake counter value", 0, 100, SiCounter, SiLong, 1, SZ_OFF(dat, a, SiULong)}, { "widgets", "Another fake counter value", 0, 100, SiCounter, SiLong, 2, SZ_OFF(dat, b, SiULong)}, }; static const struct SpmiRawStat FakeMemStats[] = { { "level", "Fake quantity value", 0, 100, SiQuantity, SiLong, 1, SZ_OFF(dat, c, SiULong)}, { "queue", "Another fake quantity value", 0, 100, SiQuantity, SiLong, 2, SZ_OFF(dat, d, SiULong)}, }; static const cx_create cx_table[] = { {"DDS/IBM", "IBM-defined Dynamic Data-Suppliers", 2, 0, NULL, 0, NULL, 0, NULL, SiNoInst}, {"DDS/IBM/Test", "Bogus Context Number 1", 220, 0, PUStats, STAT_L(PUStats), NULL, 0, NULL, SiNoInst}, {"DDS/IBM/Moretest", "Bogus Context Number 2", 221, 0, NULL, 0, NULL, 0, NULL, SiNoInst}, {"DDS/IBM/Moretest/SubTest", "Bogus Context Number 3", 222, 0, FakeMemStats, STAT_L(FakeMemStats), NULL, 0, NULL, SiNoInst}, }; static int CxCount = CX_L(cx_table); /* Count of contexts defined */ static SpmiShare *dataarea = NULL; /* Shared memory pointer */ static struct dat *d = NULL; /* Pointer to stats data area */
void SpmiStopMe() { dataarea = NULL; SpmiExit(); exit(0); } void main() { dataarea = SpmiDdsInit(cx_table, CxCount, NULL, 0, "/etc/SpmiSul1SHM"); if (!dataarea) { printf("%s", SpmiErrmsg); exit(-1); } d = (struct dat *)&dataarea->SiShArea[0]; signal(SIGTERM, SpmiStopMe); signal(SIGHUP, SpmiStopMe); signal(SIGINT, SpmiStopMe); signal(SIGSEGV, SpmiStopMe); gettimeofday &dataarea >SiShT, NULL); d->a = 22; d->b = 42; d->c = 28; d->d = 62; while(!dataarea->SiShT, NULL); { usleep(499000); gettimeofday(&dataarea->SiShT, NULL); d->a += dataarea->SiShT.tv_sec & 0xff; d->b += dataarea->SiShT.tv_sec & 0xf; d->c += (dataarea->SiShT.tv_sec & 0x20f) & 0xffff; d->d += (dataarea->SiShT.tv_sec & 0x7f) & 0xffff; } SpmiStopMe(); }
A DDS program may allow contexts and statistics to be added and deleted on the fly. For example, assume your DDS is concerned with monitoring of the response times between pairs of network hosts. On even a small network, it would be quite excessive to define all possible host pairs and keep track of them all. At any point in time, however, a limited number of sessions are active, but this number changes as do the host pairs involved. If you wanted to reflect this volatility in the statistics you present, you would need the ability to add and delete statistics on the fly.
To illustrate the use of the two subroutines that allow you to add and delete contexts dynamically, we will expand the first sample program. We are extending the context hierarchy shown in figure 8 to look like the hierarchy shown in Figure 9.
Figure 9. Dynamic Extension of Statistics
As you can see, we plan to add a context called Bingo to the hierarchy with the previously added context Moretest as parent of the new context. The context we add has two statistics values, namely problems and solutions. It is our plan to allow the context to be added and deleted dynamically. For lack of a better trigger, we let the time-of-day determine when to add and delete the context.
We shall not be writing an entire new program. Rather, we take the previous example program and merely add the code lines required for the additional functionality using the following steps:
Statistics are defined almost the same way whether they are to be added permanently or dynamically. It is still true that all statistics for a context must be defined in one array. That one array may be referenced by more contexts, if appropriate; but most likely, it is not. The only real difference is that each set of statistics meant to be added dynamically must reference a separate data structure as source of its data fields. This is quite different from permanent statistics where all statistics source fields must reside in a common structure.
Obviously, there's a reason for this. Static data values occur only once. They all reside in one contiguous area in shared memory. Dynamic data values, on the contrary, may exist in multiple instances and may come and go. They are allocated dynamically in shared memory when they are required and when the values are deleted, their shared memory areas are returned to the free list.
The definition of statistics to add the problems and solutions values is shown below:
static CONST struct SpmiRawStat InstStats[] = { { "problems", "Fake counter value", 0, 100, SiCounter, SiLong, 1, SZ_OFF(inst, a, SiLong)}, { "solutions", "Another fake counter value", 0, 100, SiCounter, SiLong, 2, SZ_OFF(inst, b, SiLong)} };
You notice that this time we do not reference the structure dat used previously but a different structure called inst, which we have yet to define.
In this example we add only a single context. We could have added many more but for each context, which the DDS program may want to add, one element must be defined in a table of contexts. No context can be dynamically added unless it was defined in a table and passed to the SpmiDdsInit function when your DDS registered with the SPMI. The table has exactly the same format as the table of permanent contexts but must not be the same table. The code segment below shows how we define the single context we need to add:
Note: The pack name, description, and ASN.1 number of the context are used as placeholders, only. The real values to use are supplied on the SpmiDDsAddCx subroutine each time a context is called.
static CONST cx_create inst_table[] = { {"DDS/IBM/Moretest/INST1", "Instantiable Context Number 1", 215, 0, InstStats, STAT_L(InstStats), NULL, 0, NULL, SiNoInst} };
We need only define the structure referenced by the declared statistics and a pointer to be used for accessing the allocated shared data area. For convenience we also define an integer to hold the number of dynamic contexts:
struct inst { float a; u_long b; }; int InstCount = CX_L(inst_table); /* Count of contexts defined */ struct inst *pt1 = NULL; /* Pointer to stats data area */
Registration with the SPMI is almost unchanged. All we need is to tell the subroutine where the dynamic context table is and how many elements it has. This is shown in the following code segment:
dataarea = SpmiDdsInit(cx_table, CxCount, inst_table, InstCount, "/etc/SpmiSupl_hook"); if (!dataarea) { fprintf(stderr, "%s\n", SpmiErrmsg); exit(-1); } d = (struct dat *)&dataarea->SiShArea[0];
Finally, the code segment below shows the modified main loop. The loop has been extended with three pieces of code. The first one uses a subroutine SpmiDdsAddCx to add the context. The second uses SpmiDdsDelCx to delete the context again, and the third updates the values in the shared data area whenever the context and its statistics are active:
while(!dataarea->SiShGoAway) { if (dataarea->SiShSubscrib) usleep(dataarea->SiShInterval * 1000); else sleep(5); gettimeofday(&dataarea>SiShT, NULL); d->a = ... ; d->b = ... ; d->c = ... ; d->d = ... ; if (((dataarea->SiShT.tv_sec % 59) == 0) && (!pt1)) { if (!(pt1 = (struct inst *)SpmiDdsAddCx(0, "DDS/IBM/Moretest/Bingo", "Dynamically added", 1))) fprintf(stderr, "Add failed: \"%s\"\n", SpmiErrmsg); } if (((dataarea->SiShT.tv_sec % 120) == 0) && (pt1)) { if (i = SpmiDdsDelCx((char *)pt1)) fprintf(stderr, "Delete failed: \"%s\"\n", SpmiErrmsg); else pt1 = NULL; } if (pt1) { pt1->a = ... ; pt1->b = ... ; } } SpmiStopMe();
The supplied sample program SpmiSupl.c does what has just been explained. It also adds yet another context dynamically. You may want to play with that program before writing your own.
When your dynamic data-supplier program adds or deletes volatile extensions, this is indicated to SPMI through fields in the shared memory area. Neither the xmservd daemon nor other local data-consumer programs become aware of your changes until some event prompts them to look in the shared memory area.
This approach keeps the updating of the context structure to a minimum. The changes are only implemented if requested. The following is a list of events that causes xmservd or other local data-consumer programs to check the shared memory area for changes to volatile extensions. The RSi calls represent requests received by xmservd over the network interface; the SPMI calls would be issued by xmservd because of incoming requests or by other local data-consumer programs as required:
The following example program accesses the SPMI data:
/* The following statistics are added by the SpmiPathAddSetStat * subroutine to form a set of statistics: * CPU/cpu0/kern * CPU/cpu0/idle * Mem/Real/%free * PagSp/%free * Proc/runque * Proc/swpque * These statistics are then retrieved every 2 seconds and their * value is displayed to the user. */
#include <sys/types.h> #include <sys/errno.h> #include <signal.h> #include <stdio.h> #include <sys/Spmidef.h>
#define TIME_DELAY 2 /* time between samplings */
extern char SpmiErrmsg[]; /* Spmi Error message array */ extern int SpmiErrno; /* Spmi Error indicator */
struct SpmiStatSet *statset; /* statistics set */
/*====================== must_exit() ==========================*/ /* This subroutine is called when the program is ready to exit. * It frees any statsets that were defined and exits the * interface. */ /*=============================================================*/
void must_exit() { /* free statsets */ if (statset) if (SpmiFreeStatSet(statset)) if (SpmiErrno) printf("%s", SpmiErrmsg);
/* exit SPMI */ SpmiExit(); if (SpmiErrno) printf("%s", SpmiErrmsg);
exit(0); }
/*======================== getstats() =========================*/ /* getstats() traverses the set of statistics and outputs the * statistics values. */ /*=============================================================*/
void getstats() { int counter=20; /* every 20 lines output * the header */ struct SpmiStatVals *statval1; float spmivalue;
/* loop until a stop signal is received. */ while (1) { if(counter == 20) { /* output header info */ /* The statistics are displayed in reverse order of how * they were entered into the set of statistics. */ printf("\nCPU/cpu0 CPU/cpu0 Mem/Real PagSp "); printf("Proc Proc\n"); printf(" kern idle %%free %%free "); printf("runque swpque\n"); printf("============================================"); printf("===============\n"); counter=0; }
/* retrieve set of statistics */ if (SpmiGetStatSet(statset, TRUE) != 0) { printf("SpmiGetStatSet failed.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
/* retrieve first statistic */ statval1 = SpmiFirstVals(statset); if (statval1 == NULL) { printf("SpmiFirstVals Failed\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
/* traverse the set of statistics */ while (statval1 != NULL) { /* value to be displayed */ Spmivalue = SpmiGetValue(statset, statval1); if (spmivalue < 0.0) { printf("SpmiGetValue Failed\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); } printf(" %6.2f ",spmivalue);
statval1 = SpmiNextVals(statset, statval1); } /* end while (statval1) */ printf("\n"); counter++; sleep(TIME_DELAY); }
return; }
/*======================== addstats() =========================*/ /* addstats() adds statistics to the statistics set. */ /* addstats() also takes advantage of the different ways a * statistic may be added to the set. */ /*=============================================================*/
void addstats() { SpmiCxHdl cxhdl, parenthdl;
/* initialize the statistics set */ statset = SpmiCreateStatSet(); if (statset == NULL) { printf("SpmiCreateStatSet Failed\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
/* Pass SpmiPathGetCx the fully qualified path name of the * context */ if (!(cxhdl = SpmiPathGetCx("Proc", NULL))) { printf("SpmiPathGetCx failed for Proc context.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
/* Pass SpmiPathAddSetStat the name of the statistic */ /* & the handle of the parent */ if (!SpmiPathAddSetStat(statset,"swpque", cxhdl)) { printf("SpmiPathAddSetStat failed for Proc/swpque statistic.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
if (!SpmiPathAddSetStat(statset,"runque", cxhdl)) { printf("SpmiPathAddSetStat failed for Proc/runque statistic.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
/* Pass SpmiPathAddSetStat the fully qualified name of the * statistic */ if (!SpmiPathAddSetStat(statset,"PagSp/%free", NULL)) { printf("SpmiPathAddSetStat failed for PagSp/%%free statistic.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
if (!(parenthdl = SpmiPathGetCx("Mem", NULL))) { printf("SpmiPathGetCx failed for Mem context.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
/* Pass SpmiPathGetCx the name of the context */ /* & the handle of the parent context */ if (!(cxhdl = SpmiPathGetCx("Real", parenthdl))) { printf("SpmiPathGetCx failed for Mem/Real context.\n"); if (SpmiErrmsg) printf("%s", SpmiErrmsg); must_exit(); }
if (!SpmiPathAddSetStat(statset,"%free", cxhdl)) { printf("SpmiPathAddSetStat failed for Mem/Real/%%free statistic.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
/* Pass SpmiPathGetCx the fully qualified path name of the * context */ if (!(cxhdl = SpmiPathGetCx("CPU/cpu0", NULL))) { printf("SpmiPathGetCx failed for CPU/cpu0 context.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
if (!SpmiPathAddSetStat(statset,"idle", cxhdl)) { printf("SpmiPathAddSetStat failed for CPU/cpu0/idle statistic.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
if (!SpmiPathAddSetStat(statset,"kern", cxhdl)) { printf("SpmiPathAddSetStat failed for CPU/cpu0/kern statistic.\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); must_exit(); }
return; }
/*=============================================================*/
main(int argc, char **argv) { int spmierr=0;
/* Initialize SPMI */ if ((spmierr = SpmiInit(15)) != 0) { printf("Unable to initialize SPMI interface\n"); if (SpmiErrno) printf("%s", SpmiErrmsg); exit(-98); }
/* set up interrupt signals */ signal(SIGINT,must_exit); signal(SIGTERM,must_exit); signal(SIGSEGV,must_exit); signal(SIGQUIT,must_exit); /* Go to statistics routines. */ addstats(); getstats(); /* Exit SPMI */ must_exit(); }
The following SPMI example program traverses a data hierarchy:
#include <sys/types.h> #include <sys/errno.h> #include <stdio.h> #include <sys/Spmidef.h>
extern char SpmiErrmsg[]; /* Error Msg array */
char stats[256]; /* statistic name info */ char cxt[256]; /* context name info */ char subcxt[256]; /* text holder */ char *blanks=" "; /* blanks for text */ char *blank2=" "; int instantiable=0;
/*======================= findstats() =========================*/ /* findstats is a function that traverses recursively down a * context link. When the end of the context link is found, * findstats traverses down the statistics links and writes the * statistic name to stdout. findstats is originally passed the * context handle for the TOP context. */ /*============================================================*/
void findstats(SpmiCxHdl cxhdl) { struct SpmiCxLink *cxlink; struct SpmiStatLink *statlink; struct SpmiCx *spmicx, *spmicxparent; struct SpmiStat *spmistat; char *statname; char num_string[30]; int cxtlen1, cxtlen2, descplace;
/* Get first context */ if (cxlink = SpmiFirstCx(cxhdl)) {
while (cxlink) {
/* output context name */ spmicx = SpmiGetCx(cxlink->context);
/* if the subcxt is a child of another context */ if (strcmp(subcxt,NULL)) { strcat(subcxt,"/"); strcat(subcxt,spmicx->name); } else strcpy(subcxt,spmicx->name);
cxtlen1 = strlen(spmicx->name); cxtlen2 = strlen(subcxt);
/* determine if the context's parent is instantiable */ /* because we don't want to have to print stats twice */ spmicxparent = SpmiGetCx(spmicx->parent); if ( spmicxparent->inst_freq == SiContInst ) { instantiable++; } else instantiable = 0;
/* only want to print out the stats for any contexts */ /* whose parents aren't instantiable. If the parent */ /* is instantiable then you only want to print out */ /* the stats for the first instance of that parent. */ if (instantiable <= 1) { strcpy(cxt,subcxt); if (!instantiable) { if (cxtlen1 == cxtlen2) descplace = 30 - cxtlen2; else descplace = 35 - cxtlen2; strncat(cxt,blanks,descplace); strcat(cxt,spmicx->description); }
fprintf(stdout,"%s\n",cxt);
/* Traverse the stats list for the context */ if (statlink = SpmiFirstStat(cxlink->context)) { while (statlink) { spmistat = SpmiGetStat(statlink->stat); statname = SpmiStatGetPath(cxlink->context, statlink->stat, 10);
/* output statistic name */ strcpy(stats,statname); descplace = strlen(stats); descplace = 40 - descplace; strncat(stats,blanks,descplace); strcat(stats,spmistat->description); fprintf(stdout, "%s\n",stats);
/* output stat info */ strcpy(stats,"Data Type("); if (spmistat->data_type == SiLong) strcat(stats,"Long) "); else strcat(stats,"Float)"); strcat(stats," Value Type("); if (spmistat->value_type == SiCounter) strcat(stats,"Counter)"); else strcat(stats,"Quantity)"); fprintf(stdout, "%s%s\n",blank2,stats);
/* output max/min info */ sprintf(num_string,"min = %ld max = %ld",spmistat->min,spmistat->max); strcpy(stats,num_string); fprintf(stdout, "%s%s\n",blank2,stats); /* Go to next statistic */ statlink = SpmiNextStat(statlink); } /* end while(statlink) */ } /* end if (statlink) */ } /* end if (instantiable) */ else { /* print out stat name info for stats with */ /* instantiable parents */ strcpy(cxt,spmicxparent->name); strcat(cxt,"/"); strcat(cxt,spmicx->name); strcat(cxt,"/....."); cxtlen1 = strlen(spmicx->name)+6;
fprintf(stdout,"%s\n",cxt); }
/* recursive call to function */ /* this gets the next context link */ findstats(cxlink->context);
if (cxtlen2 == cxtlen1) strcpy(subcxt,NULL); else subcxt[cxtlen2-cxtlen1-1] = NULL;
/* Go to next context */ cxlink = SpmiNextCx(cxlink); } /* end while(cxlink) */ } /* end if (cxlink) */ return; }
/*========================= lststats() ========================*/ /* lststats gets the TOP context handle. This handle is then * passed to the findstats routine */ /*=============================================================*/
void lststats() { SpmiCxHdl cxhdl;
if ((cxhdl = SpmiPathGetCx(NULL, NULL)) == NULL) { fprintf(stderr, "SpmiPathGetCx failed.\n"); if (strlen(SpmiErrmsg)) fprintf(stderr, "%s", SpmiErrmsg); return; } /* routine to traverse the context links */ findstats(cxhdl);
return; }
/*============================ main() =======================*/
main(int argc, char **argv) { int spmierr=0;
/* Initialize SPMI interface */ if ((spmierr = SpmiInit(15)) != 0) { fprintf(stderr, "Unable to initialize SPMI interface\n"); fprintf(stderr, "%s", SpmiErrmsg); exit(-98); }
/* Traversal routine. */ lststats(); /* Exit SPMI Interface */ SpmiExit(); if (strlen(SpmiErrmsg)) fprintf(stderr, "%s", SpmiErrmsg);
exit(0); }
The following SPMI example program expands the data hierarchy:
/* ============================================================== This module is a sample data supplier module for the Spmi interface. It is provided only as an example and has no practical use whatsoever. ============================================================== */ #include <stdio.h> #include <sys/signal.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/Spmidef.h> #ifdef _AIX #define CONST const #else #define CONST #endif extern char SpmiErrmsg[]; /* The data area where statistics are passed to the Spmi interface must be defined as a structure (not typedef'ed). The structure can reside in local memory and be copied to shared memory whenever new statistics values are calculated -- or it can be updated directly in shared memory as this module does. Please note that shared memory is NOT reserved for the entire structure size unless the last field in the structure is referenced in the table of statistics referring to the structure. For example, the structure "dat" defines 6 4-byte long integers but only the first four are referenced in the statistics table. The shared memory area reserved is thus 4x4 = 16 bytes. Attempts to reference the two last elements in shared memory will cause a segmentation fault or destroy other data areas. The structure below is used as data area definition for the sample program. */ struct dat { u_long a; u_long b; u_long c; u_long d; u_long e; u_long f; };
/* The following two tables of type (struct SpmiRawStat) define two sets of statistics. You must define one table for each set of statistics you have. A set of statistics is defines as all statistics that have identical path names, except for the name of the statistic itself. For example, DDS/IBM/Bingo/players/losers and DDS/IBM/Bingo/players/winners belong to the same set of statistics, while DDS/IBM/Bingo/players/losers and DDS/IBM/Blackjack/players/losers belong to two different sets. When the (struct SpmiRawStat) entry is defined in a dynamic data supplier program, the last field in the structure need not be specified or must be specified as NULL. Other fields must be filled in as follows: Field Format Contents ----- -------- -------------------------------------- 1 char[32] Short name of statistic 2 char[64] Description of statistic 3 numeric Lower range for plotting 4 numeric Upper range for plotting 5 ValType See Spmidef.h 6 DataType Data format to deliver to consumer (see Spmidef.h) 7 numeric The ASN.1 number assigned to the statistic 8.1 structure Name of defined statistics structure 8.2 fieldname Name of data field in statistics structure 8.3 DataType Data format of field in statistics structure */ static CONST struct SpmiRawStat PUStats[] = { {"gadgets", "Fake counter value", 0, 100, SiCounter, SiLong, 1, SZ_OFF(dat, a, SiULong), NULL}, {"widgets", "Another fake counter value", 0, 100, SiCounter, SiLong, 2, SZ_OFF(dat, b, SiULong), NULL}, }; static CONST struct SpmiRawStat FakeMemStats[] = { {"level", "Fake quantity value", 0, 100, SiQuantity, SiLong, 1, SZ_OFF(dat, c, SiULong), NULL}, {"queue", "Another fake quantity value", 0, 100, SiQuantity, SiLong, 2, SZ_OFF(dat, d, SiULong), NULL}, };
/* The following table defines the tree structure of contexts as defined by this module. Each context is defined by one table entry. The fields in the contexts are: Field Format Contents ----- -------- -------------------------------------- 1 char[64] Full path name of the context to create 2 char[64] Description of context 3 numeric ASN.1 number to be assigned to the context 4 pointer Pointer to statistics table, NULL if none 5 numeric Count of elements in above statistics table Use STAT_L to find number of elements. 7 pointer Must be specified as NULL 8 numeric Must be specified as 0 (zero) 9 pointer Must be specified as NULL 10 SiInstFreq See Spmidef.h */ static CONST cx_create cx_table[] = { {"DDS/IBM", "IBM-defined Dynamic Data Suppliers", 2, 0, NULL, 0, NULL, 0, NULL, SiNoInst}, {"DDS/IBM/sample1", "Bogus Context Number 1", 191, 0, PUStats, STAT_L(PUStats), NULL, 0, NULL, SiNoInst}, {"DDS/IBM/sample2", "Bogus Context Number 2", 192, 0, NULL, 0, NULL, 0, NULL, SiNoInst}, {"DDS/IBM/sample1/SubContext", "Bogus Context Number 3", 193, 0, FakeMemStats, STAT_L(FakeMemStats), NULL, 0, NULL, SiNoInst}, }; static int CxCount = CX_L(cx_table); /* Count of * context defined */ static SpmiShare *dataarea = NULL; /* Shared memory * pointer */ static struct dat *d = NULL; /* Pointer to stats * data area */ /* This subroutine will make sure the shared memory allocated by this module is released before the module exits. The subroutine is called whenever the module is about to exit. */ void SpmiStopMe(sig) int sig; { if (sig) printf("SiSupl killed by signal %d\n", sig); else printf("SiSupl exiting (%s)\n", SpmidmiErrmsg); SpmiExit(); dataarea = NULL; exit(0); }
/* SiSupl module main function - starts by checking that the program is executed with (required) root credentials. */ void main() { if (geteuid()) { fprintf(stderr,"Root authority req'd\n"); exit(0); } /* Call the SpmiDdsInit subroutine to allocate shared memory and contact the SPMI interface. If this succeeds, the subroutine will return with the address of the shared memory. The first two arguments are the table of static contexts to create and the count of elements in that table. The next two arguments are the table of instantiable contexts and the count of elements in that table. The latter to can be NULL and zero if your data supplier module does not require contexts to be added or deleted on the fly. The last argument is the name of a file, which either (1) must exist and be writeable by the user executing this code, or (2) can be created by the user. It is used to generate a key for the shared memory area and must, of course, be UNIQUE between data supplier medules. */ #ifdef _AIX dataarea = SpmiDdsInit(cx_table, CxCount, NULL, 0, "/etc/SiSuplSHM"); #else dataarea = SpmiDdsInit(cx_table, CxCount, NULL, 0, "/etc/SiSuplSHM", 8092); #endif if (!dataarea) { printf("%s", SpmiErrmsg); exit(-1); } /* The field SiShArea in shared memory has the address of the area where you are supposed to deliver your statistics. In this sample module, we simply set a pointer to point at this data area. */ d = (struct dat *)&dataarea->SiShArea[0]; /* We got the shared memory and SPMI registered our presence. Now make sure we free the shared memory area if we get killed. */
signal(SIGTERM, SpmiStopMe); signal(SIGHUP, SpmiStopMe); signal(SIGINT, SpmiStopMe); signal(SIGSEGV, SpmiStopMe);
/* It is normal and recommended that you initialize the data area with values that make sense, even before anybody uses the data. This includes setting the time stamp at the time you do it. */ gettimeofday(&dataarea->SiShT, NULL); d->a = 22; d->b = 42; d->c = 28; d->d = 62; /* The module now runs as long as the flag SiShGoAway is false. Data consumer programs may set this flag if abnormal conditions are detected. For each iteration, the module produces whatever statistics it can supply. In this module everything is bogus, and the loop is a sleep loop. In a real data supplier module, you could use any timer function to drive you, or you could depend on some external function waking you up. For each time the module updates the data area, the time must be set as shown in the gettimeofday() call. */ while(!dataarea->SiShGoAway) { #ifdef _AIX usleep(499000); #else sleep(1); #endif gettimeofday(&dataarea->SiShT, NULL); d->a += dataarea->SiShT.tv_sec & 0xff; d->b += dataarea->SiShT.tv_sec & 0xf; d->c += (dataarea->SiShT.tv_sec & 0x20f) & 0xffff; d->d += (dataarea->SiShT.tv_sec & 0x7f) & 0xffff; } SpmiStopMe(0); }
All SPMI subroutines use constants to define error codes. The SPMI Error Code table lists the error descriptions.
Symbolic Name | Number | Description |
SiSuccess | 0 | Successful execution. |
SiInvalidCx | 180 | The referenced context doesn't exist. |
SiNoShmPtr | 181 | Unable to identify shared memory segment. |
SiShmemFailed | 182 | Unable to access shared memory. |
SiAssumedDead | 183 | A data-supplier program appears to have terminated. |
SiInstBusy | 184 | Can't instantiate; shared memory update in progress. |
SiNotInst | 185 | Requested instantiation could not be performed. |
SiNotInit | 186 | SPMI interface not initialized. |
SiBadArgument | 187 | One or more arguments to a subroutine call is invalid. |
SiNotFound | 188 | A requested data structure doesn't exist. |
SiNoValue | 189 | No data value returned from the SpmiGetValue subroutine. |
SiInitFailed | 190 | Initializing of the SPMI API failed. |
SiSmuxFailed | 191 | Context could not be exported to the snmpddaemon through the SMUX protocol. |
SiLocked | 192 | Some other process or thread has locked the common shared memory area and prevents the subroutine from executing its the requested function. Retry the subroutine call. |
SiDuplicate | 193 | Attempt to add a context path that alreadu exists. |
SiCallocFailed | 194 | Memory allocation error. |
SiNoLicense | 195 | No licence to use is installed and valid. |
SiDeleted | 196 | The requested context has been deleted. |
SiOtherErr | 197 | Unspecified internal error. |
System Performance Measurement Interface Overview for Programming> , Understanding the SPMI Data Hierarchy , Understanding SPMI Data Areas , Dynamic Data Supplier (DDS) Program Structures .
The SPMI subroutines constitute the application programming interface (API) to the SPMI.
The SPMI subroutines are organized according to function.
The following functional lists of SPMI subroutines are provided:
The following subroutines prepare a system for SPMI processing, free memory after SPMI processing, or create an instance of a system resource or object:
SpmiInit | Initializes the SPMI. |
SpmiExit | Releases allocated memory and disconnects from the SPMI library. |
SpmiInstantiate | Explicitly instantiates the subcontexts of an instantiable context. |
The following subroutines navigate through an SPMI data hierarchy:
SpmiPathGetCx | Returns a handle to use when referencing a context. |
SpmiFirstCx | Locates the first subcontext of a context. |
SpmiNextCx | Locates the next subcontext of a context. |
SpmiFirstStat | Locates the first statistic belonging to a context. |
SpmiNextStat | Locates the next statistic belonging to a context. |
SpmiStatGetPath | Returns the full path name of a statistic. |
SpmiGetCx | Returns a pointer to the SpmiCx structure corresponding to a specified context handle. |
SpmiGetStat | Returns a pointer to the SpmiStat structure corresponding to a specified statistic handle. |
The followings SPMI subroutines create or remove a set of statistics, or add or delete statistics from the set:
SpmiCreateStatSet | Creates an empty set of statistics. |
SpmiPathAddSetStat | Adds a statistics value to a set of statistics. |
SpmiFreeStatSet | Erases a set of statistics. |
SpmiDelSetStat | Removes a single statistic from a set of statistics. |
The followings SPMI subroutines create or remove a hotset, or add or delete sets of peer statistics to or from the set:
SpmiCreateHotSet | Creates an empty set of peer statistics (hotset). |
SpmiAddSetHot | Adds a set of peer statistics values to a hotset. |
SpmiFreeHotSet | Erases a hotset. |
SpmiDelSetHot | Removes a set of peer statistics from a hotset. |
The following subroutines access SPMI statistics:
SpmiGetStatSet | Requests the SPMI to read the data values for all statistics belonging to a specified statset. |
SpmiFirstVals | Returns a pointer to the first SpmiStatVals structure belonging to a statset. |
SpmiNextVals | Returns a pointer to the next SpmiStatVals structure belonging to a statset. |
SpmiGetValue | Returns a decoded value based on the type of data value extracted from the data field of an SpmiStatVals structure. |
SpmiNextValue | Returns a pointer to the next SpmiStatVals structure in a set of statistics. Combines calls to SpmiFirstVals, SpmiNextVals, and SpmiGetValue into a single call for more efficient startset processing. |
SpmiGetHotSet | Requests the SPMI to read the data values for all sets of peer statistics belonging to a specified hotset. |
SpmiFirstHot | Returns a pointer to the first set of peer statistics (SpmiHotVals structure) belonging to a hotset. |
SpmiNextHot | Returns a pointer to the next set of peer statistics (SpmiHotVals structure) belonging to a hotset. |
SpmiNextHotItem | Returns a pointer to the next set of peer statistics (SpmiHotVals structure) belonging to a hotset and decodes the next data value from the SpmiHotVals structure. Used to walk all the returned SpmiHotItems elements returned by SpmiGetHotSet. |
The following subroutines are used by SPMI Dynamic Data Supplier (DDS) programs:
SpmiDdsInit | Initializes a DDS program, establishes access to the common shared memory area, and connects the DDS shared memory area to the SPMI. |
SpmiDdsAddCx | Adds a volatile context from a DDS program. |
SpmiDdsDelCx | Deletes a volatile context previously added from the DDS program. |
Adds a set of peer statistics values to a hotset.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiAddSetHot(HotSet, StatName, GrandParent, maxresp, threshold, frequency, feed_type, except_type, severity, trap_no) struct SpmiHotSet *HotSet; char *StatName; SpmiCxHdl GrandParent; int maxresp; int threshold; int frequency; int feed_type; int excp_type; int severity; int trap_no;
The SpmiAddSetHot subroutine adds a set of peer statistics to a hotset. The SpmiHotSet structure that provides the anchor point to the set must exist before the SpmiAddSetHot subroutine call can succeed.
HotSet
Specifies a pointer to a valid structure of type SpmiHotSet as created by the SpmiCreateHotSet
subroutine call.
StatName
Specifies the name of the statistic within the
subcontexts (peer contexts) of the context identified by the
GrandParent
parameter.
GrandParent
Specifies a valid SpmiCxHdl
handle as obtained by another subroutine call. The handle
must identify a context with at least one subcontext, which
contains the statistic identified by the StatName
parameter. If the context specified is one of the RTime
contexts, no subcontext need to exist at the time the SpmiAddSetHot
subroutine call is issued; the presence of the metric
identified by the StatName parameter is checked
against the context class description.
If the context specified has or may have multiple levels of instantiable context below it (such as the FS and RTime/ARM contexts), the metric is only searched for at the lowest context level. The SpmiHotSet created is a pseudo hotvals structure used to link together a peer group of SpmiHotVals structures, which are created under the covers, one for each subcontext of the GrandParent context. In the case of RTime/ARM, if additional contexts are later added under the GrandParent contexts, additional hotsets are added to the peer group. This is transparent to the application program, except that the SpmiFirstHot, SpmiNextHot, and SpmiNextHotItem subroutine calls will return the peer group SpmiHotVals pointer rather than the pointer to the pseudo structure.
Note that specifying a specific volume group context (such as FS/rootvg) or a specific application context (such as RTime/ARN/armpeek) is still valid and won't involve creation of pseudo SpmiHotVals structures.
maxresp
Must be non-zero if excp_type specifies that
exceptions or SNMP traps must be generated. If specified as
zero, indicates that all SpmiHotItems
that meet the criteria specified by threshold must be
returned, up-to a maximum of maxresp items. If both
exceptions/traps and feeds are requested, the maxresp
value is used to cap the number of exceptions/alerts as well
as the number of items returned. If feed_type is
specified as SiHotAlways, the maxresp parameter
is still used to return at most maxresp items.
Where the GrandParent argument specifies a context that has multiple levels of instantiable contexts below it, the maxresp is applied to each of the lowest level contexts above the the actual peer contexts at a time. For example, if the GrandParent context is FS (file systems) and the system has three volume groups, then a maxresp value of 2 could cause up to a maximum of 2 x 3 = 6 responses to be generated.
threshold
Must be non-zero if excp_type specifies that
exceptions or SNMP traps must be generated. If specified as
zero, indicates that all values read qualify to be returned
in feeds. The value specified is compared to the data value
read for each peer statistic. If the data value exceeds the
threshold,
it qualifies to be returned as an SpmiHotItems element
in the SpmiHotVals
structure. If the threshold is specified as a negative
value, the value qualifies if it is lower than the numeric
value of threshold. If feed_type is specified
as SiHotAlways, the threshold value is ignored for
feeds. For peer statistics of type SiCounter, the threshold
must be specified as a rate per second; for SiQuantity
statistics the threshold is specified as a level.
frequency
Must be non-zero if excp_type specifies that
exceptions or SNMP traps must be generated. Ignored for
feeds. Specifies the minimum number of minutes that must
expire between any two exceptions/traps generated from this
SpmiHotVals
structure. This value must be specified as no less than 5
minutes.
feed_type
Specifies if feeds of SpmiHotItems should be
returned for this SpmiHotVals structure. The following
values are valid:
excp_type
Controls the generation of exception data packets and/or
the generation of SNMP Traps from xmservd. Note
that these types of packets and traps can only actually be
sent if xmservd is running. Because of this, exception
packets and SNMP traps are only generated as long as xmservd
is active. Traps can only be generated on AIX systems. The
conditions for generating exceptions and traps are controlled
by the threshold and frequency parameters. The
following values are valid for excp_type:
severity
Required to be positive and greater than zero if
exceptions are generated, otherwise specify as zero. Used to
assign a severity code to the exception for display by exmon.
trap_no
Required to be positive and greater than zero if SNMP
traps are generated, otherwise specify as zero. Used to
assign the trap number in the generated SNMP trap.
The SpmiAddSetHot subroutine returns a pointer to a structure of type SpmiHotVals if successful. If unsuccessful, the subroutine returns a NULL value.
The SpmiAddSetHot functions in a straight forward manner and as described above in all cases where the GrandParent context is a context that has only one level of instantiable contexts below it. This covers most context types such as CPU, Disk, LAN, etc. In a few cases, currently only the FS (file system) and RTime/ARM (application response) contexts, the Spmi works by creating pseudo-hotvals structures that effectively expand the hotset. These pseudo-hotvals structures are created either at the time the SpmiAddSetHot call is issued or when new subcontexts are created for a context that's already the GrandParent of a hotvals peer set. For example:
When a peer set is created for RTime/ARM, maybe only a few or no subcontexts of this context exists. If two applications were defined at this point, say checking and savings, one valsset would be created for the RTime/ARM context and a pseudo-valsset for each of RTime/ARM/checking and RTime/ARM/savings. As new applications are added to the RTime/ARM contexts, new pseudo-valssets are automatically added to the hotset.
Pseudo-valssets represent an implementation convenience and also helps minimize the impact of retrieving and presenting data for hotsets. As far as the caller of the RSiGetHotItem subroutine call is concerned, it is completely transparent. All this caller will ever see is the real hotvals structure. That is not the case for callers of SpmiFirstHot, SpmiNextHot, and SpmiNextHotItem. All of these subroutines will return pseudo-valssets and the calling program should be prepared to handle this.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
Creates an empty hotset.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiHotSet *SpmiCreateHotSet()
The SpmiCreateHotSet subroutine creates an empty hotset and returns a pointer to an SpmiHotSet structure.This structure provides the anchor point for a hotset and must exist before the SpmiAddSetHot subroutine can be successfully called.
The SpmiCreateHotSet subroutine returns a pointer to a structure of type SpmiHotSet if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiDelSetHot subroutine , SpmiFreeHotSet subroutine , SpmiAddSetHot subroutine .
Understanding SPMI Data Areas.
Creates an empty set of statistics.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStatSet *SpmiCreateStatSet()
The SpmiCreateStatSet subroutine creates an empty set of statistics and returns a pointer to an SpmiStatSet structure.
The SpmiStatSet structure provides the anchor point to a set of statistics and must exist before the SpmiPathAddSetStat subroutine can be successfully called.
The SpmiCreateStatSet subroutine returns a pointer to a structure of type SpmiStatSet if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiDelSetStat subroutine , SpmiFreeStatSet subroutine , SpmiPathAddSetStat subroutine .
Understanding SPMI Data Areas .
Adds a volatile context to the contexts defined by an application.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
char *SpmiDdsAddCx(Ix, Path, Descr, Asnno) ushort Ix; char *Path, *Descr; int Asnno;
The SpmiDdsAddCx subroutine uses the shared memory area to inform the SPMI that a context is available to be added to the context hierarchy, moves a copy of the context to shared memory, and allocates memory for the data area.
Ix
Specifies the element number of the added context in the
table of dynamic contexts. No context can be added if the
table of dynamic contexts has not been defined in the SpmiDdsInit subroutine call.
The first element of the table is element number 0.
Path
Specifies the full path name of the context to be added.
If the context is not at the top level, the parent context
must already exist.
Descr
Provides the description of the context to be added as it
will be presented to data consumers.
Asnno
Specifies the ASN.1 number to be assigned to the new
context. All subcontexts on the same level as the new context
must have unique ASN.1 numbers. Typically, each time the SpmiDdsAddCx subroutine adds a subcontext to the same
parent context, the Asnno parameter is incremented. See Making Dynamic Data-Supplier Statistics
Unique for more information about ASN.1 numbers.
If successful, the SpmiDdsAddCx subroutine returns the address of the shared memory data area. If an error occurs, an error text is placed in the external SpmiErrmsg character array, and the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiDdsDel subroutine , SpmiDdsInit subroutine .
Understanding SPMI Data Areas .
Deletes a volatile context.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiDdsDelCx(Area) char *Area;
The SpmiDdsDelCx subroutine informs the SPMI that a previously added, volatile context should be deleted.
If the SPMI has not detected that the context to delete was previously added dynamically, the SpmiDdsDelCx subroutine removes the context from the list of to-be-added contexts and returns the allocated shared memory to the free list. Otherwise, the SpmiDdsDelCx subroutine indicates to the SPMI that a context and its associated statistics must be removed from the context hierarchy and any allocated shared memory must be returned to the free list.
Area
Specifies the address of the previously allocated shared
memory data area as returned by an SpmiDdsAddCx
subroutine call.
If successful, the SpmiDdsDelCx subroutine returns a value of 0. If an error occurs, an error text is placed in the external SpmiErrmsg character array, and the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiDdsAddCx subroutine , SpmiDdsInit subroutine .
Understanding SPMI Data Areas.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
SpmiShare *SpmiDdsInit(CxTab, CxCnt, IxTab, IxCnt, FileName) cx_create *CxTab, *IxTab; int CxCnt, IxCnt; char *FileName;
The SpmiDdsInit subroutine establishes a program as a dynamic data-supplier (DDS) program. To do so, the SpmiDdsInit subroutine:
Note: The SpmiDdsInit subroutine issues an SpmiInit subroutine call if the application program has not issued one.
Note: If the calling program uses shared memory for other purposes, including memory mapping of files, the SpmiDdsInit or the SpmiInit subroutine call must be issued before access is established to other shared memory areas.
CxTab
Specifies a pointer to the table of nonvolatile contexts
to be added.
CxCnt
Specifies the number of elements in the table of
nonvolatile contexts. Use the CX_L macro to find this
value.
IxTab
Specifies a pointer to the table of volatile contexts the
program may want to add later. If no contexts are defined,
specify NULL.
IxCnt
Specifies the number of elements in the table of volatile
contexts. Use the CX_L macro to find this value. If no
contexts are defined, specify 0.
FileName
Specifies the fully qualified path and file name to use
when creating the shared memory segment. At execution time,
if the file exists, the process running the DDS must be able
to write to the file. Otherwise, the SpmiDdsInit
subroutine call does not succeed. If the file does not exist,
it is created. If the file cannot be created, the subroutine
returns an error. If the file name includes directories that
do not exist, the subroutine returns an error.
For non-AIX systems, a sixth argument is required to inform the SPMI how much memory to allocate in the DDS shared memory segment. This is not required for AIX systems because facilities exist to expand a memory allocation in shared memory. The sixth argument is:
size
Size in bytes of the shared memory area to allocate for
the DDS program. This parameter is of type int.
If successful, the SpmiDdsInit subroutine returns the address of the shared memory control area. If an error occurs, an error text is placed in the external SpmiErrmsg character array, and the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiExit subroutine , SpmiInit subroutine .
Understanding SPMI Data Areas .
Removes a single set of peer statistics from a hotset.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiDelSetHot(HotSet, HotVal) struct SpmiHotSet *HotSet; struct SpmiHotVals *HotVal;
The SpmiDelSetHot subroutine removes a single set of peer statistics, identified by the HotVal parameter, from a hotset, identified by the HotSet parameter.
HotSet
Specifies a pointer to a valid structure of type SpmiHotSet as created by the SpmiCreateHotSet
subroutine call.
HotVal
Specifies a pointer to a valid structure of type SpmiHotVals as created by the SpmiAddSetHot subroutine
call. You can not specify an SpmiHotVals that was
internally generated by the Spmi library code as described
under the GrandParent parameter to SpmiAddSetHot.
The SpmiDelSetHot subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateHotSet subroutine , SpmiFreeHotSet subroutine , SpmiAddSetHot subroutine .
Understanding SPMI Data Areas .
Removes a single statistic from a set of statistics.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiDelSetStat(StatSet, StatVal) struct SpmiStatSet *StatSet; struct SpmiStatVals *StatVal;
The SpmiDelSetStat subroutine removes a single statistic, identified by the StatVal parameter, from a set of statistics, identified by the StatSet parameter.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet
subroutine call.
StatVal
Specifies a pointer to a valid structure of type SpmiStatVals as created by
the SpmiPathAddSetStat
subroutine call.
The SpmiDelSetStat subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes rel="pagenum"> for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateStatSet subroutine , SpmiFreeStatSet subroutine , SpmiPathAddSetStat subroutine .
Understanding SPMI Data Areas .
Terminates a dynamic data supplier (DDS) or local data consumer program's association with the SPMI, and releases allocated memory.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
void SpmiExit()
A successful SpmiInit or SpmiDdsInit subroutine call allocates shared memory. Therefore, a Dynamic Data Supplier (DDS) program that has issued a successful SpmiInit or SpmiDdsInit subroutine call should issue an SpmiExit subroutine call before the program exits the SPMI. Allocated memory is not released until the program issues an SpmiExit subroutine call.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiInit subroutine , SpmiDdsInit subroutine .
Locates the first subcontext of a context.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiCxLink *SpmiFirstCx(CxHandle) SpmiCxHdl CxHandle;
The SpmiFirstCx subroutine locates the first subcontext of a context. The subroutine returns a NULL value if no subcontexts are found.
The structure pointed to by the returned pointer contains a handle to access the contents of the corresponding SpmiCx structure through the SpmiGetCx subroutine call.
CxHandle
Specifies a valid SpmiCxHdl
handle as obtained by another subroutine call.
The SpmiFirstCx subroutine returns a pointer to an SpmiCxLink structure if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiGetCx subroutine , SpmiNextCx subroutine .
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.
Locates the first of the sets of peer statistics belonging to a hotset.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiFirstHot(HotSet) struct SpmiHotSet HotSet;
The SpmiFirstHot subroutine locates the first of the SpmiHotVals structures belonging to the specified SpmiHotSet. Using the returned pointer, the SpmiHotSet can then either be decoded directly by the calling program, or it can be used to specify the starting point for a subsequent SpmiNextHotItem subroutine call. The SpmiFirstHot subroutine should only be executed after a successful call to the SpmiGetHotSet subroutine.
HotSet
Specifies a valid SpmiHotSet structure as obtained
by another subroutine call.
The SpmiFirstHot subroutine returns a pointer to a structure of type SpmiHotVals structure if successful. If unsuccessful, the subroutine returns a NULL value. A returned pointer may refer to a pseudo-hotvals structure as described in Programming Notes for the SpmiAddSetHot subroutine.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateHotSet subroutine , SpmiAddSetHot subroutine , SpmiNextHot subroutine , SpmiNextHotItem subroutine .
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.
Locates the first of the statistics belonging to a context.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStatLink *SpmiFirstStat(CxHandle) SpmiCxHdl CxHandle;
The SpmiFirstStat subroutine locates the first of the statistics belonging to a context. The subroutine returns a NULL value if no statistics are found.
The structure pointed to by the returned pointer contains a handle to access the contents of the corresponding SpmiStat structure through the SpmiGetStat subroutine call.
CxHandle
Specifies a valid SpmiCxHdl
handle as obtained by another subroutine call.
The SpmiFirstStat subroutine returns a pointer to a structure of type SpmiStatLink if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiGetStat subroutine , SpmiNextStat subroutine .
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy .
Returns a pointer to the first SpmiStatVals structure belonging to a set of statistics.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStatVals *SpmiFirstVals(StatSet) struct SpmiStatSet *StatSet;
The SpmiFirstVals subroutine returns a pointer to the first SpmiStatVals structure belonging to the set of statistics identified by the StatSet parameter. SpmiStatVals structures are accessed in reverse order so the last statistic added to the set of statistics is the first one returned. This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet
as created by the SpmiCreateStatSet subroutine call.
The SpmiFirstVals subroutine returns a pointer to an SpmiStatVals structure if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateStatSet subroutine , SpmiNextVals subroutine .
Understanding SPMI Data Areas .
Erases a hotset.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiFreeHotSet(HotSet) struct SpmiHotSet *HotSet;
The SpmiFreeHotSet subroutine erases the hotset identified by the HotSet parameter. All SpmiHotVals structures chained off the SpmiHotSet structure are deleted before the set itself is deleted.
HotSet
Specifies a pointer to a valid structure of type SpmiHotSet
as created by the SpmiCreateHotSet
subroutine call.
The SpmiFreeHotSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateHotSet subroutine , SpmiDelSetHot subroutine , SpmiAddSetHot subroutine .
Understanding SPMI Data Areas .
Erases a set of statistics.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiFreeStatSet(StatSet) struct SpmiStatSet *StatSet;
The SpmiFreeStatSet subroutine erases the set of statistics identified by the StatSet parameter. All SpmiStatVals structures chained off the SpmiStatSet structure are deleted before the set itself is deleted.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet
as created by the SpmiCreateStatSet
subroutine call.
The SpmiFreeStatSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateStatSet subroutine , SpmiDelSetStat subroutine , SpmiPathAddSetStat subroutine .
Understanding SPMI Data Areas .
Returns a pointer to the SpmiCx structure corresponding to a specified context handle.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiCx *SpmiGetCx(CxHandle) SpmiCxHdl CxHandle;
The SpmiGetCx subroutine returns a pointer to the SpmiCx structure corresponding to the context handle identified by the CxHandle parameter.
CxHandle
Specifies a valid SpmiCxHdl
handle as obtained by another subroutine call.
The SpmiGetCx subroutine returns a a pointer to an SpmiCx data structure if successful. If unsuccessful, the subroutine returns NULL.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiFirstCx subroutine , SpmiNextCx subroutine .
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.
Requests the SPMI to read the data values for all sets of peer statistics belonging to a specified SpmiHotSet.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiGetHotSet(HotSet, Force); struct SpmiHotSet *HotSet; boolean Force;
The SpmiGetHotSet subroutine requests the SPMI to read the data values for all peer sets of statistics belonging to the SpmiHotSet identified by the HotSet parameter. The Force parameter is used to force the data values to be refreshed from their source.
The Force parameter works by resetting a switch held internally in the SPMI for all SpmiStatVals and SpmiHotVals structures, regardless of the SpmiStatSets and SpmiHotSets to which they belong. Whenever the data value for a peer statistic is requested, this switch is checked. If the switch is set, the SPMI reads the latest data value from the original data source. If the switch is not set, the SPMI reads the data value stored in the SpmiHotVals structure. This mechanism allows a program to synchronize and minimize the number of times values are retrieved from the source. One method programs can use is to ensure the force request is not issued more than once per elapsed amount of time.
HotSet
Specifies a pointer to a valid structure of type SpmiHotSet as created by the SpmiCreateHotSet
subroutine call.
Force
If set to true, forces a refresh from the original source
before the SPMI reads the data values for the set. If set to
false, causes the SPMI to read the data values as they were
previously retrieved from the data source.
When the force argument is set true, the effect is that of marking all statistics known by the SPMI as obsolete, which causes the SPMI to refresh all requested statistics from kernel memory or other sources. As each statistic is refreshed, the obsolete mark is reset. Statistics that are not part of the HotSet specified in the subroutine call remain marked as obsolete. Therefore, if an application repetitively issues a series of SpmiGetHotSet and SpmiGetStatSet subroutine calls for multiple hotsets and statsets, each time, only the first such call need set the force argument to true.
The SpmiGetHotSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateHotSet subroutine , SpmiAddSetHot subroutine .
Data Access Structures and Handles, HotSets.
Returns a pointer to the SpmiStat structure corresponding to a specified statistic handle.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStat *SpmiGetStat(StatHandle) SpmiStatHdl StatHandle;
The SpmiGetStat subroutine returns a pointer to the SpmiStat structure corresponding to the statistic handle identified by the StatHandle parameter.
StatHandle
Specifies a valid SpmiStatHdl
handle as obtained by another subroutine call.
The SpmiGetStat subroutine returns a pointer to a structure of type SpmiStat if successful. If unsuccessful, the subroutine returns a NULL value.
The SpmiGetStat subroutine returns a pointer to a structure of type SpmiStat if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiFirstStat subroutine rel="pagenum">, SpmiNextStat subroutine .
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.
Requests the SPMI to read the data values for all statistics belonging to a specified set.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiGetStatSet(StatSet, Force); struct SpmiStatSet *StatSet; boolean Force;
The SpmiGetStatSet subroutine requests the SPMI to read the data values for all statistics belonging to the SpmiStatSet identified by the StatSet parameter. The Force parameter is used to force the data values to be refreshed from their source.
The Force parameter works by resetting a switch held internally in the SPMI for all SpmiStatVals and SpmiHotVals structures, regardless of the SpmiStatSets and SpmiHotSets to which they belong. Whenever the data value for a statistic is requested, this switch is checked. If the switch is set, the SPMI reads the latest data value from the original data source. If the switch is not set, the SPMI reads the data value stored for the SpmiStatVals structure. This mechanism allows a program to synchronize and minimize the number of times values are retrieved from the source. One method is to ensure the force request is not issued more than once per elapsed amount of time.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet
subroutine call.
Force
If set to true, forces a refresh from the original source
before the SPMI reads the data values for the set. If set to
false, causes the SPMI to read the data values as they were
previously retrieved from the data source.
When the force argument is set true, the effect is that of marking all statistics known by the SPMI as obsolete, which causes the SPMI to refresh all requested statistics from kernel memory or other sources. As each statistic is refreshed, the obsolete mark is reset. Statistics that are not part of the StatSet specified in the subroutine call remain marked as obsolete. Therefore, if an application repetitively issues the SpmiGetStatSet and SpmiGetHotSet subroutine calls for multiple statsets and hotsets, each time, only the first such call need set the force argument to true.
The SpmiGetStatSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateStatSet subroutine , SpmiPathAddSetStat subroutine .
Data Access Structures and Handles, StatSets.
Returns a decoded value based on the type of data value extracted from the data field of an SpmiStatVals structure.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
float SpmiGetValue(StatSet, StatVal) struct SpmiStatSet *StatSet; struct SpmiStatVals *StatVal;
The SpmiGetValue subroutine performs the following steps:
This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet
subroutine call.
StatVal
Specifies a pointer to a valid structure of type SpmiStatVals as created by the SpmiPathAddSetStat
subroutine call or returned by the SpmiFirstVals
or SpmiNextVals subroutine
calls.
The SpmiGetValue subroutine returns the decoded value if successful. If unsuccessful, the subroutine returns a negative value that has a numerical value of at least 1.1.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes rel="pagenum"> for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiGetStatSet subroutine , SpmiCreateStatSet subroutine , SpmiPathAddSetStat subroutine .
Data Access Structures and Handles, StatSets.
Understanding SPMI Data Areas .
Initializes the SPMI for a local data consumer program.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiInit (TimeOut) int TimeOut;
The SpmiInit subroutine initializes the SPMI. During SPMI initialization, a memory segment is allocated and the application program obtains basic addressability to that segment. An application program must issue the SpmiInit subroutine call before issuing any other subroutine calls to the SPMI.
Note: The SpmiInit subroutine is automatically issued by the SpmiDdsInit subroutine call. Successive SpmiInit subroutine calls are ignored.
Note: If the calling program uses shared memory for other purposes, including memory mapping of files, the SpmiInit subroutine call must be issued before access is established to other shared memory areas.
The SPMI entry point called by the SpmiInit subroutine assigns a segment register to be used by the SPMI subroutines (and the application program) for accessing common shared memory and establishes the access mode to the common shared memory segment. After SPMI initialization, the SPMI subroutines are able to access the common shared memory segment in read-only mode.
TimeOut
Specifies the number of seconds the SPMI waits for a
Dynamic Data Supplier (DDS) program to update its shared
memory segment. If a DDS program does not update its shared
memory segment in the time specified, the SPMI assumes that
the DDS program has terminated or disconnected from shared
memory and removes all contexts and statistics added by the
DDS program.
The SPMI saves the largest TimeOut value received from the programs that invoke the SPMI. The TimeOut value must be zero or must be greater than or equal to 15 seconds and less than or equal to 600 seconds. A value of zero overrides any other value from any other program that invokes the Spmi and disables the checking for terminated DDS programs.
The SpmiInit subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value. If a nonzero value is returned, the application program should not attempt to issue additional SPMI subroutine calls.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiDdsInit subroutine , SpmiExit subroutine .
Explicitly instantiates the subcontexts of an instantiable context.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
int SpmiInstantiate(CxHandle) SpmiCxHdl CxHandle;
The SpmiInstantiate subroutine explicitly instantiates the subcontexts of an instantiable context. If the context is not instantiable, do not call the SpmiInstantiate subroutine.
An instantiation is done implicitly by the SpmiPathGetCx and SpmiFirstCx subroutine calls. Therefore, application programs usually do not need to instantiate explicitly.
CxHandle
Specifies a valid context handle (SpmiCxHdl)
as obtained by another subroutine call.
The SpmiInstantiate subroutine returns a value of 0 if successful. If the context is not instantiable, the subroutine returns a nonzero value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiFirstCx subroutine , SpmiPathGetCx subroutine .
Understanding the SPMI Data Hierarchy.
Locates the next subcontext of a context.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiCxLink *SpmiNextCx(CxLink) struct SpmiCxLink *CxLink;
The SpmiNextCx subroutine locates the next subcontext of a context, taking the context identified by the CxLink parameter as the current subcontext. The subroutine returns a NULL value if no further subcontexts are found.
The structure pointed to by the returned pointer contains an SpmiCxHdl handle to access the contents of the corresponding SpmiCx structure through the SpmiGetCx subroutine call.
CxLink
Specifies a pointer to a valid SpmiCxLink
structure as obtained by a previous SpmiFirstCx
subroutine call.
The SpmiNextCx subroutine returns a pointer to a structure of type SpmiCxLink if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiFirstCx subroutine , SpmiGetCx subroutine .
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.
Locates the next set of peer statistics (SpmiHotVals structure) belonging to an SpmiHotSet.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiNextHot(HotSet, HotVals) struct SpmiHotSet *HotSet; struct SpmiHotVals *HotVals;
The SpmiNextHot subroutine locates the next SpmiHotVals structure belonging to an SpmiHotSet, taking the set of peer statistics identified by the HotVals parameter as the current one. The subroutine returns a NULL value if no further SpmiHotVals structures are found. The SpmiNextHot subroutine should only be executed after a successful call to the SpmiGetHotSet subroutine and (usually, but not necessarily) a call to the SpmiFirstHot subroutine and one or more subsequent calls to SpmiNextHot.
The subroutine allows the application programmer to position at the next set of peer statistics in preparation for using the SpmiNextHotItem subroutine call to traverse this peer set's array of SpmiHotItems elements. Use of this subroutine is only necessary if it is desired to skip over some SpmiHotVals structores in an SpmiHotSet. Under most circumstances, the SpmiNextHotItem will be the sole means of accessing all elements of the SpmiHotItems arrays of all peer sets belonging to an SpmiHotSet.
HotSet
Specifies a valid pointer to an SpmiHotSet
structure as obtained by a previous SpmiCreateHotSet
subroutine call.
HotVals
Specifies a pointer to an SpmiHotVals
structure as returned by a previous SpmiFirstHot or
SpmiNextHot
subroutine call or as returned by an SpmiAddSetHot subroutine call.
The SpmiNextHot subroutine returns a pointer to the next SpmiHotVals structure within the hotset. If no more SpmiHotVals structures are available, the subroutine returns a NULL value. A returned pointer may refer to a pseudo-hotvals structure as described in Programming Notes for the SpmiAddSetHot subroutine.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiFirstHot subroutine , SpmiGetHotSet subroutine , SpmiNextHotItem subroutine .
Data Access Structures and Handles, HotSets.
Locates and decodes the next SpmiHotItems element at the current position in an SpmiHotSet.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiNextHotItem(HotSet, HotVals, index, value, name) struct SpmiHotSet *HotSet; struct SpmiHotVals *HotVals; int *index; float *value; char **name;
The SpmiNextHotItem subroutine locates the next SpmiHotItems structure belonging to an SpmiHotSet, taking the element identified by the HotVals and index parameters as the current one. The subroutine returns a NULL value if no further SpmiHotItems structures are found. The SpmiNextHotItem subroutine should only be executed after a successful call to the SpmiGetHotSet subroutine.
The SpmiNextHotItem subroutine is designed to be used for walking all SpmiHotItems elements returned by a call to the SpmiGetHotSet subroutine, visiting the SpmiHotVals structures one by one. By feeding the returned value and the updated integer pointed to by index back to the next call, this can be done in a tight loop. Succesful calls to SpmiNextHotItem will decode each SpmiHotItems element and return the data value in value and the name of the peer context that owns the corresponding statistic in name.
HotSet
Specifies a valid pointer to an SpmiHotSet
structure as obtained by a previous SpmiCreateHotSet
subroutine call.
HotVals
Specifies a pointer to an SpmiHotVals
structure as returned by a previousSpmiNextHotItem,
SpmiFirstHot,
or SpmiNextHot subroutine call or as returned by an SpmiAddSetHot subroutine
call. If this parameter is specified as NULL, the first SpmiHotVals
structure of the SpmiHotSet is used and the index
parameter is assumed to be set to zero, regardless of its
actual value.
index
A pointer to an integer that contains the desired element
number in the SpmiHotItems array of the SpmiHotVals
structure specified by HotVals. A value of zero
points to the first element. When the SpmiNextHotItem
subroutine returns, the integer contain the index of the next
SpmiHotItems element within the returned SpmiHotVals
structure. If the last element of the array is decoded, the
value in the integer will point beyond the end of the array,
and the SpmiHotVals pointer returned will point to the
peer set, which has now been completely decoded. By passing
the returned SpmiHotVals pointer and the index
parameter to the next call to SpmiNextHotItem, the
subroutine will detect this and proceed to the first SpmiHotItems
element of the next SpmiHotVals structure if one
exists.
value
A pointer to a float variable. A successful call will
return the decoded data value for the statistic. Before the
value is returned, the SpmiNextHotItem function:
name
A pointer to a character pointer. A successful call will
return a pointer to the name of the peer context for which
the data value was read.
The SpmiNextHotItem subroutine returns a pointer to the current SpmiHotVals structure within the hotset. If no more SpmiHotVals structures are available, the subroutine returns a NULL value. The structure returned contains the data, such as threshold, which may be relevant for presentation of the results of an SpmiGetHotSet subroutine call to end-users. A returned pointer may refer to a pseudo-hotvals structure as described in Programming Notes for the SpmiAddSetHot subroutine.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiFirstHot subroutine , SpmiNextHot subroutine , SpmiGetHotSet subroutine .
Data Access Structures and Handles, HotSets.
Locates the next statistic belonging to a context.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStatLink *SpmiNextStat(StatLink) struct SpmiStatLink *StatLink;
The SpmiNextStat subroutine locates the next statistic belonging to a context, taking the statistic identified by the StatLink parameter as the current statistic. The subroutine returns a NULL value if no further statistics are found.
The structure pointed to by the returned pointer contains an SpmiStatHdl handle to access the contents of the corresponding SpmiStat structure through the SpmiGetStat subroutine call.
StatLink
Specifies a valid pointer to a SpmiStatLink
structure as obtained by a previous SpmiFirstStat
subroutine call.
The SpmiNextStat subroutine returns a pointer to a structure of type SpmiStatLink if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiFirstStat subroutine , SpmiGetStat subroutine .
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.
Returns a pointer to the next SpmiStatVals structure in a set of statistics.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStatVals *SpmiNextVals(StatSet, StatVal) struct SpmiStatSet *StatSet; struct SpmiStatVals *StatVal;
The SpmiNextVals subroutine returns a pointer to the next SpmiStatVals structure in a set of statistics, taking the structure identified by the StatVal parameter as the current structure. The SpmiStatVals structures are accessed in reverse order so the statistic added before the current one is returned. This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet
subroutine call.
StatVal
Specifies a pointer to a valid structure of type SpmiStatVals as created by the SpmiPathAddSetStat subroutine
call or returned by a previous SpmiFirstVals
or SpmiNextVals subroutine
call.
The SpmiNextVals subroutine returns a pointer to a SpmiStatVals structure if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiCreateStatSet subroutine , SpmiFirstVals subroutine , SpmiPathAddSetStat subroutine .
Data Access Structures and Handles, StatSets.
Returns either the first SpmiStatVals structure in a set of statistics or the next SpmiStatVals structure in a set of statistics and a decoded value based on the type of data value extracted from the data field of an SpmiStatVals structure.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStatVals*SpmiNextValue(StatSet, StatVal, value) struct SpmiStatSet *StatSet; struct SpmiStatVals *StatVal; float *value;
Instead of issuing subroutine calls to SpmiFirstVals/SpmiNextVals (to get the first or next SpmiStatVals structure) followed by calls to SpmiGetValue (to get the decoded value from the SpmiStatVals structure), the SpmiNextValue subroutine returns both in one call. This subroutine call returns a pointer to the first SpmiStatVals structure belonging to the StatSet parameter if the StatVal parameter is NULL. If the StatVal partameter is not NULL, the next SpmiStatVals structure is returned, taking the structure identified by the StatVal parameter as the current structure. The data value corresponding to the returned SpmiStatVals structure is decoded and returned in the field pointed to by the value argument. In decoding the data value, the subroutine does the following:
Note: This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet
subroutine call.
StatVal
Specifies either a NULL pointer or a pointer to a valid
structure of type SpmiStatVals as created by the SpmiPathAddSetStat
subroutine call or returned by a previous SpmiNextValue
subroutine call. If StatVal is NULL, then the first
SpmiStatVals
pointer belonging to the set of statistics pointed to by StatSet
is returned.
value
A pointer used to return a decoded value based on the
type of data value extracted from the data field of the
returned SpmiStatVals structure.
The SpmiNextValue subroutine returns a pointer to a SpmiStatVals structure if successful. If unsuccessful, the subroutine returns a NULL value.
If the StatVal parameter is:
NULL
The first SpmiStatVals structure belonging to
the StatSet parameter is returned.
not NULL
The next SpmiStatVals structure after the
structure identified by the StatVal parameter is
returned and the value parameter is used to return a
decoded value based on the type of data value extracted
from the data field of the returned SpmiStatVals
structure.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
The SpmiNextValue subroutine maintains internal state information so that retrieval of the next data value from a statset can be done without traversing linked lists of data structures. The stats information is kept separate for each process, but is shared by all threads of a process.
If the subroutine is accessed from multiple threads, the state information is useless and the performance advantage is lost. The same is true if the program is simultaneously accessing two or more statsets. To benefit from the performance advantage of the SpmiNextValue subroutine, a program should retrieve all values in order from one stat set before retrieving values from the next statset.
The implementation of the subroutine allows a program to retrieve data values beginning at any point in the statset if the SpmiStatVals pointer is known. Doing so will cause a linked list traversal. If subsequent invocations of SpmiNextValue uses the value returned from the first and following invocation as their second argument, the traversal of the link list can be avoided.
It should be noted that the value returned by a successful SpmiNextValue invocation is always the pointer to the SpmiStatVals structure whose data value is decoded and returned in the value argument.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiGetStatSet subroutine , SpmiCreateStatSet subroutine , SpmiPathAddSetStat subroutine .
Data Access Structures and Handles, StatSets.
Adds a statistics value to a set of statistics.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
struct SpmiStatVals *SpmiPathAddSetStat(StatSet, StatName, Parent) struct SpmiStatSet *StatSet; char *StatName; SpmiCxHdl Parent;
The SpmiPathAddSetStat subroutine adds a statistics value to a set of statistics. The SpmiStatSet structure that provides the anchor point to the set must exist before the SpmiPathAddSetStat subroutine call can succeed.
StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet
subroutine call.
StatName
Specifies the name of the statistic within the context
identified by the Parent parameter.If the Parent
parameter is NULL, you must specify the fully qualified path
name of the statistic in the StatName parameter.
Parent
Specifies either a valid SpmiCxHdl
handle as obtained by another subroutine call or a NULL
value.
The SpmiPathAddSetStat subroutine returns a pointer to a structure of type SpmiStatVals if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
The SpmiGetStatSet subroutine , SpmiCreateStatSet subroutine , SpmiDelSetStat subroutine , SpmiFreeStatSet subroutine .
Data Access Structures and Handles, StatSets.
Returns a handle to use when referencing a context.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
SpmiCxHdl SpmiPathGetCx(CxPath, Parent) char *CxPath; SpmiCxHdl Parent;
The SpmiPathGetCx subroutine searches the context hierarchy for a given path name of a context and returns a handle to use when subsequently referencing the context.
CxPath
Specifies the path name of the context to find. If you
specify the fully qualified path name in the CxPath
parameter, you must set the Parent parameter to NULL.
If the path name is not qualified or is only partly qualified
(that is, if it does not include the names of all contexts
higher in the data hierarchy), the SpmiPathGetCx
subroutine begins searching the hierarchy at the context
identified by the Parent parameter. If the CxPath
parameter is either NULL or an empty string, the subroutine
returns a handle identifying the Top context.
Parent
Specifies the anchor context that fully qualifies the CxPath
parameter. If you specify a fully qualified path name in the CxPath
parameter, you must set the Parent parameter to NULL.
The SpmiPathGetCx subroutine returns a handle to a context if successful. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.
Returns the full path name of a statistic.
SPMI Library (libSpmi.a)
#include <sys/Spmidef.h>
char *SpmiStatGetPath(Parent, StatHandle, MaxLevels) SpmiCxHdl Parent; SpmiStatHdl StatHandle; int MaxLevels;
The SpmiStatGetPath subroutine returns the full path name of a statistic, given a parent context SpmiCxHdl handle and a statistics SpmiStatHdl handle. The MaxLevels parameter can limit the number of levels in the hierarchy that must be searched to generate the path name of the statistic.
The memory area pointed to by the returned pointer is freed when the SpmiStatGetPath subroutine call is repeated. For each invocation of the subroutine, a new memory area is allocated and its address returned.If the calling program needs the returned character string after issuing the SpmiStatGetPath subroutine call, the program must copy the returned string to locally allocated memory before reissuing the subroutine call.
Parent
Specifies a valid SpmiCxHdl handle as obtained by
another subroutine call.
StatHandle
Specifies a valid SpmiStatHdl handle as obtained
by another subroutine call. This handle must point to a
statistic belonging to the context identified by the Parent
parameter.
MaxLevels
Limits the number of levels in the hierarchy that must be
searched to generate the path name. If this parameter is set
to 0, no limit is imposed.
If successful, the SpmiStatGetPath subroutine returns a pointer to a character array containing the full path name of the statistic. If unsuccessful, the subroutine returns a NULL value.
All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:
If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.
This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.
/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and
macros that an application program can use to access the
SPMI.
Understanding SPMI Data Areas .
Understanding the SPMI Data Hierarchy.