Commit dcff1035 authored by Marc-André Lureau's avatar Marc-André Lureau Committed by Eduardo Habkost
Browse files

memfd: split qemu_memfd_alloc()



Add a function to only create a memfd, without mmap. The function is
used in the following memory backend.

Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20171023141815.17709-2-marcandre.lureau@redhat.com>
Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
parent 3e5bdc65
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#define F_SEAL_WRITE    0x0008  /* prevent writes */
#endif

int qemu_memfd_create(const char *name, size_t size, unsigned int seals);
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
                       int *fd);
void qemu_memfd_free(void *ptr, size_t size, int fd);
+36 −25
Original line number Diff line number Diff line
@@ -53,45 +53,56 @@ static int memfd_create(const char *name, unsigned int flags)
#define MFD_ALLOW_SEALING 0x0002U
#endif

/*
 * This is a best-effort helper for shared memory allocation, with
 * optional sealing. The helper will do his best to allocate using
 * memfd with sealing, but may fallback on other methods without
 * sealing.
 */
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
                       int *fd)
int qemu_memfd_create(const char *name, size_t size, unsigned int seals)
{
    void *ptr;
    int mfd = -1;

    *fd = -1;

#ifdef CONFIG_LINUX
    unsigned int flags = MFD_CLOEXEC;

    if (seals) {
        mfd = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
        flags |= MFD_ALLOW_SEALING;
    }

    if (mfd == -1) {
        /* some systems have memfd without sealing */
        mfd = memfd_create(name, MFD_CLOEXEC);
        seals = 0;
    mfd = memfd_create(name, flags);
    if (mfd < 0) {
        return -1;
    }
#endif

    if (mfd != -1) {
    if (ftruncate(mfd, size) == -1) {
        perror("ftruncate");
        close(mfd);
            return NULL;
        return -1;
    }

    if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) {
        perror("fcntl");
        close(mfd);
            return NULL;
        return -1;
    }
    } else {
#endif

    return mfd;
}

/*
 * This is a best-effort helper for shared memory allocation, with
 * optional sealing. The helper will do his best to allocate using
 * memfd with sealing, but may fallback on other methods without
 * sealing.
 */
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
                       int *fd)
{
    void *ptr;
    int mfd = qemu_memfd_create(name, size, seals);

    /* some systems have memfd without sealing */
    if (mfd == -1) {
        mfd = qemu_memfd_create(name, size, 0);
    }

    if (mfd == -1) {
        const char *tmpdir = g_get_tmp_dir();
        gchar *fname;