]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/sock/sock.c
4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/stdinc.h"
37 #include "spdk/sock.h"
38 #include "spdk_internal/sock.h"
39 #include "spdk/queue.h"
41 static STAILQ_HEAD(, spdk_net_impl
) g_net_impls
= STAILQ_HEAD_INITIALIZER(g_net_impls
);
44 spdk_sock_getaddr(struct spdk_sock
*sock
, char *saddr
, int slen
, uint16_t *sport
,
45 char *caddr
, int clen
, uint16_t *cport
)
47 return sock
->net_impl
->getaddr(sock
, saddr
, slen
, sport
, caddr
, clen
, cport
);
51 spdk_sock_connect(const char *ip
, int port
)
53 struct spdk_net_impl
*impl
= NULL
;
54 struct spdk_sock
*sock
;
56 STAILQ_FOREACH_FROM(impl
, &g_net_impls
, link
) {
57 sock
= impl
->connect(ip
, port
);
59 sock
->net_impl
= impl
;
68 spdk_sock_listen(const char *ip
, int port
)
70 struct spdk_net_impl
*impl
= NULL
;
71 struct spdk_sock
*sock
;
73 STAILQ_FOREACH_FROM(impl
, &g_net_impls
, link
) {
74 sock
= impl
->listen(ip
, port
);
76 sock
->net_impl
= impl
;
85 spdk_sock_accept(struct spdk_sock
*sock
)
87 struct spdk_sock
*new_sock
;
89 new_sock
= sock
->net_impl
->accept(sock
);
90 if (new_sock
!= NULL
) {
91 new_sock
->net_impl
= sock
->net_impl
;
98 spdk_sock_close(struct spdk_sock
**sock
)
107 if ((*sock
)->cb_fn
!= NULL
) {
108 /* This sock is still part of a sock_group. */
113 rc
= (*sock
)->net_impl
->close(*sock
);
122 spdk_sock_recv(struct spdk_sock
*sock
, void *buf
, size_t len
)
129 return sock
->net_impl
->recv(sock
, buf
, len
);
133 spdk_sock_writev(struct spdk_sock
*sock
, struct iovec
*iov
, int iovcnt
)
140 return sock
->net_impl
->writev(sock
, iov
, iovcnt
);
145 spdk_sock_set_recvlowat(struct spdk_sock
*sock
, int nbytes
)
147 return sock
->net_impl
->set_recvlowat(sock
, nbytes
);
151 spdk_sock_set_recvbuf(struct spdk_sock
*sock
, int sz
)
153 return sock
->net_impl
->set_recvbuf(sock
, sz
);
157 spdk_sock_set_sendbuf(struct spdk_sock
*sock
, int sz
)
159 return sock
->net_impl
->set_sendbuf(sock
, sz
);
163 spdk_sock_is_ipv6(struct spdk_sock
*sock
)
165 return sock
->net_impl
->is_ipv6(sock
);
169 spdk_sock_is_ipv4(struct spdk_sock
*sock
)
171 return sock
->net_impl
->is_ipv4(sock
);
174 struct spdk_sock_group
*
175 spdk_sock_group_create(void)
177 struct spdk_net_impl
*impl
= NULL
;
178 struct spdk_sock_group
*group
;
179 struct spdk_sock_group_impl
*group_impl
;
181 group
= calloc(1, sizeof(*group
));
186 STAILQ_INIT(&group
->group_impls
);
188 STAILQ_FOREACH_FROM(impl
, &g_net_impls
, link
) {
189 group_impl
= impl
->group_impl_create();
190 if (group_impl
!= NULL
) {
191 STAILQ_INSERT_TAIL(&group
->group_impls
, group_impl
, link
);
192 TAILQ_INIT(&group_impl
->socks
);
193 group_impl
->net_impl
= impl
;
201 spdk_sock_group_add_sock(struct spdk_sock_group
*group
, struct spdk_sock
*sock
,
202 spdk_sock_cb cb_fn
, void *cb_arg
)
204 struct spdk_sock_group_impl
*group_impl
= NULL
;
212 if (sock
->cb_fn
!= NULL
) {
214 * This sock is already part of a sock_group. Currently we don't
221 STAILQ_FOREACH_FROM(group_impl
, &group
->group_impls
, link
) {
222 if (sock
->net_impl
== group_impl
->net_impl
) {
227 if (group_impl
== NULL
) {
232 rc
= group_impl
->net_impl
->group_impl_add_sock(group_impl
, sock
);
234 TAILQ_INSERT_TAIL(&group_impl
->socks
, sock
, link
);
236 sock
->cb_arg
= cb_arg
;
243 spdk_sock_group_remove_sock(struct spdk_sock_group
*group
, struct spdk_sock
*sock
)
245 struct spdk_sock_group_impl
*group_impl
= NULL
;
248 STAILQ_FOREACH_FROM(group_impl
, &group
->group_impls
, link
) {
249 if (sock
->net_impl
== group_impl
->net_impl
) {
254 if (group_impl
== NULL
) {
259 rc
= group_impl
->net_impl
->group_impl_remove_sock(group_impl
, sock
);
261 TAILQ_REMOVE(&group_impl
->socks
, sock
, link
);
270 spdk_sock_group_poll(struct spdk_sock_group
*group
)
272 return spdk_sock_group_poll_count(group
, MAX_EVENTS_PER_POLL
);
276 spdk_sock_group_impl_poll_count(struct spdk_sock_group_impl
*group_impl
,
277 struct spdk_sock_group
*group
,
280 struct spdk_sock
*socks
[MAX_EVENTS_PER_POLL
];
283 if (TAILQ_EMPTY(&group_impl
->socks
)) {
287 num_events
= group_impl
->net_impl
->group_impl_poll(group_impl
, max_events
, socks
);
288 if (num_events
== -1) {
292 for (i
= 0; i
< num_events
; i
++) {
293 struct spdk_sock
*sock
= socks
[i
];
295 assert(sock
->cb_fn
!= NULL
);
296 sock
->cb_fn(sock
->cb_arg
, group
, sock
);
302 spdk_sock_group_poll_count(struct spdk_sock_group
*group
, int max_events
)
304 struct spdk_sock_group_impl
*group_impl
= NULL
;
305 int rc
, final_rc
= 0;
307 if (max_events
< 1) {
313 * Only poll for up to 32 events at a time - if more events are pending,
314 * the next call to this function will reap them.
316 if (max_events
> MAX_EVENTS_PER_POLL
) {
317 max_events
= MAX_EVENTS_PER_POLL
;
320 STAILQ_FOREACH_FROM(group_impl
, &group
->group_impls
, link
) {
321 rc
= spdk_sock_group_impl_poll_count(group_impl
, group
, max_events
);
324 SPDK_ERRLOG("group_impl_poll_count for net(%s) failed\n",
325 group_impl
->net_impl
->name
);
333 spdk_sock_group_close(struct spdk_sock_group
**group
)
335 struct spdk_sock_group_impl
*group_impl
= NULL
, *tmp
;
338 if (*group
== NULL
) {
343 STAILQ_FOREACH_SAFE(group_impl
, &(*group
)->group_impls
, link
, tmp
) {
344 if (!TAILQ_EMPTY(&group_impl
->socks
)) {
350 STAILQ_FOREACH_SAFE(group_impl
, &(*group
)->group_impls
, link
, tmp
) {
351 rc
= group_impl
->net_impl
->group_impl_close(group_impl
);
353 SPDK_ERRLOG("group_impl_close for net(%s) failed\n",
354 group_impl
->net_impl
->name
);
366 spdk_net_impl_register(struct spdk_net_impl
*impl
)
368 if (!strcmp("posix", impl
->name
)) {
369 STAILQ_INSERT_TAIL(&g_net_impls
, impl
, link
);
371 STAILQ_INSERT_HEAD(&g_net_impls
, impl
, link
);