#include #include #include #include #include #include #include //for wmi object path parser #include #include #include using namespace std; #include "objpath.h" #include "debug.h" #include "controlwrapper.h" #include "clusterwrapper.h" #include "utils.h" #include "wlbsparm.h" #include "control.h" #include "controlwrapper.tmh" #define NLB_DEFAULT_TIMEOUT 10 void CWlbsControlWrapper::Initialize() { TRACE_CRIT("->%!FUNC!"); DWORD dwRet = m_WlbsControl.Initialize(); if( dwRet != WLBS_PRESENT && dwRet != WLBS_LOCAL_ONLY) { TRACE_CRIT("%!FUNC! CWlbsControl::Initialize failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_CRIT("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsInit ); } m_WlbsControl.WlbsTimeoutSet( WLBS_ALL_CLUSTERS, NLB_DEFAULT_TIMEOUT ); CWlbsCluster** ppCluster; DWORD dwNumClusters = 0; // // Use the local password for local query // m_WlbsControl.EnumClusterObjects( ppCluster, &dwNumClusters); for (int i=0;iGetClusterIp(), ppCluster[i]->GetPassword() ); } TRACE_CRIT("<-%!FUNC!"); } void CWlbsControlWrapper::ReInitialize() { TRACE_CRIT("->%!FUNC!"); m_WlbsControl.ReInitialize(); CWlbsCluster** ppCluster; DWORD dwNumClusters = 0; // // In case pasword is changed, use the local password for local query // m_WlbsControl.EnumClusterObjects( ppCluster, &dwNumClusters); for (int i=0;iIsCommitPending()) { m_WlbsControl.WlbsCodeSet( ppCluster[i]->GetClusterIp(), ppCluster[i]->GetPassword() ); } } TRACE_CRIT("<-%!FUNC!"); } void CWlbsControlWrapper::EnumClusters(CWlbsClusterWrapper** & ppCluster, DWORD* pdwNumClusters) { TRACE_VERB("->%!FUNC!"); m_WlbsControl.EnumClusterObjects( (CWlbsCluster** &) ppCluster, pdwNumClusters); TRACE_VERB("<-%!FUNC!"); } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Disable // // Purpose: Disable ALL traffic handling for the rule containing the // specified port on specified host or all cluster hosts. Only rules // that are set for multiple host filtering mode are affected. // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Disable ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts , DWORD a_dwVip , DWORD a_dwPort ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsDisable( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts , a_dwVip , a_dwPort ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsDisable failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch( dwRet ) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsDisable, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Enable // // Purpose: Enable traffic handling for rule containing the // specified port on specified host or all cluster hosts. Only rules // that are set for multiple host filtering mode are affected. // // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Enable ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts , DWORD a_dwVip , DWORD a_dwPort ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsEnable( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts , a_dwVip , a_dwPort ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsEnable failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch(dwRet) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsEnable, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Drain // // Purpose: Disable NEW traffic handling for rule containing the specified // port on specified host or all cluster hosts. Only rules that are // set for multiple host filtering mode are affected. // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Drain ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts , DWORD a_dwVip , DWORD a_dwPort ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsDrain( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts , a_dwVip , a_dwPort ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsDrain failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch(dwRet) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsDrain, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::DrainStop // // Purpose: Enter draining mode on specified host or all cluster hosts. // New connections will not be accepted. Cluster mode will be stopped // when all existing connections finish. While draining, host will // participate in convergence and remain part of the cluster. // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::DrainStop ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsDrainStop( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsDrainStop failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch(dwRet) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsDrainStop, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Resume // // Purpose: Resume cluster operation control on specified host or all // cluster hosts. // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Resume ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsResume( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsResume failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch(dwRet) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsResume, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Start // // Purpose: Start cluster operations on specified host or all cluster hosts. // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Start ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsStart( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsStart failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch(dwRet) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsStart, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Stop // // Purpose: Stop cluster operations on specified host or all cluster hosts. // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Stop ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsStop( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsStop failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch(dwRet) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsStop, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Suspend // // Purpose: Suspend cluster operation control on specified host or // all cluster hosts. // // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Suspend ( DWORD a_dwCluster , DWORD a_dwHost , WLBS_RESPONSE* a_pResponse , DWORD& a_dwNumHosts ) { DWORD dwRet; BOOL bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); DWORD dwNumHosts = a_dwNumHosts; TRACE_VERB("->%!FUNC!"); dwRet = m_WlbsControl.WlbsSuspend( a_dwCluster , a_dwHost , a_pResponse , &dwNumHosts ); //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsSuspend failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch(dwRet) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsSuspend, bClusterWide ); break; } a_dwNumHosts = dwNumHosts; TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsControlWrapper::Query // // Purpose: This invokes WlbsQuery and returns a response structure along // with other parameters if requested. // // Errors: The function throws CErrorWlbsControl. // // Return: Status value returned by the target host // //////////////////////////////////////////////////////////////////////////////// DWORD CWlbsControlWrapper::Query ( CWlbsClusterWrapper * pCluster, DWORD a_dwHost, WLBS_RESPONSE * a_pResponse, WLBS_RESPONSE * a_pComputerNameResponse, PDWORD a_pdwNumHosts, PDWORD a_pdwHostMap ) { TRACE_VERB("->%!FUNC!"); DWORD dwRet; BOOL bClusterWide = 0; bClusterWide = ( a_dwHost == WLBS_ALL_HOSTS ); // The below check is present only to take care of the // condition where a junk pointer was passed, but the // a_pdwNumHosts is set to NULL or zero. This check // is NOT necessitated by WlbsQuery, but by the check // at the end of this function where we fill in the DIP // into the zero-th entry of the array. if ((a_pdwNumHosts == NULL) || (*a_pdwNumHosts == 0)) { a_pResponse = NULL; } dwRet = m_WlbsControl.WlbsQuery( (CWlbsCluster*)pCluster , a_dwHost , a_pResponse , a_pdwNumHosts, a_pdwHostMap, NULL ); string strOut; //check for Winsock errors if( dwRet > 10000 ) { TRACE_CRIT("%!FUNC! CWlbsControl::WlbsQuery failed : 0x%x, Throwing Wlbs error exception", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //check the return value and throw if an error occurred switch( dwRet ) { case WLBS_INIT_ERROR: case WLBS_BAD_PASSW: case WLBS_TIMEOUT: case WLBS_LOCAL_ONLY: case WLBS_REMOTE_ONLY: case WLBS_IO_ERROR: TRACE_CRIT("%!FUNC! Throwing Wlbs error exception : 0x%x", dwRet); TRACE_VERB("<-%!FUNC!"); throw CErrorWlbsControl( dwRet, CmdWlbsQuery, bClusterWide ); } //local queries do not return the dedicated IP //get the dedicated IP and fill the structure if(( a_dwHost == WLBS_LOCAL_HOST ) && (a_pResponse != NULL)) { a_pResponse[0].address = pCluster->GetDedicatedIp(); // If the local computer's fqdn is to be queried from the nlb driver, do it. if(a_pComputerNameResponse) { GUID AdapterGuid; AdapterGuid = pCluster->GetAdapterGuid(); WlbsGetSpecifiedClusterMember(&AdapterGuid, pCluster->GetHostID(), a_pComputerNameResponse); } } TRACE_VERB("<-%!FUNC! return = 0x%x", dwRet); return dwRet; } //////////////////////////////////////////////////////////////////////////////// // // CWlbsClusterWrapper::CheckMembership // // Purpose: This verifies that the local host is a member of the cluster // specified by the Cluster IP in the registry. At the time this // was written, there was a remote chance that a user can modify the // IP address in the registry prior to the load of this DLL. // // Note, this call is only required for the Node, Cluster and linked // associations and should not be invoked for any of the Setting classes. // //////////////////////////////////////////////////////////////////////////////// void CWlbsControlWrapper::CheckMembership() { // todo: make sure the host is in at least one cluster /* WLBS_RESPONSE WlbsResponse; DWORD dwResSize = 1; //get the cluster and HostID DWORD dwRes = pControl->Query( m_pWlbsCluster->GetClusterIp(), WLBS_LOCAL_HOST, &WlbsResponse, &dwResSize, NULL); switch( dwRes ) { case WLBS_SUSPENDED: case WLBS_STOPPED: case WLBS_CONVERGING: case WLBS_DRAINING: case WLBS_CONVERGED: case WLBS_DEFAULT: break; default: throw CErrorWlbsControl( dwRes, CmdWlbsQuery ); } */ // DWORD dwClusterIP; // GetClusterIP( &dwClusterIP ); //if( dwClusterIP == 0 ) //throw _com_error( WBEM_E_NOT_FOUND ); //******************************* //this section does not work when the remote control is disabled //on the local host //******************************* //call the query function // dwRes = WlbsQuery( dwClusterIP, // WlbsResponse.id, // NULL, // NULL, // NULL, // NULL ); //analyze query results for errors // switch( dwRes ) { // case WLBS_OK: // case WLBS_STOPPED: // case WLBS_CONVERGING: // case WLBS_CONVERGED: // case WLBS_DEFAULT: // case WLBS_DRAINING: // case WLBS_SUSPENDED: // return; // default: // throw CErrorWlbsControl( dwRes, CmdWlbsQuery ); // } //******************************* //this section does not work when the remote control is disabled //on the local host //******************************* } DWORD CWlbsControlWrapper::WlbsQueryState ( DWORD cluster, DWORD host, DWORD operation, PNLB_OPTIONS pOptions, PWLBS_RESPONSE pResponse, PDWORD pcResponses ) { return m_WlbsControl.WlbsQueryState(cluster, host, operation, pOptions, pResponse, pcResponses); }