mirror of https://gitee.com/openkylin/qemu.git
ivshmem-server: fix hugetlbfs support
As pointed out on the ML by Andrew Jones, glibc no longer permits creating POSIX shm on hugetlbfs directly. When given a hugetlbfs path, create a shareable file there. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
This commit is contained in:
parent
022cffe313
commit
1e21feb628
|
@ -12,6 +12,9 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#ifdef CONFIG_LINUX
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
|
||||
#include "ivshmem-server.h"
|
||||
|
||||
|
@ -271,6 +274,31 @@ ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
|
||||
#define HUGETLBFS_MAGIC 0x958458f6
|
||||
|
||||
static long gethugepagesize(const char *path)
|
||||
{
|
||||
struct statfs fs;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = statfs(path, &fs);
|
||||
} while (ret != 0 && errno == EINTR);
|
||||
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fs.f_type != HUGETLBFS_MAGIC) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fs.f_bsize;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* open shm, create and bind to the unix socket */
|
||||
int
|
||||
ivshmem_server_start(IvshmemServer *server)
|
||||
|
@ -279,7 +307,29 @@ ivshmem_server_start(IvshmemServer *server)
|
|||
int shm_fd, sock_fd, ret;
|
||||
|
||||
/* open shm file */
|
||||
shm_fd = shm_open(server->shm_path, O_CREAT|O_RDWR, S_IRWXU);
|
||||
#ifdef CONFIG_LINUX
|
||||
long hpagesize;
|
||||
|
||||
hpagesize = gethugepagesize(server->shm_path);
|
||||
if (hpagesize < 0 && errno != ENOENT) {
|
||||
IVSHMEM_SERVER_DEBUG(server, "cannot stat shm file %s: %s\n",
|
||||
server->shm_path, strerror(errno));
|
||||
}
|
||||
|
||||
if (hpagesize > 0) {
|
||||
gchar *filename = g_strdup_printf("%s/ivshmem.XXXXXX", server->shm_path);
|
||||
IVSHMEM_SERVER_DEBUG(server, "Using hugepages: %s\n", server->shm_path);
|
||||
shm_fd = mkstemp(filename);
|
||||
unlink(filename);
|
||||
g_free(filename);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
IVSHMEM_SERVER_DEBUG(server, "Using POSIX shared memory: %s\n",
|
||||
server->shm_path);
|
||||
shm_fd = shm_open(server->shm_path, O_CREAT|O_RDWR, S_IRWXU);
|
||||
}
|
||||
|
||||
if (shm_fd < 0) {
|
||||
fprintf(stderr, "cannot open shm file %s: %s\n", server->shm_path,
|
||||
strerror(errno));
|
||||
|
|
|
@ -82,8 +82,7 @@ typedef struct IvshmemServer {
|
|||
* @server: A pointer to an uninitialized IvshmemServer structure
|
||||
* @unix_sock_path: The pointer to the unix socket file name
|
||||
* @shm_path: Path to the shared memory. The path corresponds to a POSIX
|
||||
* shm name. To use a real file, for instance in a hugetlbfs,
|
||||
* it is possible to use /../../abspath/to/file.
|
||||
* shm name or a hugetlbfs mount point.
|
||||
* @shm_size: Size of shared memory
|
||||
* @n_vectors: Number of interrupt vectors per client
|
||||
* @verbose: True to enable verbose mode
|
||||
|
|
|
@ -47,9 +47,8 @@ ivshmem_server_usage(const char *name, int code)
|
|||
" to listen to.\n"
|
||||
" Default=%s\n", IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH);
|
||||
fprintf(stderr, " -m <shm_path>: path to the shared memory.\n"
|
||||
" The path corresponds to a POSIX shm name. To use a\n"
|
||||
" real file, for instance in a hugetlbfs, use\n"
|
||||
" /../../abspath/to/file.\n"
|
||||
" The path corresponds to a POSIX shm name or a\n"
|
||||
" hugetlbfs mount point.\n"
|
||||
" default=%s\n", IVSHMEM_SERVER_DEFAULT_SHM_PATH);
|
||||
fprintf(stderr, " -l <size>: size of shared memory in bytes. The suffix\n"
|
||||
" K, M and G can be used (ex: 1K means 1024).\n"
|
||||
|
|
Loading…
Reference in New Issue