xref: /qemu/contrib/ivshmem-client/ivshmem-client.h (revision 2a6a4076e117113ebec97b1821071afccfdfbc96)
1a75eb03bSDavid Marchand /*
2a75eb03bSDavid Marchand  * Copyright 6WIND S.A., 2014
3a75eb03bSDavid Marchand  *
4a75eb03bSDavid Marchand  * This work is licensed under the terms of the GNU GPL, version 2 or
5a75eb03bSDavid Marchand  * (at your option) any later version.  See the COPYING file in the
6a75eb03bSDavid Marchand  * top-level directory.
7a75eb03bSDavid Marchand  */
8a75eb03bSDavid Marchand 
9*2a6a4076SMarkus Armbruster #ifndef IVSHMEM_CLIENT_H
10*2a6a4076SMarkus Armbruster #define IVSHMEM_CLIENT_H
11a75eb03bSDavid Marchand 
12a75eb03bSDavid Marchand /**
13a75eb03bSDavid Marchand  * This file provides helper to implement an ivshmem client. It is used
14a75eb03bSDavid Marchand  * on the host to ask QEMU to send an interrupt to an ivshmem PCI device in a
15a75eb03bSDavid Marchand  * guest. QEMU also implements an ivshmem client similar to this one, they both
16a75eb03bSDavid Marchand  * connect to an ivshmem server.
17a75eb03bSDavid Marchand  *
18a75eb03bSDavid Marchand  * A standalone ivshmem client based on this file is provided for debug/test
19a75eb03bSDavid Marchand  * purposes.
20a75eb03bSDavid Marchand  */
21a75eb03bSDavid Marchand 
22a75eb03bSDavid Marchand #include <sys/select.h>
23a75eb03bSDavid Marchand 
24a75eb03bSDavid Marchand #include "qemu/queue.h"
255105b1d8SDavid Marchand #include "hw/misc/ivshmem.h"
26a75eb03bSDavid Marchand 
27a75eb03bSDavid Marchand /**
28a75eb03bSDavid Marchand  * Maximum number of notification vectors supported by the client
29a75eb03bSDavid Marchand  */
30a75eb03bSDavid Marchand #define IVSHMEM_CLIENT_MAX_VECTORS 64
31a75eb03bSDavid Marchand 
32a75eb03bSDavid Marchand /**
33a75eb03bSDavid Marchand  * Structure storing a peer
34a75eb03bSDavid Marchand  *
35a75eb03bSDavid Marchand  * Each time a client connects to an ivshmem server, it is advertised to
36a75eb03bSDavid Marchand  * all connected clients through the unix socket. When our ivshmem
37a75eb03bSDavid Marchand  * client receives a notification, it creates a IvshmemClientPeer
38a75eb03bSDavid Marchand  * structure to store the infos of this peer.
39a75eb03bSDavid Marchand  *
40a75eb03bSDavid Marchand  * This structure is also used to store the information of our own
41a75eb03bSDavid Marchand  * client in (IvshmemClient)->local.
42a75eb03bSDavid Marchand  */
43a75eb03bSDavid Marchand typedef struct IvshmemClientPeer {
44a75eb03bSDavid Marchand     QTAILQ_ENTRY(IvshmemClientPeer) next;    /**< next in list*/
45f7a199b2SMarc-André Lureau     int64_t id;                              /**< the id of the peer */
46a75eb03bSDavid Marchand     int vectors[IVSHMEM_CLIENT_MAX_VECTORS]; /**< one fd per vector */
47a75eb03bSDavid Marchand     unsigned vectors_count;                  /**< number of vectors */
48a75eb03bSDavid Marchand } IvshmemClientPeer;
49a75eb03bSDavid Marchand QTAILQ_HEAD(IvshmemClientPeerList, IvshmemClientPeer);
50a75eb03bSDavid Marchand 
51a75eb03bSDavid Marchand typedef struct IvshmemClientPeerList IvshmemClientPeerList;
52a75eb03bSDavid Marchand typedef struct IvshmemClient IvshmemClient;
53a75eb03bSDavid Marchand 
54a75eb03bSDavid Marchand /**
55a75eb03bSDavid Marchand  * Typedef of callback function used when our IvshmemClient receives a
56a75eb03bSDavid Marchand  * notification from a peer.
57a75eb03bSDavid Marchand  */
58a75eb03bSDavid Marchand typedef void (*IvshmemClientNotifCb)(
59a75eb03bSDavid Marchand     const IvshmemClient *client,
60a75eb03bSDavid Marchand     const IvshmemClientPeer *peer,
61a75eb03bSDavid Marchand     unsigned vect, void *arg);
62a75eb03bSDavid Marchand 
63a75eb03bSDavid Marchand /**
64a75eb03bSDavid Marchand  * Structure describing an ivshmem client
65a75eb03bSDavid Marchand  *
66a75eb03bSDavid Marchand  * This structure stores all information related to our client: the name
67a75eb03bSDavid Marchand  * of the server unix socket, the list of peers advertised by the
68a75eb03bSDavid Marchand  * server, our own client information, and a pointer the notification
69a75eb03bSDavid Marchand  * callback function used when we receive a notification from a peer.
70a75eb03bSDavid Marchand  */
71a75eb03bSDavid Marchand struct IvshmemClient {
72a75eb03bSDavid Marchand     char unix_sock_path[PATH_MAX];      /**< path to unix sock */
73a75eb03bSDavid Marchand     int sock_fd;                        /**< unix sock filedesc */
74a75eb03bSDavid Marchand     int shm_fd;                         /**< shm file descriptor */
75a75eb03bSDavid Marchand 
76a75eb03bSDavid Marchand     IvshmemClientPeerList peer_list;    /**< list of peers */
77a75eb03bSDavid Marchand     IvshmemClientPeer local;            /**< our own infos */
78a75eb03bSDavid Marchand 
79a75eb03bSDavid Marchand     IvshmemClientNotifCb notif_cb;      /**< notification callback */
80a75eb03bSDavid Marchand     void *notif_arg;                    /**< notification argument */
81a75eb03bSDavid Marchand 
82a75eb03bSDavid Marchand     bool verbose;                       /**< true to enable debug */
83a75eb03bSDavid Marchand };
84a75eb03bSDavid Marchand 
85a75eb03bSDavid Marchand /**
86a75eb03bSDavid Marchand  * Initialize an ivshmem client
87a75eb03bSDavid Marchand  *
88a75eb03bSDavid Marchand  * @client:         A pointer to an uninitialized IvshmemClient structure
89a75eb03bSDavid Marchand  * @unix_sock_path: The pointer to the unix socket file name
90a75eb03bSDavid Marchand  * @notif_cb:       If not NULL, the pointer to the function to be called when
91a75eb03bSDavid Marchand  *                  our IvshmemClient receives a notification from a peer
92a75eb03bSDavid Marchand  * @notif_arg:      Opaque pointer given as-is to the notification callback
93a75eb03bSDavid Marchand  *                  function
94a75eb03bSDavid Marchand  * @verbose:        True to enable debug
95a75eb03bSDavid Marchand  *
96a75eb03bSDavid Marchand  * Returns:         0 on success, or a negative value on error
97a75eb03bSDavid Marchand  */
98a75eb03bSDavid Marchand int ivshmem_client_init(IvshmemClient *client, const char *unix_sock_path,
99a75eb03bSDavid Marchand                         IvshmemClientNotifCb notif_cb, void *notif_arg,
100a75eb03bSDavid Marchand                         bool verbose);
101a75eb03bSDavid Marchand 
102a75eb03bSDavid Marchand /**
103a75eb03bSDavid Marchand  * Connect to the server
104a75eb03bSDavid Marchand  *
105a75eb03bSDavid Marchand  * Connect to the server unix socket, and read the first initial
106a75eb03bSDavid Marchand  * messages sent by the server, giving the ID of the client and the file
107a75eb03bSDavid Marchand  * descriptor of the shared memory.
108a75eb03bSDavid Marchand  *
109a75eb03bSDavid Marchand  * @client: The ivshmem client
110a75eb03bSDavid Marchand  *
111a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error
112a75eb03bSDavid Marchand  */
113a75eb03bSDavid Marchand int ivshmem_client_connect(IvshmemClient *client);
114a75eb03bSDavid Marchand 
115a75eb03bSDavid Marchand /**
116a75eb03bSDavid Marchand  * Close connection to the server and free all peer structures
117a75eb03bSDavid Marchand  *
118a75eb03bSDavid Marchand  * @client: The ivshmem client
119a75eb03bSDavid Marchand  */
120a75eb03bSDavid Marchand void ivshmem_client_close(IvshmemClient *client);
121a75eb03bSDavid Marchand 
122a75eb03bSDavid Marchand /**
123a75eb03bSDavid Marchand  * Fill a fd_set with file descriptors to be monitored
124a75eb03bSDavid Marchand  *
125a75eb03bSDavid Marchand  * This function will fill a fd_set with all file descriptors
126a75eb03bSDavid Marchand  * that must be polled (unix server socket and peers eventfd). The
127a75eb03bSDavid Marchand  * function will not initialize the fd_set, it is up to the caller
128a75eb03bSDavid Marchand  * to do this.
129a75eb03bSDavid Marchand  *
130a75eb03bSDavid Marchand  * @client: The ivshmem client
131a75eb03bSDavid Marchand  * @fds:    The fd_set to be updated
132a75eb03bSDavid Marchand  * @maxfd:  Must be set to the max file descriptor + 1 in fd_set. This value is
133a75eb03bSDavid Marchand  *          updated if this function adds a greater fd in fd_set.
134a75eb03bSDavid Marchand  */
135a75eb03bSDavid Marchand void ivshmem_client_get_fds(const IvshmemClient *client, fd_set *fds,
136a75eb03bSDavid Marchand                             int *maxfd);
137a75eb03bSDavid Marchand 
138a75eb03bSDavid Marchand /**
139a75eb03bSDavid Marchand  * Read and handle new messages
140a75eb03bSDavid Marchand  *
141a75eb03bSDavid Marchand  * Given a fd_set filled by select(), handle incoming messages from
142a75eb03bSDavid Marchand  * server or peers.
143a75eb03bSDavid Marchand  *
144a75eb03bSDavid Marchand  * @client: The ivshmem client
145a75eb03bSDavid Marchand  * @fds:    The fd_set containing the file descriptors to be checked. Note
146a75eb03bSDavid Marchand  *          that file descriptors that are not related to our client are
147a75eb03bSDavid Marchand  *          ignored.
148a75eb03bSDavid Marchand  * @maxfd:  The maximum fd in fd_set, plus one.
149a75eb03bSDavid Marchand  *
150a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error
151a75eb03bSDavid Marchand  */
152a75eb03bSDavid Marchand int ivshmem_client_handle_fds(IvshmemClient *client, fd_set *fds, int maxfd);
153a75eb03bSDavid Marchand 
154a75eb03bSDavid Marchand /**
155a75eb03bSDavid Marchand  * Send a notification to a vector of a peer
156a75eb03bSDavid Marchand  *
157a75eb03bSDavid Marchand  * @client: The ivshmem client
158a75eb03bSDavid Marchand  * @peer:   The peer to be notified
159a75eb03bSDavid Marchand  * @vector: The number of the vector
160a75eb03bSDavid Marchand  *
161a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error
162a75eb03bSDavid Marchand  */
163a75eb03bSDavid Marchand int ivshmem_client_notify(const IvshmemClient *client,
164a75eb03bSDavid Marchand                           const IvshmemClientPeer *peer, unsigned vector);
165a75eb03bSDavid Marchand 
166a75eb03bSDavid Marchand /**
167a75eb03bSDavid Marchand  * Send a notification to all vectors of a peer
168a75eb03bSDavid Marchand  *
169a75eb03bSDavid Marchand  * @client: The ivshmem client
170a75eb03bSDavid Marchand  * @peer:   The peer to be notified
171a75eb03bSDavid Marchand  *
172a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error (at least one
173a75eb03bSDavid Marchand  *          notification failed)
174a75eb03bSDavid Marchand  */
175a75eb03bSDavid Marchand int ivshmem_client_notify_all_vects(const IvshmemClient *client,
176a75eb03bSDavid Marchand                                     const IvshmemClientPeer *peer);
177a75eb03bSDavid Marchand 
178a75eb03bSDavid Marchand /**
179a75eb03bSDavid Marchand  * Broadcat a notification to all vectors of all peers
180a75eb03bSDavid Marchand  *
181a75eb03bSDavid Marchand  * @client: The ivshmem client
182a75eb03bSDavid Marchand  *
183a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error (at least one
184a75eb03bSDavid Marchand  *          notification failed)
185a75eb03bSDavid Marchand  */
186a75eb03bSDavid Marchand int ivshmem_client_notify_broadcast(const IvshmemClient *client);
187a75eb03bSDavid Marchand 
188a75eb03bSDavid Marchand /**
189a75eb03bSDavid Marchand  * Search a peer from its identifier
190a75eb03bSDavid Marchand  *
191a75eb03bSDavid Marchand  * Return the peer structure from its peer_id. If the given peer_id is
192a75eb03bSDavid Marchand  * the local id, the function returns the local peer structure.
193a75eb03bSDavid Marchand  *
194a75eb03bSDavid Marchand  * @client:  The ivshmem client
195a75eb03bSDavid Marchand  * @peer_id: The identifier of the peer structure
196a75eb03bSDavid Marchand  *
197a75eb03bSDavid Marchand  * Returns:  The peer structure, or NULL if not found
198a75eb03bSDavid Marchand  */
199a75eb03bSDavid Marchand IvshmemClientPeer *
200f7a199b2SMarc-André Lureau ivshmem_client_search_peer(IvshmemClient *client, int64_t peer_id);
201a75eb03bSDavid Marchand 
202a75eb03bSDavid Marchand /**
203a75eb03bSDavid Marchand  * Dump information of this ivshmem client on stdout
204a75eb03bSDavid Marchand  *
205a75eb03bSDavid Marchand  * Dump the id and the vectors of the given ivshmem client and the list
206a75eb03bSDavid Marchand  * of its peers and their vectors on stdout.
207a75eb03bSDavid Marchand  *
208a75eb03bSDavid Marchand  * @client: The ivshmem client
209a75eb03bSDavid Marchand  */
210a75eb03bSDavid Marchand void ivshmem_client_dump(const IvshmemClient *client);
211a75eb03bSDavid Marchand 
212*2a6a4076SMarkus Armbruster #endif /* IVSHMEM_CLIENT_H */
213