New Solution to 500.19 Network BIOS Command Limit Reached
Setup: You have an IIS with
- php/asp/aspx content. Stored locally
- gazillion static files in gazillion directories. Stored on SMB-fileserver via UNC-Path
Problem:
The FileChangeMonitors sets notifications on every accessed file and directory, thus maxing out the notification capacity of the fileserver. Resulting in the beloved >NetBios Command Limit Reached<.
Common Solution 1: Recycle the AppPool (scheduled)
You will loose your sessions
Common Solution 2: Tune the SMB-Fileserver
If the fileserver is not Windows, you cant.
http://technet.microsoft.com/en-us/library/dd296694(WS.10).aspx
http://support.microsoft.com/kb/810886/en-us
-> lanmanworkstation\parameters\MaxCmds to 65535
-> lanmanserver\parameters\MaxMpxCt to 65535
Common Solution 3: Disable FCN alltogether
It is all or nothing. You cant just disable for UNC Paths
You will lose the dynamic compile feature. Changes to *.aspx, web.config are not detected etc. pp.
http://support.microsoft.com/kb/911272/en-us
-> HKLM\Software\Microsoft\ASP.NET\FCNMode to 1 (Dont forget WOW64 Node too)
This is all wellknown and works more or less.
I needed >dynamic compile< and >static content on UNC<
Challenge:
Prevent >NetBios Command Limit Reached< und still have FCN enabled.
New Solution:
Set FCNMode = 2. Call this code on a scheduled basis
<%@ import namespace="System.Diagnostics"%>
<%@ import namespace="System.Reflection"%>
<script runat="server" language="c#">
void Page_Load()
{
HttpRuntime theRuntime = null;
object fcm = null;
object dirmon = null;
object ismoni = null;
string DirToKill = "";
BindingFlags Methodflags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod;
BindingFlags SetFieldflags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField;
BindingFlags GetFieldflags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField;
BindingFlags Runtimeflags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField;
theRuntime = (HttpRuntime)typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime",Runtimeflags,null,null,null);
fcm = theRuntime.GetType().InvokeMember("_fcm", GetFieldflags, null,theRuntime,null);
int myFCNMode = (int)fcm.GetType().InvokeMember("_FCNMode", GetFieldflags, null, fcm, null);
if (myFCNMode != 1)
{
Hashtable value = (Hashtable)fcm.GetType().InvokeMember("_dirs", GetFieldflags, null, fcm, null);
foreach (DictionaryEntry entry in value)
{
DirToKill = entry.Key.ToString();
if (DirToKill.StartsWith("\\\\")) // Check if it is UNC
{
dirmon = fcm.GetType().InvokeMember("FindDirectoryMonitor", Methodflags, null, fcm, new object[] { DirToKill, false, false });
ismoni = dirmon.GetType().InvokeMember("IsMonitoring", Methodflags, null, dirmon, new object[] { });
if ((ismoni != null) && (((bool)ismoni) == true))
{
Response.Write("<br \> Stopping "+DirToKill);
dirmon.GetType().InvokeMember("StopMonitoring", Methodflags, null, dirmon, new object[] { });
}
}
}
}
}
</script>
How it works:
It calls the FCN, lists the monitored directories, and stops the monitoring if it is an UNC path.
FCN is not officially published. So it may change.
Adjust it to your needs, use it on your on risk.
Regards
Kai