在vxWorks下,经常会遇到突然掉电后,文件系统被破坏,文件不能使用的情况。前几天我做了一个reboot的hook,使用rebootHookAdd增加到reboot函数中后,可以在系统复位前中止正在做写操作的任务,然后关闭文件和文件系统,同步cache,做到安全掉电。代码如下:
#include "vxWorks.h"
#include "private/dosFsVerP.h"
#include "private/dosFsLibP.h"
#include "private/iosLibP.h"
#include "taskLib.h"
#include "intLib.h"
#define DOSFS_REBOOT_HOOK_DEBUG     1
#if DOSFS_REBOOT_HOOK_DEBUG
char *g_pszDbgDosfsHookBuf = 0x6000;
#endif
extern int dosFsDrvNum;
extern int maxDrivers;
extern int maxFiles;
extern DRV_ENTRY *drvTable;
void usrDosfsShutdown()
{
    int iLoop, fdNum, iCount = 0, iStatus = 0;
    DEV_HDR *pDev = NULL;
    DOS_VOLUME_DESC_ID pVolDesc;
    DOS_FILE_DESC_ID pFd = pVolDesc->pFdList;
    
#if DOSFS_REBOOT_HOOK_DEBUG
    int  iCloseFlag = 0;
    char szTmpBuf[1024];
    int  curTick = tickGet();
    
    *(unsigned long *)g_pszDbgDosfsHookBuf = 0;
#endif
    if ((drvTable != NULL)
      &&(dosFsDrvNum != ERROR)&&(dosFsDrvNum < maxDrivers)
      &&(drvTable[dosFsDrvNum].de_inuse == TRUE))
    {
        for (iLoop = 0; iLoop < maxDrivers; iLoop++)
        {
            pDev = iosNextDevGet(pDev);
            if (pDev == NULL)
            {
                break;
            }
            /* All used dosfs function group is dosfs vol */
            if (pDev->drvNum == dosFsDrvNum)
            {
                pVolDesc = (DOS_VOLUME_DESC_ID)pDev;
#if DOSFS_REBOOT_HOOK_DEBUG
                sprintf(g_pszDbgDosfsHookBuf + strlen(g_pszDbgDosfsHookBuf), 
                        "Start check volume %s, can open max %d files, have used %d fds.\r\n", 
                        pDev->name, pVolDesc->maxFiles, pVolDesc->nBusyFd);
#endif
                iCount = 0;
                for (pFd = pVolDesc->pFdList; 
                     pFd < pVolDesc->pFdList + pVolDesc->maxFiles; pFd++)
                {
                    if (pFd->busy == TRUE)
                    {
#if DOSFS_REBOOT_HOOK_DEBUG
                        iCloseFlag = 0;
#endif
                        /* Force dosfs make a mistake, the operating will exit. */
                        pFd->fatHdl.errCode = TRUE;
                        for (fdNum = 0; fdNum < maxFiles; fdNum++)
                        {
                            if ((DOS_FILE_DESC_ID)iosFdValue(fdNum) == pFd)
                            {
#if DOSFS_REBOOT_HOOK_DEBUG
                                strcpy(szTmpBuf, fdTable[STD_MAP(fdNum)].name);
#endif
                                if (close(fdNum) == OK)
                                {
#if DOSFS_REBOOT_HOOK_DEBUG
                                    sprintf(g_pszDbgDosfsHookBuf + strlen(g_pszDbgDosfsHookBuf), 
                                            "  Closed %s success(fd==%d).\r\n", 
                                            szTmpBuf, fdNum);
#endif
                                    iCount++;
                                    iCloseFlag = TRUE;
                                }
                                else
                                {
#if DOSFS_REBOOT_HOOK_DEBUG
                                    sprintf(g_pszDbgDosfsHookBuf + strlen(g_pszDbgDosfsHookBuf), 
                                            "  Close %s failed(fd==%d).\r\n",
                                            szTmpBuf, fdNum);
#endif
                                }
                            }
                        }
#if DOSFS_REBOOT_HOOK_DEBUG
                        if (iCloseFlag == 0)
                        {
                            sprintf(g_pszDbgDosfsHookBuf + strlen(g_pszDbgDosfsHookBuf), 
                                    "  Find a file openned, but can't find its fd.");
                        }
#endif
                    }
                }
                iStatus = dosFsVolUnmount(pVolDesc);
#if DOSFS_REBOOT_HOOK_DEBUG
                sprintf(g_pszDbgDosfsHookBuf + strlen(g_pszDbgDosfsHookBuf), 
                        "Check volume %s over, closed %d files, unmount volume %s.\r\n", 
                        pDev->name,iCount,((iStatus==OK)?"success":"failed"));
#endif
            }
        }
    }
    else
    {
#if DOSFS_REBOOT_HOOK_DEBUG
        sprintf(g_pszDbgDosfsHookBuf + strlen(g_pszDbgDosfsHookBuf), 
                "Can't find dosfs volume!\r\n");
#endif
    }
#if DOSFS_REBOOT_HOOK_DEBUG
    sprintf(g_pszDbgDosfsHookBuf + strlen(g_pszDbgDosfsHookBuf), 
            "Check all dosfs volume, cost %d ticks.!\r\n", tickGet() - curTick);
#endif
}
			
			
			
						
			
 我要赚赏金
