From: Chris B. <buc...@us...> - 2012-03-07 00:52:38
|
Update of /cvsroot/sblim/sfcb In directory vz-cvs-3.sog:/tmp/cvs-serv21832 Modified Files: providerDrv.c providerMgr.c ChangeLog NEWS Log Message: [ 3497950 ] SFCB Semaphore Handling Improvements Index: NEWS =================================================================== RCS file: /cvsroot/sblim/sfcb/NEWS,v retrieving revision 1.653 retrieving revision 1.654 diff -u -d -r1.653 -r1.654 --- NEWS 6 Mar 2012 17:33:55 -0000 1.653 +++ NEWS 7 Mar 2012 00:52:36 -0000 1.654 @@ -44,6 +44,7 @@ - 3416060 sigsegv in tool_mm_flush() - 3497096 double free during stopProc - 3497765 Better Error Handling in sfcb Provider Manager and Driver +- 3497950 SFCB Semaphore Handling Improvements Changes in 1.3.13 ================= Index: providerMgr.c =================================================================== RCS file: /cvsroot/sblim/sfcb/providerMgr.c,v retrieving revision 1.79 retrieving revision 1.80 diff -u -d -r1.79 -r1.80 --- providerMgr.c 6 Mar 2012 17:33:55 -0000 1.79 +++ providerMgr.c 7 Mar 2012 00:52:36 -0000 1.80 @@ -1004,13 +1004,25 @@ int i = 0; _SFCB_ENTER(TRACE_PROVIDERMGR, "closeProviderContext"); for(i = 0; i < ctx->pCount; i++) { - semAcquire(sfcbSem,PROV_GUARD(ctx->pAs[i].ids.procId)); - if(semGetValue(sfcbSem, PROV_INUSE(ctx->pAs[i].ids.procId)) != 0) { - semAcquire(sfcbSem,PROV_INUSE(ctx->pAs[i].ids.procId)); + if (semAcquireUnDo(sfcbSem,PROV_GUARD(ctx->pAs[i].ids.procId))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + ctx->pAs[i].ids.procId, strerror(errno)); + _SFCB_ABORT(); + } + if(semGetValue(sfcbSem, PROV_INUSE(ctx->pAs[i].ids.procId)) > 0) { + if (semAcquireUnDo(sfcbSem,PROV_INUSE(ctx->pAs[i].ids.procId))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error decreasing inuse semaphore for %d, reason: %s\n", + ctx->pAs[i].ids.procId, strerror(errno)); + _SFCB_ABORT(); + } } else { fprintf(stderr, "--- closeProviderContext not touching sem %d; already zero\n", PROV_INUSE(ctx->pAs[i].ids.procId)); } - semRelease(sfcbSem,PROV_GUARD(ctx->pAs[i].ids.procId)); + if (semReleaseUnDo(sfcbSem,PROV_GUARD(ctx->pAs[i].ids.procId))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + ctx->pAs[i].ids.procId, strerror(errno)); + _SFCB_ABORT(); + } } if (ctx->pAs) free(ctx->pAs); } @@ -1023,15 +1035,30 @@ _SFCB_ENTER(TRACE_PROVIDERMGR, "setInuseSem"); if (sfcbSem < 0) { //Semaphore Not initialized. semKey=ftok(SFCB_BINARY,'S'); - sfcbSem=semget(semKey,1, 0600); + if ((sfcbSem=semget(semKey,1, 0600)) < 0) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error getting semaphore set, reason: %s\n", + strerror(errno)); + _SFCB_ABORT(); + } } ids.ids=id; - semAcquire(sfcbSem,PROV_GUARD(ids.procId)); - //semAcquire(sfcbSem,PROV_INUSE(ids.procId)); - //semReleaseUnDo(sfcbSem,PROV_INUSE(ids.procId)); - semRelease(sfcbSem,PROV_GUARD(ids.procId)); + if (semAcquireUnDo(sfcbSem,PROV_GUARD(ids.procId))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + ids.procId, strerror(errno)); + _SFCB_ABORT(); + } + if (semReleaseUnDo(sfcbSem,PROV_INUSE(ids.procId))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error increasing inuse semaphore for %d, reason: %s\n", + ids.procId, strerror(errno)); + _SFCB_ABORT(); + } + if (semReleaseUnDo(sfcbSem,PROV_GUARD(ids.procId))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + ids.procId, strerror(errno)); + _SFCB_ABORT(); + } _SFCB_EXIT(); } Index: providerDrv.c =================================================================== RCS file: /cvsroot/sblim/sfcb/providerDrv.c,v retrieving revision 1.108 retrieving revision 1.109 diff -u -d -r1.108 -r1.109 --- providerDrv.c 6 Mar 2012 17:33:55 -0000 1.108 +++ providerDrv.c 7 Mar 2012 00:52:36 -0000 1.109 @@ -156,6 +156,9 @@ ProviderInfo *activProvs = NULL; +static void increaseInUseSem(int id); +static void decreaseInUseSem(int id); + unsigned long provSampleInterval=10; unsigned long provTimeoutInterval=25; unsigned provAutoGroup=0; @@ -290,6 +293,52 @@ return count; } +static void increaseInUseSem(int id) +{ + _SFCB_ENTER(TRACE_PROVIDERDRV, "increaseInUseSem"); + + if (semAcquireUnDo(sfcbSem,PROV_GUARD(id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + id, strerror(errno)); + _SFCB_ABORT(); + } + if (semReleaseUnDo(sfcbSem,PROV_INUSE(id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error increasing inuse semaphore for %d, reason: %s\n", + id, strerror(errno)); + _SFCB_ABORT(); + } + if (semReleaseUnDo(sfcbSem,PROV_GUARD(id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + id, strerror(errno)); + _SFCB_ABORT(); + } + _SFCB_EXIT(); +} + +static void decreaseInUseSem(int id) +{ + _SFCB_ENTER(TRACE_PROVIDERDRV, "decreaseInUseSem"); + + if (semAcquireUnDo(sfcbSem,PROV_GUARD(id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + id, strerror(errno)); + _SFCB_ABORT(); + } + if (semGetValue(sfcbSem,PROV_INUSE(id)) > 0) { + if (semAcquireUnDo(sfcbSem,PROV_INUSE(id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error decreasing inuse semaphore for %d, reason: %s\n", + id, strerror(errno)); + _SFCB_ABORT(); + } + } + if (semReleaseUnDo(sfcbSem,PROV_GUARD(id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + id, strerror(errno)); + _SFCB_ABORT(); + } + _SFCB_EXIT(); +} + typedef struct _provLibAndTypes { void* lib; #define INST 1 @@ -474,8 +523,12 @@ if (pInfo) { proc=curProvProc; if (proc) { - semAcquireUnDo(sfcbSem,PROV_GUARD(proc->id)); - if ((val=semGetValue(sfcbSem,PROV_INUSE(proc->id)))==0) { + if (semAcquireUnDo(sfcbSem,PROV_GUARD(proc->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + proc->id, strerror(errno)); + _SFCB_ABORT(); + } + if ((val=semGetValue(sfcbSem,PROV_INUSE(proc->id)))==0) { if ((now-proc->lastActivity)>provTimeoutInterval) { ctx = native_new_CMPIContext(MEM_TRACKED,NULL); noBreak=0; @@ -542,7 +595,11 @@ } } } - semRelease(sfcbSem,PROV_GUARD(proc->id)); + if (semReleaseUnDo(sfcbSem,PROV_GUARD(proc->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + proc->id, strerror(errno)); + _SFCB_ABORT(); + } } } } @@ -692,19 +749,35 @@ for (i = 0; i < provProcMax; i++) { if ((provProc+i) && provProc[i].pid && provProc[i].group && strcmp(provProc[i].group,info->group)==0) { - semAcquire(sfcbSem,PROV_GUARD(provProc[i].id)); - semRelease(sfcbSem,PROV_INUSE(provProc[i].id)); - semRelease(sfcbSem,PROV_GUARD(provProc[i].id)); - info->pid=provProc[i].pid; - info->providerSockets=provProc[i].providerSockets; - _SFCB_TRACE(1,("--- Process %d shared by %s and %s",provProc[i].pid,info->providerName, - provProc[i].firstProv->providerName)); - if (provProc[i].firstProv) info->next=provProc[i].firstProv; - else info->next = NULL; - provProc[i].firstProv=info; - info->proc=provProc+i; - if (info->unload<provProc[i].unload) provProc[i].unload=info->unload; - _SFCB_RETURN(provProc[i].pid); + if (semAcquireUnDo(sfcbSem,PROV_GUARD(provProc[i].id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + provProc[i].id, strerror(errno)); + _SFCB_ABORT(); + } + /* double checking pattern required to prevent race ! */ + if ((provProc+i) && provProc[i].pid && + provProc[i].group && strcmp(provProc[i].group,info->group)==0) { + info->pid=provProc[i].pid; + info->providerSockets=provProc[i].providerSockets; + _SFCB_TRACE(1,("--- Process %d shared by %s and %s",provProc[i].pid,info->providerName, + provProc[i].firstProv->providerName)); + if (provProc[i].firstProv) info->next=provProc[i].firstProv; + else info->next = NULL; + provProc[i].firstProv=info; + info->proc=provProc+i; + if (info->unload<provProc[i].unload) provProc[i].unload=info->unload; + if (semReleaseUnDo(sfcbSem,PROV_GUARD(provProc[i].id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + provProc[i].id, strerror(errno)); + _SFCB_ABORT(); + } + _SFCB_RETURN(provProc[i].pid); + } + if (semReleaseUnDo(sfcbSem,PROV_GUARD(provProc[i].id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + provProc[i].id, strerror(errno)); + _SFCB_ABORT(); + } } } } @@ -761,13 +834,41 @@ providerProcess=1; info->proc=*proc; info->pid=currentProc; - - semSetValue(sfcbSem,PROV_GUARD((*proc)->id),0); - semSetValue(sfcbSem,PROV_INUSE((*proc)->id),0); - semSetValue(sfcbSem,PROV_ALIVE((*proc)->id),0); - semReleaseUnDo(sfcbSem,PROV_ALIVE((*proc)->id)); - semReleaseUnDo(sfcbSem,PROV_INUSE((*proc)->id)); - semRelease(sfcbSem,PROV_GUARD((*proc)->id)); + + /* The guard semaphore may never increase beyond 1, unless it is relased more often than + acquired. Therefore it is cleaner to acquire it than to set it to 0 unconditionally, + which can lead to a race, but we will also check the value to be sure. + */ + if (semAcquireUnDo(sfcbSem,PROV_GUARD((*proc)->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + (*proc)->id, strerror(errno)); + _SFCB_ABORT(); + } + if (semGetValue(sfcbSem,PROV_GUARD((*proc)->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error, guard semaphore for %d is not zero\n", + (*proc)->id); + _SFCB_ABORT(); + } + if (semSetValue(sfcbSem,PROV_INUSE((*proc)->id),0)) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error resetting inuse semaphore for %d, reason: %s\n", + (*proc)->id, strerror(errno)); + _SFCB_ABORT(); + } + if (semSetValue(sfcbSem,PROV_ALIVE((*proc)->id),0)) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error resetting alive semaphore for %d, step 1, reason: %s\n", + (*proc)->id, strerror(errno)); + _SFCB_ABORT(); + } + if (semReleaseUnDo(sfcbSem,PROV_ALIVE((*proc)->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error resetting alive semaphore for %d, step 2, reason: %s\n", + (*proc)->id, strerror(errno)); + _SFCB_ABORT(); + } + if (semReleaseUnDo(sfcbSem,PROV_GUARD((*proc)->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + (*proc)->id, strerror(errno)); + _SFCB_ABORT(); + } processProviderInvocationRequests(info->providerName); _SFCB_RETURN(0); @@ -797,17 +898,21 @@ if (info->pid ) { proc=info->proc; - semAcquire(sfcbSem,PROV_GUARD(proc->id)); - if ((val=semGetValue(sfcbSem,PROV_ALIVE(proc->id)))) { - semRelease(sfcbSem,PROV_INUSE(proc->id)); - semRelease(sfcbSem,PROV_GUARD(proc->id)); - _SFCB_TRACE(1, ("--- Provider %s still loaded",info->providerName)); - _SFCB_RETURN(CMPI_RC_OK) + if (semAcquireUnDo(sfcbSem,PROV_GUARD(proc->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error acquiring semaphore for %d, reason: %s\n", + proc->id, strerror(errno)); + _SFCB_ABORT(); + } + if ((val=semGetValue(sfcbSem,PROV_ALIVE(proc->id))) > 0) { + if (semReleaseUnDo(sfcbSem,PROV_GUARD(proc->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + proc->id, strerror(errno)); + _SFCB_ABORT(); + } + _SFCB_TRACE(1, ("--- Provider %s still loaded",info->providerName)); + _SFCB_RETURN(CMPI_RC_OK); } - semRelease(sfcbSem,PROV_GUARD(proc->id)); - _SFCB_TRACE(1, ("--- Provider has been unloaded prevously, will reload")); - info->pid=0; for (pInfo=proc->firstProv; pInfo; pInfo=pInfo->next) { pInfo->pid=0; @@ -815,6 +920,14 @@ proc->firstProv=NULL; proc->pid=0; proc->group=NULL; + + if (semReleaseUnDo(sfcbSem,PROV_GUARD(proc->id))) { + mlogf(M_ERROR,M_SHOW,"-#- Fatal error releasing semaphore for %d, reason: %s\n", + proc->id, strerror(errno)); + _SFCB_ABORT(); + } + _SFCB_TRACE(1, ("--- Provider has been unloaded prevously, will reload")); + } _SFCB_TRACE(1, ("--- Forking provider for %s", info->providerName)); @@ -2252,8 +2365,9 @@ _SFCB_TRACE(1, ("--- Back from provider rc: %d", rci.rc)); if (rci.rc==CMPI_RC_OK) { - resp = (BinResponseHdr *) calloc(1,sizeof(BinResponseHdr)); - resp->rc=1; + increaseInUseSem(info->provIds.procId); + resp = (BinResponseHdr *) calloc(1,sizeof(BinResponseHdr)); + resp->rc=1; } } @@ -2319,8 +2433,9 @@ } TIMING_STOP(hdr,info) if (rci.rc==CMPI_RC_OK) { - resp->rc=1; - _SFCB_RETURN(resp); + decreaseInUseSem(info->provIds.procId); + resp->rc=1; + _SFCB_RETURN(resp); } if (resp) free(resp); @@ -2366,8 +2481,8 @@ } if (rci.rc==CMPI_RC_OK) { - resp = (BinResponseHdr *) calloc(1,sizeof(BinResponseHdr)); - resp->rc=1; + resp = (BinResponseHdr *) calloc(1,sizeof(BinResponseHdr)); + resp->rc=1; } if (rci.rc!=CMPI_RC_OK) { resp = errorResp(&rci); Index: ChangeLog =================================================================== RCS file: /cvsroot/sblim/sfcb/ChangeLog,v retrieving revision 1.730 retrieving revision 1.731 diff -u -d -r1.730 -r1.731 --- ChangeLog 6 Mar 2012 17:33:55 -0000 1.730 +++ ChangeLog 7 Mar 2012 00:52:36 -0000 1.731 @@ -1,6 +1,10 @@ 2012-03-06 Chris Buccella <buc...@li...> * providerDrv.c, providerMgr.c: + [ 3497950 ] SFCB Semaphore Handling Improvements + (patch by Viktor Mihajlovski) + + * providerDrv.c, providerMgr.c: [ 3497765 ] Better Error Handling in sfcb Provider Manager and Driver (patch by Viktor Mihajlovski) |