Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

519 lines
18 KiB

TO DO LIST
----------
0. Change ip address to bind string in connect-dialog, first ping for the
address, etc...
1. Switch from events to using two mutexes
2. Explicitly report the following errors
- other update pending
- netcfg write lock held
3. Report true client description, not "unspecified WMI client."
4. Use resource strings
6. Use internal constants for error codes and literal strings
7. Remove client-side dependency on wlbsctrl.dll.
4. Hook into nlb manager
4. Add "partial-update" semantics
New parameter: BOOL PartialUpdate
OPTIONAL parameter Generation -- if specified, we'll verify that the
Generation matches the current generation.
parameter value NULL === don't change
port rules: require the following property on each PR for partial-updates:
action=[ADD|DELETE|UPDATE]
IP addresses: require the ip address to be prefixed by
"add:" "delete:" or "update:" (latter for changing subnet masks)
UI:
add:{10.1.1.3}
delete:{10.1.1.3, 255.0.0}
update:{10.1.1.3, 255.0.0}
EXAMPLE 1:
PartialUpdate=TRUE
PortRules="action=update ip=10.1.1.3 start=80 end=288 weight=20 ...."
EXAMPLE 2:
PartialUpdate=TRUE
IpAddresses="add:10.0.0.1/255.255.0.0", "delete:10.0.0.2"
Generation=8
9. Follow up on WMI SDK errors -- DaveIce
WBEM_E_SERVER_NOT_FOUND -- where is this defined.
0x800706bf -- no definition in any header (and I checked in
index2a with interesting results), recoverable error.
0x80070767 -- no defn
0x80070005 -- no defn
control ip=x port=y start/stop/enable/disable/nop
------------------------------------
"Persistant" state for a particular NIC is mainained as a (for now)
volatile key under SYSTEM\CurrentControlSet\Services\WLBS\ConfigurationHistory\{GUID}
Under this GUID, there is are a set of reg-binary values (which are lighter weight than keys). They value-name is the generation number, and the value is a struct concatenated with a log. The struct has the format:
typedef struct {
UINT Version;
UINT HeaderSize;
UINT Generation;
UINT CompletionCode;
UINT OffsetToLog; // from start of this structure
UINT LogSize; // 0 == no log
UINT Reserved1;
UINT Reserved2;
};
swprintf (reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\
\Interface\\%s",
szAdapterGuid);
RegOpenKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L,
fReadOnly? KEY_READ : KEY_WRITE, & hKey);
return hKey;
status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L,
KEY_QUERY_VALUE, & key);
HKEY hKey;
status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L, L"",
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, & key, & disp);
[HLKM\SYSTEM\CurrentControlSet\Services\WLBS\ConfigurationHistory]
[{EBE09517-07B4-4E88-AAF1-E06F5540608B}]
Generation (DWORD)
[PendingOperation]
Generation (DWORD)
ThreadId (String)
[Completions]
1 Binary
2 Binary
Mutex Name
NLB_D6901862{EBE09517-07B4-4E88-AAF1-E06F5540608B}
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
// pointer to security attributes
BOOL bInitialOwner, // flag for initial ownership
LPCTSTR lpName // pointer to mutex-object name
);
04/10/2001 JosephJ Mutex vs Event vs Registry
Finally settled on a named event because:
1. Needs to recover from a process crash (so can't use registry)
2. Needs to be cross process -- so must used named object
3. Need to "acquire" in one thread and "release" in another -- so can't
use mutex.
The auto-reset event is normally signalled. It is non-signalled whenever
an operation is pending. It is manually set back to signalled whenever
the operation is completed.
bp tprov!NlbConfigurationUpdate__DoUpdate
bp tprov!NlbConfigurationUpdate__s_AsyncUpdateThreadProc
-------
Sean, you can do this semi-automatically by creating a new and temporary tree just for the merging process.
So for example, create a new directory driver2 in the private tree (or your scratch depot) and checkin the latest netvbl2 checked-in sources..
From one enlistment, open the files for edit, and copy over your BDA privates (but dont checkin).
From a second enlistment, open the files for edit, and copy over the latest privates from the private tree (this has virtual cluster support), and check this in.
Go back to the first enlistment and resolve.
-------
04/15/2001 JosephJ lightweight wmi wrapper.
Connect-to-machine
Get-object
04/15/2001 JosephJ Consider using IWbemServices::ExecQuery
04/25/2001 JosephJ Adding/removing IP addresses.
Binding/Re-binding NLB:
we require the explicit list of IP addresses to be specified.
We'll check that
(a) dedicated ip address, if specified, is first.
(b) cluster_vip and subnet mask match are present.
(c) vips for any per-ip port rules are present.
We honor the specified order of ip addresses.
Unbinding NLB:
We set the specified list of ip addresses.
If NULL, we'll switch the adapter to DHCP, which could take a while.
z:\nt\net\wlbs\api\obj\i386;Z:\nt\net\wlbs\nlbmgr\provider\tests\obj\i386;symsrv*symsrv.dll*\\symbols\symbols
10.1.x.x {A25EF21A-4634-4B15-AE7F-6825DFAD9FA6}
10.0.x.x {AD4DA14D-CAAE-42DD-97E3-5355E55247C2}
Utility function wrappers for exec method
CfgUtilGetWmiObjectInstance(szRoot, szPropertyName, szPropertyValue)
CfgUtilGetWmiRelPath(szRoot, szPropertyName, szPropertyValue)
CfgUtilGetWmiInputInstance(
IN szRoot,
IN szPropertyName, "NlbsNic"
IN szPropertyValue, "guid"
IN szMethod "EnableStatic"
OUT IInputInstance,
OUT szRelPath,
GetMethodInstanceByProperty
SetupInParams -->
ExecMethod
GetOutParams
bp tprov!CfgUtilGetWmiInputInstanceAndRelPath
WBEMSTATUS
IWbemSvc *pSvc
WBEMSTATUS
ConnectToWMi(
MACHINE-NAME, // NULL == Don't us WMI, "" == local,
szAdminPassword, // OPTIONAL
szAdminDomain, // OPTIONAL
szNicGuid,
info
);
WBEMSTATUS
GetClusterConfig(
MACHINE-NAME, // NULL == Don't us WMI, "" == local,
szAdminPassword, // OPTIONAL
szAdminDomain, // OPTIONAL
szNicGuid,
info
);
05/12/2001 JosephJ
To do:
1. Remove NlbState property, add BOOL NlbBound property
2. Get rid of SubnetMask string array -- Instead place subnet mask
after ip address: "10.1.1.1/255.255.255.255"
3. Demonstrate fundamental plumbing is working:
x Modify existing test to optionally go through WMI
-- get rid of nlbhost class (nlbhost.cpp)
x Verify we can get partial input and output parameters for GetConfig
x Implement and test GetClusterConfig with partial params
x Re-test local (non-wmi) functionality, including bind/unbind, change IPs
x Implement QueryUpdate and UpdateConfig
x test UpdateConfig with partial params
- Implement and test getting port rules information
- Implement and test settings port rule information
- Implement and test getting full information
- Implement and test setting full information
4. Hook into nlb manager
4. Add "partial-update" semantics
New parameter: BOOL PartialUpdate
OPTIONAL parameter Generation -- if specified, we'll verify that the
Generation matches the current generation.
parameter value NULL === don't change
port rules: require the following property on each PR for partial-updates:
action=[ADD|DELETE|UPDATE]
IP addresses: require the ip address to be prefixed by
"add:" "delete:" or "update:" (latter for changing subnet masks)
UI:
add:{10.1.1.3}
delete:{10.1.1.3, 255.0.0}
update:{10.1.1.3, 255.0.0}
EXAMPLE 1:
PartialUpdate=TRUE
PortRules="action=update ip=10.1.1.3 start=80 end=288 weight=20 ...."
EXAMPLE 2:
PartialUpdate=TRUE
IpAddresses="add:10.0.0.1/255.255.0.0", "delete:10.0.0.2"
Generation=8
5. Switch from events to using two mutexes
6. Explicitly report the following errors
- other update pending
- netcfg write lock held
7. Use resource strings
8. Use internal constants for error codes and literal strings
9. Follow up on WMI SDK errors -- DaveIce
WBEM_E_SERVER_NOT_FOUND -- where is this defined.
0x800706bf -- no definition in any header (and I checked in
index2a with interesting results), recoverable error.
0x80070767 -- no defn
0x80070005 -- no defn
!sympath .\obj\i386;symsrv*symsrv.dll*\\symbols\symbols
bp tprov!CfgUtilGetWmiInputInstanceAndRelPath
bp tprov!NlbHostGetConfiguration
05/17/2001 JosephJ more on partial updates
// Determine if this is a partial or full update.
// If partial update, we allow a subset of cluster configuration
// parameters to be specified, but allow only a restricted set
// of update operations.
//
// Disallowed partial update operations:
// - Transitions between bound and !bound
// - Currently bound but nlb parameters are invalid
//
// Some allowed partial updates:
// - Modifying IP address lists
// - Modifying cluster / dedicated addresses/subnets
// - Modifying existing portrules
// - Adding/deleting port rules
//
Successfully connected to NLB on JOSEPHJ4E...
Going call QueryConfigurationUpdateStatus...
QueryConfigurationUpdateStatus returns successfully
Connecting to NLB on JOSEPHJ4E ...
Successfully connected to NLB on JOSEPHJ4E...
Going call QueryConfigurationUpdateStatus...
QueryConfigurationUpdateStatus returns successfully
Connecting to NLB on JOSEPHJ4E ...
Sample framework provier...
C:\Microsoft Platform SDK\Samples\SysMgmt\WMI\VC\FrameworkProv
http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/wmisdk/framework_1h0l.htm
Static methods -- implementation
Declaring static: add "static" in mof ... [Implemented, static, ...]
Them in the ExecMethod class, simply ignore the Instance parameter.
Static methods -- calling
A method may or may not be static. Static methods are designated by the presence of the Static qualifier on their definition. Static methods are executed against a class, not a particular instance of that class. The path specified to a method execution API for a static method must, therefore, be a class name. Non-static methods are executed against a particular instance of a class. The path specified to a method execution for a non-static method must, therefore, be an instance path
Nadir Ahmed
Nadir Ahmed
PortRules= {
ip=1.1.1.1 protocol=TCP start=80 end=288 mode=SINGLE,
ip=1.1.1.1 protocol=TCP start=80 end=288 mode=SINGLE,
ip=1.1.1.1 protocol=TCP start=80 end=288 mode=SINGLE
}
NA = {
1.1.1.1/255.255.0.0,
}
read_string_array(out ppStrings,):
look for { [xxx,]* }
wmiupdate
nlbcfg wmiupdate>AdapterGuid={....}
nlbcfg \\asdasdfasdfsadf /u:ntdev\josephj *
enter password: *****
nlbcfg> wmiupdate {asdfasdfasdfsdf}
nlbcfg wmiupdate> niclist
blah
blah
blah
niclist> wmiupdate {guid}
blah
blah
blah
nlbcfg wmiupdate> NLBBound=true
nlbcfg wmiupdate> PortRules = {
ip=1.1.1.1 protocol=TCP start=80 end=288 mode=SINGLE
}
nlbcfg wmiupdate>
while(1)
{
Parse();
}
if (!scanf("%ws")==1)
{
if (!strncmpi(...., wmiupdate))
return ParseWmiUpdate());
}
SPECIFICATION --- COMMAND LINE
nlbcfg [machinename|-|.] [command_and_parameters] [options]
machinemame machine name
OR IP address
OR fully-qualified machine name
- Indicates not to use WMI -- call lower-level functions
directly
. Connect to local machine using wmi
command_and_parameters AdapterList
OR Update [adapter_guid]
OR Help
options /u domain\user [password | *]
Examples:
nlbcfg . AdapterList
nlbcfg . al
nlbcfg - Update
nlbcfg josephj4c /u:ntdev\josephj *
SPECIFICATION --- SHELL
AdapterList al
Update u
Quit q
Help h, ?
AdapterGuid ag
PartialUpdate pu
NetworkAddresses na
NLBBound nb
ClusterNetworkAddress cna
ClusterName cn
TrafficMode tm
PortRules pr
HostPriority hp
DedicatedNetworkAddress dna
ClusterModeOnStart cmos
RemoteControlEnabled rce
Password p
[IN] String ClientDescription,
[IN] String AdapterGuid,
[IN] uint32 Generation,
[IN] Boolean PartialUpdate,
[IN] String NetworkAddresses[], // "10.1.1.1/255.255.255.255"
[IN] Boolean NLBBound,
[IN] String ClusterNetworkAddress, // "10.1.1.1/255.0.0.0"
[IN] String ClusterName,
[IN] String TrafficMode, // UNICAST MULTICAST IGMPMULTICAST
[IN] String PortRules[],
[IN] uint32 HostPriority,
[IN] String DedicatedNetworkAddress, // "10.1.1.1/255.0.0.0"
[IN] Boolean ClusterModeOnStart,
[IN] Boolean RemoteControlEnabled,
[IN] String Password,
[OUT] uint32 NewGeneration,
[OUT] String Log
nlbcfg> update {guid}
Enter Adapter GUID: {guid}
NLB Configuration for Adapter xxxx xxxx:
Enter updated configuration, or type help for more information.
nlbcfg update> cna=10.0.0.1/255.255.255.0
nlbcfg update> cna=10.0.0.1/255.255.255.0
nlbcfg update> cna=10.0.0.1/255.255.255.0
nlbcfg update> .
Proposed new configuration:
.....
Enter y to confirm:
nlbcfg update> y
Going to perform update
...
....
complete
Reading configuration:
.......
Enter updated configuration or other command.
nlbcfg update>q
----------------
07/22/2001 JosephJ Reorganization
--------
Identifying dependencies on wlbsctrl.dll
CfgUtilInitialize(VOID);
CfgUtilDeitialize(VOID);
CfgUtilGetNlbConfig <- touches registry
CfgUtilSetNlbConfig <- touches registry
CfgUtilControlCluster <- touches driver
Following have no side effects....
CfgUtilInitializeParams
CfgUtilsAnalyzeNlbUpdate
CfgUtilGetPortRules
CfgUtilSetPortRules
To Do:
-----
Create two libs:
1. CfgUtil -- current CfgUtil* functionality
Used by: NlbClient (below) and nlbmprov.dll (wmi provider)
- Dynamically loads wlbsctrl.dll
- Works with W2K wlbsctrl.dll too!
- Unlike current version, it does NOT use the
wlbsctrl!CWlbsControl class.
2. NlbClient -- current NlbHost functionality (client side wmi wrappers)
Used by: tprov.exe, nlbmprov.dll
tprov.exe -- continues to live where it is -- because it directly compiles
the update functionality. Update functionality lives where it
is (in nlbmprov.dll) because we want to use it on w2k as-is (i.e.
xp nlbmprov.dll can be used as-is on W2K.
cfgutil.h cfgutil.lib
nlbclient.h nlbclient.lib
08/08/2001 JosephJ got this error from tracing. Turned out to because I'd
defined USE_MSVCRT=1 building cfgutil.lib but NOT when building tprov.exe.
Linking Executable - obj\i386\tprov.exe for i386
cfgutil.lib(cfgutil.obj) : warning LNK4217: locally defined symbol _wcslen
imported in function "void __stdcall WPP_SF_S(unsigned __int64,unsigned
short,struct _GUID const *,unsigned short const *)"
(?WPP_SF_S@@YGX_KGPBU_GUID@@PBG@Z)
link() : error LNK1218: warning treated as error; no output file generated
09/10/2001 JosephJ added ..\..\..\util\$(O)\wlbsutil.lib \
This is because cfgutil.lib needs it
and the latter needs it for a trivial
reason (see nlbmgr\cfgutillib\notes.txt) which we should consider
cleaning up so we don't need to do this.
09/27/2001 JosephJ tprov in demo mode:
dot cheese-a u back1
nb=t
na={10.0.0.1/255.0.0.0, 10.0.0.11/255.0.0.0}
dna=10.0.0.1/255.0.0.0
cna=10.0.0.11/255.0.0.0
09/27/2001 THings to change for multi-value initial state, and persist state.
o
add new cmos state "suspend" or "s"
parse_cluster_mode_on_start:
parse new initial state
PersistSuspend = true/false
display_config2: display new stuff
You can test by commenting out the // NlbHostFake line in tprov.cpp
To test
dot cheese-x u nic1
TO update, type a final "." character, followed by y to actually do
the update.
10/09/2001 JosephJ Support for control cluster.
Added support for control cluster. To use, use the "update" command.
The sub command is "control".
Format:
control [start|stop|drain|query] <- adapter wide
control port=xxx [ip=yyy] [enable|disable|drain|query] <- port specific
Samples:
control start
control ip=10.0.0.1 port=80 enable
control query
control port=80 query
control ip=10.0.0.1 port=80 query
At this point, to actually enable this, #define NEWSTUFF in function
tprov.cpp: parse_control.
01/01/2002 JosephJ Changes to make TPROV.EXE build again
sources: added a line ..\log_msgs.mc
tprov.cpp: added a global ghModule (referred to by ..\updatecfg.cpp)
04/15/2002 JosephJ