/*
 * Copyright 6WIND S.A., 2014
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */

#ifndef _IVSHMEM_SERVER_H_
#define _IVSHMEM_SERVER_H_

/**
 * The ivshmem server is a daemon that creates a unix socket in listen
 * mode. The ivshmem clients (qemu or ivshmem-client) connect to this
 * unix socket. For each client, the server will create some eventfd
 * (see EVENTFD(2)), one per vector. These fd are transmitted to all
 * clients using the SCM_RIGHTS cmsg message. Therefore, each client is
 * able to send a notification to another client without beeing
 * "profixied" by the server.
 *
 * We use this mechanism to send interruptions between guests.
 * qemu is able to transform an event on a eventfd into a PCI MSI-x
 * interruption in the guest.
 *
 * The ivshmem server is also able to share the file descriptor
 * associated to the ivshmem shared memory.
 */

#include <limits.h>
#include <sys/select.h>
#include <stdint.h>
#include <stdbool.h>

#include "qemu/event_notifier.h"
#include "qemu/queue.h"
#include "hw/misc/ivshmem.h"

/**
 * Maximum number of notification vectors supported by the server
 */
#define IVSHMEM_SERVER_MAX_VECTORS 64

/**
 * Structure storing a peer
 *
 * Each time a client connects to an ivshmem server, a new
 * IvshmemServerPeer structure is created. This peer and all its
 * vectors are advertised to all connected clients through the connected
 * unix sockets.
 */
typedef struct IvshmemServerPeer {
    QTAILQ_ENTRY(IvshmemServerPeer) next;    /**< next in list*/
    int sock_fd;                             /**< connected unix sock */
    int64_t id;                              /**< the id of the peer */
    EventNotifier vectors[IVSHMEM_SERVER_MAX_VECTORS]; /**< one per vector */
    unsigned vectors_count;                  /**< number of vectors */
} IvshmemServerPeer;
QTAILQ_HEAD(IvshmemServerPeerList, IvshmemServerPeer);

typedef struct IvshmemServerPeerList IvshmemServerPeerList;

/**
 * Structure describing an ivshmem server
 *
 * This structure stores all information related to our server: the name
 * of the server unix socket and the list of connected peers.
 */
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 */
    size_t shm_size;                 /**< size of shm */
    int shm_fd;                      /**< shm file descriptor */
    unsigned n_vectors;              /**< number of vectors */
    uint16_t cur_id;                 /**< id to be given to next client */
    bool verbose;                    /**< true in verbose mode */
    IvshmemServerPeerList peer_list; /**< list of peers */
} IvshmemServer;

/**
 * Initialize an ivshmem server
 *
 * @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 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
 *
 * Returns:         0 on success, or a negative value on error
 */
int
ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path,
                    const char *shm_path, size_t shm_size, unsigned n_vectors,
                    bool verbose);

/**
 * Open the shm, then create and bind to the unix socket
 *
 * @server: The pointer to the initialized IvshmemServer structure
 *
 * Returns: 0 on success, or a negative value on error
 */
int ivshmem_server_start(IvshmemServer *server);

/**
 * Close the server
 *
 * Close connections to all clients, close the unix socket and the
 * shared memory file descriptor. The structure remains initialized, so
 * it is possible to call ivshmem_server_start() again after a call to
 * ivshmem_server_close().
 *
 * @server: The ivshmem server
 */
void ivshmem_server_close(IvshmemServer *server);

/**
 * Fill a fd_set with file descriptors to be monitored
 *
 * This function will fill a fd_set with all file descriptors that must
 * be polled (unix server socket and peers unix socket). The function
 * will not initialize the fd_set, it is up to the caller to do it.
 *
 * @server: The ivshmem server
 * @fds:    The fd_set to be updated
 * @maxfd:  Must be set to the max file descriptor + 1 in fd_set. This value is
 *          updated if this function adds a greater fd in fd_set.
 */
void
ivshmem_server_get_fds(const IvshmemServer *server, fd_set *fds, int *maxfd);

/**
 * Read and handle new messages
 *
 * Given a fd_set (for instance filled by a call to select()), handle
 * incoming messages from peers.
 *
 * @server: The ivshmem server
 * @fds:    The fd_set containing the file descriptors to be checked. Note that
 *          file descriptors that are not related to our server are ignored.
 * @maxfd:  The maximum fd in fd_set, plus one.
 *
 * Returns: 0 on success, or a negative value on error
 */
int ivshmem_server_handle_fds(IvshmemServer *server, fd_set *fds, int maxfd);

/**
 * Search a peer from its identifier
 *
 * @server:  The ivshmem server
 * @peer_id: The identifier of the peer structure
 *
 * Returns:  The peer structure, or NULL if not found
 */
IvshmemServerPeer *
ivshmem_server_search_peer(IvshmemServer *server, int64_t peer_id);

/**
 * Dump information of this ivshmem server and its peers on stdout
 *
 * @server: The ivshmem server
 */
void ivshmem_server_dump(const IvshmemServer *server);

#endif /* _IVSHMEM_SERVER_H_ */
