Windows: cleanup redirector pipes
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 7 May 2012 15:35:07 +0000 (11:35 -0400)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 7 May 2012 17:04:00 +0000 (10:04 -0700)
If pipe creation fails, cleanup the mess.

At shutdown, if there are pipes that have not been closed by
Windows, clean them up.

This is just to ensure that at shutdown the reference counts of
cm_scache_t objects in the cache are reset to zero.

Change-Id: I1d738c31faafce445f05adc4884c7711123589e2
Reviewed-on: http://gerrit.openafs.org/7366
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsrdr/user/RDRInit.cpp
src/WINNT/afsrdr/user/RDRIoctl.c
src/WINNT/afsrdr/user/RDRIoctl.h
src/WINNT/afsrdr/user/RDRPipe.c
src/WINNT/afsrdr/user/RDRPipe.h
src/WINNT/afsrdr/user/RDRPrototypes.h

index 3870e6f..c8310a9 100644 (file)
@@ -168,6 +168,7 @@ RDR_Initialize(void)
     if (dwRet == ERROR_SUCCESS) {
 
         RDR_InitIoctl();
+        RDR_InitPipe();
     }
 
     return dwRet;
@@ -279,6 +280,10 @@ RDR_ShutdownNotify(void)
         // log the error, nothing to do
     }
 
+
+    RDR_ShutdownIoctl();
+    RDR_ShutdownPipe();
+
     return 0;
 }
 
index 2b5bd6f..804074a 100644 (file)
@@ -143,6 +143,12 @@ RDR_InitIoctl(void)
     RDR_ioctlProcsp[VIOC_SETVERIFYDATA] = RDR_IoctlSetVerifyData;
 }
 
+void
+RDR_ShutdownIoctl(void)
+{
+    lock_FinalizeRWLock(&RDR_globalIoctlLock);
+}
+
 /* called to make a fid structure into an IOCTL fid structure */
 void
 RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *userp)
index 821431e..0bf1689 100644 (file)
@@ -31,6 +31,8 @@
 
 extern void RDR_InitIoctl(void);
 
+extern void RDR_ShutdownIoctl(void);
+
 extern void RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *userp);
 
 extern void RDR_CleanupIoctl(ULONG index);
index e16b4db..8a86190 100644 (file)
@@ -69,6 +69,15 @@ RDR_InitPipe(void)
     lock_InitializeRWLock(&RDR_globalPipeLock, "RDR global pipe lock", LOCK_HIERARCHY_RDR_GLOBAL);
 }
 
+void
+RDR_ShutdownPipe(void)
+{
+    while (RDR_allPipes) {
+        RDR_CleanupPipe(RDR_allPipes->index);
+    }
+    lock_FinalizeRWLock(&RDR_globalPipeLock);
+}
+
 RDR_pipe_t *
 RDR_FindPipe(ULONG index, int locked)
 {
@@ -95,6 +104,7 @@ RDR_SetupPipe( ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid,
     cm_req_t req;
     DWORD status;
     char name[MAX_PATH];
+    int newpipe = 0;
 
     cm_InitReq(&req);
 
@@ -114,19 +124,13 @@ RDR_SetupPipe( ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid,
         }
     } else {
         /* need to allocate a new one */
+        newpipe = 1;
         pipep = malloc(sizeof(*pipep));
         if (pipep == NULL) {
             status = STATUS_NO_MEMORY;
             goto done;
         }
         memset(pipep, 0, sizeof(*pipep));
-        if (RDR_allPipes == NULL)
-            RDR_allPipes = RDR_allPipesLast = pipep;
-        else {
-            pipep->prev = RDR_allPipesLast;
-            RDR_allPipesLast->next = pipep;
-            RDR_allPipesLast = pipep;
-        }
         pipep->index = index;
         if (parentFid->cell == 0) {
             pipep->parentFid = cm_data.rootFid;
@@ -152,6 +156,43 @@ RDR_SetupPipe( ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid,
         pipep->devstate = RDR_DEVICESTATE_READMSGFROMPIPE |
                           RDR_DEVICESTATE_MESSAGEMODEPIPE |
                           RDR_DEVICESTATE_PIPECLIENTEND;
+
+        if (newpipe) {
+            if (RDR_allPipes == NULL)
+                RDR_allPipes = RDR_allPipesLast = pipep;
+            else {
+                pipep->prev = RDR_allPipesLast;
+                RDR_allPipesLast->next = pipep;
+                RDR_allPipesLast = pipep;
+            }
+        }
+    }
+    else
+    {
+        if (pipep->parentScp)
+            cm_ReleaseSCache(pipep->parentScp);
+
+        if (pipep->inAllocp)
+            free(pipep->inAllocp);
+        if (pipep->outAllocp)
+            free(pipep->outAllocp);
+
+        if (!newpipe) {
+            if (RDR_allPipes == RDR_allPipesLast)
+                RDR_allPipes = RDR_allPipesLast = NULL;
+            else {
+                if (pipep->prev == NULL)
+                    RDR_allPipes = pipep->next;
+                else
+                    pipep->prev->next = pipep->next;
+                if (pipep->next == NULL) {
+                    RDR_allPipesLast = pipep->prev;
+                    pipep->prev->next = NULL;
+                } else
+                    pipep->next->prev = pipep->prev;
+            }
+        }
+        free(pipep);
     }
 
   done:
index 740a2d5..eb6a8c8 100644 (file)
@@ -31,6 +31,8 @@
 
 extern void RDR_InitPipe(void);
 
+extern void RDR_ShutdownPipe(void);
+
 extern DWORD RDR_SetupPipe( ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid,
                             WCHAR *Name, DWORD NameLength,
                             cm_user_t *userp);
index 5ec9af3..d71a0c9 100644 (file)
@@ -289,6 +289,12 @@ RDR_ReleaseFid( IN cm_user_t     *userp,
                 IN OUT AFSCommResult **ResultCB);
 
 void
+RDR_InitPipe(void);
+
+void
+RDR_ShutdownPipe(void);
+
+void
 RDR_PipeOpen( IN cm_user_t *userp,
               IN AFSFileID  ParentId,
               IN WCHAR     *Name,
@@ -369,6 +375,9 @@ RDR_FID2fid( IN AFSFileID *FileId,
 void
 RDR_InitIoctl(void);
 
+void
+RDR_ShutdownIoctl(void);
+
 #ifdef __cplusplus
 }
 #endif