VirtualBox

Changeset 77895 in vbox for trunk


Ignore:
Timestamp:
Mar 27, 2019 2:14:16 AM (6 years ago)
Author:
vboxsync
Message:

FsPerf: Added file-to-file sendfile testcase for linux. bugref:9172

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp

    r77894 r77895  
    5151#include <iprt/string.h>
    5252#include <iprt/stream.h>
     53#include <iprt/system.h>
    5354#include <iprt/test.h>
    5455#include <iprt/time.h>
     
    6768#  include <sys/uio.h>
    6869# endif
     70# include <sys/sendfile.h>
    6971#endif
    7072
     
    32423244
    32433245
     3246#ifdef RT_OS_LINUX
     3247DECL_FORCE_INLINE(int) fsPerfCopyWorkerSendFile(RTFILE hFile1, RTFILE hFile2, size_t cbFile)
     3248{
     3249    RTTESTI_CHECK_RC_RET(RTFileSeek(hFile2, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck);
     3250
     3251    loff_t off = 0;
     3252    ssize_t cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), &off, cbFile);
     3253    if (cbSent > 0 && (size_t)cbSent == cbFile)
     3254        return 0;
     3255
     3256    int rc = VERR_GENERAL_FAILURE;
     3257    if (cbSent < 0)
     3258    {
     3259        rc = RTErrConvertFromErrno(errno);
     3260        RTTestIFailed("sendfile(file,file,NULL,%#zx) failed (%zd): %d (%Rrc)", cbFile, cbSent, errno, rc);
     3261    }
     3262    else
     3263        RTTestIFailed("sendfile(file,file,NULL,%#zx) returned %#zx, expected %#zx (diff %zd)",
     3264                      cbFile, cbSent, cbFile, cbSent - cbFile);
     3265    return rc;
     3266}
     3267#endif /* RT_OS_LINUX */
     3268
     3269
    32443270static void fsPerfCopy(void)
    32453271{
     
    33303356        RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS);
    33313357        RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS);
     3358
     3359#ifdef RT_OS_LINUX
     3360        /*
     3361         * On linux we can also use sendfile between two files, except for 2.5.x to 2.6.33.
     3362         */
     3363        char szRelease[64];
     3364        RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szRelease, sizeof(szRelease));
     3365        bool const fSendFileBetweenFiles = RTStrVersionCompare(szRelease, "2.5.0") < 0
     3366                                        || RTStrVersionCompare(szRelease, "2.6.33") >= 0;
     3367        if (fSendFileBetweenFiles)
     3368        {
     3369            /* Copy the whole file: */
     3370            hFile1 = NIL_RTFILE;
     3371            RTTESTI_CHECK_RC(RTFileOpen(&hFile1, g_szDir, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ), VINF_SUCCESS);
     3372            RTFileDelete(g_szDir2);
     3373            hFile2 = NIL_RTFILE;
     3374            RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS);
     3375            ssize_t cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), NULL, cbFile);
     3376            if (cbSent < 0)
     3377                RTTestIFailed("sendfile(file,file,NULL,%#zx) failed (%zd): %d (%Rrc)",
     3378                              cbFile, cbSent, errno, RTErrConvertFromErrno(errno));
     3379            else if ((size_t)cbSent != cbFile)
     3380                RTTestIFailed("sendfile(file,file,NULL,%#zx) returned %#zx, expected %#zx (diff %zd)",
     3381                              cbFile, cbSent, cbFile, cbSent - cbFile);
     3382            RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
     3383            RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS);
     3384            RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS);
     3385
     3386            /* Try copy a little bit too much: */
     3387            hFile1 = NIL_RTFILE;
     3388            RTTESTI_CHECK_RC(RTFileOpen(&hFile1, g_szDir, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ), VINF_SUCCESS);
     3389            RTFileDelete(g_szDir2);
     3390            hFile2 = NIL_RTFILE;
     3391            RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS);
     3392            size_t cbToCopy = cbFile + RTRandU32Ex(1, _64M);
     3393            cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), NULL, cbToCopy);
     3394            if (cbSent < 0)
     3395                RTTestIFailed("sendfile(file,file,NULL,%#zx) failed (%zd): %d (%Rrc)",
     3396                              cbToCopy, cbSent, errno, RTErrConvertFromErrno(errno));
     3397            else if ((size_t)cbSent != cbFile)
     3398                RTTestIFailed("sendfile(file,file,NULL,%#zx) returned %#zx, expected %#zx (diff %zd)",
     3399                              cbToCopy, cbSent, cbFile, cbSent - cbFile);
     3400            RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
     3401            RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS);
     3402
     3403            /* Do partial copy: */
     3404            hFile2 = NIL_RTFILE;
     3405            RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS);
     3406            for (uint32_t i = 0; i < 64; i++)
     3407            {
     3408                cbToCopy = RTRandU32Ex(0, cbFile - 1);
     3409                uint32_t const offFile  = RTRandU32Ex(1, (uint64_t)RT_MIN(cbFile - cbToCopy, UINT32_MAX));
     3410                RTTESTI_CHECK_RC_BREAK(RTFileSeek(hFile2, offFile, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
     3411                loff_t offFile2 = offFile;
     3412                cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), &offFile2, cbToCopy);
     3413                if (cbSent < 0)
     3414                    RTTestIFailed("sendfile(file,file,%#x,%#zx) failed (%zd): %d (%Rrc)",
     3415                                  offFile, cbToCopy, cbSent, errno, RTErrConvertFromErrno(errno));
     3416                else if ((size_t)cbSent != cbToCopy)
     3417                    RTTestIFailed("sendfile(file,file,%#x,%#zx) returned %#zx, expected %#zx (diff %zd)",
     3418                                  offFile, cbToCopy, cbSent, cbToCopy, cbSent - cbToCopy);
     3419                else if (offFile2 != (loff_t)(offFile + cbToCopy))
     3420                    RTTestIFailed("sendfile(file,file,%#x,%#zx) returned %#zx + off=%#RX64, expected off %#x",
     3421                                  offFile, cbToCopy, cbSent, offFile2, offFile + cbToCopy);
     3422            }
     3423            RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
     3424            RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS);
     3425            RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS);
     3426        }
     3427#endif
    33323428
    33333429        /*
     
    34033499        /* We could benchmark RTFileCopyPart with various block sizes and whatnot...
    34043500           But it's currently well covered by the two previous operations. */
     3501
     3502#ifdef RT_OS_LINUX
     3503        if (fSendFileBetweenFiles)
     3504        {
     3505            hFile1 = NIL_RTFILE;
     3506            RTTESTI_CHECK_RC(RTFileOpen(&hFile1, g_szDir, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ), VINF_SUCCESS);
     3507            RTFileDelete(g_szDir2);
     3508            hFile2 = NIL_RTFILE;
     3509            RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS);
     3510            PROFILE_COPY_FN("sendfile/overwrite", fsPerfCopyWorkerSendFile(hFile1, hFile2, cbFile));
     3511            RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
     3512            RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS);
     3513        }
     3514#endif
     3515
    34053516    }
    34063517
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