Document revision date: 19 July 1999 | |
Previous | Contents | Index |
The process information procedures return information about processes by using the process identification (PID) or the process name. The PID is a 32-bit number that is unique for each process in the cluster. Specify the PID by using the pidadr argument. All the significant digits of a PID must be specified; only leading zeros can be omitted.
With kernel threads, the PID continues to identify a process, but it
can also identify a kernel thread within that process. In a
multithreaded process each kernel thread has its own PID that is based
on the initial threads PID.
3.2.2 Using the Process Name to Obtain Information
To obtain information about a process using the process name, specify the prcnam argument. Although a PID is unique for each process in the cluster, a process name is unique (within a UIC group) only for each process on a node. To locate information about processes on the local node, specify a process name string of 1 to 15 characters. To locate information about a process on a particular node, specify the full process name, which can be up to 23 characters long. The full process name is configured in the following way:
Note that a local process name can look like a remote process name. Therefore, if you specify ATHENS::SMITH, the system checks for a process named ATHENS::SMITH on the local node before checking node ATHENS for a process named SMITH.
OpenVMS Programming Interfaces: Calling a System Routine and the OpenVMS System Services Reference Manual describe these routines completely, listing all items of information that you can request. LIB$GETJPI, SYS$GETJPI, and SYS$GETJPIW share the same item codes with the following exception: LIB$K_ items can be accessed only by LIB$GETJPI.
In the following example, the string argument rather than the numeric argument is specified, causing LIB$GETJPI to return the UIC of the current process as a string:
! Define request codes INCLUDE '($JPIDEF)' ! Variables for LIB$GETJPI CHARACTER*9 UIC INTEGER LEN STATUS = LIB$GETJPI (JPI$_UIC, 2 ,,, 2 UIC, 2 LEN) |
To specify a list of items for SYS$GETJPI or SYS$GETJPI(W) (even if that list contains only one item), use a record structure. Example 3-1 uses SYS$GETJPI(W) to request the process name and user name associated with the process whose process identification number is in SUBPROCESS_PID.
Example 3-1 Obtaining Different Types of Process Information |
---|
. . . ! PID of subprocess INTEGER SUBPROCESS_PID ! Include the request codes INCLUDE '($JPIDEF)' ! Define itmlst structure STRUCTURE /ITMLST/ UNION MAP INTEGER*2 BUFLEN INTEGER*2 CODE INTEGER*4 BUFADR INTEGER*4 RETLENADR END MAP MAP INTEGER*4 END_LIST END MAP END UNION END STRUCTURE ! Declare GETJPI itmlst RECORD /ITMLST/ JPI_LIST(3) ! Declare buffers for information CHARACTER*15 PROCESS_NAME CHARACTER*12 USER_NAME INTEGER*4 PNAME_LEN, 2 UNAME_LEN ! Declare I/O status structure STRUCTURE /IOSB/ INTEGER*2 STATUS, 2 COUNT INTEGER*4 %FILL END STRUCTURE ! Declare I/O status variable RECORD /IOSB/ JPISTAT ! Declare status and routine INTEGER*4 STATUS, 2 SYS$GETJPIW . . ! Define SUBPROCESS_PID . ! Set up itmlst JPI_LIST(1).BUFLEN = 15 JPI_LIST(1).CODE = JPI$_PRCNAM JPI_LIST(1).BUFADR = %LOC(PROCESS_NAME) JPI_LIST(1).RETLENADR = %LOC(PNAME_LEN) JPI_LIST(2).BUFLEN = 12 JPI_LIST(2).CODE = JPI$_USERNAME JPI_LIST(2).BUFADR = %LOC(USER_NAME) JPI_LIST(2).RETLENADR = %LOC(UNAME_LEN) JPI_LIST(3).END_LIST = 0 ! Request information and wait for it STATUS = SYS$GETJPIW (, 2 SUBPROCESS_PID, 2 , 2 JPI_LIST, 2 JPISTAT, 2 ,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Check final return status IF (.NOT. JPISTAT.STATUS) THEN CALL LIB$SIGNAL (%VAL(JPISTAT.STATUS)) END IF . . . |
SYS$GETJPI uses the PID or the process name to obtain information about
one process and the -1 wildcard as the pidadr to
obtain information about all processes on the local system. If a PID or
process name is not specified, SYS$GETJPI returns information about the
calling process. SYS$GETJPI cannot perform a selective search---it can
search for only one process at a time in the cluster or for all
processes on the local system. If you want to perform a selective
search for information or get information about processes across the
cluster, use SYS$GETJPI with SYS$PROCESS_SCAN.
3.2.3.1 Requesting Information About a Single Process
Example 3-2 is a Fortran program that displays the process name and the PID of the calling program. If you want to get the same information about each process on the system, specify the initial process identification argument as -1 when you invoke LIB$GETJPI or SYS$GETJPI(W). Call the GETJPI routine (whichever you choose) repeatedly until it returns a status of SS$_NOMOREPROC, indicating that all processes on the system have been examined.
Example 3-2 Using SYS$GETJPI to Obtain Calling Process Information |
---|
! No process name or PID is specified; $GETJPI returns data on the ! calling process. PROGRAM CALLING_PROCESS IMPLICIT NONE ! Implicit none INCLUDE '($jpidef) /nolist' ! Definitions for $GETJPI INCLUDE '($ssdef) /nolist' ! System status codes STRUCTURE /JPIITMLST/ ! Structure declaration for UNION ! $GETJPI item lists MAP INTEGER*2 BUFLEN, 2 CODE INTEGER*4 BUFADR, 2 RETLENADR END MAP MAP ! A longword of 0 terminates INTEGER*4 END_LIST ! an item list END MAP END UNION END STRUCTURE RECORD /JPIITMLST/ ! Declare the item list for 2 JPILIST(3) ! $GETJPI INTEGER*4 SYS$GETJPIW ! System service entry points INTEGER*4 STATUS, ! Status variable 2 PID ! PID from $GETJPI INTEGER*2 IOSB(4) ! I/O Status Block for $GETJPI CHARACTER*16 2 PRCNAM ! Process name from $GETJPI INTEGER*2 PRCNAM_LEN ! Process name length ! Initialize $GETJPI item list JPILIST(1).BUFLEN = 4 JPILIST(1).CODE = JPI$_PID JPILIST(1).BUFADR = %LOC(PID) JPILIST(1).RETLENADR = 0 JPILIST(2).BUFLEN = LEN(PRCNAM) JPILIST(2).CODE = JPI$_PRCNAM JPILIST(2).BUFADR = %LOC(PRCNAM) JPILIST(2).RETLENADR = %LOC(PRCNAM_LEN) JPILIST(3).END_LIST = 0 ! Call $GETJPI to get data for this process STATUS = SYS$GETJPIW ( 2 , ! No event flag 2 , ! No PID 2 , ! No process name 2 JPILIST, ! Item list 2 IOSB, ! Always use IOSB with $GETJPI! 2 , ! No AST 2 ) ! No AST arg ! Check the status in both STATUS and the IOSB, if ! STATUS is OK then copy IOSB(1) to STATUS IF (STATUS) STATUS = IOSB(1) ! If $GETJPI worked, display the process, if done then ! prepare to exit, otherwise signal an error IF (STATUS) THEN TYPE 1010, PID, PRCNAM(1:PRCNAM_LEN) 1010 FORMAT (' ',Z8.8,' ',A) ELSE CALL LIB$SIGNAL(%VAL(STATUS)) END IF END |
Example 3-3 creates the file PROCNAME.RPT that lists, using LIB$GETJPI, the process name of each process on the system. If the process running this program does not have the privilege necessary to access a particular process, the program writes the words NO PRIVILEGE in place of the process name. If a process is suspended, LIB$GETJPI cannot access it and the program writes the word SUSPENDED in place of the process name. Note that, in either of these cases, the program changes the error value in STATUS to a success value so that the loop calling LIB$GETJPI continues to execute.
Example 3-3 Obtaining the Process Name |
---|
. . . ! Status variable and error codes INTEGER STATUS, 2 STATUS_OK, 2 LIB$GET_LUN, 2 LIB$GETJPI INCLUDE '($SSDEF)' PARAMETER (STATUS_OK = 1) ! Logical unit number and file name INTEGER*4 LUN CHARACTER*(*) FILE_NAME PARAMETER (FILE_NAME = 'PROCNAME.RPT') ! Define item codes for LIB$GETJPI INCLUDE '($JPIDEF)' ! Process name CHARACTER*15 NAME INTEGER LEN ! Process identification INTEGER PID /-1/ . . . ! Get logical unit number and open the file STATUS = LIB$GET_LUN (LUN) OPEN (UNIT = LUN, 2 FILE = 'PROCNAME.RPT', 2 STATUS = 'NEW') ! Get information and write it to file DO WHILE (STATUS) STATUS = LIB$GETJPI(JPI$_PRCNAM, 2 PID, 2 ,, 2 NAME, 2 LEN) ! Extra space in WRITE commands is for ! FORTRAN carriage control IF (STATUS) THEN WRITE (UNIT = LUN, 2 FMT = '(2A)') ' ', NAME(1:LEN) STATUS = STATUS_OK ELSE IF (STATUS .EQ. SS$_NOPRIV) THEN WRITE (UNIT = LUN, 2 FMT = '(2A)') ' ', 'NO PRIVILEGE' STATUS = STATUS_OK ELSE IF (STATUS .EQ. SS$_SUSPENDED) THEN WRITE (UNIT = LUN, 2 FMT = '(2A)') ' ', 'SUSPENDED' STATUS = STATUS_OK END IF END DO ! Close file IF (STATUS .EQ. SS$_NOMOREPROC) 2 CLOSE (UNIT = LUN) . . . |
Example 3-4 demonstrates how to use the process name to obtain information about a process.
Example 3-4 Using SYS$GETJPI and the Process Name to Obtain Information About a Process |
---|
! To find information for a particular process by name, ! substitute this code, which includes a process name, ! to call $GETJPI in Example 3-2 ! Call $GETJPI to get data for a named process STATUS = SYS$GETJPIW ( 2 , ! No event flag 2 , ! No PID 2 'SMITH_1', ! Process name 2 JPILIST, ! Item list 2 IOSB, ! Always use IOSB with $GETJPI! 2 , ! No AST 2 ) ! No AST arg |
You can use SYS$GETJPI to perform a wildcard search on all processes on the local system. When the initial pidadr argument is specified as -1 , SYS$GETJPI returns requested information for each process that the program has privilege to access. The requested information is returned for one process per call to SYS$GETJPI.
To perform a wildcard search, call SYS$GETJPI in a loop, testing the return status.
When performing wildcard searches, SYS$GETJPI returns an error status for processes that are inaccessible. When a program that uses a -1 wildcard checks the status value returned by SYS$GETJPI, it should test for the following status codes:
Status | Explanation |
---|---|
SS$_NOMOREPROC | All processes have been returned. |
SS$_NOPRIV | The caller lacks sufficient privilege to examine a process. |
SS$_SUSPENDED | The target process is being deleted or is suspended and cannot return the information. |
Example 3-5 is a C program that demonstrates how to use the SYS$GETJPI -1 wildcard to search for all processes on the local system.
Example 3-5 Using SYS$GETJPI to Request Information About All Processes on the Local System |
---|
#include <stdio.h> #include <jpidef.h> #include <stdlib.h> #include <ssdef.h> /* Item descriptor */ struct { unsigned short buflen, item_code; void *bufaddr; void *retlenaddr; unsigned int terminator; }itm_lst; /* I/O Status Block */ struct { unsigned short iostat; unsigned short iolen; unsigned int device_info; }iosb; main() { unsigned short len; unsigned int efn=1,pidadr = -1,status, usersize; char username[12]; /* Initialize the item list */ itm_lst.buflen = 12; itm_lst.item_code = JPI$_USERNAME; itm_lst.bufaddr = username; itm_lst.retlenaddr = &usersize; itm_lst.terminator = 0; do{ status = SYS$GETJPIW(0, /* no event flag */ &pidadr, /* process id */ 0, /* process name */ &itm_lst, /* item list */ &iosb, /* I/O status block */ 0, /* astadr (AST routine) */ 0); /* astprm (AST parameter) */ switch(status) { case SS$_NOPRIV: printf("\nError: No privileges for attempted operation"); break; case SS$_SUSPENDED: printf("\nError: Process is suspended"); break; case SS$_NORMAL: if (iosb.iostat == SS$_NORMAL) printf("\nUsername: %s",username); else printf("\nIOSB condition value %d returned",iosb.iostat); } }while(status != SS$_NOMOREPROC); } |
Using the SYS$PROCESS_SCAN system service greatly enhances the power of SYS$GETJPI. With this combination, you can search for selected groups of processes or kernel threads on the local system as well as for processes or kernel threads on remote nodes or across the cluster. When you use SYS$GETJPI alone, you specify the pidadr or the prcnam argument to locate information about one process. When you use SYS$GETJPI with SYS$PROCESS_SCAN, the pidctx argument generated by SYS$PROCESS_SCAN is used as the pidadr argument to SYS$GETJPI. This context allows SYS$GETJPI to use the selection criteria that are set up in the call to SYS$PROCESS_SCAN.
When using SYS$GETJPI with a PRCNAM specified, SYS$GETJPI returns data for only the initial thread. This parallels the behavior of the DCL commands SHOW SYSTEM, SHOW PROCESS, and MONITOR PROCESS. If a valid PIDADR is specified, then the data returned describes only that specific kernel thread. If a PIDADR of zero is specified, then the data returned describes the calling kernel thread.
SYS$GETJPI has the flag, JPI$_THREAD, as part of the JPI$_GETJPI_CONTROL_FLAGS item code. The JPI$_THREAD flag designates that the service call is requesting data for all of the kernel threads in a multithreaded process. If the call is made with JPI$_THREAD set, then SYS$GETJPI begins with the initial thread, and SYS$GETJPI returns SS$_NORMAL. Subsequent calls to SYS$GETJPI with JPI$_THREAD specified returns data for the next thread until there are no more threads, at which time the service returns SS$_NOMORETHREAD.
If you specify a wildcard PIDADR -1 along with JPI$_THREAD, you cause SYS$GETJPI to return information for all threads for all processes on the system on subsequent calls. SYS$GETJPI returns the status SS$_NORMAL until there are no more processes, at which time it returns SS$_NOMOREPROC. If you specify a wildcard search, you must request either the JPI$_PROC_INDEX or the JPI$_INITIAL_THREAD_PID item code to distinguish the transition from the last thread of a multithreaded process to the next process. The PROC_INDEX and the INITIAL_THREAD_PID are different for each process on the system.
Table 3-3 shows four item codes of SYS$GETJPI that provide kernel threads information.
Item Code | Meaning |
---|---|
JPI$_INITIAL_THREAD_PID | Returns the PID of the initial thread for the target process. |
JPI$_KT_COUNT | Returns the current count of kernel threads for the target process. |
JPI$_MULTITHREAD | Returns the maximum kernel thread count allowed for the target process. |
JPI$_THREAD_INDEX | Returns the kernel thread index for the target thread or process. |
This wildcard search is initiated by invoking SYS$GETJPI with a -1 specified for the PID, and is available only on the local node. With kernel threads, a search for all threads in a single process is available, both on the local node and on another node on the cluster.
In a dual architecture or mixed-version cluster, one or more nodes in the cluster may not support kernel threads. To indicate this condition, a threads capability bit (CSB$M_CAP_THREADS) exists in the CSB$L_CAPABILITY cell in the cluster status block. If this bit is set for a node, it indicates that the node supports kernel threads. This information is passed around as part of the normal cluster management activity when a node is added to a cluster. If a SYS$GETJPI request that requires threads support needs to be passed to another node in the cluster, a check is made on whether the node supports kernel threads before the request is sent to that node. If the node supports kernel threads, the request is sent. If the node does not support kernel threads, the status SS$_INCOMPAT is returned to the caller, and the request is not sent to the other node.
You can use SYS$PROCESS_SCAN only with SYS$GETJPI; you cannot use it alone. The process context generated by SYS$PROCESS_SCAN is used like the -1 wildcard except that it is initialized by calling the SYS$PROCESS_SCAN service instead of by a simple assignment statement. However, the SYS$PROCESS_SCAN context is more powerful and more flexible than the -1 wildcard. SYS$PROCESS_SCAN uses an item list to specify selection criteria to be used in a search for processes and produces a context longword that describes a selective search for SYS$GETJPI.
Using SYS$GETJPI with SYS$PROCESS_SCAN to perform a selective search is a more efficient way to locate information because only information about the processes you have selected is returned. For example, you can specify a search for processes owned by one user name, and SYS$GETJPI returns only the processes that match the specified user name. You can specify a search for all batch processes, and SYS$GETJPI returns only information about processes running as batch jobs. You can specify a search for all batch processes owned by one user name and SYS$GETJPI returns only information about processes owned by that user name that are running as batch jobs.
By default, SYS$PROCESS_SCAN sets up a context for only the initial thread of a multithreaded process. However, if the value PSCAN$_THREAD is specified for the item code PSCAN$_PSCAN_CONTOL_FLAGS, then threads are included in the scan. The PSCAN$_THREAD flag takes precedence over the JPI$_THREAD flag in the SYS$GETJPI call. With PSCAN$_THREAD specified, threads are included in the entire scan. With PSCAN$_THREAD not specified, threads are included in the scan for a specific SYS$GETJPI call only if JPI$_THREAD is specified.
Table 3-4 shows two item codes of SYS$PROCESS_SCAN that provide kernel thread information.
Item Code | Meaning |
---|---|
PSCAN$_KT_COUNT | Uses the current count of kernel threads for the process as a selection criteria. The valid item-specific flags for this item code are EQL, GEQ, GTR, LEQ, LSS, NEQ, and OR. |
PSCAN$_MULTITHREAD | Uses the maximum count of kernel threads for the process as a selection criteria. The valid item-specific flags for this item code are EQL, GEQ, GTR, LEQ, LSS, NEQ, and OR. |
SYS$PROCESS_SCAN uses an item list to specify the selection criteria for the SYS$GETJPI search.
Each entry in the SYS$PROCESS_SCAN item list contains the following:
Item-specific flags enable you to control selection information. For example, you can use flags to select only those processes that have attribute values that correspond to the value in the item list, as shown in Table 3-5.
Item-Specific Flag | Description |
---|---|
PSCAN$M_OR | Match this value or the next value. |
PSCAN$M_EQL | Match value exactly (the default). |
PSCAN$M_NEQ | Match if value is not equal. |
PSCAN$M_GEQ | Match if value is greater than or equal to. |
PSCAN$M_GTR | Match if value is greater than. |
PSCAN$M_LEQ | Match if value is less than or equal to. |
PSCAN$M_LSS | Match if value is less than. |
PSCAN$M_CASE_BLIND | Match without regard to case of letters. |
PSCAN$M_PREFIX_MATCH | Match on the leading substring. |
PSCAN$M_WILDCARD | Match string is a wildcard pattern. |
The PSCAN$M_OR flag is used to connect entries in an item list. For example, in a program that searches for processes owned by several specified users, each user name must be specified in a separate item list entry. The item list entries are connected with the PSCAN$M_OR flag as shown in the following Fortran example. This example connects all the processes on the local node that belong to SMITH, JONES, or JOHNSON.
PSCANLIST(1).BUFLEN = LEN('SMITH') PSCANLIST(1).CODE = PSCAN$_USERNAME PSCANLIST(1).BUFADR = %LOC('SMITH') PSCANLIST(1).ITMFLAGS = PSCAN$M_OR PSCANLIST(2).BUFLEN = LEN('JONES') PSCANLIST(2).CODE = PSCAN$_USERNAME PSCANLIST(2).BUFADR = %LOC('JONES') PSCANLIST(2).ITMFLAGS = PSCAN$M_OR PSCANLIST(3).BUFLEN = LEN('JOHNSON') PSCANLIST(3).CODE = PSCAN$_USERNAME PSCANLIST(3).BUFADR = %LOC('JOHNSON') PSCANLIST(3).ITMFLAGS = 0 PSCANLIST(4).END_LIST = 0 |
Use the PSCAN$M_WILDCARD flag to specify that a character string is to be treated as a wildcard. For example, to find all process names that begin with the letter A and end with the string ER, use the string A*ER with the PSCAN$M_WILDCARD flag. If the PSCAN$M_WILDCARD flag is not specified, the search looks for the 4-character process name A*ER.
The PSCAN$M_PREFIX_MATCH defines a wildcard search to match the initial characters of a string. For example, to find all process names that start with the letters AB, use the string AB with the PSCAN$M_PREFIX_MATCH flag. If you do not specify the PSCAN$M_PREFIX_MATCH flag, the search looks for a process with the 2-character process name AB.
Previous | Next | Contents | Index |
privacy and legal statement | ||
5841PRO_006.HTML |