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:
Marc-André Lureau 2018-02-01 14:27:51 +01:00 committed by Paolo Bonzini
parent dbadee4ff4
commit 0f2956f915
3 changed files with 40 additions and 30 deletions

View File

@ -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) static struct vhost_log *vhost_log_alloc(uint64_t size, bool share)
{ {
Error *err = NULL;
struct vhost_log *log; struct vhost_log *log;
uint64_t logsize = size * sizeof(*(log->log)); uint64_t logsize = size * sizeof(*(log->log));
int fd = -1; int fd = -1;
@ -338,7 +339,12 @@ static struct vhost_log *vhost_log_alloc(uint64_t size, bool share)
if (share) { if (share) {
log->log = qemu_memfd_alloc("vhost-log", logsize, log->log = qemu_memfd_alloc("vhost-log", logsize,
F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL, 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); memset(log->log, 0, logsize);
} else { } else {
log->log = g_malloc0(logsize); log->log = g_malloc0(logsize);

View File

@ -16,9 +16,10 @@
#define F_SEAL_WRITE 0x0008 /* prevent writes */ #define F_SEAL_WRITE 0x0008 /* prevent writes */
#endif #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, 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); void qemu_memfd_free(void *ptr, size_t size, int fd);
bool qemu_memfd_check(void); bool qemu_memfd_check(void);

View File

@ -27,6 +27,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/memfd.h" #include "qemu/memfd.h"
#if defined CONFIG_LINUX && !defined CONFIG_MEMFD #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 #define MFD_ALLOW_SEALING 0x0002U
#endif #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 #ifdef CONFIG_LINUX
int mfd = -1;
unsigned int flags = MFD_CLOEXEC; unsigned int flags = MFD_CLOEXEC;
if (seals) { if (seals) {
@ -64,23 +65,26 @@ int qemu_memfd_create(const char *name, size_t size, unsigned int seals)
mfd = memfd_create(name, flags); mfd = memfd_create(name, flags);
if (mfd < 0) { if (mfd < 0) {
return -1; goto err;
} }
if (ftruncate(mfd, size) == -1) { if (ftruncate(mfd, size) == -1) {
perror("ftruncate"); goto err;
close(mfd);
return -1;
} }
if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) { if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) {
perror("fcntl"); goto err;
close(mfd);
return -1;
} }
#endif
return mfd; 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. * sealing.
*/ */
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
int *fd) int *fd, Error **errp)
{ {
void *ptr; 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 */ /* some systems have memfd without sealing */
if (mfd == -1) { if (mfd == -1) {
mfd = qemu_memfd_create(name, size, 0); mfd = qemu_memfd_create(name, size, 0, NULL);
} }
if (mfd == -1) { if (mfd == -1) {
@ -109,27 +113,26 @@ void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
unlink(fname); unlink(fname);
g_free(fname); g_free(fname);
if (mfd == -1) { if (mfd == -1 ||
perror("mkstemp"); ftruncate(mfd, size) == -1) {
return NULL; goto err;
}
if (ftruncate(mfd, size) == -1) {
perror("ftruncate");
close(mfd);
return NULL;
} }
} }
ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0); ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0);
if (ptr == MAP_FAILED) { if (ptr == MAP_FAILED) {
perror("mmap"); goto err;
close(mfd);
return NULL;
} }
*fd = mfd; *fd = mfd;
return ptr; 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) void qemu_memfd_free(void *ptr, size_t size, int fd)
@ -157,7 +160,7 @@ bool qemu_memfd_check(void)
int fd; int fd;
void *ptr; 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; memfd_check = ptr ? MEMFD_OK : MEMFD_KO;
qemu_memfd_free(ptr, 4096, fd); qemu_memfd_free(ptr, 4096, fd);
} }