HP OpenVMS Systems Documentation

Content starts here

OpenVMS Programming Concepts Manual


Previous Contents Index

4.2.3.2 Requesting Information About All Processes on the Local System

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 4-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 4-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);

}

4.2.4 Using SYS$GETJPI with SYS$PROCESS_SCAN

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 4-3 shows four item codes of SYS$GETJPI that provide kernel threads information.

Table 4-3 SYS$GETJPI Kernel Threads Item Codes
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 4-4 shows two item codes of SYS$PROCESS_SCAN that provide kernel thread information.

Table 4-4 SYS$PROCESS_SCAN Kernel Threads Item Codes
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.

4.2.4.1 Using SYS$PROCESS_SCAN Item List and Item-Specific Flags

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:

  • The attribute of the process to be examined
  • The value of the attribute or a pointer to the value
  • Item-specific flags to control how to interpret the value

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 4-5.

Table 4-5 Item-Specific Flags
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, you must specify each user name 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 you do not specify the PSCAN$M_WILDCARD flag, 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.

4.2.4.2 Requesting Information About Processes That Match One Criterion

You can use SYS$GETJPI with SYS$PROCESS_SCAN to search for processes that match an item list with one criterion. For example, if you specify a search for processes owned by one user name, SYS$GETJPI returns only those processes that match the specified user name.

Example 4-6 demonstrates how to perform a SYS$PROCESS_SCAN search on the local node to select all processes that are owned by user SMITH.

Example 4-6 Using SYS$GETJPI and SYS$PROCESS_SCAN to Select Process Information by User Name

        PROGRAM PROCESS_SCAN

        IMPLICIT NONE                   ! Implicit none

        INCLUDE '($jpidef)   /nolist'   ! Definitions for $GETJPI
        INCLUDE '($pscandef) /nolist'   ! Definitions for $PROCESS_SCAN
        INCLUDE '($ssdef)    /nolist'   ! Definitions for SS$_NAMES

        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
        STRUCTURE /PSCANITMLST/         ! Structure declaration for
         UNION                          !  $PROCESS_SCAN item lists
          MAP
           INTEGER*2 BUFLEN,
        2            CODE
           INTEGER*4 BUFADR,
        2            ITMFLAGS
          END MAP
          MAP                           ! A longword of 0 terminates
           INTEGER*4 END_LIST           !  an item list
          END MAP
         END UNION
        END STRUCTURE
        RECORD /PSCANITMLST/            ! Declare the item list for
        2         PSCANLIST(12)         !  $PROCESS_SCAN

        RECORD /JPIITMLST/              ! Declare the item list for
        2         JPILIST(3)            !  $GETJPI

        INTEGER*4 SYS$GETJPIW,          ! System service entry points
        2         SYS$PROCESS_SCAN

        INTEGER*4 STATUS,               ! Status variable
        2         CONTEXT,              ! Context from $PROCESS_SCAN
        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

        LOGICAL*4 DONE                  ! Done with data loop

        !********************************************
        !*  Initialize item list for $PROCESS_SCAN  *
        !********************************************

        ! Look for processes owned by user SMITH

        PSCANLIST(1).BUFLEN   = LEN('SMITH')
        PSCANLIST(1).CODE     = PSCAN$_USERNAME
        PSCANLIST(1).BUFADR   = %LOC('SMITH')
        PSCANLIST(1).ITMFLAGS = 0
        PSCANLIST(2).END_LIST = 0
        !********************************************
        !*     End of item list initialization      *
        !********************************************


        STATUS = SYS$PROCESS_SCAN (        ! Set up the scan context
        2                        CONTEXT,
        2                        PSCANLIST)

        IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))

        ! Loop calling $GETJPI with the context

        DONE = .FALSE.
        DO WHILE (.NOT. DONE)

                ! 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 the next SMITH process

                STATUS = SYS$GETJPIW (
        2                    ,           ! No event flag
        2                    CONTEXT,    ! Process context
        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 IF (STATUS .EQ. SS$_NOMOREPROC) THEN
                        DONE = .TRUE.
                ELSE
                        CALL LIB$SIGNAL(%VAL(STATUS))
                END IF

        END DO

        END

4.2.4.3 Requesting Information About Processes That Match Multiple Values for One Criterion

You can use SYS$PROCESS_SCAN to search for processes that match one of a number of values for a single criterion, such as processes owned by several specified users.

You must specify each value in a separate item list entry, and connect the item list entries with the PSCAN$M_OR item-specific flag. SYS$GETJPI selects each process that matches any of the item values.

For example, to look for processes with user names SMITH, JONES, or JOHNSON, substitute code such as that shown in Example 4-7 to initialize the item list in Example 4-6.

Example 4-7 Using SYS$GETJPI and SYS$PROCESS_SCAN with Multiple Values for One Criterion

!********************************************
!*  Initialize item list for $PROCESS_SCAN  *
!********************************************

! Look for users SMITH, JONES and 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

!********************************************
!*     End of item list initialization      *
!********************************************

4.2.4.4 Requesting Information About Processes That Match Multiple Criteria

You can use SYS$PROCESS_SCAN to search for processes that match values for more than one criterion. When multiple criteria are used, a process must match at least one value for each specified criterion.

Example 4-8 demonstrates how to find any batch process owned by either SMITH or JONES. The program uses syntax like the following logical expression to initialize the item list:


((username = "SMITH") OR (username = "JONES"))

                     AND

            (MODE = JPI$K_BATCH)

Example 4-8 Selecting Processes That Match Multiple Criteria

!********************************************
!*  Initialize item list for $PROCESS_SCAN  *
!********************************************

! Look for BATCH jobs owned by users SMITH and JONES

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 = 0
PSCANLIST(3).BUFLEN   = 0
PSCANLIST(3).CODE     = PSCAN$_MODE
PSCANLIST(3).BUFADR   = JPI$K_BATCH
PSCANLIST(3).ITMFLAGS = 0
PSCANLIST(4).END_LIST = 0

!********************************************
!*     End of item list initialization      *
!********************************************

See the OpenVMS System Services Reference Manual for more information about SYS$PROCESS_SCAN item codes and flags.

4.2.5 Specifying a Node as Selection Criterion

Several SYS$PROCESS_SCAN item codes do not refer to attributes of a process, but to the VMScluster node on which the target process resides. When SYS$PROCESS_SCAN encounters an item code that refers to a node attribute, it creates an alphabetized list of node names. SYS$PROCESS_SCAN then directs SYS$GETJPI to compare the selection criteria against processes on these nodes.

SYS$PROCESS_SCAN ignores a node specification if it is running on a node that is not part of a VMScluster system. For example, if you request that SYS$PROCESS_SCAN select all nodes with the hardware model name VAX 6360, this search returns information about local processes on a nonclustered system, even if it is a MicroVAX system.

A remote SYS$GETJPI operation currently requires the system to send a message to the CLUSTER_SERVER process on the remote node. The CLUSTER_SERVER process then collects the information and returns it to the requesting node. This has several implications for clusterwide searches:

  • All remote SYS$GETJPI operations are asynchronous and must be synchronized properly. Many applications that are not correctly synchronized might seem to work on a single node because some SYS$GETJPI operations are actually synchronous; however, these applications fail if they attempt to examine processes on remote nodes. For more information on how to synchronize SYS$GETJPI operations, see Chapter 6.
  • The CLUSTER_SERVER process is always a current process, because it is executing on behalf of SYS$GETJPI.
  • Attempts by SYS$GETJPI to examine a node do not succeed during a brief period between the time a node joins the cluster and the time that the CLUSTER_SERVER process is started. Searches that occur during this period skip such a node. Searches that specify only such a booting node fail with a SYS$GETJPI status of SS$_UNREACHABLE.
  • SS$_NOMOREPROC is returned after all processes on all specified nodes have been scanned.


Previous Next Contents Index