/******************************************************************************* ** ** Source File Name = db2mon.c ** ** Licensed Materials - Property of IBM ** ** (C) COPYRIGHT International Business Machines Corp. 1995, 2000 ** All Rights Reserved. ** ** US Government Users Restricted Rights - Use, duplication or ** disclosure restricted by GSA ADP Schedule Contract with IBM Corp. ** ** ** PURPOSE: This sample program demonstrates how to use the Database ** System Monitor APIs, and how to process the output data ** buffer returned from the Snapshot API. ** It is a menu-driven program that allows the user to ** access the functionality of the Database System ** Monitor APIs: ** - Turn ON/OFF any of the monitoring groups ** - Reset data areas for specific databases or all ** active databases ** - Monitor DB2 activity in a wide variety of ** object combinations. ** ** STRUCTURES USED : ** sqlma ** sqlm_collected ** sqlm_recording_group ** sqlca ** ** MONOTOR APIs USED: ** GET/UPDATE MONITOR SWITCHES sqlmon() ** GET SNAPSHOT sqlmonss() ** ESTIMATE SIZE REQUIRED FOR ** sqlmonss() OUTPUT BUFFER sqlmonsz() ** RESET MONOTOR sqlmrset() ** ** ** OTHER APIs USED: ** INSTANCE ATTACH sqleatin() ** ** RUN: To run this sample, just enter "db2mon" and follow the ** on-screen menus. Ensure that DB2 has been started ** before attempting to monitor any activity. ** ** EXTERNAL DEPENDENCIES : ** - Ensure existence of database for precompile purposes. ** - Compile and link with the IBM Cset++ compiler (AIX and OS/2) ** or the Microsoft Visual C++ compiler (Windows) ** or the compiler supported on your platform. ** ** ** For more information about these samples see the README file. ** ** For more information on programming in C, see the: ** - "Programming in C and C++" section of the Application Development Guide ** For more information on Building C Applications, see the: ** - "Building C Applications" section of the Application Building Guide. ** ** For more information on the SQL language see the SQL Reference. ** *******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "sqlenv.h" #include "sqlmon.h" #include "sqlca.h" #include "sqlutil.h" #if (defined(DB2AIX) || defined(DB2SCO) || defined(DB2SUN) || defined(DB2HP) || defined(DB2SNI) || defined(DB2IRIX) || defined(DB2LINUX)) #define CLEARSCR "clear" #define min(a, b) ((a < b) ? a : b) #else #define CLEARSCR "cls" #endif /*****************************************************************************/ /* Constants definitions */ /*****************************************************************************/ #define SCREEN_OUTPUT 1 /* output data to screen */ #define FILE_OUTPUT 2 /* output data to user file */ /*****************************************************************************/ /* Internal Function Prototypes */ /*****************************************************************************/ int dbmon_switch(); int dbmon_reset(); int dbmon_snapshot(); void pause(); void clrscrn(); void pr_sqlca(struct sqlca *); void process_db2(); void process_dbase(); void process_appl(); void process_applinfo(); void process_dcs_applinfo(); void process_table(); void process_lock(); void process_tablespace(); void process_dcs_app(); void cleanup(struct sqlma *ma_ptr); /*****************************************************************************/ /* Global Variables */ /*****************************************************************************/ FILE *outstream; /* output stream if directed to file */ unsigned int output_opt = SCREEN_OUTPUT; /* output to screen or file*/ struct sqlm_collected collected; /* returned sqlm_collected structure */ char *buffer_ptr = NULL; /* buffer returned from snapshot */ char *buffer_index; /* current position in buffer */ sqluint32 buffer_sz; /* Estimated buffer size */ /*****************************************************************************/ /* MAIN routine. */ /*****************************************************************************/ int main( int argc, char *argv[], char *envp[]) { int ssout= 0; /* exit flag */ int ssrc= 0; /* program return code */ unsigned int numsel = 999; /* numeric input selection */ struct sqlca sqlca; char userid[9]; char passwd[19]; char nodename[9]; if (argc == 4) { strcpy (userid, argv[1]); strcpy (passwd, argv[2]); strcpy (nodename, argv[3]); /*************************/ /* ATTACH API called */ /*************************/ sqleatin (nodename, userid, passwd, &sqlca); } else if (argc != 1) { printf ("\nUSAGE: db2mon [userid passwd remote_nodename]\n"); return 1; } /*************************************************************************/ /* initialize outstream for screen output */ /*************************************************************************/ outstream = stdout; /*************************************************************************/ /* Perform main loop until users wants to exit. */ /*************************************************************************/ while (!ssout) { clrscrn(); printf("******************************************************************************\n"); printf("**** ****\n"); printf("**** DB2 DATABASE MONITOR SAMPLE PROGRAM ****\n"); printf("**** ****\n"); printf("******************************************************************************\n"); while (numsel < 0 || numsel > 3) { printf("\nPlease choose one of the following options:\n\n"); printf(" 1 - Turn ON/OFF monitoring switches\n"); printf(" 2 - Reset data areas\n"); printf(" 3 - Get a Snapshot\n"); printf(" 0 - Exit the Database Monitor sample program\n"); fflush(stdin); scanf("%u", &numsel); if (numsel < 0 || numsel > 3) printf("\nInvalid selection. Please choose again.\n"); } /* while */ /**********************************************************************/ /* Process user selection */ /**********************************************************************/ switch (numsel) { case 0: ssout = 1; break; case 1: ssrc = dbmon_switch(); if (ssrc != 0) { printf("\nreturn code from dbmon_switch : %i\n", ssrc); pause(); } break; case 2: ssrc = dbmon_reset(); if (ssrc != 0) { printf("\nreturn code from dbmon_reset : %i\n", ssrc); pause(); } break; case 3: ssrc = dbmon_snapshot(); if (ssrc != 0) { printf("\nreturn code from dbmon_snapshot : %i\n", ssrc); pause(); } break; default: break; } /* switch numsel */ numsel = 999; } /* while !ssout */ return 0; } /*****************************************************************************/ /* dbmon_switch. */ /* This function is called when the user wants to turn ON or OFF any of */ /* the Database Monitor groups. */ /*****************************************************************************/ int dbmon_switch() { unsigned int numsel = 999; /* numeric input selection */ unsigned int numsel2 = 999; /* numeric input selection */ unsigned int i; /* loop counter */ int rc = 0; /* return code */ struct sqlca sqlca; struct sqlm_recording_group states[SQLM_NUM_GROUPS]; clrscrn(); printf("******************************************************************************\n"); printf("* Database Monitor Switch *\n"); printf("******************************************************************************\n"); /********************************************************/ /* Query the current state of the switches */ /********************************************************/ for (i = 0; i < SQLM_NUM_GROUPS; i++) { states[i].input_state = SQLM_HOLD; } rc = sqlmon(SQLM_DBMON_VERSION5_2, NULL, states, &sqlca); if (rc != 0) { printf("\nReturn code from SQLMON is %d \n", rc); return(rc); } if (sqlca.sqlcode != 0L) { printf("\nSqlcode from SQLMON is not 0. \n"); pr_sqlca(&sqlca); } /********************************************************/ /* Display the current state of the switches */ /********************************************************/ printf("\nCurrent Switch settings:\n"); printf("1 - UOW Switch state : %s %24.24s\n", (states[0].output_state) ? "ON , start time :" : "OFF", (states[0].start_time.seconds) ? ctime((time_t *)&states[0].start_time.seconds) : ""); printf("2 - STMT Switch state : %s %24.24s\n", (states[1].output_state) ? "ON , start time :" : "OFF", (states[1].start_time.seconds) ? ctime((time_t *)&states[1].start_time.seconds) : ""); printf("3 - TABLE Switch state : %s %24.24s\n", (states[2].output_state) ? "ON , start time :" : "OFF", (states[2].start_time.seconds) ? ctime((time_t *)&states[2].start_time.seconds) : ""); printf("4 - BUFF POOL Switch state : %s %24.24s\n", (states[3].output_state) ? "ON , start time :" : "OFF", (states[3].start_time.seconds) ? ctime((time_t *)&states[3].start_time.seconds) : ""); printf("5 - LOCK Switch state : %s %24.24s\n", (states[4].output_state) ? "ON , start time :" : "OFF", (states[4].start_time.seconds) ? ctime((time_t *)&states[4].start_time.seconds) : ""); printf("6 - SORT Switch state : %s %24.24s\n", (states[5].output_state) ? "ON , start time :" : "OFF", (states[5].start_time.seconds) ? ctime((time_t *)&states[5].start_time.seconds) : ""); for (i = 0; i < SQLM_NUM_GROUPS; i++) { states[i].input_state = SQLM_HOLD; } /**************************************************************/ /* loop to let user select switches to be turned ON or OFF */ /**************************************************************/ do { printf("\nPlease enter the switch number you wish to set:\n"); printf("This function toggles the switch state ON/OFF.\n"); printf(" Enter 0 when you are done with your selections.\n"); fflush(stdin); scanf("%u", &numsel); if (numsel < 0 || numsel > 6) printf("\nInvalid selection. Please try again.\n"); else if (numsel != 0) { if (states[numsel-1].output_state == SQLM_ON) states[numsel-1].input_state = SQLM_OFF; else states[numsel-1].input_state = SQLM_ON; } /* if */ } while (numsel != 0); /********************************************************/ /* Set new switch states */ /********************************************************/ rc = sqlmon(SQLM_DBMON_VERSION5_2, NULL, states, &sqlca); if (rc != 0) { printf("\nReturn code from SQLMON is %d \n", rc); return(rc); } if (sqlca.sqlcode != 0L) { printf("\nSqlcode from SQLMON is not 0. \n"); pr_sqlca(&sqlca); if (sqlca.sqlcode < 0L) /* negative sqlcodes are errors */ { printf("Negative sqlcode... exiting\n"); return((int)sqlca.sqlcode); } pause(); } /********************************************************/ /* Display new switch states */ /********************************************************/ printf("\nNew states:\n"); printf("1 - UOW Switch state : %s %24.24s\n", (states[0].output_state) ? "ON , start time :" : "OFF", (states[0].start_time.seconds) ? ctime((time_t *)&states[0].start_time.seconds) : ""); printf("2 - STMT Switch state : %s %24.24s\n", (states[1].output_state) ? "ON , start time :" : "OFF", (states[1].start_time.seconds) ? ctime((time_t *)&states[1].start_time.seconds) : ""); printf("3 - TABLE Switch state : %s %24.24s\n", (states[2].output_state) ? "ON , start time :" : "OFF", (states[2].start_time.seconds) ? ctime((time_t *)&states[2].start_time.seconds) : ""); printf("4 - BUFF POOL Switch state : %s %24.24s\n", (states[3].output_state) ? "ON , start time :" : "OFF", (states[3].start_time.seconds) ? ctime((time_t *)&states[3].start_time.seconds) : ""); printf("5 - LOCK Switch state : %s %24.24s\n", (states[4].output_state) ? "ON , start time :" : "OFF", (states[4].start_time.seconds) ? ctime((time_t *)&states[4].start_time.seconds) : ""); printf("6 - SORT Switch state : %s %24.24s\n", (states[5].output_state) ? "ON , start time :" : "OFF", (states[5].start_time.seconds) ? ctime((time_t *)&states[5].start_time.seconds) : ""); pause(); return(0); } /* dbmon_switch() */ /*****************************************************************************/ /* dbmon_reset. */ /* This function is called when the user wants to reset Database Monitor */ /* data areas. */ /*****************************************************************************/ int dbmon_reset() { unsigned int numsel = 999; /* numeric input selection */ sqluint32 reset_all; /* reset indicator */ int rc = 0; /* return code */ struct sqlca sqlca; char db_alias[SQLM_IDENT_SZ]; /* input database alias */ clrscrn(); printf("******************************************************************************\n"); printf("* Database Monitor Reset *\n"); printf("******************************************************************************\n"); do { printf("\nDo you wish to reset data areas for :\n"); printf(" 1 - a specifc database, or\n"); printf(" 2 - all active databases ?\n"); printf(" (Press 0 to exit to return to the previous menu)\n"); fflush(stdin); scanf("%u", &numsel); if (numsel < 0 || numsel > 2) printf ("\nInvalid selection. Please try again.\n"); } while (numsel < 0 || numsel > 2); switch (numsel) { case 0: return(0); break; case 1: reset_all = SQLM_OFF; printf("\nPlease enter the database alias of the database you wish to reset:\n"); fflush(stdin); scanf("%s", db_alias); break; case 2: reset_all = SQLM_ON; break; default: printf("\nError in Reset... should not happen... exiting...\n"); exit(99); break; } /* switch numsel */ /***************************************************************/ /* Reset the Database Monitor data areas */ /***************************************************************/ rc = sqlmrset(SQLM_DBMON_VERSION5_2, NULL, reset_all, db_alias, &sqlca); if (rc != 0) { printf("\nReturn code from SQLMONRSET is %d \n", rc); return(rc); } if (sqlca.sqlcode != 0L) { printf("\nSqlcode from SQLMRSET is not 0. \n"); pr_sqlca(&sqlca); if (sqlca.sqlcode < 0L) /* negative sqlcodes are errors */ { printf("Negative sqlcode... exiting\n"); return((int)sqlca.sqlcode); } } else printf("\nReset was successful. \n"); pause(); return(0); } /* dbmon_reset() */ /*****************************************************************************/ /* dbmon_snapshot */ /* This function is called when the user wishes to perform a Database */ /* Monitor Snapshot. */ /* The user will select the types of information the snapshot will collect */ /* and return in the buffer. */ /*****************************************************************************/ int dbmon_snapshot() { time_t ltime; unsigned int ma_sz; /* size of sqlma structure */ unsigned int input_opt; unsigned int obj_num = 0; /* # of objects to monitor */ unsigned int numstruct = 0; /* # of structures returned */ unsigned int i; /* loop counter */ int rc = 0; /* return code */ int ssrc= 0; /* driver return code */ char outfilename[81]; /* name for data output file */ struct sqlca sqlca; struct sqlma *ma_ptr = NULL; /* sqlma structure pointer */ struct ma_unit /* working sqlma element */ { sqluint32 agent_id; sqluint32 obj_type; char object[SQLM_OBJECT_SZ]; struct ma_unit *next; }; struct ma_unit ma_unit_head; struct ma_unit *ma_unit_ptr; struct ma_unit *free_ptr; /**************************************************************************/ /* Initialize various character arrays to nulls */ /**************************************************************************/ memset(&collected, '\0', sizeof(struct sqlm_collected)); memset(outfilename, '\0', sizeof(outfilename)); /**************************************************************************/ /* Prompt the user for the tpyes of objects to monitor */ /**************************************************************************/ do { clrscrn(); printf("******************************************************************************\n"); printf("* Database Monitor Snapshot *\n"); printf("******************************************************************************\n"); printf("\nPlease choose the type of object to monitor.\n"); printf("You can choose as many as you want, one at a time\n"); printf("\n Enter 0 when done with your selections\n"); printf(" 1 --- General information for DB2\n"); printf(" 2 --- Information for a specific DATABASE\n"); printf(" 3 --- Information for a specific APPLICATION (by APPL-ID)\n"); printf(" 4 --- Information for a specific APPLICATION (by AGENT-ID)\n"); printf(" 5 --- TABLE information for a specific database\n"); printf(" 6 --- APPLICATION information for a SPECIFIC DATABASE\n"); printf(" 7 --- SUMMARY APPLICATION information for a SPECIFIC DATABASE\n"); printf(" 8 --- LOCK information for a specific database\n"); printf(" 9 --- Information for ALL ACTIVE DATABASES\n"); printf(" 10 --- Information for ALL ACTIVE APPLICATIONS\n"); printf(" 11 --- SUMMARY information for ALL ACTIVE APPLICATIONS\n"); printf(" 12 --- Information for ALL ACTIVE DCS APPLICATIONS\n"); printf(" 13 --- TABLESPACE information for a SPECIFIC DATABASE\n"); printf(" 14 --- Information about a specific DCS application (by APPL. HANDLE)\n"); printf("Please enter the number of your choice==> "); fflush(stdin); scanf("%u", &input_opt); /*******************************************************/ /* If the user entered a vaild number, allocate */ /* memory for working temporary sqlma information */ /*******************************************************/ if (input_opt > 0 && input_opt <= 14) { obj_num++; /* increment # of objects to monitor */ if (obj_num == 1) { ma_unit_ptr = &ma_unit_head; } else { ma_unit_ptr->next = (struct ma_unit *) malloc(sizeof(struct ma_unit)); if (ma_unit_ptr->next != NULL) { ma_unit_ptr = ma_unit_ptr->next; memset(ma_unit_ptr, '\0', sizeof(struct ma_unit)); } else { printf("error allocating ma_unit memory. Exiting\n"); return(99); } } /* else */ } /* if */ /********************************************************/ /* Fill in temporary sqlma info with user choice */ /********************************************************/ switch (input_opt) { case 0: break; case 1: ma_unit_ptr->obj_type = SQLMA_DB2; ma_unit_ptr->agent_id = 0L; break; case 2: ma_unit_ptr->obj_type = SQLMA_DBASE; printf("\nPlease enter the database alias name ==> "); fflush(stdin); scanf("%s", ma_unit_ptr->object); ma_unit_ptr->agent_id = 0L; break; case 3 : ma_unit_ptr->obj_type = SQLMA_APPL; printf("\nPlease enter the application ID ==> "); fflush(stdin); scanf("%s", ma_unit_ptr->object); ma_unit_ptr->agent_id = 0L; break; case 4 : ma_unit_ptr->obj_type = SQLMA_AGENT_ID; printf("\nPlease enter the agent ID ==> "); fflush(stdin); scanf("%ul", &(ma_unit_ptr->agent_id)); break; case 5: ma_unit_ptr->obj_type = SQLMA_DBASE_TABLES; printf("\nPlease enter the database alias name ==> "); fflush(stdin); scanf("%s", ma_unit_ptr->object); ma_unit_ptr->agent_id = 0L; break; case 6: ma_unit_ptr->obj_type = SQLMA_DBASE_APPLS; printf("\nPlease enter the database alias name ==> "); fflush(stdin); scanf("%s", ma_unit_ptr->object); ma_unit_ptr->agent_id = 0L; break; case 7: ma_unit_ptr->obj_type = SQLMA_DBASE_APPLINFO; printf("\nPlease enter the database alias name ==> "); fflush(stdin); scanf("%s", ma_unit_ptr->object); ma_unit_ptr->agent_id = 0L; break; case 8: ma_unit_ptr->obj_type = SQLMA_DBASE_LOCKS; printf("\nPlease enter the database alias name ==> "); fflush(stdin); scanf("%s", ma_unit_ptr->object); ma_unit_ptr->agent_id = 0L; break; case 9: ma_unit_ptr->obj_type = SQLMA_DBASE_ALL; ma_unit_ptr->agent_id = 0L; break; case 10: ma_unit_ptr->obj_type = SQLMA_APPL_ALL; ma_unit_ptr->agent_id = 0L; break; case 11: ma_unit_ptr->obj_type = SQLMA_APPLINFO_ALL; ma_unit_ptr->agent_id = 0L; break; case 12: ma_unit_ptr->obj_type = SQLMA_DCS_APPLINFO_ALL; ma_unit_ptr->agent_id = 0L; break; case 13: ma_unit_ptr->obj_type = SQLMA_DBASE_TABLESPACES; printf("\nPlease enter the database alias name ==> "); fflush(stdin); scanf("%s", ma_unit_ptr->object); ma_unit_ptr->agent_id = 0L; break; case 14 : ma_unit_ptr->obj_type = SQLMA_DCS_APPL_HANDLE; printf("\nPlease enter the DCS application handle ==> "); fflush(stdin); scanf("%ul", &(ma_unit_ptr->agent_id)); break; default: printf("\n\nThe input selection is not valid. Please try again.\n"); pause(); break; } /* end switch */ } while ( input_opt != 0 ); /* enddo */ /********************************************************************/ /* transfer user selections to sqlma structure */ /********************************************************************/ if (obj_num == 0) return(0); /* Determine required size for sqlma structure */ ma_sz = SQLMASIZE(obj_num); ma_ptr = (struct sqlma *) malloc(ma_sz); if ( ma_ptr == NULL) { printf("error allocating sqlma. Exiting.\n"); return(99); } /* Initialize sqlma structure to nulls */ memset(ma_ptr, '\0', ma_sz); ma_ptr->obj_num = obj_num; ma_unit_ptr = &ma_unit_head; for (i = 0; i < obj_num; i++) { ma_ptr->obj_var[i].agent_id = ma_unit_ptr->agent_id; ma_ptr->obj_var[i].obj_type = ma_unit_ptr->obj_type; strncpy((char *)ma_ptr->obj_var[i].object, (char *)ma_unit_ptr->object, SQLM_OBJECT_SZ); free_ptr = ma_unit_ptr; /* remember pointer before going to next */ ma_unit_ptr = ma_unit_ptr->next; if (i != 0) free(free_ptr); /* free memory when done */ } /***************************************************************************/ /* Selection of output destination. The user can have the snapshot */ /* output sent either to the screen or to an output file of their choice. */ /* All output will be written out using "fprintf". This code will either */ /* assign stdout to outstream for screen output or open the appropriate */ /* file. */ /***************************************************************************/ clrscrn(); do { printf("\n\nPlease select output destination (0 to exit now):\n"); printf(" %u : screen\n", SCREEN_OUTPUT); printf(" %u : file\n", FILE_OUTPUT); printf(" ==>"); fflush(stdin); scanf("%u", &output_opt); switch (output_opt) { case SCREEN_OUTPUT : outstream = stdout; break; case FILE_OUTPUT : printf("\nNew results will be appended to existing file, if any.\n"); printf("Please enter filename of the output file (80 chars max): "); fflush(stdin); scanf("%s", &outfilename); outstream = fopen(outfilename, "a"); if (outstream == NULL) { printf("\nERROR opening output file. Output defaults to SCREEN.\n"); output_opt = SCREEN_OUTPUT; outstream = stdout; pause(); } break; case 0 : printf("Exiting...\n"); return(0); break; default : printf("\nInvalid selection. Please try again.\n"); break; } /* end switch(output_opt) */ } while (output_opt < 1 | output_opt > 2); /**************************************************************************/ /* Call the Database Monitor Estimate Buffer Size API to determine the */ /* size of the buffer required to store the Snapshot Monitor data. */ /**************************************************************************/ rc = sqlmonsz(SQLM_DBMON_VERSION5_2, NULL, ma_ptr, &buffer_sz, &sqlca); if (rc != 0) { printf("\nReturn code from SQLMONSZ is %d \n", rc); return(rc); } if (sqlca.sqlcode != 0L) { printf("\nSqlcode from SQLMONSZ is not 0. \n"); pr_sqlca(&sqlca); if (sqlca.sqlcode < 0L) /* negative sqlcodes are errors */ { printf("Negative sqlcode... exiting\n"); cleanup(ma_ptr); return((int)sqlca.sqlcode); } pause(); } if (buffer_sz == 0) { return(0); } buffer_ptr = (char *) malloc(buffer_sz); /* allocate buffer */ if (buffer_ptr == NULL) { printf("Error allocating memory for buffer area... exiting\n"); cleanup(ma_ptr); return(99); } memset(buffer_ptr, '\0', buffer_sz); /* set contents to nulls */ /**************************************************************************/ /* Call Snapshot Monitor and verify the return codes. */ /* If rc return code from call to the Snapshot Monitor api is non-zero, */ /* exit the sample program. */ /* A non-zero sqlcode is not necessarily an error. If the sqlcode is */ /* negative, than it is an error and db2mon exits. If the sqlcode is */ /* positive, than processing continues. In both cases, the contents of */ /* the sqlca are displayed on the screen. */ /* Note that in version2 snapshots, agent_id (application handle) is the */ /* id of the agent on the server. In version 5 and later this value is */ /* no longer the agent id. If you wish to use the agent_id field to take */ /* snapshots for a version 5 server, you must take a version 5 level */ /* snapshot. */ /**************************************************************************/ rc = sqlmonss(SQLM_DBMON_VERSION5_2, NULL, ma_ptr, buffer_sz, buffer_ptr, &collected, &sqlca); if (rc != 0) { printf("\nReturn code from SQLMONSS is %d \n", rc); cleanup(ma_ptr); return(rc); } if (sqlca.sqlcode != 0L) { printf("\nSqlcode from SQLMONSS is not 0. \n"); pr_sqlca(&sqlca); if (sqlca.sqlcode < 0L) /* negative sqlcodes are errors */ { printf("Negative sqlcode... exiting\n"); cleanup(ma_ptr); return((int)sqlca.sqlcode); } pause(); } /**************************************************************************/ /* Print out some general information about the results. */ /* This information is contained in the sqlm_collected data structure */ /* returned from the call to sqlmonss. It is not part of the output */ /* buffer. */ /**************************************************************************/ if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* GENERAL INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); ltime = collected.time_stamp.seconds; fprintf(outstream, "Time Stamp of the Snapshot call ===> %24.24s\n", (ltime) ? ctime(<ime) : ""); switch (collected.server_db2_type) { case SQLF_NT_SERVER: fprintf(outstream, "Server Type ===> Server with Local and Remote Clients\n"); break; case SQLF_NT_STAND_REQ: fprintf(outstream, "Server Type ===> Server with Local Clients \n"); break; case SQLF_NT_SATELLITE: fprintf(outstream, "Server Type ===> Satellite Server with Local Clients \n"); break; case SQLF_NT_MPP: fprintf(outstream, "Server Type ===> Partitioned Server with Local and Remote Clients \n"); break; default: fprintf(outstream, "Server Type ===> UNKNOWN(%lu)\n", collected.server_db2_type); break; } /* switch */ fprintf(outstream, "Product Signature (prdid) ===> %0.*s\n", SQLM_IDENT_SZ, collected.server_prdid); fprintf(outstream, "Server Instance Name ===> %0.*s\n", SQLM_IDENT_SZ, collected.server_instance_name); fprintf(outstream, "\nMonitor Switch settings:\n"); fprintf(outstream, "1 - UOW Switch state : %s %24.24s\n", (collected.group_states[0].output_state) ? "ON , start time :" : "OFF", (collected.group_states[0].start_time.seconds) ? ctime((time_t *)&collected.group_states[0].start_time.seconds) : ""); fprintf(outstream, "2 - STMT Switch state : %s %24.24s\n", (collected.group_states[1].output_state) ? "ON , start time :" : "OFF", (collected.group_states[1].start_time.seconds) ? ctime((time_t *)&collected.group_states[1].start_time.seconds) : ""); fprintf(outstream, "3 - TABLE Switch state : %s %24.24s\n", (collected.group_states[2].output_state) ? "ON , start time :" : "OFF", (collected.group_states[2].start_time.seconds) ? ctime((time_t *)&collected.group_states[2].start_time.seconds) : ""); fprintf(outstream, "4 - BUFF POOL Switch state : %s %24.24s\n", (collected.group_states[3].output_state) ? "ON , start time :" : "OFF", (collected.group_states[3].start_time.seconds) ? ctime((time_t *)&collected.group_states[3].start_time.seconds) : ""); fprintf(outstream, "5 - LOCK Switch state : %s %24.24s\n", (collected.group_states[4].output_state) ? "ON , start time :" : "OFF", (collected.group_states[4].start_time.seconds) ? ctime((time_t *)&collected.group_states[4].start_time.seconds) : ""); fprintf(outstream, "6 - SORT Switch state : %s %24.24s\n", (collected.group_states[5].output_state) ? "ON , start time :" : "OFF", (collected.group_states[5].start_time.seconds) ? ctime((time_t *)&collected.group_states[5].start_time.seconds) : ""); if (output_opt == SCREEN_OUTPUT) pause(); /**************************************************************************/ /* Process the buffer returned from Snapshot Monitor API. */ /* The buffer will contain the data structures of the objects that were */ /* monitored. The first 4 bytes of each structure indicates its size and */ /* the next character identifies the type of information returned. */ /* The program goes through the whole buffer, processing each structure as*/ /* it encounters it. It first determines what type of information it */ /* currently points to, then processes it accordingly. After processing */ /* a structure, it advances in the buffer to the next one, until it */ /* has processed the whole buffer. */ /* Processing is complete when all returned structures have been */ /* processed, as indicated by the numbers in the sqlm_collected data */ /* structure. */ /**************************************************************************/ /* add up all the structures returned in the buffer */ numstruct = collected.num_top_level_structs; buffer_index = buffer_ptr; /* loop until all data structures have been processed */ while (numstruct > 0) { /* Determine the type of structure at current position in the buffer */ switch ((unsigned char)*(buffer_index + 4)) { case SQLM_DB2_SS: /* DB2 information */ process_db2(); break; case SQLM_DBASE_SS: /* Database information */ process_dbase(); break; case SQLM_APPL_SS: /* Application information */ process_appl(); break; case SQLM_TABLE_HEADER_SS: /* Table information */ process_table(); break; case SQLM_DBASE_LOCK_SS: /* Lock information */ process_lock(); break; case SQLM_APPLINFO_SS: /* Summary application information */ process_applinfo(); break; case SQLM_DCS_APPLINFO_SS: /* List DCS applications info */ process_dcs_applinfo(); break; case SQLM_TABLESPACE_HEADER_SS: /* Tablespace information */ process_tablespace(); break; case SQLM_DCS_APPL_SS: /* DCS application information */ process_dcs_app(); break; default: /* Unexpected data in buffer */ printf("\n\n***************************************************************\n"); printf("* ERROR processing output buffer from snapshot monitor. *\n"); printf("* Expecting start of new structure. First chars: %10c *\n",(unsigned char)*buffer_index); printf("* buffer offset where error occurred: %10u *\n",(ptrdiff_t)(buffer_index - buffer_ptr)); printf("* Exiting db2mon. *\n\n"); printf("\n***************************************************************\n"); cleanup(ma_ptr); exit(99); break; } /* end switch (*buffer_index) */ --numstruct; } /* end while (buffer_index < ...) */ cleanup(ma_ptr); /* cleanup before exiting */ return(ssrc); } /* snapshot */ /*****************************************************************************/ /* process_db2 */ /* This function processes DB2 level information. The information is in */ /* an sqlm_db2 data structure. */ /*****************************************************************************/ void process_db2() { time_t ltime; struct sqlm_db2 *db2_ptr; if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* DB2 GENERAL INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* cast buffer contents to an sqlm_db2 structure */ db2_ptr = (struct sqlm_db2 *)buffer_index; switch (db2_ptr->db2_status) { case SQLM_DB2_ACTIVE: fprintf(outstream, "\nDatabase manager status ===> %s", "Active"); break; case SQLM_DB2_QUIESCE_PEND: fprintf(outstream, "\nDatabase manager status ===> %s", "Quiesce Pending"); break; case SQLM_DB2_QUIESCED: fprintf(outstream, "\nDatabase manager status ===> %s", "Quiesced"); break; } /* end switch on database manager status */ fprintf(outstream, "\n\nSorting Information:"); fprintf(outstream, "\n Sort heap currently allocated ===> %lu", db2_ptr->sort_heap_allocated); fprintf(outstream, "\n Post Threshold sorts ===> %lu", db2_ptr->post_threshold_sorts); fprintf(outstream, "\n Piped sorts requested ===> %lu", db2_ptr->piped_sorts_requested); fprintf(outstream, "\n Piped sorts accepted ===> %lu", db2_ptr->piped_sorts_accepted); fprintf(outstream, "\n\nConnection Information:"); fprintf(outstream, "\n Remote connects to the target DB2 ===> %lu", db2_ptr->rem_cons_in); fprintf(outstream, "\n Remote connects to target exec in DB2 ===> %lu", db2_ptr->rem_cons_in_exec); fprintf(outstream, "\n Local connections ===> %lu", db2_ptr->local_cons); fprintf(outstream, "\n Local connections exec in DB2 ===> %lu", db2_ptr->local_cons_in_exec); fprintf(outstream, "\n Local active databases ===> %lu", db2_ptr->con_local_dbases); fprintf(outstream, "\n Number of agents registered ===> %lu", db2_ptr->agents_registered); fprintf(outstream, "\n Number of agents waiting on a token ===> %lu", db2_ptr->agents_waiting_on_token); fprintf(outstream, "\n High water mark of agents registered ===> %lu", db2_ptr->agents_registered_top); fprintf(outstream, "\n High water mark of agents waiting ===> %lu", db2_ptr->agents_waiting_top); fprintf(outstream, "\n Number of idle agents ===> %lu", db2_ptr->idle_agents); fprintf(outstream, "\n\nMemory Usage Information:"); fprintf(outstream, "\n Committed Private Memory (bytes) ===> %lu", db2_ptr->comm_private_mem); fprintf(outstream, "\n\nTimestamps:"); ltime = db2_ptr->db2start_time.seconds; fprintf(outstream, "\n Db2start time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = db2_ptr->last_reset.seconds; fprintf(outstream, "\n Last Reset time ===> %24.24s\n", (ltime) ? ctime(<ime) : ""); buffer_index += db2_ptr->size; /* move pointer to next structure */ /* in output buffer */ if (output_opt == SCREEN_OUTPUT) /* pause only if output is screen */ pause(); } /* process_db2 */ /*****************************************************************************/ /* process_dbase */ /* This function processes database information. The information is in an */ /* sqlm_dbase data structure */ /*****************************************************************************/ void process_dbase() { time_t ltime; unsigned int i, j; /* counters */ int rc = 0; struct sqlm_dbase *dbase_ptr; if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* DATABASE INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* cast buffer contents to an sqlm_dbase structure */ dbase_ptr = (struct sqlm_dbase *)(buffer_index); fprintf(outstream, "\nDatabase Identification:"); fprintf(outstream, "\n Input Database Alias ===> %0.*s", SQLM_IDENT_SZ, dbase_ptr->input_db_alias); fprintf(outstream, "\n Database Name ===> %0.*s", SQLM_IDENT_SZ, dbase_ptr->db_name); fprintf(outstream, "\n Database Path (truncated to 70 chars)\n ===> %0.70s", dbase_ptr->db_path); switch (dbase_ptr->db_status) { case SQLM_DB_ACTIVE: fprintf(outstream, "\n Database status ===> %s", "Active"); break; case SQLM_DB_QUIESCE_PEND: fprintf(outstream, "\n Database status ===> %s", "Quiesce Pending"); break; case SQLM_DB_QUIESCED: fprintf(outstream, "\n Database status ===> %s", "Quiesced"); break; } /* end switch on database manager status */ fprintf(outstream, "\n\nLocking Identification:"); fprintf(outstream, "\n Locks currently held ===> %lu", dbase_ptr->locks_held); fprintf(outstream, "\n No. of waits on lock since 1st connect ===> %lu", dbase_ptr->lock_waits); fprintf(outstream, "\n Total time waited on locks since connect===> %lu milliseconds", dbase_ptr->lock_wait_time); fprintf(outstream, "\n Total Lock list memory in use ===> %lu", dbase_ptr->lock_list_in_use); fprintf(outstream, "\n Deadlocks since 1st connect ===> %lu", dbase_ptr->deadlocks); fprintf(outstream, "\n Lock escalations since 1st connect ===> %lu", dbase_ptr->lock_escals); fprintf(outstream, "\n X lock escalations since 1st connect ===> %lu", dbase_ptr->x_lock_escals); fprintf(outstream, "\n Lock timeouts since 1st connect ===> %lu", dbase_ptr->lock_timeouts); fprintf(outstream, "\n Applications waiting on locks ===> %lu", dbase_ptr->locks_waiting); fprintf(outstream, "\n\nSorting Identification:"); fprintf(outstream, "\n Sort Heap currently allocated ===> %lu", dbase_ptr->sort_heap_allocated); fprintf(outstream, "\n Total number of sorts ===> %lu", dbase_ptr->total_sorts); fprintf(outstream, "\n Total sort time ===> %lu milliseconds", dbase_ptr->total_sort_time); fprintf(outstream, "\n Number of sort overflows ===> %lu", dbase_ptr->sort_overflows); fprintf(outstream, "\n Number of sorts currently active ===> %lu", dbase_ptr->active_sorts); fprintf(outstream, "\n\nBuffer Pool Information:"); fprintf(outstream, "\n Buffer pool logical data page reads ===> %lu", dbase_ptr->pool_data_l_reads); fprintf(outstream, "\n Buffer pool physical data page reads ===> %lu", dbase_ptr->pool_data_p_reads); fprintf(outstream, "\n Buffer pool data page writes ===> %lu", dbase_ptr->pool_data_writes); fprintf(outstream, "\n Buffer pool logical index page reads ===> %lu", dbase_ptr->pool_index_l_reads); fprintf(outstream, "\n Buffer pool physical index page reads ===> %lu", dbase_ptr->pool_index_p_reads); fprintf(outstream, "\n Buffer pool index page writes ===> %lu", dbase_ptr->pool_index_writes); fprintf(outstream, "\n Buffer pool read time since 1st connect ===> %lu milliseconds", dbase_ptr->pool_read_time); fprintf(outstream, "\n Buffer pool write time since 1st connect===> %lu milliseconds", dbase_ptr->pool_write_time); fprintf(outstream, "\n Files closed since 1st connect ===> %lu", dbase_ptr->files_closed); fprintf(outstream, "\n Buffer pool asynch data page reads ===> %lu", dbase_ptr->pool_async_data_reads); fprintf(outstream, "\n Buffer pool asynch data page reads reqs ===> %lu", dbase_ptr->pool_async_data_read_reqs); fprintf(outstream, "\n Buffer pool asynch data page writes ===> %lu", dbase_ptr->pool_async_data_writes); fprintf(outstream, "\n Buffer pool asynch index page reads ===> %lu", dbase_ptr->pool_async_index_reads); fprintf(outstream, "\n Buffer pool asynch index page writes ===> %lu", dbase_ptr->pool_async_index_writes); fprintf(outstream, "\n Buffer pool asynch read time ===> %lu milliseconds", dbase_ptr->pool_async_read_time); fprintf(outstream, "\n Buffer pool asynch write time ===> %lu milliseconds", dbase_ptr->pool_async_write_time); fprintf(outstream, "\n Buffer pool LSN gap cleans ===> %lu", dbase_ptr->pool_lsn_gap_clns); fprintf(outstream, "\n Buffer pool dirty page steal cleans ===> %lu", dbase_ptr->pool_drty_pg_steal_clns); fprintf(outstream, "\n Buffer pool dirty page threshold cleans ===> %lu", dbase_ptr->pool_drty_pg_thrsh_clns); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nDirect I/O Information:"); fprintf(outstream, "\n Sectors read directly ===> %lu", dbase_ptr->direct_reads); fprintf(outstream, "\n Sectors written directly ===> %lu", dbase_ptr->direct_writes); fprintf(outstream, "\n Number of direct read requests ===> %lu", dbase_ptr->direct_read_reqs); fprintf(outstream, "\n Number of direct write requests ===> %lu", dbase_ptr->direct_write_reqs); fprintf(outstream, "\n Direct read time ===> %lu milliseconds", dbase_ptr->direct_read_time); fprintf(outstream, "\n Direct write time ===> %lu milliseconds", dbase_ptr->direct_write_time); fprintf(outstream, "\n\nSQL Statement counts"); fprintf(outstream, "\n Number of Commit SQL statements ===> %lu", dbase_ptr->commit_sql_stmts); fprintf(outstream, "\n Number of Rollback SQL statements ===> %lu", dbase_ptr->rollback_sql_stmts); fprintf(outstream, "\n Number of Dynamic SQL statements ===> %lu", dbase_ptr->dynamic_sql_stmts); fprintf(outstream, "\n Number of Static SQL statements ===> %lu", dbase_ptr->static_sql_stmts); fprintf(outstream, "\n Number of Failed SQL statements ===> %lu", dbase_ptr->failed_sql_stmts); fprintf(outstream, "\n Number of Select SQL statements ===> %lu", dbase_ptr->select_sql_stmts); fprintf(outstream, "\n Number of Data Def. Language SQL stmts ===> %lu", dbase_ptr->ddl_sql_stmts); fprintf(outstream, "\n Number of Update/Insert/Delete SQL stmts===> %lu", dbase_ptr->uid_sql_stmts); fprintf(outstream, "\n\nInternal counts"); fprintf(outstream, "\n Number of auto rebinds ===> %lu", dbase_ptr->int_auto_rebinds); fprintf(outstream, "\n Number of internal row deletions ===> %lu", dbase_ptr->int_rows_deleted); fprintf(outstream, "\n Number of internal row updates ===> %lu", dbase_ptr->int_rows_updated); fprintf(outstream, "\n Number of internal row inserts ===> %lu", dbase_ptr->int_rows_inserted); fprintf(outstream, "\n Number of internal commits ===> %lu", dbase_ptr->int_commits); fprintf(outstream, "\n Number of internal rollbacks ===> %lu", dbase_ptr->int_rollbacks); fprintf(outstream, "\n Number of rollbacks due to deadlocks ===> %lu", dbase_ptr->int_deadlock_rollbacks); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nRow counts"); fprintf(outstream, "\n Number of row deletions ===> %lu", dbase_ptr->rows_deleted); fprintf(outstream, "\n Number of row insertions ===> %lu", dbase_ptr->rows_inserted); fprintf(outstream, "\n Number of row updates ===> %lu", dbase_ptr->rows_updated); fprintf(outstream, "\n Number of row selections ===> %lu", dbase_ptr->rows_selected); fprintf(outstream, "\n\n Number of binds/precompiles ===> %lu", dbase_ptr->binds_precompiles); fprintf(outstream, "\n\nTimestamps"); ltime = dbase_ptr->db_conn_time.seconds; fprintf(outstream, "\n First database connect time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = dbase_ptr->last_reset.seconds; fprintf(outstream, "\n Last Database Monitor reset time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = dbase_ptr->last_backup.seconds; fprintf(outstream, "\n Last backup time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n\nConnection information"); fprintf(outstream, "\n Connections since 1st connect ===> %lu", dbase_ptr->total_cons); fprintf(outstream, "\n No. of applications currently connected ===> %lu", dbase_ptr->appls_cur_cons); fprintf(outstream, "\n Applications executing in DB2 ===> %lu", dbase_ptr->appls_in_db2); fprintf(outstream, "\n Maximum number of connections ===> %lu", dbase_ptr->connections_top); fprintf(outstream, "\n\nDatabase heap information"); fprintf(outstream, "\n Maximum amount of database heap used ===> %lu", dbase_ptr->db_heap_top); fprintf(outstream, "\n\nLogging information"); fprintf(outstream, "\n Maximum Secondary Log space used ===> %lu", dbase_ptr->sec_log_used_top); fprintf(outstream, "\n Maximum Total Log space used ===> %lu", dbase_ptr->tot_log_used_top); fprintf(outstream, "\n Number of secondary Logs allocated ===> %lu", dbase_ptr->sec_logs_allocated); fprintf(outstream, "\n Log pages read ===> %lu", dbase_ptr->log_reads); fprintf(outstream, "\n Log pages written ===> %lu", dbase_ptr->log_writes); fprintf(outstream, "\n\nPackage Cache information"); fprintf(outstream, "\n Package Cache Lookups ===> %lu", dbase_ptr->pkg_cache_lookups); fprintf(outstream, "\n Package Cache Inserts ===> %lu", dbase_ptr->pkg_cache_inserts); fprintf(outstream, "\n\nCatalog Cache information"); fprintf(outstream, "\n Catalog Cache Lookups ===> %lu", dbase_ptr->cat_cache_lookups); fprintf(outstream, "\n Catalog Cache Inserts ===> %lu", dbase_ptr->cat_cache_inserts); fprintf(outstream, "\n Catalog Cache Overflows ===> %lu", dbase_ptr->cat_cache_overflows); fprintf(outstream, "\n Catalog Cache Heap Full ===> %lu\n", dbase_ptr->cat_cache_heap_full); buffer_index += dbase_ptr->size; /* move pointer to the next structure */ if (output_opt == SCREEN_OUTPUT) pause(); } /* process_dbase */ /*****************************************************************************/ /* process_appl */ /* This function processes application information. The information is */ /* contained in an sqlm_appl data structure. */ /*****************************************************************************/ void process_appl() { time_t ltime; struct sqlm_appl *appl_ptr; char *stmt_text_ptr; /* Dynamic SQL Statement Text ptr */ if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* APPLICATION INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* cast the buffer contents to an sqlm_appl data structure */ appl_ptr = (struct sqlm_appl *)(buffer_index); fprintf(outstream, "\nApplication Identification Information:"); fprintf(outstream, "\n Application agent id ===> %lu\n", appl_ptr->id_info.agent_id); switch (appl_ptr->id_info.appl_status) { case SQLM_CONNECTPEND: fprintf(outstream, "\n Application Status ===> Connect Pending"); break; case SQLM_CONNECTED: fprintf(outstream, "\n Application Status ===> Connected"); break; case SQLM_UOWEXEC: fprintf(outstream, "\n Application Status ===> UOW Executing"); break; case SQLM_UOWWAIT: fprintf(outstream, "\n Application Status ===> UOW Waiting in the application"); break; case SQLM_LOCKWAIT: fprintf(outstream, "\n Application Status ===> Lock Waiting"); break; case SQLM_COMMIT_ACT: fprintf(outstream, "\n Application Status ===> Commit Active"); break; case SQLM_ROLLBACK_ACT: fprintf(outstream, "\n Application Status ===> Rollback Active"); break; case SQLM_RECOMP: fprintf(outstream, "\n Application Status ===> Recompiling Plan"); break; case SQLM_COMP: fprintf(outstream, "\n Application Status ===> Compiling SQL Stmt"); break; case SQLM_INTR: fprintf(outstream, "\n Application Status ===> Request Interupted"); break; case SQLM_DISCONNECTPEND: fprintf(outstream, "\n Application Status ===> Disconnect Pending"); break; case SQLM_TPREP: fprintf(outstream, "\n Application Status ===> Prepared Transaction"); break; case SQLM_THCOMT: fprintf(outstream, "\n Application Status ===> Trans. heuristically committed"); break; case SQLM_THABRT: fprintf(outstream, "\n Application Status ===> Trans. heuristically aborted"); break; case SQLM_TEND: fprintf(outstream, "\n Application Status ===> Transaction ended"); break; case SQLM_CREATE_DB: fprintf(outstream, "\n Application Status ===> Creating Database"); break; case SQLM_RESTART: fprintf(outstream, "\n Application Status ===> Restarting Database"); break; case SQLM_RESTORE: fprintf(outstream, "\n Application Status ===> Restoring Database"); break; case SQLM_BACKUP: fprintf(outstream, "\n Application Status ===> Backing Up Database"); break; case SQLM_LOAD: fprintf(outstream, "\n Application Status ===> Loading Database"); break; case SQLM_UNLOAD: fprintf(outstream, "\n Application Status ===> Unloading Database"); break; case SQLM_IOERROR_WAIT: fprintf(outstream, "\n Application Status ===> I/O Error Waiting"); break; case SQLM_QUIESCE_TABLESPACE: fprintf(outstream, "\n Application Status ===> Quiescing a Tablespace"); break; default: fprintf(outstream, "\n Application Status ===> Unknown (%lu)", appl_ptr->id_info.appl_status); break; } /* endswitch */ fprintf(outstream, "\n Application codepage id ===> %lu", appl_ptr->id_info.codepage_id); fprintf(outstream, "\n Application country code ===> %lu", appl_ptr->country_code); ltime = appl_ptr->id_info.status_change_time.seconds; fprintf(outstream, "\n Application Status change time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Application Name ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.appl_name); fprintf(outstream, "\n Application Id ===> %0.*s", SQLM_APPLID_SZ, appl_ptr->id_info.appl_id); fprintf(outstream, "\n Application Id Sequence number ===> %0.*s", SQLM_SEQ_SZ, appl_ptr->id_info.sequence_no); fprintf(outstream, "\n DRDA AS Correlation Token ===> %0.*s", SQLM_APPLID_SZ, appl_ptr->corr_token); fprintf(outstream, "\n Application Authorization Id ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.auth_id); fprintf(outstream, "\n Application Execution Id ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->execution_id); fprintf(outstream, "\n Application client NNAME ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.client_nname); fprintf(outstream, "\n Application client Product name ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.client_prdid); fprintf(outstream, "\n Application client Process Id ===> %lu", appl_ptr->client_pid); switch (appl_ptr->client_platform) { case SQLM_PLATFORM_OS2: fprintf(outstream, "\n Application client platform ===> OS/2"); break; case SQLM_PLATFORM_DOS: fprintf(outstream, "\n Application client platform ===> DOS"); break; case SQLM_PLATFORM_WINDOWS: fprintf(outstream, "\n Application client platform ===> WINDOWS"); break; case SQLM_PLATFORM_AIX: fprintf(outstream, "\n Application client platform ===> AIX"); break; case SQLM_PLATFORM_HP: fprintf(outstream, "\n Application client platform ===> HP"); break; case SQLM_PLATFORM_SUN: fprintf(outstream, "\n Application client platform ===> SUN"); break; case SQLM_PLATFORM_SNI: /*@db41773ygs*/ fprintf(outstream, "\n Application client platform ===> SINIX"); break; case SQLM_PLATFORM_MAC: fprintf(outstream, "\n Application client platform ===> MacIntosh"); break; case SQLM_PLATFORM_WINDOWS95: fprintf(outstream, "\n Application client platform ===> Windows95"); break; case SQLM_PLATFORM_VSE_DRDA: fprintf(outstream, "\n Application client platform ===> VSE via DRDA"); break; /*@de41773ygs*/ case SQLM_PLATFORM_MVS_DRDA: fprintf(outstream, "\n Application client platform ===> MVS via DRDA"); break; case SQLM_PLATFORM_AS400_DRDA: fprintf(outstream, "\n Application client platform ===> AS400 via DRDA"); break; case SQLM_PLATFORM_VM_DRDA: fprintf(outstream, "\n Application client platform ===> VM via DRDA"); break; case SQLM_PLATFORM_UNKNOWN_DRDA: fprintf(outstream, "\n Application client platform ===> Unknown via DRDA"); break; case SQLM_PLATFORM_UNKNOWN: fprintf(outstream, "\n Application client platform ===> Unknown"); break; default: fprintf(outstream, "\n Application client platform ===> Unknown (%lu)", appl_ptr->client_platform); break; } /* endswitch */ switch (appl_ptr->client_protocol) { case SQLM_PROT_APPC: fprintf(outstream, "\n Application client comms protocol ===> APPC"); break; case SQLM_PROT_NETBIOS: fprintf(outstream, "\n Application client comms protocol ===> Netbios"); break; case SQLM_PROT_APPN: fprintf(outstream, "\n Application client comms protocol ===> APPN"); break; case SQLM_PROT_TCPIP: fprintf(outstream, "\n Application client comms protocol ===> TCPIP"); break; case SQLM_PROT_CPIC: fprintf(outstream, "\n Application client comms protocol ===> CPIC"); break; case SQLM_PROT_IPXSPX: fprintf(outstream, "\n Application client comms protocol ===> IPX/SPX"); break; case SQLM_PROT_LOCAL: fprintf(outstream, "\n Application client comms protocol ===> Local"); break; case SQLM_PROT_NPIPE: fprintf(outstream, "\n Application client comms protocol ===> Named Pipe"); break; default: fprintf(outstream, "\n Application client comms protocol ===> Unknown (%lu)", appl_ptr->client_protocol); break; } /* endswitch */ fprintf(outstream, "\n Input Database Alias ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.input_db_alias); fprintf(outstream, "\n Client Database Alias ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.client_db_alias); fprintf(outstream, "\n Database Name ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.db_name); fprintf(outstream, "\n Database path (truncated to 70 chars)\n ===> %0.70s", appl_ptr->id_info.db_path); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nLock Information:"); fprintf(outstream, "\n Locks currently held by the application ===> %lu", appl_ptr->locks_held); fprintf(outstream, "\n Number of waits on lock since connect ===> %lu", appl_ptr->lock_waits); fprintf(outstream, "\n Total time waited on locks since connect===> %lu milliseconds", appl_ptr->lock_wait_time); fprintf(outstream, "\n Lock escalations since appl connect ===> %lu", appl_ptr->lock_escals); fprintf(outstream, "\n X lock escalations since appl connect ===> %lu", appl_ptr->x_lock_escals); fprintf(outstream, "\n Deadlocks since appl connect ===> %lu", appl_ptr->deadlocks); fprintf(outstream, "\n Lock timeouts since appl connect ===> %lu", appl_ptr->lock_timeouts); fprintf(outstream, "\n Time UOW waited on locks ===> %lu milliseconds", appl_ptr->uow_lock_wait_time); fprintf(outstream, "\n\nSorting Information:"); fprintf(outstream, "\n Total number of sorts ===> %lu", appl_ptr->total_sorts); fprintf(outstream, "\n Total Sort time ===> %lu milliseconds", appl_ptr->total_sort_time); fprintf(outstream, "\n Number of sort overflows ===> %lu", appl_ptr->sort_overflows); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nBuffer Pool Information:"); fprintf(outstream, "\n Buffer pool data logical reads ===> %lu", appl_ptr->pool_data_l_reads); fprintf(outstream, "\n Buffer pool data physical reads ===> %lu", appl_ptr->pool_data_p_reads); fprintf(outstream, "\n Buffer pool data writes ===> %lu", appl_ptr->pool_data_writes); fprintf(outstream, "\n Buffer pool index logical reads ===> %lu", appl_ptr->pool_index_l_reads); fprintf(outstream, "\n Buffer pool index physical reads ===> %lu", appl_ptr->pool_index_p_reads); fprintf(outstream, "\n Buffer pool index writes ===> %lu", appl_ptr->pool_index_writes); fprintf(outstream, "\n Buffer pool read time since 1st connect ===> %lu milliseconds", appl_ptr->pool_read_time); fprintf(outstream, "\n Buffer pool write time since 1st connect===> %lu milliseconds", appl_ptr->pool_write_time); fprintf(outstream, "\n\nDirect I/O Information:"); fprintf(outstream, "\n Sectors read directly ===> %lu", appl_ptr->direct_reads); fprintf(outstream, "\n Sectors written directly ===> %lu", appl_ptr->direct_writes); fprintf(outstream, "\n Number of direct read requests ===> %lu", appl_ptr->direct_read_reqs); fprintf(outstream, "\n Number of direct write requests ===> %lu", appl_ptr->direct_write_reqs); fprintf(outstream, "\n Direct read time ===> %lu milliseconds", appl_ptr->direct_read_time); fprintf(outstream, "\n Direct write time ===> %lu milliseconds", appl_ptr->direct_write_time); fprintf(outstream, "\n\nSQL Statement counts"); fprintf(outstream, "\n Number of Commit SQL statements ===> %lu", appl_ptr->commit_sql_stmts); fprintf(outstream, "\n Number of Rollback SQL statements ===> %lu", appl_ptr->rollback_sql_stmts); fprintf(outstream, "\n Number of Dynamic SQL statements ===> %lu", appl_ptr->dynamic_sql_stmts); fprintf(outstream, "\n Number of Static SQL statements ===> %lu", appl_ptr->static_sql_stmts); fprintf(outstream, "\n Number of Failed SQL statements ===> %lu", appl_ptr->failed_sql_stmts); fprintf(outstream, "\n Number of Select SQL statements ===> %lu", appl_ptr->select_sql_stmts); fprintf(outstream, "\n Number of Data Def. Language SQL stmts ===> %lu", appl_ptr->ddl_sql_stmts); fprintf(outstream, "\n Number of Update/Insert/Delete SQL stmts===> %lu", appl_ptr->uid_sql_stmts); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nInternal counts"); fprintf(outstream, "\n Number of auto rebinds ===> %lu", appl_ptr->int_auto_rebinds); fprintf(outstream, "\n Number of internal row deletions ===> %lu", appl_ptr->int_rows_deleted); fprintf(outstream, "\n Number of internal row updates ===> %lu", appl_ptr->int_rows_updated); fprintf(outstream, "\n Number of internal row inserts ===> %lu", appl_ptr->int_rows_inserted); fprintf(outstream, "\n Number of internal commits ===> %lu", appl_ptr->int_commits); fprintf(outstream, "\n Number of internal rollbacks ===> %lu", appl_ptr->int_rollbacks); fprintf(outstream, "\n Number of rollbacks due to deadlocks ===> %lu", appl_ptr->int_deadlock_rollbacks); fprintf(outstream, "\n\nRow counts"); fprintf(outstream, "\n Number of row deletions ===> %lu", appl_ptr->rows_deleted); fprintf(outstream, "\n Number of row insertions ===> %lu", appl_ptr->rows_inserted); fprintf(outstream, "\n Number of row updates ===> %lu", appl_ptr->rows_updated); fprintf(outstream, "\n Number of row selections ===> %lu", appl_ptr->rows_selected); fprintf(outstream, "\n Number of rows read ===> %lu", appl_ptr->rows_read); fprintf(outstream, "\n Number of rows written ===> %lu", appl_ptr->rows_written); fprintf(outstream, "\n\n Number of binds/precompiles ===> %lu", appl_ptr->binds_precompiles); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nStatement Information:"); switch (appl_ptr->stmt_type) { case SQLM_STATIC: fprintf(outstream, "\n Statement Type ===> STATIC"); break; case SQLM_DYNAMIC: fprintf(outstream, "\n Statement Type ===> DYNAMIC"); break; case SQLM_NON_STMT: fprintf(outstream, "\n Statement Type ===> NON-STATEMENT OPERATION"); break; case 0: fprintf(outstream, "\n Statement Type ===> "); break; default: fprintf(outstream, "\n Statement Type ===> UNKNOWN (%lu)", appl_ptr->stmt_type); break; } switch (appl_ptr->stmt_operation) { case SQLM_PREPARE: fprintf(outstream, "\n Statement Operation ===> PREPARE"); break; case SQLM_EXECUTE: fprintf(outstream, "\n Statement Operation ===> EXECUTE"); break; case SQLM_EXECUTE_IMMEDIATE: fprintf(outstream, "\n Statement Operation ===> EXECUTE IMMEDIATE"); break; case SQLM_OPEN: fprintf(outstream, "\n Statement Operation ===> OPEN"); break; case SQLM_FETCH: fprintf(outstream, "\n Statement Operation ===> FETCH"); break; case SQLM_CLOSE: fprintf(outstream, "\n Statement Operation ===> CLOSE"); break; case SQLM_DESCRIBE: fprintf(outstream, "\n Statement Operation ===> DESCRIBE"); break; case SQLM_STATIC_COMMIT: fprintf(outstream, "\n Statement Operation ===> STATIC COMMIT"); break; case SQLM_STATIC_ROLLBACK: fprintf(outstream, "\n Statement Operation ===> STATIC ROLLBACK"); break; case 0: fprintf(outstream, "\n Statement Operation ===>"); break; default: fprintf(outstream, "\n Statement Operation ===>UNKNOWN (%lu", appl_ptr->stmt_operation); break; } /* switch (appl_ptr->stmt_operation) */ fprintf(outstream, "\n Section Number ===> %lu", appl_ptr->section_number); ltime = appl_ptr->stmt_start.seconds; fprintf(outstream, "\n Statement Operation Start Time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = appl_ptr->stmt_stop.seconds; fprintf(outstream, "\n Statement Operation Stop Time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Cursor Name ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->cursor_name); fprintf(outstream, "\n Application Creator ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->creator); fprintf(outstream, "\n Package Name ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->package_name); fprintf(outstream, "\n\nUOW Information:"); fprintf(outstream, "\n Log space used in current UOW ===> %lu", appl_ptr->uow_log_space_used); switch (appl_ptr->uow_comp_status) { case SQLM_UOWCOMMIT: fprintf(outstream, "\n UOW Completion Status ===> UOW Commit"); break; case SQLM_UOWROLLBACK: fprintf(outstream, "\n UOW Completion Status ===> UOW Rolled Back"); break; case SQLM_UOWDEADLOCK: fprintf(outstream, "\n UOW Completion Status ===> UOW RB due to Deadlock"); break; case SQLM_UOWABEND: fprintf(outstream, "\n UOW Completion Status ===> UOW RB due to Abend"); break; case SQLM_APPL_END: fprintf(outstream, "\n UOW Completion Status ===> Appl Normal Termination"); break; case SQLM_UOWLOCKTIMEOUT: fprintf(outstream, "\n UOW Completion Status ===> UOW RB - Lock Timeout"); break; case 0: fprintf(outstream, "\n UOW Completion Status ===> "); break; default: fprintf(outstream, "\n UOW Completion Status ===> Unknown (%lu)", appl_ptr->uow_comp_status); break; } /* endswitch */ ltime = appl_ptr->prev_uow_stop_time.seconds; fprintf(outstream, "\n Previous UOW stop time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = appl_ptr->uow_start_time.seconds; fprintf(outstream, "\n UOW start time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = appl_ptr->uow_stop_time.seconds; fprintf(outstream, "\n UOW stop time ===> %24.24s", (ltime) ? ctime(<ime) : ""); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nCursor Information:"); fprintf(outstream, "\n Currently open remote cursors ===> %lu", appl_ptr->open_rem_curs); fprintf(outstream, "\n Currently open remote blocked cursors ===> %lu", appl_ptr->open_rem_curs_blk); fprintf(outstream, "\n Currently open local cursors ===> %lu", appl_ptr->open_loc_curs); fprintf(outstream, "\n Currently open local blocked cursors ===> %lu", appl_ptr->open_loc_curs_blk); fprintf(outstream, "\n Rejected block cursor requests ===> %lu", appl_ptr->rej_curs_blk); fprintf(outstream, "\n Accepted block cursor requests ===> %lu", appl_ptr->acc_curs_blk); fprintf(outstream, "\n\nApplication Times/Timestamps:"); ltime = appl_ptr->appl_con_time.seconds; fprintf(outstream, "\n Application connect start time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = appl_ptr->conn_complete_time.seconds; fprintf(outstream, "\n Connect completion time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = appl_ptr->last_reset.seconds; fprintf(outstream, "\n Last reset time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Application User CPU time ===> %lu.%0.6lu seconds", appl_ptr->agent_usr_cpu_time.seconds, appl_ptr->agent_usr_cpu_time.microsec); fprintf(outstream, "\n Application System CPU time ===> %lu.%0.6lu seconds", appl_ptr->agent_sys_cpu_time.seconds, appl_ptr->agent_sys_cpu_time.microsec); fprintf(outstream, "\n Application Idle CPU time ===> %lu seconds", appl_ptr->appl_idle_time); fprintf(outstream, "\n\nPackage Cache Information:"); fprintf(outstream, "\n Package Cache Lookups ===> %lu", appl_ptr->pkg_cache_lookups); fprintf(outstream, "\n Package Cache Inserts ===> %lu", appl_ptr->pkg_cache_inserts); fprintf(outstream, "\n\nCatalog Cache Information:"); fprintf(outstream, "\n Catalog Cache Overflows ===> %lu", appl_ptr->cat_cache_overflows); fprintf(outstream, "\n Catalog Cache Heap Full ===> %lu", appl_ptr->cat_cache_heap_full); /* advance buffer_index to next structure in the output buffer */ buffer_index += appl_ptr->size; if (output_opt == SCREEN_OUTPUT) pause(); } /* process_appl */ /*****************************************************************************/ /* process_applinfo */ /* This function processes summary application information. The information */ /* is in an sqlm_applinfo data structure */ /*****************************************************************************/ void process_applinfo() { time_t ltime; struct sqlm_applinfo *applinfo_ptr; if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* SUMMARY APPLICATION INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* cast buffer contents to an sqlm_applinfo data structure */ applinfo_ptr = (struct sqlm_applinfo *)(buffer_index); fprintf(outstream, "\n Application agent id ===> %lu\n", applinfo_ptr->id_info.agent_id); switch (applinfo_ptr->id_info.appl_status) { case SQLM_CONNECTPEND: fprintf(outstream, "\n Application Status ===> Connect Pending"); break; case SQLM_CONNECTED: fprintf(outstream, "\n Application Status ===> Connected"); break; case SQLM_UOWEXEC: fprintf(outstream, "\n Application Status ===> UOW Executing"); break; case SQLM_UOWWAIT: fprintf(outstream, "\n Application Status ===> UOW Waiting in the application"); break; case SQLM_LOCKWAIT: fprintf(outstream, "\n Application Status ===> Lock Waiting"); break; case SQLM_COMMIT_ACT: fprintf(outstream, "\n Application Status ===> Commit Active"); break; case SQLM_ROLLBACK_ACT: fprintf(outstream, "\n Application Status ===> Rollback Active"); break; case SQLM_RECOMP: fprintf(outstream, "\n Application Status ===> Recompiling Plan"); break; case SQLM_COMP: fprintf(outstream, "\n Application Status ===> Compiling SQL Stmt"); break; case SQLM_INTR: fprintf(outstream, "\n Application Status ===> Request Interupted"); break; case SQLM_DISCONNECTPEND: fprintf(outstream, "\n Application Status ===> Disconnect Pending"); break; case SQLM_TPREP: fprintf(outstream, "\n Application Status ===> Prepared Transaction"); break; case SQLM_THCOMT: fprintf(outstream, "\n Application Status ===> Trans. heuristically committed"); break; case SQLM_THABRT: fprintf(outstream, "\n Application Status ===> Trans. heuristically aborted"); break; case SQLM_TEND: fprintf(outstream, "\n Application Status ===> Transaction ended"); break; case SQLM_CREATE_DB: fprintf(outstream, "\n Application Status ===> Creating Database"); break; case SQLM_RESTART: fprintf(outstream, "\n Application Status ===> Restarting Database"); break; case SQLM_RESTORE: fprintf(outstream, "\n Application Status ===> Restoring Database"); break; case SQLM_BACKUP: fprintf(outstream, "\n Application Status ===> Backing Up Database"); break; case SQLM_LOAD: fprintf(outstream, "\n Application Status ===> Loading Database"); break; case SQLM_UNLOAD: fprintf(outstream, "\n Application Status ===> Unloading Database"); break; case SQLM_IOERROR_WAIT: fprintf(outstream, "\n Application Status ===> I/O Error Waiting"); break; case SQLM_QUIESCE_TABLESPACE: fprintf(outstream, "\n Application Status ===> Quiescing a Tablespace"); break; default: fprintf(outstream, "\n Application Status ===> Unknown (%lu)", applinfo_ptr->id_info.appl_status ); break; } /* endswitch */ fprintf(outstream, "\n Application codepage id ===> %lu", applinfo_ptr->id_info.codepage_id); fprintf(outstream, "\n Application country code ===> %lu", applinfo_ptr->country_code); ltime = applinfo_ptr->id_info.status_change_time.seconds; fprintf(outstream, "\n Application Status change time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Application Name ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.appl_name); fprintf(outstream, "\n Application Id ===> %0.*s", SQLM_APPLID_SZ, applinfo_ptr->id_info.appl_id); fprintf(outstream, "\n Application Id Sequence number ===> %0.*s", SQLM_SEQ_SZ, applinfo_ptr->id_info.sequence_no); fprintf(outstream, "\n DRDA AS Correlation Token ===> %0.*s", SQLM_APPLID_SZ, applinfo_ptr->corr_token); fprintf(outstream, "\n Application Authorization Id ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.auth_id); fprintf(outstream, "\n Application Execution Id ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->execution_id); fprintf(outstream, "\n Application client NNAME ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.client_nname); fprintf(outstream, "\n Application client Product name ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.client_prdid); fprintf(outstream, "\n Application client Process Id ===> %lu", applinfo_ptr->client_pid); switch (applinfo_ptr->client_platform) { case SQLM_PLATFORM_OS2: fprintf(outstream, "\n Application client platform ===> OS/2"); break; case SQLM_PLATFORM_DOS: fprintf(outstream, "\n Application client platform ===> DOS"); break; case SQLM_PLATFORM_WINDOWS: fprintf(outstream, "\n Application client platform ===> WINDOWS"); break; case SQLM_PLATFORM_AIX: fprintf(outstream, "\n Application client platform ===> AIX"); break; case SQLM_PLATFORM_HP: fprintf(outstream, "\n Application client platform ===> HP"); break; case SQLM_PLATFORM_SUN: fprintf(outstream, "\n Application client platform ===> SUN"); break; case SQLM_PLATFORM_MVS_DRDA: fprintf(outstream, "\n Application client platform ===> MVS via DRDA"); break; case SQLM_PLATFORM_AS400_DRDA: fprintf(outstream, "\n Application client platform ===> AS400 via DRDA"); break; case SQLM_PLATFORM_VM_DRDA: fprintf(outstream, "\n Application client platform ===> VM via DRDA"); break; case SQLM_PLATFORM_UNKNOWN_DRDA: fprintf(outstream, "\n Application client platform ===> Unknown via DRDA"); break; case SQLM_PLATFORM_UNKNOWN: fprintf(outstream, "\n Application client platform ===> Unknown"); break; default: fprintf(outstream, "\n Application client platform ===> Unknown (%lu)", applinfo_ptr->client_platform); break; } /* endswitch */ switch (applinfo_ptr->client_protocol) { case SQLM_PROT_APPC: fprintf(outstream, "\n Application client comms protocol ===> APPC"); break; case SQLM_PROT_NETBIOS: fprintf(outstream, "\n Application client comms protocol ===> Netbios"); break; case SQLM_PROT_APPN: fprintf(outstream, "\n Application client comms protocol ===> APPN"); break; case SQLM_PROT_TCPIP: fprintf(outstream, "\n Application client comms protocol ===> TCPIP"); break; case SQLM_PROT_CPIC: fprintf(outstream, "\n Application client comms protocol ===> CPIC"); break; case SQLM_PROT_IPXSPX: fprintf(outstream, "\n Application client comms protocol ===> IPX/SPX"); break; case SQLM_PROT_LOCAL: fprintf(outstream, "\n Application client comms protocol ===> Local"); break; case SQLM_PROT_NPIPE: fprintf(outstream, "\n Application client comms protocol ===> Named Pipe"); break; default: fprintf(outstream, "\n Application client comms protocol ===> Unknown (%lu)", applinfo_ptr->client_protocol); break; } /* endswitch */ fprintf(outstream, "\n Input Database Alias ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.input_db_alias); fprintf(outstream, "\n Client Database Alias ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.client_db_alias); fprintf(outstream, "\n Database Name ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.db_name); fprintf(outstream, "\n Database path (truncated to 70 chars)\n ===> %0.70s\n", applinfo_ptr->id_info.db_path); buffer_index += (unsigned int) applinfo_ptr->size; /* move to next struct */ if (output_opt == SCREEN_OUTPUT) pause(); } /* process_applinfo */ /********************************************************************************/ /* process_dcs_applinfo */ /* This function processes DB2 Connect application information. The information */ /* is in an sqlm_dcs_applid_info data structure . */ /* This information is only available from a DB2 Connect server (gateway). */ /********************************************************************************/ void process_dcs_applinfo() { time_t ltime; struct sqlm_dcs_applinfo *dcs_appl1; /* work pointer */ struct sqlm_dcs_applid_info *dcs_appl; /* work pointer */ if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* DB2 Connect APPLICATION INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* Cast the buffer contents to an sqlm_dcs_applinfo data structure */ dcs_appl1 = (struct sqlm_dcs_applinfo *)(buffer_index); /* Skip the structure sqlm_dcs_applinfo and point to the secondary */ /* structure sqlm_dcs_applid_info: */ buffer_index += dcs_appl1->size; dcs_appl = (sqlm_dcs_applid_info *) buffer_index; fprintf(outstream, "\n Application handle (agent ID) ===> %lu", dcs_appl->agent_id); fprintf(outstream, "\n Application codepage ID ===> %lu", dcs_appl->codepage_id); fprintf(outstream, "\n Application name ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->appl_name); fprintf(outstream, "\n Client application ID ===> %0.*s", SQLM_APPLID_SZ, dcs_appl->appl_id); fprintf(outstream, "\n Application ID Sequence number ===> %0.*s", SQLM_SEQ_SZ, dcs_appl->sequence_no); fprintf(outstream, "\n Application Authorization Id ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->auth_id); fprintf(outstream, "\n Application client execution ID ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->execution_id); fprintf(outstream, "\n Application client NNAME ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->client_nname); fprintf(outstream, "\n Application client Product name ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->client_prdid); switch (dcs_appl->dcs_appl_status) { case SQLM_DCS_CONNECTPEND_OUTBOUND: fprintf(outstream, "\n Application status ===> %s", "connect pending - outbound"); break; case SQLM_DCS_UOWWAIT_OUTBOUND: fprintf(outstream, "\n Application status ===> %s", "waiting for host reply"); break; case SQLM_DCS_UOWWAIT_INBOUND: fprintf(outstream, "\n Application status ===> %s", "waiting for client request"); break; } /* end switch on DCS application status */ ltime = dcs_appl->status_change_time.seconds; fprintf(outstream, "\n Status change time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Gateway Database Alias ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->gw_db_alias); fprintf(outstream, "\n DCS Database Name ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->dcs_db_name); fprintf(outstream, "\n Host Database Name ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->host_db_name); fprintf(outstream, "\n Host Product Id ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->host_prdid); fprintf(outstream, "\n Host Application Id ===> %0.*s", SQLM_APPLID_SZ, dcs_appl->outbound_appl_id); fprintf(outstream, "\n Outbound Sequence number ===> %0.*s\n", SQLM_SEQ_SZ, dcs_appl->outbound_sequence_no); buffer_index += (unsigned int) dcs_appl->size; /* move to next struct */ if (output_opt == SCREEN_OUTPUT) pause(); } /* process_dcs_applinfo */ /*****************************************************************************/ /* process_table */ /* This function processes table information. This information is stored in */ /* sqlm_table_header and sqlm_table data structures. First, we find an */ /* sqlm_table_header structure, which provides general information, and the */ /* number of sqlm_table structures following in the buffer. */ /*****************************************************************************/ void process_table() { time_t ltime; unsigned int i; /* counter */ struct sqlm_table *table_ptr; struct sqlm_table_header *table_header_ptr; char table_type[21]; char *c; if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* TABLE INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* cast buffer contents to an sqlm_table_header data structure */ table_header_ptr = (struct sqlm_table_header *) (buffer_index); fprintf(outstream, "\nTable Header Information:"); fprintf(outstream, "\n Number of tables collected ===> %lu", table_header_ptr->num_tables); ltime = table_header_ptr->db_conn_time.seconds; fprintf(outstream, "\n First database connect time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = table_header_ptr->last_reset.seconds; fprintf(outstream, "\n Last reset time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Input Database Alias ===> %0.*s", SQLM_IDENT_SZ, table_header_ptr->input_db_alias); fprintf(outstream, "\n Database Name ===> %0.*s", SQLM_IDENT_SZ, table_header_ptr->db_name); fprintf(outstream, "\n Database path (truncated to 70 chars)\n ===> %0.70s", table_header_ptr->db_path); if (output_opt == SCREEN_OUTPUT) pause(); /* advance pointer to first sqlm_table structure */ buffer_index += table_header_ptr->size; /* process each sqlm_table structure returned */ for (i = 0; i < table_header_ptr->num_tables; ++i) { /* cast buffer contents to an sqlm_table data structure */ table_ptr = (struct sqlm_table *)(buffer_index); if (table_ptr->info_type != SQLM_TABLE_SS) { printf("\n\n***************************************************************\n"); printf("* ERROR processing output buffer from snapshot monitor. *\n"); printf("* Expecting sqlm_table structure. First chars: %10c *\n",(unsigned char)*buffer_index); printf("* buffer offset where error occurred: %10u *\n",(ptrdiff_t)(buffer_index - buffer_ptr)); printf("* Exiting ssdriver. *\n\n"); printf("\n***************************************************************\n"); cleanup(NULL); exit(99); } /***************************************************************/ /* Print the headers before the first table's info */ /***************************************************************/ if (i == 0) { fprintf(outstream, "Individual Table Information:\n"); fprintf(outstream, "Table Name Table Type Rows Written Rows Read Overflows\n"); fprintf(outstream, "--------------------------- ------------ ------------ ---------- ----------\n"); } switch(table_ptr->table_type) { case SQLM_USER_TABLE: strcpy(table_type, "User"); break; case SQLM_DROPPED_TABLE: strcpy(table_type, "Dropped User"); break; case SQLM_TEMP_TABLE: strcpy(table_type, "Temporary"); break; case SQLM_CATALOG_TABLE: strcpy(table_type, "Catalog"); break; case SQLM_REORG_TABLE: strcpy(table_type, "Reorg"); break; default: strcpy(table_type, "Unknown"); break; } /***********************************************************************/ /* Null terminate the table_schema */ /***********************************************************************/ for (c = table_ptr->table_schema; *c != ' '; ++c); *c = '\0'; /***********************************************************************/ /* Display information about each table in a tabular format similar */ /* to the one provided by the CLP command. */ /***********************************************************************/ fprintf(outstream, "%s.%-.*s %-*s %*lu %*lu %*lu\n", table_ptr->table_schema, 18 + 8 - strlen(table_ptr->table_schema), table_ptr->table_name, 12, table_type, 10, table_ptr->rows_written, 10, table_ptr->rows_read, 10, table_ptr->overflow_accesses); /* move pointer to next structure */ buffer_index += table_ptr->size; } /* end of for loop */ if ((output_opt == SCREEN_OUTPUT) && (table_header_ptr->num_tables > 0)) pause(); } /* process_table */ /*****************************************************************************/ /* process_lock */ /* This function processes lock information. This information is contained */ /* in sqlm_dbase_lock, sqlm_appl_lock, and sqlm_lock data structures. */ /* First, an sqlm_dbase_lock structure with information on the database, and */ /* the number of sqlm_appl_lock structures returned. Each sqlm_appl_lock */ /* structure contains application info, and the number of sqlm_lock */ /* structures following in the buffer. */ /*****************************************************************************/ void process_lock() { time_t ltime; unsigned int i, j; /* counters */ struct sqlm_dbase_lock *dbase_lock_ptr; /* local ptr to sqlm_dbase_lock */ struct sqlm_appl_lock *appl_lock_ptr; /* local ptr to sqlm_appl_lock */ struct sqlm_lock *lock_ptr; /* local ptr to sqlm_lock */ char lock_type[15]; /* string for lock object type */ char lock_mode[5]; /* string for lock mode */ char lock_status[11]; /* string for lock status */ char lock_obj_name[41]; /* string for lock object name */ char *c; if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* LOCK INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* cast the buffer contents to an sqlm_dbase_lock data structure */ dbase_lock_ptr = (struct sqlm_dbase_lock *)(buffer_index); fprintf(outstream, "\nDatabase Lock Information:"); fprintf(outstream, "\n Locks currently held ===> %lu", dbase_lock_ptr->locks_held); fprintf(outstream, "\n No. of applications currently connected ===> %lu", dbase_lock_ptr->appls_cur_cons); fprintf(outstream, "\n Applications waiting on locks ===> %lu", dbase_lock_ptr->locks_waiting); fprintf(outstream, "\n Input Database Alias ===> %0.*s", SQLM_IDENT_SZ, dbase_lock_ptr->input_db_alias); fprintf(outstream, "\n Database Name ===> %0.*s", SQLM_IDENT_SZ, dbase_lock_ptr->db_name); fprintf(outstream, "\n Database path (truncated to 70 chars)\n ===> %0.70s", dbase_lock_ptr->db_path); fprintf(outstream, "\n Number of sqlm_appl_lock returned ===> %lu\n", dbase_lock_ptr->num_appls); /* advance buffer_index to the next structure in the buffer */ buffer_index += dbase_lock_ptr->size; if (output_opt == SCREEN_OUTPUT) pause(); /*******************************************************************************/ /* Loop until all sqlm_appl_lock structures are processed */ /*******************************************************************************/ for (i = 0; i < dbase_lock_ptr->num_appls; i++) { /* cast the buffer contents to an sqlm_appl_lock data structure */ appl_lock_ptr = (struct sqlm_appl_lock *)(buffer_index); if (appl_lock_ptr->info_type != SQLM_APPL_LOCK_SS) { printf("\n\n***************************************************************\n"); printf("* ERROR processing output buffer from snapshot monitor. *\n"); printf("* Expecting sqlm_appl_lock structure. First chars: %10c *\n",(unsigned char)*buffer_index); printf("* buffer offset where error occurred: %10u *\n",(ptrdiff_t)(buffer_index - buffer_ptr)); printf("* Exiting ssdriver. *\n\n"); printf("\n***************************************************************\n"); cleanup(NULL); exit(99); } fprintf(outstream, "\n\nApplication Lock Information:"); fprintf(outstream, "\n Agent ID ===> %lu", appl_lock_ptr->agent_id); switch (appl_lock_ptr->appl_status) { case SQLM_CONNECTPEND: fprintf(outstream, "\n Application Status ===> Connect Pending"); break; case SQLM_CONNECTED: fprintf(outstream, "\n Application Status ===> Connected"); break; case SQLM_UOWEXEC: fprintf(outstream, "\n Application Status ===> UOW Executing"); break; case SQLM_UOWWAIT: fprintf(outstream, "\n Application Status ===> UOW Waiting in the application"); break; case SQLM_LOCKWAIT: fprintf(outstream, "\n Application Status ===> Lock Waiting"); break; case SQLM_COMMIT_ACT: fprintf(outstream, "\n Application Status ===> Commit Active"); break; case SQLM_ROLLBACK_ACT: fprintf(outstream, "\n Application Status ===> Rollback Active"); break; case SQLM_RECOMP: fprintf(outstream, "\n Application Status ===> Recompiling Plan"); break; case SQLM_COMP: fprintf(outstream, "\n Application Status ===> Compiling SQL Stmt"); break; case SQLM_INTR: fprintf(outstream, "\n Application Status ===> Request Interupted"); break; case SQLM_DISCONNECTPEND: fprintf(outstream, "\n Application Status ===> Disconnect Pending"); break; case SQLM_TPREP: fprintf(outstream, "\n Application Status ===> Prepared Transaction"); break; case SQLM_THCOMT: fprintf(outstream, "\n Application Status ===> Trans. heuristically committed"); break; case SQLM_THABRT: fprintf(outstream, "\n Application Status ===> Trans. heuristically aborted"); break; case SQLM_TEND: fprintf(outstream, "\n Application Status ===> Transaction ended"); break; case SQLM_CREATE_DB: fprintf(outstream, "\n Application Status ===> Creating Database"); break; case SQLM_RESTART: fprintf(outstream, "\n Application Status ===> Restarting Database"); break; case SQLM_RESTORE: fprintf(outstream, "\n Application Status ===> Restoring Database"); break; case SQLM_BACKUP: fprintf(outstream, "\n Application Status ===> Backing Up Database"); break; case SQLM_LOAD: fprintf(outstream, "\n Application Status ===> Loading Database"); break; case SQLM_UNLOAD: fprintf(outstream, "\n Application Status ===> Unloading Database"); break; case SQLM_IOERROR_WAIT: fprintf(outstream, "\n Application Status ===> I/O Error Waiting"); break; case SQLM_QUIESCE_TABLESPACE: fprintf(outstream, "\n Application Status ===> Quiescing a Tablespace"); break; default: fprintf(outstream, "\n Application Status ===> Unknown (%lu)", appl_lock_ptr->appl_status); break; } /* endswitch */ fprintf(outstream, "\n Application Codepage Id ===> %lu", appl_lock_ptr->codepage_id); fprintf(outstream, "\n Locks currently held by application ===> %lu", appl_lock_ptr->locks_held); ltime = appl_lock_ptr->status_change_time.seconds; fprintf(outstream, "\n Application status change time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Application Id ===> %0.*s", SQLM_APPLID_SZ, appl_lock_ptr->appl_id); fprintf(outstream, "\n Application Id sequence number ===> %0.*s", SQLM_SEQ_SZ, appl_lock_ptr->sequence_no); fprintf(outstream, "\n Application name ===> %0.*s", SQLM_IDENT_SZ, appl_lock_ptr->appl_name); fprintf(outstream, "\n Authorization ID ===> %0.*s", SQLM_IDENT_SZ, appl_lock_ptr->auth_id); fprintf(outstream, "\n Client database alias ===> %0.*s", SQLM_IDENT_SZ, appl_lock_ptr->client_db_alias); fprintf(outstream, "\n Lock waited on information:"); fprintf(outstream, "\n number of locks returned ===> %lu\n", appl_lock_ptr->num_locks); /* advance to next structure in the buffer */ buffer_index += appl_lock_ptr->size; if (output_opt == SCREEN_OUTPUT) pause(); /*********************************************************************/ /* Display information for each of the locks held by the application */ /*********************************************************************/ for (j = 0; j < appl_lock_ptr->num_locks; j++) { /* cast the buffer contents to an sqlm_lock data structure */ lock_ptr = (struct sqlm_lock *)(buffer_index); if (lock_ptr->info_type != SQLM_LOCK_SS) { printf("\n\n***************************************************************\n"); printf("* ERROR processing output buffer from snapshot monitor. *\n"); printf("* Expecting sqlm_lock structure. First chars: %10c *\n",(unsigned char)*buffer_index); printf("* buffer offset where error occurred: %10u *\n",(ptrdiff_t)(buffer_index - buffer_ptr)); printf("* Exiting ssdriver. *\n\n"); printf("\n***************************************************************\n"); cleanup(NULL); exit(99); } /*****************************************************************/ /* Print headers before first lock information */ /*****************************************************************/ if (j == 0) { fprintf(outstream, "\nIndividual Lock Information:"); fprintf(outstream, "\nObject Name Object Type Mode Status\n"); fprintf(outstream, "---------------------------------------- --------------- ---- ----------\n"); } /* Null terminate table schema */ for (c = lock_ptr->table_schema; *c != ' '; ++c); *c = '\0'; switch (lock_ptr->lock_object_type) { case SQLM_ROW_LOCK: strcpy(lock_type, "Row"); sprintf(lock_obj_name, "%s.%-.*s (%ld)", lock_ptr->table_schema, 18 + 8 - strlen(lock_ptr->table_schema), lock_ptr->table_name, lock_ptr->lock_object_name); break; case SQLM_TABLE_LOCK: strcpy(lock_type, "Table"); sprintf(lock_obj_name, "%s.%-.*s", lock_ptr->table_schema, 18 + 8 - strlen(lock_ptr->table_schema), lock_ptr->table_name); break; case SQLM_INTERNAL_LOCK: strcpy(lock_type, "Internal"); lock_obj_name[0] = '\0'; break; case SQLM_TABLESPACE_LOCK: strcpy(lock_type, "Tablespace"); sprintf(lock_obj_name, "%.*s", 18, lock_ptr->tablespace_name); break; default: strcpy(lock_type, "Unknown"); break; } /* switch */ switch (lock_ptr->lock_mode) { case SQLM_LNON: strcpy(lock_mode, "NO"); break; case SQLM_LOIS: strcpy(lock_mode, "IS"); break; case SQLM_LOIX: strcpy(lock_mode, "IX"); break; case SQLM_LOOS: strcpy(lock_mode, "S"); break; case SQLM_LSIX: strcpy(lock_mode, "SIX"); break; case SQLM_LOOX: strcpy(lock_mode, "X"); break; case SQLM_LOIN: strcpy(lock_mode, "IN"); break; case SQLM_LOOZ: strcpy(lock_mode, "Z"); break; case SQLM_LOOU: strcpy(lock_mode, "U"); break; default: strcpy(lock_mode, "????"); break; } /* endswitch */ switch (lock_ptr->lock_status) { case SQLM_LRBGRNT: strcpy(lock_status, "Granted"); break; case SQLM_LRBCONV: strcpy(lock_status, "Converting"); break; default: strcpy(lock_status, "Unknown"); break; } /* switch */ /*******************************************************************/ /* Display information about each lock in a tabular format similar */ /* to the one returned by the CLP Get Snapshot command. */ /*******************************************************************/ fprintf(outstream, " %-*s %-*s %-*s %-*s\n", 40, lock_obj_name, 15, lock_type, 4, lock_mode, 10, lock_status); /* advance to next structure in the buffer */ buffer_index += lock_ptr->size; } /* endfor */ if (output_opt == SCREEN_OUTPUT) pause(); } /* end of for loop */ } /* process_lock */ /*****************************************************************************/ /* process_tablespace */ /* This function processes tablespace information. This information is */ /* contained in sqlm_tablespace_header and sqlm_tablespace data structures. */ /* First, an sqlm_tablespace_header structure with information on the */ /* database, and the number of sqlm_tablespace structures returned. */ /*****************************************************************************/ void process_tablespace() { time_t ltime; unsigned int i, j; /* counters */ sqlm_tablespace_header *ts_header_ptr; /* local ptr to tablespace header*/ sqlm_tablespace *ts_ptr; /* local ptr to tablespace info */ if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* TABLESPACE INFORMATION *\n"); fprintf(outstream, "**********************************************************************\n"); /* cast the buffer contents to an sqlm_tablespace_header data structure */ ts_header_ptr = (sqlm_tablespace_header *)(buffer_index); fprintf(outstream, "\nDatabase Information:"); fprintf(outstream, "\n Number of tablespaces collected ===> %lu", ts_header_ptr->num_tablespaces); ltime = ts_header_ptr->db_conn_time.seconds; fprintf(outstream, "\n First database connect time ===> %24.24s", (ltime) ? ctime(<ime) : ""); ltime = ts_header_ptr->last_reset.seconds; fprintf(outstream, "\n Last reset time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Input Database Alias ===> %0.*s", SQLM_IDENT_SZ, ts_header_ptr->input_db_alias); fprintf(outstream, "\n Database Name ===> %0.*s", SQLM_IDENT_SZ, ts_header_ptr->db_name); fprintf(outstream, "\n Database path (truncated to 70 chars)\n ===> %0.70s", ts_header_ptr->db_path); /* advance buffer_index to the next structure in the buffer */ buffer_index += ts_header_ptr->size; if (output_opt == SCREEN_OUTPUT) pause(); /*******************************************************************************/ /* Loop until all sqlm_tablespace structures are processed */ /*******************************************************************************/ for (i = 0; i < ts_header_ptr->num_tablespaces; i++) { /* cast the buffer contents to an sqlm_tablespace data structure */ ts_ptr = (struct sqlm_tablespace *)(buffer_index); if (ts_ptr->info_type != SQLM_TABLESPACE_SS) { printf("\n\n***************************************************************\n"); printf("* ERROR processing output buffer from snapshot monitor. *\n"); printf("* Expecting sqlm_tablespace structure. First chars: %10c*\n",(unsigned char)*buffer_index); printf("* buffer offset where error occurred: %10u *\n",(ptrdiff_t)(buffer_index - buffer_ptr)); printf("* Exiting ssdriver. *\n\n"); printf("\n***************************************************************\n"); cleanup(NULL); exit(99); } fprintf(outstream, "\n\nTablespace Information:"); fprintf(outstream, "\n Tablespace Name ===> %0.*s", SQLM_IDENT_SZ, ts_ptr->tablespace_name); fprintf(outstream, "\n\nBuffer Pool Information:"); fprintf(outstream, "\n Buffer pool logical data page reads ===> %lu", ts_ptr->pool_data_l_reads); fprintf(outstream, "\n Buffer pool physical data page reads ===> %lu", ts_ptr->pool_data_p_reads); fprintf(outstream, "\n Buffer pool data page writes ===> %lu", ts_ptr->pool_data_writes); fprintf(outstream, "\n Buffer pool logical index page reads ===> %lu", ts_ptr->pool_index_l_reads); fprintf(outstream, "\n Buffer pool physical index page reads ===> %lu", ts_ptr->pool_index_p_reads); fprintf(outstream, "\n Buffer pool index page writes ===> %lu", ts_ptr->pool_index_writes); fprintf(outstream, "\n Buffer pool read time since 1st connect ===> %lu milliseconds", ts_ptr->pool_read_time); fprintf(outstream, "\n Buffer pool write time since 1st connect===> %lu milliseconds", ts_ptr->pool_write_time); fprintf(outstream, "\n Files closed since 1st connect ===> %lu", ts_ptr->files_closed); fprintf(outstream, "\n Buffer pool asynch data page reads ===> %lu", ts_ptr->pool_async_data_reads); fprintf(outstream, "\n Buffer pool asynch data page reads reqs ===> %lu", ts_ptr->pool_async_data_read_reqs); fprintf(outstream, "\n Buffer pool asynch data page writes ===> %lu", ts_ptr->pool_async_data_writes); fprintf(outstream, "\n Buffer pool asynch index page reads ===> %lu", ts_ptr->pool_async_index_reads); fprintf(outstream, "\n Buffer pool asynch index page writes ===> %lu", ts_ptr->pool_async_index_writes); fprintf(outstream, "\n Buffer pool asynch read time ===> %lu milliseconds", ts_ptr->pool_async_read_time); fprintf(outstream, "\n Buffer pool asynch write time ===> %lu milliseconds", ts_ptr->pool_async_write_time); if (output_opt == SCREEN_OUTPUT) pause(); fprintf(outstream, "\n\nDirect I/O Information:"); fprintf(outstream, "\n Sectors read directly ===> %lu", ts_ptr->direct_reads); fprintf(outstream, "\n Sectors written directly ===> %lu", ts_ptr->direct_writes); fprintf(outstream, "\n Number of direct read requests ===> %lu", ts_ptr->direct_read_reqs); fprintf(outstream, "\n Number of direct write requests ===> %lu", ts_ptr->direct_write_reqs); fprintf(outstream, "\n Direct read time ===> %lu milliseconds", ts_ptr->direct_read_time); fprintf(outstream, "\n Direct write time ===> %lu milliseconds", ts_ptr->direct_write_time); if (output_opt == SCREEN_OUTPUT) pause(); buffer_index += ts_ptr->size; } /* end of for loop */ } /* process_tablespace */ /*****************************************************************************/ /* process_dcs_app */ /* This function processes DCS application information. This information is */ /* contained in structure sqlm_dcs_appl . Secondary structures of different */ /* types may follow this structure in the buffer. This code assumes that */ /* only the statement structure (sqlm_dcs_stmt) may follow it. */ /*****************************************************************************/ void process_dcs_app() { time_t ltime; sqlm_dcs_appl *appl; /* work pointer */ sqlm_dcs_applid_info *applid; /* work pointer */ sqlm_dcs_appl_snap_stats *stats; /* work pointer */ sqlm_dcs_stmt *stmt; /* work pointer */ char curr_sqlm_structure; /* work variable */ char statement[32001]; /* work variable - stmt text */ /* Cast the buffer contents to an sqlm_dcs_appl data structure */ appl = (sqlm_dcs_appl *)(buffer_index); /******************************************************************/ /* Get the pointers to secondary structures sqlm_dcs_applid_info */ /* and sqlm_dcs_appl_snap_stats that immediately follow the main */ /* structure sqlm_dcs_appl. */ /******************************************************************/ buffer_index += appl->size; applid = (sqlm_dcs_applid_info *) buffer_index; buffer_index += applid->size; stats = (sqlm_dcs_appl_snap_stats *) buffer_index; if (output_opt == SCREEN_OUTPUT) clrscrn(); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "* DCS APPLICATION SNAPSHOT INFO *\n"); fprintf(outstream, "**********************************************************************\n"); fprintf(outstream, "\n(a) Application ID info - examples of data elements retrieved from \n"); fprintf(outstream, " secondary structure sqlm_dcs_applid_info:\n"); fprintf(outstream, "\n Application handle (agent ID) ===> %lu", applid->agent_id); fprintf(outstream, "\n Client application ID ===> %0.*s", SQLM_APPLID_SZ, applid->appl_id); switch (applid->dcs_appl_status) { case SQLM_DCS_CONNECTPEND_OUTBOUND: fprintf(outstream, "\n Application status ===> %s", "connect pending - outbound"); break; case SQLM_DCS_UOWWAIT_OUTBOUND: fprintf(outstream, "\n Application status ===> %s", "waiting for host reply"); break; case SQLM_DCS_UOWWAIT_INBOUND: fprintf(outstream, "\n Application status ===> %s", "waiting for client request"); break; } /* end switch on DCS application status */ ltime = applid->status_change_time.seconds; fprintf(outstream, "\n Status change time ===> %24.24s", (ltime) ? ctime(<ime) : ""); fprintf(outstream, "\n Host Database Name ===> %0.*s", SQLM_IDENT_SZ, applid->host_db_name); fprintf(outstream, "\n Host Product Id ===> %0.*s", SQLM_IDENT_SZ, applid->host_prdid); fprintf(outstream, "\n Host Application Id ===> %0.*s", SQLM_APPLID_SZ, applid->outbound_appl_id); fprintf(outstream, "\n\n(b) Application stats - examples of data elements retrieved from \n"); fprintf(outstream, " the main structure sqlm_dcs_appl:\n"); fprintf(outstream, "\n Open cursors ===> %lu", appl->open_cursors); fprintf(outstream, "\n Application idle time ===> %lu", appl->appl_idle_time); fprintf(outstream, "\n\n(c) Application stats - examples of data elements retrieved from \n"); fprintf(outstream, " the secondary structure sqlm_appl_snap_stats:\n"); /* Time spent on gateway processing */ if (collected.group_states[SQLM_STATEMENT_SW].output_state == SQLM_ON) { fprintf(outstream, "\n Time spent on gateway processing ===> %lu.%0.6lu", stats->appl_stats.gw_exec_time.seconds, stats->appl_stats.gw_exec_time.microsec); } /* Number of SQL statements attempted */ fprintf(outstream, "\n Number of SQL statements attempted ===> %lu", stats->appl_stats.sql_stmts); if (collected.group_states[SQLM_UOW_SW].output_state == SQLM_ON) { /* UOW start timestamp */ ltime = appl->uow_start_time.seconds; fprintf(outstream, "\n UOW start timestamp ===> %24.24s", (ltime) ? ctime(<ime) : ""); /* UOW stop timestamp */ ltime = appl->uow_stop_time.seconds; fprintf(outstream, "\n UOW stop timestamp ===> %24.24s", (ltime) ? ctime(<ime) : ""); } /* advance buffer_index to the next structure in the buffer */ buffer_index += stats->size; curr_sqlm_structure = *(buffer_index + 4); switch(curr_sqlm_structure) { case SQLM_DCS_STMT_SS: /* This is statement secondary str. */ stmt = (struct sqlm_dcs_stmt *) buffer_index; fprintf(outstream, "\n\n(d) Application stats - examples of data elements retrieved from \n"); fprintf(outstream, " the secondary structure sqlm_dcs_stmt (statement-level information):\n"); switch (stmt->stmt_operation) { case SQLM_PREPARE: fprintf(outstream, "\n Statement operation ===> %s", "Prepare"); break; case SQLM_EXECUTE: fprintf(outstream, "\n Statement operation ===> %s", "Execute"); break; case SQLM_EXECUTE_IMMEDIATE: fprintf(outstream, "\n Statement operation ===> %s", "Execute immediate"); break; case SQLM_OPEN: fprintf(outstream, "\n Statement operation ===> %s", "Open"); break; case SQLM_FETCH: fprintf(outstream, "\n Statement operation ===> %s", "Fetch"); break; case SQLM_CLOSE: fprintf(outstream, "\n Statement operation ===> %s", "Close"); break; case SQLM_DESCRIBE: fprintf(outstream, "\n Statement operation ===> %s", "Describe"); break; case SQLM_STATIC_COMMIT: fprintf(outstream, "\n Statement operation ===> %s", "Static COMMIT"); break; case SQLM_STATIC_ROLLBACK: fprintf(outstream, "\n Statement operation ===> %s", "Static ROLLBACK"); break; case SQLM_FREE_LOCATOR: fprintf(outstream, "\n Statement operation ===> %s", "Free locator"); break; case SQLM_PREP_COMMIT: fprintf(outstream, "\n Statement operation ===> %s", "Prepare to commit"); break; case SQLM_CALL: fprintf(outstream, "\n Statement operation ===> %s", "Call stored procedure"); break; case SQLM_SELECT: fprintf(outstream, "\n Statement operation ===> %s", "Select"); break; case SQLM_PREP_OPEN: fprintf(outstream, "\n Statement operation ===> %s", "Prepare and open"); break; case SQLM_PREP_EXEC: fprintf(outstream, "\n Statement operation ===> %s", "Prepare and execute"); break; case SQLM_COMPILE: fprintf(outstream, "\n Statement operation ===> %s", "Compile"); break; default : fprintf(outstream, "\n Statement operation ===> %s", "Non-SQL operation"); break; } /* end switch on statement operation */ fprintf(outstream, "\n Section number ===> %lu", stmt->section_number); fprintf(outstream, "\n Application creator ===> %0.*s", SQLM_IDENT_SZ, stmt->creator ); fprintf(outstream, "\n Package name ===> %0.*s", SQLM_IDENT_SZ, stmt->package_name); /* Statement start timestamp */ ltime = stmt->stmt_start.seconds; fprintf(outstream, "\n Statement start timestamp ===> %24.24s", (ltime) ? ctime(<ime) : ""); /* Statement stop timestamp */ ltime = stmt->stmt_stop.seconds; fprintf(outstream, "\n Statement stop timestamp ===> %24.24s", (ltime) ? ctime(<ime) : ""); /* Time spent on gateway processing for the statement: */ fprintf(outstream, "\n Time spent on gateway processing ===> %lu.%0.6lu", stmt->gw_exec_time.seconds, stmt->gw_exec_time.microsec); /* Statement text (if present) */ if (stmt->stmt_length > 0) /* Print only if there is some text */ { /* Copy the statement text to a local char array and null-terminate */ char *stmt_text= (char*) stmt + stmt->stmt_text_offset; memcpy(statement, stmt_text, stmt->stmt_length); statement[stmt->stmt_length] = '\0'; fprintf(outstream, "\n Statement text:\n %s", statement); } buffer_index += stmt->size; /* Point to the next structure in buffer */ break; case SQLM_APPL_XID_SS: /* This is xid sec. structure */ /* ===> Add code here to process the xid structure ... */ /* ===> Add code here to point to the next structure in buffer: */ /* ===> buffer_index += ...->size; */ break; case SQLM_TPMON_INFO_SS: /* This is tpmon secondary struct. */ /* ===> Add code here to process the tpmon structure ... */ /* ===> Add code here to point to the next structure in buffer: */ /* ===> buffer_index += ...->size; */ break; default: goto exit; } exit: if (output_opt == SCREEN_OUTPUT) pause(); } /* process_dcs_app */ /*****************************************************************************/ /* pr_sqlca */ /* This function prints the contents of the sqlca error information */ /* structure. */ /*****************************************************************************/ void pr_sqlca(struct sqlca *ca) { char buffer[200]; unsigned short i; /*Print out header for DUMP*/ fprintf(outstream, "*************************************\n"); fprintf(outstream, "* CONTENTS OF SQLCA *\n"); fprintf(outstream, "*************************************\n\n"); /*Print out contents of SQLCA variables*/ fprintf(outstream, "SQLCABC = %ld\n", ca->sqlcabc); fprintf(outstream, "SQLCODE = %ld\n", ca->sqlcode); fprintf(outstream, "SQLERRMC = %0.70s\n", ca->sqlerrmc); fprintf(outstream, "SQLERRP = %0.8s\n", ca->sqlerrp); sqlaintp(buffer, sizeof(buffer), 80, ca); fprintf(outstream, "%0.200s\n", buffer); for (i = 0; i < 6; i++) { fprintf(outstream, "sqlerrd[%d] = %lu \n", i, ca->sqlerrd[i]); } fprintf(outstream, "SQLWARN = %0.11s\n", ca->sqlwarn); fprintf(outstream, "SQLSTATE = %0.5s\n", ca->sqlstate); } /* pr_sqlca */ /*****************************************************************************/ /* cleanup */ /* General cleanup routine to close open files and release memory buffers. */ /*****************************************************************************/ void cleanup(struct sqlma *ma_ptr) { int rc = 0; if (output_opt == FILE_OUTPUT) { /* close output file */ rc = fclose(outstream); if (rc != 0) { fprintf(outstream, "error closing output file at cleanup. rc= %d\n", rc); } } if (buffer_ptr != NULL) free(buffer_ptr); /* free output buffer */ if (ma_ptr != NULL) /* free sqlma */ free(ma_ptr); } /* cleanup */ /*****************************************************************************/ /* pause. */ /* Waits for user input before proceeding */ /*****************************************************************************/ void pause() { printf("\nPress Enter to continue!\n"); fflush(stdin); getchar(); } /* pause */ /*****************************************************************************/ /* clrscrn. */ /* Clears the user's screen */ /*****************************************************************************/ void clrscrn() { system(CLEARSCR); } /* clrscrn */