Commit 3625c739 authored by Markus Armbruster's avatar Markus Armbruster
Browse files

ivshmem-server: Don't overload POSIX shmem and file name



Option -m NAME is interpreted as directory name if we can statfs() it
and its on hugetlbfs.  Else it's interpreted as POSIX shared memory
object name.  This is nuts.

Always interpret -m as directory.  Create new -M for POSIX shared
memory.  Last of -m or -M wins.

Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Message-Id: <1458066895-20632-4-git-send-email-armbru@redhat.com>
Reviewed-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
parent e3ad7296
Loading
Loading
Loading
Loading
+10 −46
Original line number Diff line number Diff line
@@ -12,9 +12,6 @@
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef CONFIG_LINUX
#include <sys/vfs.h>
#endif

#include "ivshmem-server.h"

@@ -257,7 +254,8 @@ ivshmem_server_ftruncate(int fd, unsigned shmsize)
/* Init a new ivshmem server */
int
ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path,
                    const char *shm_path, size_t shm_size, unsigned n_vectors,
                    const char *shm_path, bool use_shm_open,
                    size_t shm_size, unsigned n_vectors,
                    bool verbose)
{
    int ret;
@@ -278,6 +276,7 @@ ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path,
        return -1;
    }

    server->use_shm_open = use_shm_open;
    server->shm_size = shm_size;
    server->n_vectors = n_vectors;

@@ -286,31 +285,6 @@ 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)
@@ -319,27 +293,17 @@ ivshmem_server_start(IvshmemServer *server)
    int shm_fd, sock_fd, ret;

    /* open shm file */
#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) {
    if (server->use_shm_open) {
        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);
    } else {
        gchar *filename = g_strdup_printf("%s/ivshmem.XXXXXX", server->shm_path);
        IVSHMEM_SERVER_DEBUG(server, "Using hugepages: %s\n", server->shm_path);
        IVSHMEM_SERVER_DEBUG(server, "Using file-backed shared memory: %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) {
+3 −1
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ typedef struct IvshmemServer {
    char unix_sock_path[PATH_MAX];   /**< path to unix socket */
    int sock_fd;                     /**< unix sock file descriptor */
    char shm_path[PATH_MAX];         /**< path to shm */
    bool use_shm_open;
    size_t shm_size;                 /**< size of shm */
    int shm_fd;                      /**< shm file descriptor */
    unsigned n_vectors;              /**< number of vectors */
@@ -89,7 +90,8 @@ typedef struct IvshmemServer {
 */
int
ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path,
                    const char *shm_path, size_t shm_size, unsigned n_vectors,
                    const char *shm_path, bool use_shm_open,
                    size_t shm_size, unsigned n_vectors,
                    bool verbose);

/**
+10 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ typedef struct IvshmemServerArgs {
    const char *pid_file;
    const char *unix_socket_path;
    const char *shm_path;
    bool use_shm_open;
    uint64_t shm_size;
    unsigned n_vectors;
} IvshmemServerArgs;
@@ -44,8 +45,9 @@ ivshmem_server_usage(const char *progname)
           "     default " IVSHMEM_SERVER_DEFAULT_PID_FILE "\n"
           "  -S <unix-socket-path>: path to the unix socket to listen to\n"
           "     default " IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH "\n"
           "  -m <shm-path>: POSIX shared memory object name or a hugetlbfs mount point\n"
           "  -M <shm-name>: POSIX shared memory object to use\n"
           "     default " IVSHMEM_SERVER_DEFAULT_SHM_PATH "\n"
           "  -m <dir-name>: where to create shared memory\n"
           "  -l <size>: size of shared memory in bytes\n"
           "     suffixes K, M and G can be used, e.g. 1K means 1024\n"
           "     default %u\n"
@@ -69,7 +71,7 @@ ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[])
    unsigned long long v;
    Error *err = NULL;

    while ((c = getopt(argc, argv, "hvFp:S:m:l:n:")) != -1) {
    while ((c = getopt(argc, argv, "hvFp:S:m:M:l:n:")) != -1) {

        switch (c) {
        case 'h': /* help */
@@ -93,8 +95,10 @@ ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[])
            args->unix_socket_path = optarg;
            break;

        case 'm': /* shm path */
        case 'M': /* shm name */
        case 'm': /* dir name */
            args->shm_path = optarg;
            args->use_shm_open = c == 'M';
            break;

        case 'l': /* shm size */
@@ -190,6 +194,7 @@ main(int argc, char *argv[])
        .pid_file = IVSHMEM_SERVER_DEFAULT_PID_FILE,
        .unix_socket_path = IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH,
        .shm_path = IVSHMEM_SERVER_DEFAULT_SHM_PATH,
        .use_shm_open = true,
        .shm_size = IVSHMEM_SERVER_DEFAULT_SHM_SIZE,
        .n_vectors = IVSHMEM_SERVER_DEFAULT_N_VECTORS,
    };
@@ -217,7 +222,8 @@ main(int argc, char *argv[])
    }

    /* init the ivshms structure */
    if (ivshmem_server_init(&server, args.unix_socket_path, args.shm_path,
    if (ivshmem_server_init(&server, args.unix_socket_path,
                            args.shm_path, args.use_shm_open,
                            args.shm_size, args.n_vectors, args.verbose) < 0) {
        fprintf(stderr, "cannot init server\n");
        goto err;
+1 −1
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ static void test_ivshmem_server(bool msi)
    guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;

    memset(tmpshmem, 0x42, TMPSHMSIZE);
    ret = ivshmem_server_init(&server, tmpserver, tmpshm,
    ret = ivshmem_server_init(&server, tmpserver, tmpshm, true,
                              TMPSHMSIZE, nvectors,
                              g_test_verbose());
    g_assert_cmpint(ret, ==, 0);