[WSD] Add perfmon counter object implementation. WSD installation now
[mirror/winof/.git] / tools / wsdinstall / user / installsp.c
index 8111f08..c721210 100644 (file)
 #include <stdio.h>\r
 \r
 /* Initialize the LSP's provider path for Infiband Service Provider dll */\r
-static const WCHAR *provider_path = L"%SYSTEMROOT%\\system32\\ibwsd.dll";\r
-static const WCHAR *provider_name = L"OpenIB Winsock Direct for InfiniBand";\r
-static const char *winsock_key_path = "System\\CurrentControlSet\\Services\\Winsock\\Parameters\\TCP on SAN";\r
-static const char *openib_key_name = "OpenIB Alliance";\r
+static const WCHAR provider_path[] = L"%SYSTEMROOT%\\system32\\ibwsd.dll";\r
+static const WCHAR provider_name[] = L"OpenIB Winsock Direct for InfiniBand";\r
+static const char winsock_key_path[] =\r
+       "System\\CurrentControlSet\\Services\\Winsock\\Parameters\\TCP on SAN";\r
+static const char openib_key_name[] = "OpenIB Alliance";\r
 \r
 /* Unique provider GUID generated with "uuidgen -s" */\r
 static GUID provider_guid = {\r
@@ -60,6 +61,316 @@ static GUID provider_guid = {
 #define WSCInstallProvider     WSCInstallProvider64_32\r
 #endif /* _WIN64 */\r
 \r
+#ifdef PERFMON_ENABLED\r
+#include <Loadperf.h>\r
+#include "wsd/ibsp_regpath.h"\r
+\r
+\r
+typedef struct _pm_symbol_def\r
+{\r
+       DWORD   name_def;\r
+       CHAR    name_str[40];\r
+       CHAR    name_desc[40];\r
+       CHAR    help_desc[256];\r
+\r
+} pm_symbol_def_t;\r
+\r
+static pm_symbol_def_t  _pm_symbols[]=\r
+{\r
+       { IBSP_PM_OBJ,\r
+       "IBSP_PM_OBJ",\r
+       "IB Winsock Direct",\r
+       "InfiniBand Windows Sockets Direct Provider."\r
+       },\r
+       { IBSP_PM_COUNTER(BYTES_SEND),\r
+       "IBSP_PM_BYTES_TX_SEC",\r
+       "Send bytes/sec",\r
+       "Send bytes/second, excluding RDMA Write."\r
+       },\r
+       { IBSP_PM_COUNTER(BYTES_RECV),\r
+       "IBSP_PM_BYTES_RX_SEC",\r
+       "Recv bytes/sec",\r
+       "Receive bytes/second, excluding RDMA Read."\r
+       },\r
+       { IBSP_PM_COUNTER(BYTES_WRITE),\r
+       "IBSP_PM_RDMA_WR_SEC",\r
+       "RDMA Write bytes/sec",\r
+       "RDMA Write bytes/second."\r
+       },\r
+       { IBSP_PM_COUNTER(BYTES_READ),\r
+       "IBSP_PM_RDMA_RD_SEC",\r
+       "RDMA Read bytes/sec",\r
+       "RDMA Read bytes/second."\r
+       },\r
+       { IBSP_PM_COUNTER(BYTES_TOTAL),\r
+       "IBSP_PM_BYTES_SEC",\r
+       "Total bytes/sec",\r
+       "Total bytes transmitted per second, including send, "\r
+       "receive, RDMA Write, and RDMA Read."\r
+       },\r
+       { IBSP_PM_COUNTER(COMP_SEND),\r
+       "IBSP_PM_SEND_COMPLETIONS_SEC",\r
+       "Send Completions/sec",\r
+       "Send and RDMA Write Completions/sec."\r
+       },\r
+       { IBSP_PM_COUNTER(COMP_RECV),\r
+       "IBSP_PM_RECV_COMPLETIONS_SEC",\r
+       "Recv Completions/sec",\r
+       "Recv and RDMA Read Completions/sec."\r
+       },\r
+       { IBSP_PM_COUNTER(COMP_TOTAL),\r
+       "IBSP_PM_COMPLETIONS_SEC",\r
+       "Total Completions/sec",\r
+       "Total Completions processed per second."\r
+       },\r
+       { IBSP_PM_COUNTER(INTR_TOTAL),\r
+       "IBSP_PM_COMPLETIONS_INTR",\r
+       "Total Interrupts/sec",\r
+       "Completion Queue events per second."\r
+       }\r
+};\r
+\r
+#define IBSP_PM_NUM_SYMBOLS  (sizeof(_pm_symbols)/sizeof(pm_symbol_def_t))\r
+#define IBSP_PM_LANGUAGE "009" /* good for English */\r
+\r
+\r
+static DWORD\r
+_IBSPPerfmonIniFilesGenerate( void )\r
+{\r
+       FILE    *f_handle;\r
+       DWORD   num;\r
+\r
+       /* create ".h" file first */\r
+       f_handle = fopen( IBSP_PM_SYM_H_FILE, "w+" );\r
+\r
+       if( !f_handle )\r
+       {\r
+               fprintf(\r
+                       stderr, "Create Header file %s  failed\n", IBSP_PM_SYM_H_FILE );\r
+               return ERROR_FILE_INVALID;\r
+       }\r
+\r
+       fprintf(\r
+               f_handle, "/* %s Generated by program */ \r\n", IBSP_PM_SYM_H_FILE );\r
+               \r
+       \r
+       for( num = 0; num < IBSP_PM_NUM_SYMBOLS; num++ )\r
+       {\r
+               fprintf( f_handle, "#define\t%s\t%d\r\n",\r
+                       _pm_symbols[num].name_str, _pm_symbols[num].name_def );\r
+       }\r
+\r
+       fflush( f_handle );\r
+       fclose( f_handle );\r
+\r
+       /* create 'ini' file next */\r
+       f_handle = fopen( IBSP_PM_INI_FILE, "w+" );\r
+\r
+       if( !f_handle )\r
+       {\r
+               fprintf( stderr, "Create INI file %s  failed\n", IBSP_PM_INI_FILE );\r
+               return ERROR_FILE_INVALID;\r
+       }\r
+       \r
+       fprintf( f_handle, "[info]\r\ndrivername=" IBSP_PM_SUBKEY_NAME\r
+               "\r\nsymbolfile=" IBSP_PM_SYM_H_FILE "\r\n\r\n" );\r
+       fprintf( f_handle,"[languages]\r\n" IBSP_PM_LANGUAGE\r
+               "=language" IBSP_PM_LANGUAGE "\r\n\r\n" );\r
+\r
+       fprintf( f_handle, \r
+               "[objects]\r\n%s_" IBSP_PM_LANGUAGE "_NAME=%s\r\n\r\n[text]\r\n",\r
+               _pm_symbols[0].name_str, _pm_symbols[0].name_desc );\r
+       \r
+       for( num = 0; num < IBSP_PM_NUM_SYMBOLS; num++ )\r
+       {\r
+               fprintf( f_handle,"%s_" IBSP_PM_LANGUAGE "_NAME=%s\r\n",\r
+                       _pm_symbols[num].name_str, _pm_symbols[num].name_desc );\r
+               fprintf( f_handle,"%s_" IBSP_PM_LANGUAGE "_HELP=%s\r\n",\r
+                       _pm_symbols[num].name_str, _pm_symbols[num].help_desc );\r
+       }\r
+\r
+       fflush( f_handle );\r
+       fclose( f_handle );\r
+\r
+       return ERROR_SUCCESS;\r
+}\r
+\r
+\r
+static void\r
+_IBSPPerfmonIniFilesRemove( void )\r
+{\r
+       if( !DeleteFile( IBSP_PM_INI_FILE ) )\r
+       {\r
+               fprintf( stderr, "Delete file %s failed status %d\n",\r
+                       IBSP_PM_INI_FILE, GetLastError() );\r
+       }\r
+       if( !DeleteFile( IBSP_PM_SYM_H_FILE ) )\r
+       {\r
+               fprintf( stderr,"Delete file %s failed status %d\n",\r
+                       IBSP_PM_SYM_H_FILE, GetLastError() );\r
+       }\r
+}\r
+\r
+\r
+/* Try to create IB WSD Performance Register Keys */\r
+static LONG\r
+_IBSPPerfmonRegisterKeys( void )\r
+{\r
+       LONG    reg_status;\r
+       HKEY    pm_hkey;\r
+       DWORD   typesSupp = 7;\r
+\r
+       reg_status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,\r
+               IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF, 0, NULL,\r
+               REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &pm_hkey, NULL );\r
+\r
+       if( reg_status != ERROR_SUCCESS )\r
+       {\r
+               fprintf( stderr,\r
+                       "_IBSPPerfmonRegisterKeys Create Key %s failed with %d\n",\r
+                       IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF, reg_status );\r
+               return reg_status;\r
+       }\r
+\r
+       /* create/assign values to the key */\r
+       RegSetValueExW( pm_hkey, L"Library", 0, REG_EXPAND_SZ,\r
+               (LPBYTE)provider_path, sizeof(provider_path) );\r
+\r
+       RegSetValueEx( pm_hkey, TEXT("Open"), 0, REG_SZ,\r
+               (LPBYTE)TEXT("IBSPPmOpen"), sizeof(TEXT("IBSPPmOpen")) );\r
+\r
+       RegSetValueEx( pm_hkey, TEXT("Collect"), 0, REG_SZ,\r
+               (LPBYTE)TEXT("IBSPPmCollectData"), sizeof(TEXT("IBSPPmCollectData")) );\r
+\r
+       RegSetValueEx( pm_hkey, TEXT("Close"), 0, REG_SZ,\r
+               (LPBYTE)TEXT("IBSPPmClose"), sizeof(TEXT("IBSPPmClose")) );\r
+\r
+       RegFlushKey( pm_hkey );\r
+       RegCloseKey( pm_hkey );\r
+\r
+       reg_status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,\r
+               IBSP_PM_EVENTLOG_PATH, 0, NULL,\r
+               REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &pm_hkey, NULL );\r
+\r
+       if( reg_status != ERROR_SUCCESS )\r
+       {\r
+               fprintf(stderr, "Create EventLog Key failed with %d\n", reg_status );\r
+               return reg_status;\r
+       }\r
+\r
+       /* create/assign values to the key */\r
+       RegSetValueExW( pm_hkey, L"EventMessageFile", 0, REG_EXPAND_SZ,\\r
+               (LPBYTE)provider_path, sizeof(provider_path) );\r
+\r
+       RegSetValueEx( pm_hkey, TEXT("TypesSupported"), 0, REG_DWORD,\r
+               (LPBYTE)&typesSupp, sizeof(typesSupp) );\r
+\r
+       RegFlushKey( pm_hkey );\r
+       RegCloseKey( pm_hkey );\r
+\r
+       return reg_status;\r
+}\r
+\r
+\r
+/* Try to destroy IB WSD Performance Register Keys */\r
+static LONG\r
+_IBSPPerfmonDeregisterKeys( void )\r
+{\r
+       LONG    reg_status;\r
+\r
+       reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
+               IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF,\r
+               (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
+\r
+       if( reg_status != ERROR_SUCCESS )\r
+       {\r
+               fprintf( stderr,\r
+                       "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
+                       GetLastError() );\r
+       }\r
+\r
+       reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
+               IBSP_PM_REGISTRY_PATH, (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
+\r
+       if( reg_status != ERROR_SUCCESS )\r
+       {\r
+               fprintf( stderr,\r
+                       "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
+                       GetLastError() );\r
+       }\r
+\r
+       reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
+               IBSP_PM_EVENTLOG_PATH, (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
+\r
+       if( reg_status != ERROR_SUCCESS )\r
+       {\r
+               fprintf( stderr,\r
+                       "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
+                       GetLastError() );\r
+       }\r
+\r
+       return reg_status;\r
+}\r
+\r
+\r
+/*\r
+ * functions will try to register performance counters\r
+ * definitions with PerfMon application.\r
+ * API externally called by lodctr.exe/unlodctr.exe utilities.\r
+ */\r
+static DWORD\r
+_IBSPPerfmonRegisterCounters( void )\r
+{\r
+       DWORD status;\r
+       /*\r
+        * format commandline string, as per SDK :\r
+        *      Pointer to a null-terminated string that consists of one or more \r
+        *      arbitrary letters, a space, and then the name of the initialization\r
+        *      file.\r
+        */\r
+       status = LoadPerfCounterTextStrings(\r
+               TEXT("unused ") TEXT(IBSP_PM_INI_FILE), TRUE );\r
+       if( status != ERROR_SUCCESS )\r
+       {\r
+               status = GetLastError();\r
+               fprintf( stderr,\r
+                       "IBSPPerfmonRegisterCounters install failed status %d\n", status );\r
+       }\r
+\r
+       return status;\r
+}\r
+\r
+\r
+/*\r
+ * functions will try to unregister performance counters\r
+ * definitions with PerfMon application.\r
+ * API externally called by lodctr.exe/unlodctr.exe utilities.\r
+ */\r
+static DWORD\r
+_IBSPPerfmonDeregisterCounters( void )\r
+{\r
+       DWORD status;\r
+\r
+       /*\r
+        * format commandline string, as per SDK :\r
+        *      Pointer to a null-terminated string that consists of one or more \r
+        *      arbitrary letters, a space, and then the name of the initialization\r
+        *      file.\r
+        */\r
+       status = UnloadPerfCounterTextStrings(\r
+               TEXT("unused ") TEXT(IBSP_PM_SUBKEY_NAME), TRUE );\r
+       if( status != ERROR_SUCCESS )\r
+       {\r
+               fprintf( stderr,\r
+                       "IBSPPerfmonDeregisterCounters remove failed status %d\n",\r
+                       status );\r
+       }\r
+       return status;\r
+}\r
+\r
+#endif /* PERFMON_ENABLED */\r
+\r
+\r
 /*\r
  * Function: usage\r
  *   Description: Prints usage information.\r
@@ -67,7 +378,7 @@ static GUID provider_guid = {
 static void\r
 usage (char *progname)\r
 {\r
-       printf ("usage: %s [-i/-r]\n", progname);\r
+       printf ("usage: %s [-i/-r [-p]]\n", progname);\r
        printf ("    -i   Install the service provider\n"\r
                        "    -r   Remove the OpenIB service provider\n"\r
                        "    -r <name>   Remove the specified service provider\n"\r
@@ -144,11 +455,12 @@ static void install_provider(void)
        HKEY hkey;\r
 \r
        /* Now setup the key. */\r
-       reg_error = RegCreateKeyEx( HKEY_LOCAL_MACHINE, winsock_key_path, 0, NULL,\r
-               REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL, &hkey, NULL );\r
+       reg_error = RegCreateKeyExA( HKEY_LOCAL_MACHINE, winsock_key_path,\r
+               0, NULL, REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL,\r
+               &hkey, NULL );\r
        if( reg_error == ERROR_SUCCESS )\r
        {\r
-               reg_error = RegSetValueEx( hkey, openib_key_name, 0, REG_BINARY,\r
+               reg_error = RegSetValueExA( hkey, openib_key_name, 0, REG_BINARY,\r
                        (PBYTE)&provider_guid, sizeof(GUID) );\r
                if( reg_error == ERROR_SUCCESS )\r
                {\r
@@ -216,14 +528,14 @@ static void remove_provider( const char* const provider_name )
        HKEY hkey;\r
 \r
        /* Remove our key */\r
-       reg_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,\r
+       reg_error = RegOpenKeyExA(HKEY_LOCAL_MACHINE,\r
                                                         winsock_key_path,\r
                                                         0,\r
                                                         (KEY_WRITE | KEY_READ),\r
                                                         &hkey);\r
        if (reg_error == ERROR_SUCCESS) {\r
 \r
-               reg_error = RegDeleteValue(hkey, provider_name);\r
+               reg_error = RegDeleteValueA(hkey, provider_name);\r
                if (reg_error == ERROR_SUCCESS) {\r
                        /* Force the system to remove the key now. */\r
                        RegFlushKey(hkey);\r
@@ -291,6 +603,11 @@ int __cdecl main (int argc, char *argv[])
        case 'i':\r
                /* Install the Infiniband Service Provider */\r
                install_provider ();\r
+#ifdef PERFMON_ENABLED\r
+               _IBSPPerfmonIniFilesGenerate();\r
+               if ( _IBSPPerfmonRegisterKeys() == ERROR_SUCCESS )\r
+                               _IBSPPerfmonRegisterCounters();\r
+#endif\r
                break;\r
 \r
        case 'r':\r
@@ -299,13 +616,18 @@ int __cdecl main (int argc, char *argv[])
                        remove_provider( openib_key_name );\r
                else\r
                        remove_provider( argv[2] );\r
+#ifdef PERFMON_ENABLED\r
+               _IBSPPerfmonIniFilesRemove();\r
+               if ( _IBSPPerfmonDeregisterCounters() == ERROR_SUCCESS )\r
+                       _IBSPPerfmonDeregisterKeys();\r
+#endif\r
                break;\r
 \r
        case 'l':\r
                /* List existing providers */\r
                print_providers();\r
                break;\r
-\r
+       \r
        default:\r
                usage (argv[0]);\r
                break;\r