VirtualBox

Changeset 98481 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Feb 7, 2023 9:52:23 AM (2 years ago)
Author:
vboxsync
Message:

Devices/PC/DevQemuFwCfg: Add ability to create a initrd on the fly from a given directory. Allows remastering an initrd on the host which will be picked by the guest after a VM reset

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevQemuFwCfg.cpp

    r98103 r98481  
    4646 *
    4747 * The only mandatory item is the KernelImage one, the others are optional if the
    48  * kernel is configured to not require it. If the kernel is not an EFI compatible
    49  * executable (CONFIG_EFI_STUB=y for Linux) a dedicated setup image might be required
     48 * kernel is configured to not require it. The InitrdImage item accepts a path to a directory as well.
     49 * If a directory is encountered, the CPIO initrd image is created on the fly and passed to the guest.
     50 * If the kernel is not an EFI compatible executable (CONFIG_EFI_STUB=y for Linux) a dedicated setup image might be required
    5051 * which can be set with:
    5152 *
     
    7172#include <iprt/errcore.h>
    7273#include <iprt/assert.h>
     74#include <iprt/dir.h>
    7375#include <iprt/file.h>
     76#include <iprt/path.h>
    7477#include <iprt/string.h>
    7578#include <iprt/vfs.h>
    7679#include <iprt/zero.h>
     80#include <iprt/zip.h>
    7781
    7882#include "VBoxDD.h"
     
    147151/** @} */
    148152
     153/** The size of the directory entry buffer we're using. */
     154#define QEMUFWCFG_DIRENTRY_BUF_SIZE (sizeof(RTDIRENTRYEX) + RTPATH_MAX)
     155
    149156
    150157/*********************************************************************************************************************************
     
    193200    /** Guest physical address of the DMA descriptor. */
    194201    RTGCPHYS                    GCPhysDma;
     202    /** VFS file of the on-the-fly created initramfs. */
     203    RTVFSFILE                   hVfsFileInitrd;
    195204
    196205    /** Scratch buffer for config item specific data. */
     
    303312    PCPDMDEVHLPR3 pHlp  = pThis->pDevIns->pHlpR3;
    304313
    305     /* Query the path from the CFGM key. */
    306     char *pszFilePath = NULL;
    307     int rc = pHlp->pfnCFGMQueryStringAlloc(pThis->pCfg, pItem->pszCfgmKey, &pszFilePath);
     314    int rc = VINF_SUCCESS;
     315    RTVFSFILE hVfsFile = NIL_RTVFSFILE;
     316    if (   pItem->uCfgItem == QEMU_FW_CFG_ITEM_INITRD_SIZE
     317        && pThis->hVfsFileInitrd != NIL_RTVFSFILE)
     318    {
     319        RTVfsFileRetain(pThis->hVfsFileInitrd);
     320        hVfsFile = pThis->hVfsFileInitrd;
     321    }
     322    else
     323    {
     324        /* Query the path from the CFGM key. */
     325        char *pszFilePath = NULL;
     326        rc = pHlp->pfnCFGMQueryStringAlloc(pThis->pCfg, pItem->pszCfgmKey, &pszFilePath);
     327        if (RT_SUCCESS(rc))
     328        {
     329            rc = RTVfsFileOpenNormal(pszFilePath, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile);
     330            if (RT_FAILURE(rc))
     331                LogRel(("QemuFwCfg: Failed to open file \"%s\" -> %Rrc\n", pszFilePath, rc));
     332            PDMDevHlpMMHeapFree(pThis->pDevIns, pszFilePath);
     333        }
     334        else
     335            LogRel(("QemuFwCfg: Failed to query \"%s\" -> %Rrc\n", pItem->pszCfgmKey, rc));
     336    }
     337
    308338    if (RT_SUCCESS(rc))
    309339    {
    310         RTVFSFILE hVfsFile = NIL_RTVFSFILE;
    311         rc = RTVfsFileOpenNormal(pszFilePath, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile);
     340        uint64_t cbFile = 0;
     341        rc = RTVfsFileQuerySize(hVfsFile, &cbFile);
    312342        if (RT_SUCCESS(rc))
    313343        {
    314             uint64_t cbFile = 0;
    315             rc = RTVfsFileQuerySize(hVfsFile, &cbFile);
    316             if (RT_SUCCESS(rc))
     344            if (cbFile < _4G)
    317345            {
    318                 if (cbFile < _4G)
    319                 {
    320                     pThis->u.u32 = (uint32_t)cbFile;
    321                     *pcbItem = sizeof(uint32_t);
    322                 }
    323                 else
    324                 {
    325                     rc = VERR_BUFFER_OVERFLOW;
    326                     LogRel(("QemuFwCfg: File \"%s\" exceeds 4G limit (%llu)\n", pszFilePath, cbFile));
    327                 }
     346                pThis->u.u32 = (uint32_t)cbFile;
     347                *pcbItem = sizeof(uint32_t);
    328348            }
    329349            else
    330                 LogRel(("QemuFwCfg: Failed to query file size from \"%s\" -> %Rrc\n", pszFilePath, rc));
    331             RTVfsFileRelease(hVfsFile);
     350            {
     351                rc = VERR_BUFFER_OVERFLOW;
     352                LogRel(("QemuFwCfg: File exceeds 4G limit (%llu)\n", cbFile));
     353            }
    332354        }
    333355        else
    334             LogRel(("QemuFwCfg: Failed to open file \"%s\" -> %Rrc\n", pszFilePath, rc));
    335         PDMDevHlpMMHeapFree(pThis->pDevIns, pszFilePath);
    336     }
    337     else
    338         LogRel(("QemuFwCfg: Failed to query \"%s\" -> %Rrc\n", pItem->pszCfgmKey, rc));
     356            LogRel(("QemuFwCfg: Failed to query file size from -> %Rrc\n", rc));
     357        RTVfsFileRelease(hVfsFile);
     358    }
    339359
    340360    return rc;
     
    390410    PCPDMDEVHLPR3 pHlp  = pThis->pDevIns->pHlpR3;
    391411
    392     /* Query the path from the CFGM key. */
    393     char *pszFilePath = NULL;
    394     int rc = pHlp->pfnCFGMQueryStringAlloc(pThis->pCfg, pItem->pszCfgmKey, &pszFilePath);
     412    int rc = VINF_SUCCESS;
     413    if (   pItem->uCfgItem == QEMU_FW_CFG_ITEM_INITRD_DATA
     414        && pThis->hVfsFileInitrd != NIL_RTVFSFILE)
     415    {
     416        RTVfsFileRetain(pThis->hVfsFileInitrd);
     417        pThis->u.hVfsFile = pThis->hVfsFileInitrd;
     418    }
     419    else
     420    {
     421        /* Query the path from the CFGM key. */
     422        char *pszFilePath = NULL;
     423        rc = pHlp->pfnCFGMQueryStringAlloc(pThis->pCfg, pItem->pszCfgmKey, &pszFilePath);
     424        if (RT_SUCCESS(rc))
     425        {
     426            rc = RTVfsFileOpenNormal(pszFilePath, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &pThis->u.hVfsFile);
     427            if (RT_FAILURE(rc))
     428                LogRel(("QemuFwCfg: Failed to open file \"%s\" -> %Rrc\n", pszFilePath, rc));
     429            PDMDevHlpMMHeapFree(pThis->pDevIns, pszFilePath);
     430        }
     431        else
     432            LogRel(("QemuFwCfg: Failed to query \"%s\" -> %Rrc\n", pItem->pszCfgmKey, rc));
     433    }
     434
    395435    if (RT_SUCCESS(rc))
    396436    {
    397         rc = RTVfsFileOpenNormal(pszFilePath, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &pThis->u.hVfsFile);
     437        uint64_t cbFile = 0;
     438        rc = RTVfsFileQuerySize(pThis->u.hVfsFile, &cbFile);
    398439        if (RT_SUCCESS(rc))
    399440        {
    400             uint64_t cbFile = 0;
    401             rc = RTVfsFileQuerySize(pThis->u.hVfsFile, &cbFile);
    402             if (RT_SUCCESS(rc))
     441            if (cbFile < _4G)
     442                *pcbItem = (uint32_t)cbFile;
     443            else
    403444            {
    404                 if (cbFile < _4G)
    405                     *pcbItem = (uint32_t)cbFile;
    406                 else
    407                 {
    408                     rc = VERR_BUFFER_OVERFLOW;
    409                     LogRel(("QemuFwCfg: File \"%s\" exceeds 4G limit (%llu)\n", pszFilePath, cbFile));
    410                 }
     445                rc = VERR_BUFFER_OVERFLOW;
     446                LogRel(("QemuFwCfg: File exceeds 4G limit (%llu)\n", cbFile));
    411447            }
    412             else
    413                 LogRel(("QemuFwCfg: Failed to query file size from \"%s\" -> %Rrc\n", pszFilePath, rc));
    414448        }
    415449        else
    416             LogRel(("QemuFwCfg: Failed to open file \"%s\" -> %Rrc\n", pszFilePath, rc));
    417         PDMDevHlpMMHeapFree(pThis->pDevIns, pszFilePath);
    418     }
    419     else
    420         LogRel(("QemuFwCfg: Failed to query \"%s\" -> %Rrc\n", pItem->pszCfgmKey, rc));
     450            LogRel(("QemuFwCfg: Failed to query file size from -> %Rrc\n", rc));
     451    }
    421452
    422453    return rc;
     
    762793
    763794/**
     795 * Sets up the initrd memory file and CPIO filesystem stream for writing.
     796 *
     797 * @returns VBox status code.
     798 * @param   pThis               The QEMU fw config device instance.
     799 * @param   phVfsFss            Where to return the filesystem stream handle.
     800 */
     801static int qemuFwCfgCreateOutputArchive(PDEVQEMUFWCFG pThis, PRTVFSFSSTREAM phVfsFss)
     802{
     803    int rc = RTVfsMemFileCreate(NIL_RTVFSIOSTREAM, 0 /*cbEstimate*/, &pThis->hVfsFileInitrd);
     804    if (RT_SUCCESS(rc))
     805    {
     806        RTVFSFSSTREAM hVfsFss;
     807        RTVFSIOSTREAM hVfsIosOut = RTVfsFileToIoStream(pThis->hVfsFileInitrd);
     808        rc = RTZipTarFsStreamToIoStream(hVfsIosOut, RTZIPTARFORMAT_CPIO_ASCII_NEW, 0 /*fFlags*/, &hVfsFss);
     809        if (RT_SUCCESS(rc))
     810        {
     811            rc = RTZipTarFsStreamSetOwner(hVfsFss, 0, "root");
     812            if (RT_SUCCESS(rc))
     813                rc = RTZipTarFsStreamSetGroup(hVfsFss, 0, "root");
     814
     815            if (RT_SUCCESS(rc))
     816                *phVfsFss = hVfsFss;
     817            else
     818            {
     819                RTVfsFsStrmRelease(hVfsFss);
     820                *phVfsFss = NIL_RTVFSFSSTREAM;
     821            }
     822        }
     823        RTVfsIoStrmRelease(hVfsIosOut);
     824    }
     825
     826    return rc;
     827}
     828
     829
     830/**
     831 * Archives a file.
     832 *
     833 * @returns VBox status code.
     834 * @param   hVfsFss         The TAR filesystem stream handle.
     835 * @param   pszSrc          The file path or VFS spec.
     836 * @param   pszDst          The name to archive the file under.
     837 * @param   pErrInfo        Error info buffer (saves stack space).
     838 */
     839static int qemuFwCfgInitrdArchiveFile(RTVFSFSSTREAM hVfsFss, const char *pszSrc,
     840                                      const char *pszDst, PRTERRINFOSTATIC pErrInfo)
     841{
     842    /* Open the file. */
     843    uint32_t        offError;
     844    RTVFSIOSTREAM   hVfsIosSrc;
     845    int rc = RTVfsChainOpenIoStream(pszSrc, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
     846                                    &hVfsIosSrc, &offError, RTErrInfoInitStatic(pErrInfo));
     847    if (RT_FAILURE(rc))
     848        return rc;
     849
     850    /* I/O stream to base object. */
     851    RTVFSOBJ hVfsObjSrc = RTVfsObjFromIoStream(hVfsIosSrc);
     852    if (hVfsObjSrc != NIL_RTVFSOBJ)
     853    {
     854        /*
     855         * Add it to the stream.
     856         */
     857        rc = RTVfsFsStrmAdd(hVfsFss, pszDst, hVfsObjSrc, 0 /*fFlags*/);
     858        RTVfsIoStrmRelease(hVfsIosSrc);
     859        RTVfsObjRelease(hVfsObjSrc);
     860        return rc;
     861    }
     862    RTVfsIoStrmRelease(hVfsIosSrc);
     863    return VERR_INVALID_POINTER;
     864}
     865
     866
     867/**
     868 * Archives a symlink.
     869 *
     870 * @returns VBox status code.
     871 * @param   hVfsFss         The TAR filesystem stream handle.
     872 * @param   pszSrc          The file path or VFS spec.
     873 * @param   pszDst          The name to archive the file under.
     874 * @param   pErrInfo        Error info buffer (saves stack space).
     875 */
     876static int qemuFwCfgInitrdArchiveSymlink(RTVFSFSSTREAM hVfsFss, const char *pszSrc,
     877                                         const char *pszDst, PRTERRINFOSTATIC pErrInfo)
     878{
     879    /* Open the file. */
     880    uint32_t        offError;
     881    RTVFSOBJ        hVfsObjSrc;
     882    int rc = RTVfsChainOpenObj(pszSrc, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
     883                               RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_CREATE_NOTHING | RTPATH_F_ON_LINK,
     884                               &hVfsObjSrc, &offError, RTErrInfoInitStatic(pErrInfo));
     885    if (RT_FAILURE(rc))
     886        return rc;
     887
     888    rc = RTVfsFsStrmAdd(hVfsFss, pszDst, hVfsObjSrc, 0 /*fFlags*/);
     889    RTVfsObjRelease(hVfsObjSrc);
     890    return rc;
     891}
     892
     893
     894/**
     895 * Sub-directory helper for creating archives.
     896 *
     897 * @returns VBox status code.
     898 * @param   hVfsFss         The TAR filesystem stream handle.
     899 * @param   pszSrc          The directory path or VFS spec.  We append to the
     900 *                          buffer as we decend.
     901 * @param   cchSrc          The length of the input.
     902 * @param   pszDst          The name to archive it the under.  We append to the
     903 *                          buffer as we decend.
     904 * @param   cchDst          The length of the input.
     905 * @param   pDirEntry       Directory entry to use for the directory to handle.
     906 * @param   pErrInfo        Error info buffer (saves stack space).
     907 */
     908static int qemuFwCfgInitrdArchiveDirSub(RTVFSFSSTREAM hVfsFss,
     909                                        char *pszSrc, size_t cchSrc,
     910                                        char pszDst[RTPATH_MAX], size_t cchDst, PRTDIRENTRYEX pDirEntry,
     911                                        PRTERRINFOSTATIC pErrInfo)
     912{
     913    uint32_t offError;
     914    RTVFSDIR hVfsIoDir;
     915    int rc = RTVfsChainOpenDir(pszSrc, 0 /*fFlags*/,
     916                               &hVfsIoDir, &offError, RTErrInfoInitStatic(pErrInfo));
     917    if (RT_FAILURE(rc))
     918        return rc;
     919
     920    /* Make sure we've got some room in the path, to save us extra work further down. */
     921    if (cchSrc + 3 >= RTPATH_MAX)
     922        return VERR_FILENAME_TOO_LONG;
     923
     924    /* Ensure we've got a trailing slash (there is space for it see above). */
     925    if (!RTPATH_IS_SEP(pszSrc[cchSrc - 1]))
     926    {
     927        pszSrc[cchSrc++] = RTPATH_SLASH;
     928        pszSrc[cchSrc]   = '\0';
     929    }
     930
     931    /* Ditto for destination. */
     932    if (cchDst + 3 >= RTPATH_MAX)
     933        return VERR_FILENAME_TOO_LONG;
     934
     935    /* Don't try adding the root directory. */
     936    if (*pszDst != '\0')
     937    {
     938        RTVFSOBJ hVfsObjSrc = RTVfsObjFromDir(hVfsIoDir);
     939        rc = RTVfsFsStrmAdd(hVfsFss, pszDst, hVfsObjSrc, 0 /*fFlags*/);
     940        RTVfsObjRelease(hVfsObjSrc);
     941        if (RT_FAILURE(rc))
     942            return rc;
     943
     944        if (!RTPATH_IS_SEP(pszDst[cchDst - 1]))
     945        {
     946            pszDst[cchDst++] = RTPATH_SLASH;
     947            pszDst[cchDst]   = '\0';
     948        }
     949    }
     950
     951    /*
     952     * Process the files and subdirs.
     953     */
     954    for (;;)
     955    {
     956        size_t cbDirEntry = QEMUFWCFG_DIRENTRY_BUF_SIZE;
     957        rc = RTVfsDirReadEx(hVfsIoDir, pDirEntry, &cbDirEntry, RTFSOBJATTRADD_UNIX);
     958        if (RT_FAILURE(rc))
     959            break;
     960
     961        /* Check length. */
     962        if (pDirEntry->cbName + cchSrc + 3 >= RTPATH_MAX)
     963        {
     964            rc = VERR_BUFFER_OVERFLOW;
     965            break;
     966        }
     967
     968        switch (pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK)
     969        {
     970            case RTFS_TYPE_DIRECTORY:
     971            {
     972                if (RTDirEntryExIsStdDotLink(pDirEntry))
     973                    continue;
     974
     975                memcpy(&pszSrc[cchSrc], pDirEntry->szName, pDirEntry->cbName + 1);
     976                memcpy(&pszDst[cchDst], pDirEntry->szName, pDirEntry->cbName + 1);
     977                rc = qemuFwCfgInitrdArchiveDirSub(hVfsFss, pszSrc, cchSrc + pDirEntry->cbName,
     978                                                  pszDst, cchDst + pDirEntry->cbName, pDirEntry, pErrInfo);
     979                break;
     980            }
     981
     982            case RTFS_TYPE_FILE:
     983            {
     984                memcpy(&pszSrc[cchSrc], pDirEntry->szName, pDirEntry->cbName + 1);
     985                memcpy(&pszDst[cchDst], pDirEntry->szName, pDirEntry->cbName + 1);
     986                rc = qemuFwCfgInitrdArchiveFile(hVfsFss, pszSrc, pszDst, pErrInfo);
     987                break;
     988            }
     989
     990            case RTFS_TYPE_SYMLINK:
     991            {
     992                memcpy(&pszSrc[cchSrc], pDirEntry->szName, pDirEntry->cbName + 1);
     993                memcpy(&pszDst[cchDst], pDirEntry->szName, pDirEntry->cbName + 1);
     994                rc = qemuFwCfgInitrdArchiveSymlink(hVfsFss, pszSrc, pszDst, pErrInfo);
     995                break;
     996            }
     997
     998            default:
     999            {
     1000                LogRel(("Warning: File system type %#x for '%s' not implemented yet, sorry! Skipping ...\n",
     1001                        pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK, pDirEntry->szName));
     1002                break;
     1003            }
     1004        }
     1005    }
     1006
     1007    if (rc == VERR_NO_MORE_FILES)
     1008        rc = VINF_SUCCESS;
     1009
     1010    RTVfsDirRelease(hVfsIoDir);
     1011    return rc;
     1012}
     1013
     1014
     1015/**
     1016 * Archives a directory recursively.
     1017 *
     1018 * @returns VBox status code.
     1019 * @param   hVfsFss         The CPIO filesystem stream handle.
     1020 * @param   pszSrc          The directory path or VFS spec.  We append to the
     1021 *                          buffer as we decend.
     1022 * @param   cchSrc          The length of the input.
     1023 * @param   pszDst          The name to archive it the under.  We append to the
     1024 *                          buffer as we decend.
     1025 * @param   cchDst          The length of the input.
     1026 * @param   pErrInfo        Error info buffer (saves stack space).
     1027 */
     1028static int qemuFwCfgInitrdArchiveDir(RTVFSFSSTREAM hVfsFss, char pszSrc[RTPATH_MAX], size_t cchSrc,
     1029                                     char pszDst[RTPATH_MAX], size_t cchDst,
     1030                                     PRTERRINFOSTATIC pErrInfo)
     1031{
     1032    RT_NOREF(cchSrc);
     1033
     1034    char szSrcAbs[RTPATH_MAX];
     1035    int rc = RTPathAbs(pszSrc, szSrcAbs, sizeof(szSrcAbs));
     1036    if (RT_FAILURE(rc))
     1037        return rc;
     1038
     1039    union
     1040    {
     1041        uint8_t         abPadding[QEMUFWCFG_DIRENTRY_BUF_SIZE];
     1042        RTDIRENTRYEX    DirEntry;
     1043    } uBuf;
     1044
     1045    return qemuFwCfgInitrdArchiveDirSub(hVfsFss, szSrcAbs, strlen(szSrcAbs), pszDst, cchDst, &uBuf.DirEntry, pErrInfo);
     1046}
     1047
     1048
     1049/**
     1050 * Creates an on the fly initramfs for a given root directory.
     1051 *
     1052 * @returns VBox status code.
     1053 * @param   pThis               The QEMU fw config device instance.
     1054 * @param   pszPath             The path to work on.
     1055 */
     1056static int qemuFwCfgInitrdCreate(PDEVQEMUFWCFG pThis, const char *pszPath)
     1057{
     1058    /*
     1059     * First open the output file.
     1060     */
     1061    RTVFSFSSTREAM hVfsFss;
     1062    int rc = qemuFwCfgCreateOutputArchive(pThis, &hVfsFss);
     1063    if (RT_FAILURE(rc))
     1064        return rc;
     1065
     1066    /*
     1067     * Construct/copy the source name.
     1068     */
     1069    char szSrc[RTPATH_MAX];
     1070    rc = RTStrCopy(szSrc, sizeof(szSrc), pszPath);
     1071    if (RT_SUCCESS(rc))
     1072    {
     1073        RTERRINFOSTATIC ErrInfo;
     1074        char  szDst[RTPATH_MAX]; RT_ZERO(szDst);
     1075        rc = qemuFwCfgInitrdArchiveDir(hVfsFss, szSrc, strlen(szSrc),
     1076                                       szDst, strlen(szDst), &ErrInfo);
     1077    }
     1078
     1079    /*
     1080     * Finalize the archive.
     1081     */
     1082    int rc2 = RTVfsFsStrmEnd(hVfsFss); AssertRC(rc2);
     1083    RTVfsFsStrmRelease(hVfsFss);
     1084    return rc;
     1085}
     1086
     1087
     1088/**
     1089 * Checks whether creation of the initrd should be done on the fly.
     1090 *
     1091 * @returns VBox status code.
     1092 * @param   pThis               The QEMU fw config device instance.
     1093 */
     1094static int qemuFwCfgInitrdMaybeCreate(PDEVQEMUFWCFG pThis)
     1095{
     1096    PPDMDEVINS pDevIns = pThis->pDevIns;
     1097    PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
     1098
     1099    /* Query the path from the CFGM key. */
     1100    char *pszFilePath = NULL;
     1101    int rc = pHlp->pfnCFGMQueryStringAlloc(pThis->pCfg, "InitrdImage", &pszFilePath);
     1102    if (RT_SUCCESS(rc))
     1103    {
     1104        if (RTDirExists(pszFilePath))
     1105        {
     1106            rc = qemuFwCfgInitrdCreate(pThis, pszFilePath);
     1107            if (RT_FAILURE(rc))
     1108                rc = PDMDEV_SET_ERROR(pDevIns, rc,
     1109                                      N_("QemuFwCfg: failed to create the in memory initram filesystem"));
     1110        }
     1111        /*else: Probably a normal file. */
     1112        PDMDevHlpMMHeapFree(pDevIns, pszFilePath);
     1113    }
     1114    else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
     1115        rc = PDMDEV_SET_ERROR(pDevIns, rc,
     1116                              N_("Configuration error: Querying \"InitrdImage\" as a string failed"));
     1117    else
     1118        rc = VINF_SUCCESS;
     1119
     1120    return rc;
     1121}
     1122
     1123
     1124/**
    7641125 * @interface_method_impl{PDMDEVREG,pfnReset}
    7651126 */
     
    7701131    qemuFwCfgR3ItemReset(pThis);
    7711132    pThis->GCPhysDma = 0;
     1133
     1134    if (pThis->hVfsFileInitrd != NIL_RTVFSFILE)
     1135        RTVfsFileRelease(pThis->hVfsFileInitrd);
     1136    pThis->hVfsFileInitrd = NIL_RTVFSFILE;
     1137
     1138    qemuFwCfgInitrdMaybeCreate(pThis); /* Ignores status code. */
    7721139}
    7731140
     
    7831150    qemuFwCfgR3ItemReset(pThis);
    7841151    pThis->GCPhysDma = 0;
     1152
     1153    if (pThis->hVfsFileInitrd != NIL_RTVFSFILE)
     1154        RTVfsFileRelease(pThis->hVfsFileInitrd);
     1155    pThis->hVfsFileInitrd = NIL_RTVFSFILE;
    7851156
    7861157    return VINF_SUCCESS;
     
    8201191    pThis->u32Version     = QEMU_FW_CFG_VERSION_LEGACY | (fDmaEnabled ? QEMU_FW_CFG_VERSION_DMA : 0);
    8211192    pThis->GCPhysDma      = 0;
     1193    pThis->hVfsFileInitrd = NIL_RTVFSFILE;
    8221194
    8231195    qemuFwCfgR3ItemReset(pThis);
     1196
     1197    rc = qemuFwCfgInitrdMaybeCreate(pThis);
     1198    if (RT_FAILURE(rc))
     1199        return rc; /* Error set. */
    8241200
    8251201    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette