I have a class that encapsulates the cloud drive code for creating the page blob, the container, the cloud drive and mounting it. The resultant drive letter is stored as a static string that's then accessible by my web role (actually methods in
Default.aspx). When I start up the web role and start interacting with the web pages, everything works fine--the page is basically a from for user input that then gets stored on the cloud drive. But after some time period (15 min?) the next access (when loading
the page anew) of the drive letter reults in this error:
Could not find a part of the path 'F:\'.
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.IO.DirectoryNotFoundException: Could not find a part of the path 'F:\'.
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
[DirectoryNotFoundException: Could not find a part of the path 'F:\'.]
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +239
System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption) +2134
System.IO.DirectoryInfo.GetDirectories(String searchPattern, SearchOption searchOption) +140
JNBridge.CloudInterop.AzrInterOpCore.FileSystem.getAllProjectDirectories() in C:\Data\JNBridge\Cloud projects\InteropService\Prototype\AzrInteropCore\FileSystem.cs:164
JNBridge.CloudInterop.AzrInterOpCore.AzrInteropProjectManager.loadProjects() in C:\Data\JNBridge\Cloud projects\InteropService\Prototype\AzrInteropCore\AzrInteropProject.cs:197
JNBridge.CloudInterop.InterOpDistrib._Default.Page_Load(Object sender, EventArgs e) in C:\Data\JNBridge\Cloud projects\InteropService\Prototype\JNBAzrInteropSvc\InterOpDistrib\Default.aspx.cs:53
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +42
System.Web.UI.Control.OnLoad(EventArgs e) +132
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2428
Since you are running locally you should be able to use subst at a command prompt to verify that the drive has been mounted. Indeed you should be able to navigate the drive using Explorer. After your app starts it is probably worth doing this to check
that everything is OK.
One of the Azure Drive documents (Storage Team whitepaper?) suggests it may be worthwhile to try and write to a drive after mounting it just to ensure the drive was mounted OK.
Actually, I'm not running locally. This is all in Azure, not the Dev Fabric. The problem isn't that the mount doesn't work--I can read and write to the cloud drive fine. The problem is that after about 15 minutes (roughly) the drive letter, stored as a globally
available string, becomes stale resulting in the error. Because the drive is being accessed from a method in Default.aspx, are there issues with accessing the drive from different threads?
I can bring up the form the first time after the web role starts (the mount occurs when the code first asks for the drive letter from the global property, that's when the drive letter is cached), store that information to the drive. However, when I
wait 15 minutes and bring up the page a second time and grab the drive letter from the cache, the save to the cloud drive fails.
When you mount a Windows Azure Drive, a thread is created in your process to maintain the temporary signature the drive uses to authenticate with Windows Azure Storage. If your process exits, this thread is destroyed and your drive will be unmounted
in about 30 minutes because the authentication stops working. I'm guessing this is what is happening. The workaround is to call Mount() every time you need the drive. If the drive is already mounted, Mount() will return very quickly with
the current drive letter.
Even though this thread is marked as answered, I'd like to point out that Mount()/Unmount() of a read/write cloud drive carries a substantial penalty resulting in significant latency. For example, a simple ASP.NET form with a 'Submit' button
will invariably timeout if the click handler mounts the cloud drive followed by an unmount. Also, if the read/write drive is already mounted and another VM tries to mount the drive, that mount appears to block for some unspecified time--a behavior
that's not documented or configurable. The second mount should immediately throw an exception. Writing code that allows several roles to access a drive with read/write privleges is tatamount to writing an OS disk driver. Can't the Azure driver handle
Finally, using cloud drives in the dev fabric does not reflect the behavior of that same code running in Azure--in fact, something will run perfectly in the dev fabric, but throw an exception in Azure.
Beginnning with Azure SDK version 1.4 (or later) and Guest OS versions 1.9 or 2.1 (or later), the mount will persist even after the process that mounted the drive exits. Note for web and worker roles, it is necessary for the application to
be using both the correct SDK and Guest OS. A listing of OS versions is available here
For VM roles, the integration components in SDK 1.4 are sufficient for the mounts to persist.