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