memfd: add error argument, instead of perror()
This will allow callers to silence error report when the call is allowed to failed. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180201132757.23063-2-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									dbadee4ff4
								
							
						
					
					
						commit
						0f2956f915
					
				| 
						 | 
				
			
			@ -330,6 +330,7 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev)
 | 
			
		|||
 | 
			
		||||
static struct vhost_log *vhost_log_alloc(uint64_t size, bool share)
 | 
			
		||||
{
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
    struct vhost_log *log;
 | 
			
		||||
    uint64_t logsize = size * sizeof(*(log->log));
 | 
			
		||||
    int fd = -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -338,7 +339,12 @@ static struct vhost_log *vhost_log_alloc(uint64_t size, bool share)
 | 
			
		|||
    if (share) {
 | 
			
		||||
        log->log = qemu_memfd_alloc("vhost-log", logsize,
 | 
			
		||||
                                    F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
 | 
			
		||||
                                    &fd);
 | 
			
		||||
                                    &fd, &err);
 | 
			
		||||
        if (err) {
 | 
			
		||||
            error_report_err(err);
 | 
			
		||||
            g_free(log);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        memset(log->log, 0, logsize);
 | 
			
		||||
    } else {
 | 
			
		||||
        log->log = g_malloc0(logsize);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,9 +16,10 @@
 | 
			
		|||
#define F_SEAL_WRITE    0x0008  /* prevent writes */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int qemu_memfd_create(const char *name, size_t size, unsigned int seals);
 | 
			
		||||
int qemu_memfd_create(const char *name, size_t size, unsigned int seals,
 | 
			
		||||
                      Error **errp);
 | 
			
		||||
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
 | 
			
		||||
                       int *fd);
 | 
			
		||||
                       int *fd, Error **errp);
 | 
			
		||||
void qemu_memfd_free(void *ptr, size_t size, int fd);
 | 
			
		||||
bool qemu_memfd_check(void);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										57
									
								
								util/memfd.c
								
								
								
								
							
							
						
						
									
										57
									
								
								util/memfd.c
								
								
								
								
							| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
 | 
			
		||||
#include "qemu/osdep.h"
 | 
			
		||||
 | 
			
		||||
#include "qapi/error.h"
 | 
			
		||||
#include "qemu/memfd.h"
 | 
			
		||||
 | 
			
		||||
#if defined CONFIG_LINUX && !defined CONFIG_MEMFD
 | 
			
		||||
| 
						 | 
				
			
			@ -51,11 +52,11 @@ static int memfd_create(const char *name, unsigned int flags)
 | 
			
		|||
#define MFD_ALLOW_SEALING 0x0002U
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int qemu_memfd_create(const char *name, size_t size, unsigned int seals)
 | 
			
		||||
int qemu_memfd_create(const char *name, size_t size,
 | 
			
		||||
                      unsigned int seals, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    int mfd = -1;
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_LINUX
 | 
			
		||||
    int mfd = -1;
 | 
			
		||||
    unsigned int flags = MFD_CLOEXEC;
 | 
			
		||||
 | 
			
		||||
    if (seals) {
 | 
			
		||||
| 
						 | 
				
			
			@ -64,23 +65,26 @@ int qemu_memfd_create(const char *name, size_t size, unsigned int seals)
 | 
			
		|||
 | 
			
		||||
    mfd = memfd_create(name, flags);
 | 
			
		||||
    if (mfd < 0) {
 | 
			
		||||
        return -1;
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ftruncate(mfd, size) == -1) {
 | 
			
		||||
        perror("ftruncate");
 | 
			
		||||
        close(mfd);
 | 
			
		||||
        return -1;
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) {
 | 
			
		||||
        perror("fcntl");
 | 
			
		||||
        close(mfd);
 | 
			
		||||
        return -1;
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return mfd;
 | 
			
		||||
 | 
			
		||||
err:
 | 
			
		||||
    if (mfd >= 0) {
 | 
			
		||||
        close(mfd);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    error_setg_errno(errp, errno, "failed to create memfd");
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -90,14 +94,14 @@ int qemu_memfd_create(const char *name, size_t size, unsigned int seals)
 | 
			
		|||
 * sealing.
 | 
			
		||||
 */
 | 
			
		||||
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
 | 
			
		||||
                       int *fd)
 | 
			
		||||
                       int *fd, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    void *ptr;
 | 
			
		||||
    int mfd = qemu_memfd_create(name, size, seals);
 | 
			
		||||
    int mfd = qemu_memfd_create(name, size, seals, NULL);
 | 
			
		||||
 | 
			
		||||
    /* some systems have memfd without sealing */
 | 
			
		||||
    if (mfd == -1) {
 | 
			
		||||
        mfd = qemu_memfd_create(name, size, 0);
 | 
			
		||||
        mfd = qemu_memfd_create(name, size, 0, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (mfd == -1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -109,27 +113,26 @@ void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
 | 
			
		|||
        unlink(fname);
 | 
			
		||||
        g_free(fname);
 | 
			
		||||
 | 
			
		||||
        if (mfd == -1) {
 | 
			
		||||
            perror("mkstemp");
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ftruncate(mfd, size) == -1) {
 | 
			
		||||
            perror("ftruncate");
 | 
			
		||||
            close(mfd);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        if (mfd == -1 ||
 | 
			
		||||
            ftruncate(mfd, size) == -1) {
 | 
			
		||||
            goto err;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0);
 | 
			
		||||
    if (ptr == MAP_FAILED) {
 | 
			
		||||
        perror("mmap");
 | 
			
		||||
        close(mfd);
 | 
			
		||||
        return NULL;
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *fd = mfd;
 | 
			
		||||
    return ptr;
 | 
			
		||||
 | 
			
		||||
err:
 | 
			
		||||
    error_setg_errno(errp, errno, "failed to allocate shared memory");
 | 
			
		||||
    if (mfd >= 0) {
 | 
			
		||||
        close(mfd);
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qemu_memfd_free(void *ptr, size_t size, int fd)
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +160,7 @@ bool qemu_memfd_check(void)
 | 
			
		|||
        int fd;
 | 
			
		||||
        void *ptr;
 | 
			
		||||
 | 
			
		||||
        ptr = qemu_memfd_alloc("test", 4096, 0, &fd);
 | 
			
		||||
        ptr = qemu_memfd_alloc("test", 4096, 0, &fd, NULL);
 | 
			
		||||
        memfd_check = ptr ? MEMFD_OK : MEMFD_KO;
 | 
			
		||||
        qemu_memfd_free(ptr, 4096, fd);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue