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