b58deb344d
Most list head structs need not be given a name. In most cases the name is given just in case one is going to use QTAILQ_LAST, QTAILQ_PREV or reverse iteration, but this does not apply to lists of other kinds, and even for QTAILQ in practice this is only rarely needed. In addition, we will soon reimplement those macros completely so that they do not need a name for the head struct. So clean up everything, not giving a name except in the rare case where it is necessary. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
164 lines
5.5 KiB
C
164 lines
5.5 KiB
C
/*
|
|
* 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 being
|
|
* "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 <sys/select.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;
|
|
|
|
/**
|
|
* 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 */
|
|
bool use_shm_open;
|
|
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 */
|
|
QTAILQ_HEAD(, IvshmemServerPeer) 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, bool use_shm_open,
|
|
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 */
|