*/
osm_opensm_t osm;
volatile unsigned int osm_exit_flag = 0;
+HANDLE osm_exit_event = NULL;
#define GUID_ARRAY_SIZE 64
#define INVALID_GUID (0xFFFFFFFFFFFFFFFFULL)
osm_main_args_t osm_main_args;
+enum service_state {
+ SERVICE_STATE_STARTING,
+ SERVICE_STATE_STARTED_OK,
+ SERVICE_STATE_START_FAILED
+};
+
+enum service_state g_service_state = SERVICE_STATE_STARTING;
+
+void OsmReportState(IN const char *p_str)
+{
+ if (!strcmp(p_str, "SUBNET UP\n") ||
+ (!strcmp(p_str, "SM port is down\n")) ||
+ (!strcmp(p_str, "Errors during initialization\n")) ||
+ (!strcmp(p_str, "Entering STANDBY state\n")))
+ {
+ InterlockedCompareExchange((LONG *)&g_service_state , SERVICE_STATE_STARTED_OK, SERVICE_STATE_STARTING);
+ return;
+ }
+
+ if (!strcmp(p_str, "Found remote SM with non-matching sm_key. Exiting\n") ||
+ (!strcmp(p_str, "Errors on subnet. Duplicate GUID found ""by link from a port to itself. ""See osm log for more details\n")) ||
+ (!strcmp(p_str, "Errors on subnet. SM found duplicated guids or 12x ""link with lane reversal badly configured. ""See osm log for more details\n")) ||
+ (!strcmp(p_str, "Fatal: Error restoring Guid-to-Lid persistent database\n")))
+
+ {
+ InterlockedCompareExchange((LONG *)&g_service_state , SERVICE_STATE_START_FAILED, SERVICE_STATE_STARTING);
+ return;
+ }
+
+ if(!strcmp(p_str, "OpenSM Rev:openib-1.2.0\n") ||
+ (!strcmp(p_str, "Entering MASTER state\n"))||
+ (!strcmp(p_str, "Exiting SM\n")))
+ {
+ // This are messages that it is safe to ignore
+ return;
+ }
+ CL_ASSERT(FALSE);
+
+}
/**********************************************************************
**********************************************************************/
printf( "-?\n"
" Display this usage info then exit.\n\n" );
fflush( stdout );
- osm_exit_flag = 1;
+ osm_exit_flag = TRUE;
}
/**********************************************************************
uint32_t val;
const char * const short_option = "i:f:ed:g:l:s:t:a:uvVhorcyx";
+
/*
In the array below, the 2nd parameter specified the number
of arguments as follows:
{ "honor_guid2lid", 0, NULL, 'x'},
{ NULL, 0, NULL, 0 } /* Required at the end of the array */
};
-
printf("-------------------------------------------------\n");
printf("%s\n", OSM_VERSION);
case '?':
case ':':
show_usage();
+ return 0;
break;
case -1:
}
while(next_option != -1);
- if (osm_exit_flag) {
- return( 0 );
- }
if (opt.log_file != NULL )
printf(" Log File: %s\n", opt.log_file );
/* Done with options description */
goto Exit;
}
- if( run_once_flag == TRUE )
- {
- status = osm_opensm_wait_for_subnet_up(
+ status = osm_opensm_wait_for_subnet_up(
&osm, EVENT_NO_TIMEOUT, TRUE );
- osm_exit_flag = 1;
+
+ if( status != CL_SUCCESS )
+ {
+ printf( "\nError from osm_opensm_wait_for_subnet_up (0x%X)\n", status );
+ goto Exit;
}
- else
+
+ if( run_once_flag == FALSE )
{
/*
Sit here forever
In the future, some sort of console interactivity could
be implemented in this loop.
*/
- while( !osm_exit_flag )
- cl_thread_suspend( 10000 );
+ WaitForSingleObject(osm_exit_event, INFINITE);
+ osm_exit_flag = TRUE;
}
/* wait for all transactions to end */
osm.mad_pool.mads_out);
Exit:
+ g_service_state = SERVICE_STATE_START_FAILED;
osm_opensm_destroy( &osm );
if (mem_track) cl_mem_display();
DWORD OsmServiceInitialization (DWORD argc, LPTSTR *argv,
DWORD *specificError);
-void __cdecl
+int __cdecl
main (
int argc,
char* argv[] )
run_as_service = TRUE;
break;
}
+ osm_exit_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if(osm_exit_event == NULL)
+ {
+ printf( "\nCreateEvent failed gle=%d\n", GetLastError());
+ return( 1 );
+ }
if (!run_as_service)
+ {
/* Running as executable */
- opensm_main(&osm_main_args);
+ return opensm_main(&osm_main_args);
+ }
else
{
/* Running as service */
{ "OsmService", OsmServiceStart },
{ NULL, NULL }
};
-
+ // Give older versions of opensm a chance to stop
+ Sleep(3000);
+
if (!StartServiceCtrlDispatcher( DispatchTable))
{
SvcDebugOut(" [OSM_SERVICE] StartServiceCtrlDispatcher (%d)\n",
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
// Do whatever it takes to stop here.
- osm_exit_flag = TRUE;
+ osm_exit_flag = TRUE;
+ SetEvent(osm_exit_event);
OsmServiceStatus.dwWin32ExitCode = 0;
OsmServiceStatus.dwCurrentState = SERVICE_STOPPED;
OsmServiceStatus.dwCheckPoint = 0;
OsmServiceStatus.dwWin32ExitCode = 0;
OsmServiceStatus.dwServiceSpecificExitCode = 0;
OsmServiceStatus.dwCheckPoint = 0;
- OsmServiceStatus.dwWaitHint = 0;
+ OsmServiceStatus.dwWaitHint = 2000;
OsmServiceStatusHandle = RegisterServiceCtrlHandler(
"OsmService",
SvcDebugOut(" [OSM_SERVICE] RegisterServiceCtrlHandler failed %d\n", GetLastError());
return 0;
}
-
+
// Initialization code goes here.
status = OsmServiceInitialization(argc,argv, &specificError);
+ while (status == NO_ERROR && g_service_state == SERVICE_STATE_STARTING)
+ {
+ Sleep(1000);
+ OsmServiceStatus.dwCheckPoint++;
+ if (!SetServiceStatus (OsmServiceStatusHandle, &OsmServiceStatus))
+ {
+ status = GetLastError();
+ SvcDebugOut(" [OSM_SERVICE] SetServiceStatus error %ld\n",status);
+ }
+
+ }
+ CL_ASSERT(g_service_state == SERVICE_STATE_STARTED_OK ||
+ g_service_state == SERVICE_STATE_START_FAILED ||
+ status != NO_ERROR);
// Handle error condition
- if (status != NO_ERROR)
+ if (status != NO_ERROR || g_service_state == SERVICE_STATE_START_FAILED)
{
OsmServiceStatus.dwCurrentState = SERVICE_STOPPED;
OsmServiceStatus.dwCheckPoint = 0;