diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/contrib/ivshmem-client | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/contrib/ivshmem-client')
-rw-r--r-- | qemu/contrib/ivshmem-client/Makefile.objs | 1 | ||||
-rw-r--r-- | qemu/contrib/ivshmem-client/ivshmem-client.c | 446 | ||||
-rw-r--r-- | qemu/contrib/ivshmem-client/ivshmem-client.h | 212 | ||||
-rw-r--r-- | qemu/contrib/ivshmem-client/main.c | 241 |
4 files changed, 0 insertions, 900 deletions
diff --git a/qemu/contrib/ivshmem-client/Makefile.objs b/qemu/contrib/ivshmem-client/Makefile.objs deleted file mode 100644 index bfab2d20d..000000000 --- a/qemu/contrib/ivshmem-client/Makefile.objs +++ /dev/null @@ -1 +0,0 @@ -ivshmem-client-obj-y = ivshmem-client.o main.o diff --git a/qemu/contrib/ivshmem-client/ivshmem-client.c b/qemu/contrib/ivshmem-client/ivshmem-client.c deleted file mode 100644 index 44ae3646e..000000000 --- a/qemu/contrib/ivshmem-client/ivshmem-client.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * 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. - */ - -#include "qemu/osdep.h" -#include <sys/socket.h> -#include <sys/un.h> - -#include "qemu-common.h" -#include "qemu/queue.h" - -#include "ivshmem-client.h" - -/* log a message on stdout if verbose=1 */ -#define IVSHMEM_CLIENT_DEBUG(client, fmt, ...) do { \ - if ((client)->verbose) { \ - printf(fmt, ## __VA_ARGS__); \ - } \ - } while (0) - -/* read message from the unix socket */ -static int -ivshmem_client_read_one_msg(IvshmemClient *client, int64_t *index, int *fd) -{ - int ret; - struct msghdr msg; - struct iovec iov[1]; - union { - struct cmsghdr cmsg; - char control[CMSG_SPACE(sizeof(int))]; - } msg_control; - struct cmsghdr *cmsg; - - iov[0].iov_base = index; - iov[0].iov_len = sizeof(*index); - - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_control = &msg_control; - msg.msg_controllen = sizeof(msg_control); - - ret = recvmsg(client->sock_fd, &msg, 0); - if (ret < sizeof(*index)) { - IVSHMEM_CLIENT_DEBUG(client, "cannot read message: %s\n", - strerror(errno)); - return -1; - } - if (ret == 0) { - IVSHMEM_CLIENT_DEBUG(client, "lost connection to server\n"); - return -1; - } - - *index = GINT64_FROM_LE(*index); - *fd = -1; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - - if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || - cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) { - continue; - } - - memcpy(fd, CMSG_DATA(cmsg), sizeof(*fd)); - } - - return 0; -} - -/* free a peer when the server advertises a disconnection or when the - * client is freed */ -static void -ivshmem_client_free_peer(IvshmemClient *client, IvshmemClientPeer *peer) -{ - unsigned vector; - - QTAILQ_REMOVE(&client->peer_list, peer, next); - for (vector = 0; vector < peer->vectors_count; vector++) { - close(peer->vectors[vector]); - } - - g_free(peer); -} - -/* handle message coming from server (new peer, new vectors) */ -static int -ivshmem_client_handle_server_msg(IvshmemClient *client) -{ - IvshmemClientPeer *peer; - int64_t peer_id; - int ret, fd; - - ret = ivshmem_client_read_one_msg(client, &peer_id, &fd); - if (ret < 0) { - return -1; - } - - /* can return a peer or the local client */ - peer = ivshmem_client_search_peer(client, peer_id); - - /* delete peer */ - if (fd == -1) { - - if (peer == NULL || peer == &client->local) { - IVSHMEM_CLIENT_DEBUG(client, "receive delete for invalid " - "peer %" PRId64 "\n", peer_id); - return -1; - } - - IVSHMEM_CLIENT_DEBUG(client, "delete peer id = %" PRId64 "\n", peer_id); - ivshmem_client_free_peer(client, peer); - return 0; - } - - /* new peer */ - if (peer == NULL) { - peer = g_malloc0(sizeof(*peer)); - peer->id = peer_id; - peer->vectors_count = 0; - QTAILQ_INSERT_TAIL(&client->peer_list, peer, next); - IVSHMEM_CLIENT_DEBUG(client, "new peer id = %" PRId64 "\n", peer_id); - } - - /* new vector */ - IVSHMEM_CLIENT_DEBUG(client, " new vector %d (fd=%d) for peer id %" - PRId64 "\n", peer->vectors_count, fd, peer->id); - if (peer->vectors_count >= G_N_ELEMENTS(peer->vectors)) { - IVSHMEM_CLIENT_DEBUG(client, "Too many vectors received, failing"); - return -1; - } - - peer->vectors[peer->vectors_count] = fd; - peer->vectors_count++; - - return 0; -} - -/* init a new ivshmem client */ -int -ivshmem_client_init(IvshmemClient *client, const char *unix_sock_path, - IvshmemClientNotifCb notif_cb, void *notif_arg, - bool verbose) -{ - int ret; - unsigned i; - - memset(client, 0, sizeof(*client)); - - ret = snprintf(client->unix_sock_path, sizeof(client->unix_sock_path), - "%s", unix_sock_path); - - if (ret < 0 || ret >= sizeof(client->unix_sock_path)) { - IVSHMEM_CLIENT_DEBUG(client, "could not copy unix socket path\n"); - return -1; - } - - for (i = 0; i < IVSHMEM_CLIENT_MAX_VECTORS; i++) { - client->local.vectors[i] = -1; - } - - QTAILQ_INIT(&client->peer_list); - client->local.id = -1; - - client->notif_cb = notif_cb; - client->notif_arg = notif_arg; - client->verbose = verbose; - client->shm_fd = -1; - client->sock_fd = -1; - - return 0; -} - -/* create and connect to the unix socket */ -int -ivshmem_client_connect(IvshmemClient *client) -{ - struct sockaddr_un sun; - int fd, ret; - int64_t tmp; - - IVSHMEM_CLIENT_DEBUG(client, "connect to client %s\n", - client->unix_sock_path); - - client->sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (client->sock_fd < 0) { - IVSHMEM_CLIENT_DEBUG(client, "cannot create socket: %s\n", - strerror(errno)); - return -1; - } - - sun.sun_family = AF_UNIX; - ret = snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", - client->unix_sock_path); - if (ret < 0 || ret >= sizeof(sun.sun_path)) { - IVSHMEM_CLIENT_DEBUG(client, "could not copy unix socket path\n"); - goto err_close; - } - - if (connect(client->sock_fd, (struct sockaddr *)&sun, sizeof(sun)) < 0) { - IVSHMEM_CLIENT_DEBUG(client, "cannot connect to %s: %s\n", sun.sun_path, - strerror(errno)); - goto err_close; - } - - /* first, we expect a protocol version */ - if (ivshmem_client_read_one_msg(client, &tmp, &fd) < 0 || - (tmp != IVSHMEM_PROTOCOL_VERSION) || fd != -1) { - IVSHMEM_CLIENT_DEBUG(client, "cannot read from server\n"); - goto err_close; - } - - /* then, we expect our index + a fd == -1 */ - if (ivshmem_client_read_one_msg(client, &client->local.id, &fd) < 0 || - client->local.id < 0 || fd != -1) { - IVSHMEM_CLIENT_DEBUG(client, "cannot read from server (2)\n"); - goto err_close; - } - IVSHMEM_CLIENT_DEBUG(client, "our_id=%" PRId64 "\n", client->local.id); - - /* now, we expect shared mem fd + a -1 index, note that shm fd - * is not used */ - if (ivshmem_client_read_one_msg(client, &tmp, &fd) < 0 || - tmp != -1 || fd < 0) { - if (fd >= 0) { - close(fd); - } - IVSHMEM_CLIENT_DEBUG(client, "cannot read from server (3)\n"); - goto err_close; - } - client->shm_fd = fd; - IVSHMEM_CLIENT_DEBUG(client, "shm_fd=%d\n", fd); - - return 0; - -err_close: - close(client->sock_fd); - client->sock_fd = -1; - return -1; -} - -/* close connection to the server, and free all peer structures */ -void -ivshmem_client_close(IvshmemClient *client) -{ - IvshmemClientPeer *peer; - unsigned i; - - IVSHMEM_CLIENT_DEBUG(client, "close client\n"); - - while ((peer = QTAILQ_FIRST(&client->peer_list)) != NULL) { - ivshmem_client_free_peer(client, peer); - } - - close(client->shm_fd); - client->shm_fd = -1; - close(client->sock_fd); - client->sock_fd = -1; - client->local.id = -1; - for (i = 0; i < IVSHMEM_CLIENT_MAX_VECTORS; i++) { - close(client->local.vectors[i]); - client->local.vectors[i] = -1; - } - client->local.vectors_count = 0; -} - -/* get the fd_set according to the unix socket and peer list */ -void -ivshmem_client_get_fds(const IvshmemClient *client, fd_set *fds, int *maxfd) -{ - int fd; - unsigned vector; - - FD_SET(client->sock_fd, fds); - if (client->sock_fd >= *maxfd) { - *maxfd = client->sock_fd + 1; - } - - for (vector = 0; vector < client->local.vectors_count; vector++) { - fd = client->local.vectors[vector]; - FD_SET(fd, fds); - if (fd >= *maxfd) { - *maxfd = fd + 1; - } - } -} - -/* handle events from eventfd: just print a message on notification */ -static int -ivshmem_client_handle_event(IvshmemClient *client, const fd_set *cur, int maxfd) -{ - IvshmemClientPeer *peer; - uint64_t kick; - unsigned i; - int ret; - - peer = &client->local; - - for (i = 0; i < peer->vectors_count; i++) { - if (peer->vectors[i] >= maxfd || !FD_ISSET(peer->vectors[i], cur)) { - continue; - } - - ret = read(peer->vectors[i], &kick, sizeof(kick)); - if (ret < 0) { - return ret; - } - if (ret != sizeof(kick)) { - IVSHMEM_CLIENT_DEBUG(client, "invalid read size = %d\n", ret); - errno = EINVAL; - return -1; - } - IVSHMEM_CLIENT_DEBUG(client, "received event on fd %d vector %d: %" - PRIu64 "\n", peer->vectors[i], i, kick); - if (client->notif_cb != NULL) { - client->notif_cb(client, peer, i, client->notif_arg); - } - } - - return 0; -} - -/* read and handle new messages on the given fd_set */ -int -ivshmem_client_handle_fds(IvshmemClient *client, fd_set *fds, int maxfd) -{ - if (client->sock_fd < maxfd && FD_ISSET(client->sock_fd, fds) && - ivshmem_client_handle_server_msg(client) < 0 && errno != EINTR) { - IVSHMEM_CLIENT_DEBUG(client, "ivshmem_client_handle_server_msg() " - "failed\n"); - return -1; - } else if (ivshmem_client_handle_event(client, fds, maxfd) < 0 && - errno != EINTR) { - IVSHMEM_CLIENT_DEBUG(client, "ivshmem_client_handle_event() failed\n"); - return -1; - } - - return 0; -} - -/* send a notification on a vector of a peer */ -int -ivshmem_client_notify(const IvshmemClient *client, - const IvshmemClientPeer *peer, unsigned vector) -{ - uint64_t kick; - int fd; - - if (vector >= peer->vectors_count) { - IVSHMEM_CLIENT_DEBUG(client, "invalid vector %u on peer %" PRId64 "\n", - vector, peer->id); - return -1; - } - fd = peer->vectors[vector]; - IVSHMEM_CLIENT_DEBUG(client, "notify peer %" PRId64 - " on vector %d, fd %d\n", peer->id, vector, fd); - - kick = 1; - if (write(fd, &kick, sizeof(kick)) != sizeof(kick)) { - fprintf(stderr, "could not write to %d: %s\n", peer->vectors[vector], - strerror(errno)); - return -1; - } - return 0; -} - -/* send a notification to all vectors of a peer */ -int -ivshmem_client_notify_all_vects(const IvshmemClient *client, - const IvshmemClientPeer *peer) -{ - unsigned vector; - int ret = 0; - - for (vector = 0; vector < peer->vectors_count; vector++) { - if (ivshmem_client_notify(client, peer, vector) < 0) { - ret = -1; - } - } - - return ret; -} - -/* send a notification to all peers */ -int -ivshmem_client_notify_broadcast(const IvshmemClient *client) -{ - IvshmemClientPeer *peer; - int ret = 0; - - QTAILQ_FOREACH(peer, &client->peer_list, next) { - if (ivshmem_client_notify_all_vects(client, peer) < 0) { - ret = -1; - } - } - - return ret; -} - -/* lookup peer from its id */ -IvshmemClientPeer * -ivshmem_client_search_peer(IvshmemClient *client, int64_t peer_id) -{ - IvshmemClientPeer *peer; - - if (peer_id == client->local.id) { - return &client->local; - } - - QTAILQ_FOREACH(peer, &client->peer_list, next) { - if (peer->id == peer_id) { - return peer; - } - } - return NULL; -} - -/* dump our info, the list of peers their vectors on stdout */ -void -ivshmem_client_dump(const IvshmemClient *client) -{ - const IvshmemClientPeer *peer; - unsigned vector; - - /* dump local infos */ - peer = &client->local; - printf("our_id = %" PRId64 "\n", peer->id); - for (vector = 0; vector < peer->vectors_count; vector++) { - printf(" vector %d is enabled (fd=%d)\n", vector, - peer->vectors[vector]); - } - - /* dump peers */ - QTAILQ_FOREACH(peer, &client->peer_list, next) { - printf("peer_id = %" PRId64 "\n", peer->id); - - for (vector = 0; vector < peer->vectors_count; vector++) { - printf(" vector %d is enabled (fd=%d)\n", vector, - peer->vectors[vector]); - } - } -} diff --git a/qemu/contrib/ivshmem-client/ivshmem-client.h b/qemu/contrib/ivshmem-client/ivshmem-client.h deleted file mode 100644 index 54cde17d9..000000000 --- a/qemu/contrib/ivshmem-client/ivshmem-client.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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_CLIENT_H_ -#define _IVSHMEM_CLIENT_H_ - -/** - * This file provides helper to implement an ivshmem client. It is used - * on the host to ask QEMU to send an interrupt to an ivshmem PCI device in a - * guest. QEMU also implements an ivshmem client similar to this one, they both - * connect to an ivshmem server. - * - * A standalone ivshmem client based on this file is provided for debug/test - * purposes. - */ - -#include <sys/select.h> - -#include "qemu/queue.h" -#include "hw/misc/ivshmem.h" - -/** - * Maximum number of notification vectors supported by the client - */ -#define IVSHMEM_CLIENT_MAX_VECTORS 64 - -/** - * Structure storing a peer - * - * Each time a client connects to an ivshmem server, it is advertised to - * all connected clients through the unix socket. When our ivshmem - * client receives a notification, it creates a IvshmemClientPeer - * structure to store the infos of this peer. - * - * This structure is also used to store the information of our own - * client in (IvshmemClient)->local. - */ -typedef struct IvshmemClientPeer { - QTAILQ_ENTRY(IvshmemClientPeer) next; /**< next in list*/ - int64_t id; /**< the id of the peer */ - int vectors[IVSHMEM_CLIENT_MAX_VECTORS]; /**< one fd per vector */ - unsigned vectors_count; /**< number of vectors */ -} IvshmemClientPeer; -QTAILQ_HEAD(IvshmemClientPeerList, IvshmemClientPeer); - -typedef struct IvshmemClientPeerList IvshmemClientPeerList; -typedef struct IvshmemClient IvshmemClient; - -/** - * Typedef of callback function used when our IvshmemClient receives a - * notification from a peer. - */ -typedef void (*IvshmemClientNotifCb)( - const IvshmemClient *client, - const IvshmemClientPeer *peer, - unsigned vect, void *arg); - -/** - * Structure describing an ivshmem client - * - * This structure stores all information related to our client: the name - * of the server unix socket, the list of peers advertised by the - * server, our own client information, and a pointer the notification - * callback function used when we receive a notification from a peer. - */ -struct IvshmemClient { - char unix_sock_path[PATH_MAX]; /**< path to unix sock */ - int sock_fd; /**< unix sock filedesc */ - int shm_fd; /**< shm file descriptor */ - - IvshmemClientPeerList peer_list; /**< list of peers */ - IvshmemClientPeer local; /**< our own infos */ - - IvshmemClientNotifCb notif_cb; /**< notification callback */ - void *notif_arg; /**< notification argument */ - - bool verbose; /**< true to enable debug */ -}; - -/** - * Initialize an ivshmem client - * - * @client: A pointer to an uninitialized IvshmemClient structure - * @unix_sock_path: The pointer to the unix socket file name - * @notif_cb: If not NULL, the pointer to the function to be called when - * our IvshmemClient receives a notification from a peer - * @notif_arg: Opaque pointer given as-is to the notification callback - * function - * @verbose: True to enable debug - * - * Returns: 0 on success, or a negative value on error - */ -int ivshmem_client_init(IvshmemClient *client, const char *unix_sock_path, - IvshmemClientNotifCb notif_cb, void *notif_arg, - bool verbose); - -/** - * Connect to the server - * - * Connect to the server unix socket, and read the first initial - * messages sent by the server, giving the ID of the client and the file - * descriptor of the shared memory. - * - * @client: The ivshmem client - * - * Returns: 0 on success, or a negative value on error - */ -int ivshmem_client_connect(IvshmemClient *client); - -/** - * Close connection to the server and free all peer structures - * - * @client: The ivshmem client - */ -void ivshmem_client_close(IvshmemClient *client); - -/** - * 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 eventfd). The - * function will not initialize the fd_set, it is up to the caller - * to do this. - * - * @client: The ivshmem client - * @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_client_get_fds(const IvshmemClient *client, fd_set *fds, - int *maxfd); - -/** - * Read and handle new messages - * - * Given a fd_set filled by select(), handle incoming messages from - * server or peers. - * - * @client: The ivshmem client - * @fds: The fd_set containing the file descriptors to be checked. Note - * that file descriptors that are not related to our client are - * ignored. - * @maxfd: The maximum fd in fd_set, plus one. - * - * Returns: 0 on success, or a negative value on error - */ -int ivshmem_client_handle_fds(IvshmemClient *client, fd_set *fds, int maxfd); - -/** - * Send a notification to a vector of a peer - * - * @client: The ivshmem client - * @peer: The peer to be notified - * @vector: The number of the vector - * - * Returns: 0 on success, or a negative value on error - */ -int ivshmem_client_notify(const IvshmemClient *client, - const IvshmemClientPeer *peer, unsigned vector); - -/** - * Send a notification to all vectors of a peer - * - * @client: The ivshmem client - * @peer: The peer to be notified - * - * Returns: 0 on success, or a negative value on error (at least one - * notification failed) - */ -int ivshmem_client_notify_all_vects(const IvshmemClient *client, - const IvshmemClientPeer *peer); - -/** - * Broadcat a notification to all vectors of all peers - * - * @client: The ivshmem client - * - * Returns: 0 on success, or a negative value on error (at least one - * notification failed) - */ -int ivshmem_client_notify_broadcast(const IvshmemClient *client); - -/** - * Search a peer from its identifier - * - * Return the peer structure from its peer_id. If the given peer_id is - * the local id, the function returns the local peer structure. - * - * @client: The ivshmem client - * @peer_id: The identifier of the peer structure - * - * Returns: The peer structure, or NULL if not found - */ -IvshmemClientPeer * -ivshmem_client_search_peer(IvshmemClient *client, int64_t peer_id); - -/** - * Dump information of this ivshmem client on stdout - * - * Dump the id and the vectors of the given ivshmem client and the list - * of its peers and their vectors on stdout. - * - * @client: The ivshmem client - */ -void ivshmem_client_dump(const IvshmemClient *client); - -#endif /* _IVSHMEM_CLIENT_H_ */ diff --git a/qemu/contrib/ivshmem-client/main.c b/qemu/contrib/ivshmem-client/main.c deleted file mode 100644 index 33ae1daa1..000000000 --- a/qemu/contrib/ivshmem-client/main.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * 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. - */ - -#include "qemu/osdep.h" -#include "qemu-common.h" - -#include "ivshmem-client.h" - -#define IVSHMEM_CLIENT_DEFAULT_VERBOSE 0 -#define IVSHMEM_CLIENT_DEFAULT_UNIX_SOCK_PATH "/tmp/ivshmem_socket" - -typedef struct IvshmemClientArgs { - bool verbose; - const char *unix_sock_path; -} IvshmemClientArgs; - -/* show ivshmem_client_usage and exit with given error code */ -static void -ivshmem_client_usage(const char *name, int code) -{ - fprintf(stderr, "%s [opts]\n", name); - fprintf(stderr, " -h: show this help\n"); - fprintf(stderr, " -v: verbose mode\n"); - fprintf(stderr, " -S <unix_sock_path>: path to the unix socket\n" - " to connect to.\n" - " default=%s\n", IVSHMEM_CLIENT_DEFAULT_UNIX_SOCK_PATH); - exit(code); -} - -/* parse the program arguments, exit on error */ -static void -ivshmem_client_parse_args(IvshmemClientArgs *args, int argc, char *argv[]) -{ - int c; - - while ((c = getopt(argc, argv, - "h" /* help */ - "v" /* verbose */ - "S:" /* unix_sock_path */ - )) != -1) { - - switch (c) { - case 'h': /* help */ - ivshmem_client_usage(argv[0], 0); - break; - - case 'v': /* verbose */ - args->verbose = 1; - break; - - case 'S': /* unix_sock_path */ - args->unix_sock_path = optarg; - break; - - default: - ivshmem_client_usage(argv[0], 1); - break; - } - } -} - -/* show command line help */ -static void -ivshmem_client_cmdline_help(void) -{ - printf("dump: dump peers (including us)\n" - "int <peer> <vector>: notify one vector on a peer\n" - "int <peer> all: notify all vectors of a peer\n" - "int all: notify all vectors of all peers (excepting us)\n"); -} - -/* read stdin and handle commands */ -static int -ivshmem_client_handle_stdin_command(IvshmemClient *client) -{ - IvshmemClientPeer *peer; - char buf[128]; - char *s, *token; - int ret; - int peer_id, vector; - - memset(buf, 0, sizeof(buf)); - ret = read(0, buf, sizeof(buf) - 1); - if (ret < 0) { - return -1; - } - - s = buf; - while ((token = strsep(&s, "\n\r;")) != NULL) { - if (!strcmp(token, "")) { - continue; - } - if (!strcmp(token, "?")) { - ivshmem_client_cmdline_help(); - } - if (!strcmp(token, "help")) { - ivshmem_client_cmdline_help(); - } else if (!strcmp(token, "dump")) { - ivshmem_client_dump(client); - } else if (!strcmp(token, "int all")) { - ivshmem_client_notify_broadcast(client); - } else if (sscanf(token, "int %d %d", &peer_id, &vector) == 2) { - peer = ivshmem_client_search_peer(client, peer_id); - if (peer == NULL) { - printf("cannot find peer_id = %d\n", peer_id); - continue; - } - ivshmem_client_notify(client, peer, vector); - } else if (sscanf(token, "int %d all", &peer_id) == 1) { - peer = ivshmem_client_search_peer(client, peer_id); - if (peer == NULL) { - printf("cannot find peer_id = %d\n", peer_id); - continue; - } - ivshmem_client_notify_all_vects(client, peer); - } else { - printf("invalid command, type help\n"); - } - } - - printf("cmd> "); - fflush(stdout); - return 0; -} - -/* listen on stdin (command line), on unix socket (notifications of new - * and dead peers), and on eventfd (IRQ request) */ -static int -ivshmem_client_poll_events(IvshmemClient *client) -{ - fd_set fds; - int ret, maxfd; - - while (1) { - - FD_ZERO(&fds); - FD_SET(0, &fds); /* add stdin in fd_set */ - maxfd = 1; - - ivshmem_client_get_fds(client, &fds, &maxfd); - - ret = select(maxfd, &fds, NULL, NULL, NULL); - if (ret < 0) { - if (errno == EINTR) { - continue; - } - - fprintf(stderr, "select error: %s\n", strerror(errno)); - break; - } - if (ret == 0) { - continue; - } - - if (FD_ISSET(0, &fds) && - ivshmem_client_handle_stdin_command(client) < 0 && errno != EINTR) { - fprintf(stderr, "ivshmem_client_handle_stdin_command() failed\n"); - break; - } - - if (ivshmem_client_handle_fds(client, &fds, maxfd) < 0) { - fprintf(stderr, "ivshmem_client_handle_fds() failed\n"); - break; - } - } - - return ret; -} - -/* callback when we receive a notification (just display it) */ -static void -ivshmem_client_notification_cb(const IvshmemClient *client, - const IvshmemClientPeer *peer, - unsigned vect, void *arg) -{ - (void)client; - (void)arg; - printf("receive notification from peer_id=%" PRId64 " vector=%u\n", - peer->id, vect); -} - -int -main(int argc, char *argv[]) -{ - struct sigaction sa; - IvshmemClient client; - IvshmemClientArgs args = { - .verbose = IVSHMEM_CLIENT_DEFAULT_VERBOSE, - .unix_sock_path = IVSHMEM_CLIENT_DEFAULT_UNIX_SOCK_PATH, - }; - - /* parse arguments, will exit on error */ - ivshmem_client_parse_args(&args, argc, argv); - - /* Ignore SIGPIPE, see this link for more info: - * http://www.mail-archive.com/libevent-users@monkey.org/msg01606.html */ - sa.sa_handler = SIG_IGN; - sa.sa_flags = 0; - if (sigemptyset(&sa.sa_mask) == -1 || - sigaction(SIGPIPE, &sa, 0) == -1) { - perror("failed to ignore SIGPIPE; sigaction"); - return 1; - } - - ivshmem_client_cmdline_help(); - printf("cmd> "); - fflush(stdout); - - if (ivshmem_client_init(&client, args.unix_sock_path, - ivshmem_client_notification_cb, NULL, - args.verbose) < 0) { - fprintf(stderr, "cannot init client\n"); - return 1; - } - - while (1) { - if (ivshmem_client_connect(&client) < 0) { - fprintf(stderr, "cannot connect to server, retry in 1 second\n"); - sleep(1); - continue; - } - - fprintf(stdout, "listen on server socket %d\n", client.sock_fd); - - if (ivshmem_client_poll_events(&client) == 0) { - continue; - } - - /* disconnected from server, reset all peers */ - fprintf(stdout, "disconnected from server\n"); - - ivshmem_client_close(&client); - } - - return 0; -} |