]>
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_readv(struct spdk_sock
*sock
, struct iovec
*iov
, int iovcnt
)
140 return sock
->net_impl
->readv(sock
, iov
, iovcnt
);
144 spdk_sock_writev(struct spdk_sock
*sock
, struct iovec
*iov
, int iovcnt
)
151 return sock
->net_impl
->writev(sock
, iov
, iovcnt
);
155 spdk_sock_set_recvlowat(struct spdk_sock
*sock
, int nbytes
)
157 return sock
->net_impl
->set_recvlowat(sock
, nbytes
);
161 spdk_sock_set_recvbuf(struct spdk_sock
*sock
, int sz
)
163 return sock
->net_impl
->set_recvbuf(sock
, sz
);
167 spdk_sock_set_sendbuf(struct spdk_sock
*sock
, int sz
)
169 return sock
->net_impl
->set_sendbuf(sock
, sz
);
173 spdk_sock_is_ipv6(struct spdk_sock
*sock
)
175 return sock
->net_impl
->is_ipv6(sock
);
179 spdk_sock_is_ipv4(struct spdk_sock
*sock
)
181 return sock
->net_impl
->is_ipv4(sock
);
184 struct spdk_sock_group
*
185 spdk_sock_group_create(void)
187 struct spdk_net_impl
*impl
= NULL
;
188 struct spdk_sock_group
*group
;
189 struct spdk_sock_group_impl
*group_impl
;
191 group
= calloc(1, sizeof(*group
));
196 STAILQ_INIT(&group
->group_impls
);
198 STAILQ_FOREACH_FROM(impl
, &g_net_impls
, link
) {
199 group_impl
= impl
->group_impl_create();
200 if (group_impl
!= NULL
) {
201 STAILQ_INSERT_TAIL(&group
->group_impls
, group_impl
, link
);
202 TAILQ_INIT(&group_impl
->socks
);
203 group_impl
->net_impl
= impl
;
211 spdk_sock_group_add_sock(struct spdk_sock_group
*group
, struct spdk_sock
*sock
,
212 spdk_sock_cb cb_fn
, void *cb_arg
)
214 struct spdk_sock_group_impl
*group_impl
= NULL
;
222 if (sock
->cb_fn
!= NULL
) {
224 * This sock is already part of a sock_group. Currently we don't
231 STAILQ_FOREACH_FROM(group_impl
, &group
->group_impls
, link
) {
232 if (sock
->net_impl
== group_impl
->net_impl
) {
237 if (group_impl
== NULL
) {
242 rc
= group_impl
->net_impl
->group_impl_add_sock(group_impl
, sock
);
244 TAILQ_INSERT_TAIL(&group_impl
->socks
, sock
, link
);
246 sock
->cb_arg
= cb_arg
;
253 spdk_sock_group_remove_sock(struct spdk_sock_group
*group
, struct spdk_sock
*sock
)
255 struct spdk_sock_group_impl
*group_impl
= NULL
;
258 STAILQ_FOREACH_FROM(group_impl
, &group
->group_impls
, link
) {
259 if (sock
->net_impl
== group_impl
->net_impl
) {
264 if (group_impl
== NULL
) {
269 rc
= group_impl
->net_impl
->group_impl_remove_sock(group_impl
, sock
);
271 TAILQ_REMOVE(&group_impl
->socks
, sock
, link
);
280 spdk_sock_group_poll(struct spdk_sock_group
*group
)
282 return spdk_sock_group_poll_count(group
, MAX_EVENTS_PER_POLL
);
286 spdk_sock_group_impl_poll_count(struct spdk_sock_group_impl
*group_impl
,
287 struct spdk_sock_group
*group
,
290 struct spdk_sock
*socks
[MAX_EVENTS_PER_POLL
];
293 if (TAILQ_EMPTY(&group_impl
->socks
)) {
297 num_events
= group_impl
->net_impl
->group_impl_poll(group_impl
, max_events
, socks
);
298 if (num_events
== -1) {
302 for (i
= 0; i
< num_events
; i
++) {
303 struct spdk_sock
*sock
= socks
[i
];
305 assert(sock
->cb_fn
!= NULL
);
306 sock
->cb_fn(sock
->cb_arg
, group
, sock
);
312 spdk_sock_group_poll_count(struct spdk_sock_group
*group
, int max_events
)
314 struct spdk_sock_group_impl
*group_impl
= NULL
;
315 int rc
, final_rc
= 0;
317 if (max_events
< 1) {
323 * Only poll for up to 32 events at a time - if more events are pending,
324 * the next call to this function will reap them.
326 if (max_events
> MAX_EVENTS_PER_POLL
) {
327 max_events
= MAX_EVENTS_PER_POLL
;
330 STAILQ_FOREACH_FROM(group_impl
, &group
->group_impls
, link
) {
331 rc
= spdk_sock_group_impl_poll_count(group_impl
, group
, max_events
);
334 SPDK_ERRLOG("group_impl_poll_count for net(%s) failed\n",
335 group_impl
->net_impl
->name
);
343 spdk_sock_group_close(struct spdk_sock_group
**group
)
345 struct spdk_sock_group_impl
*group_impl
= NULL
, *tmp
;
348 if (*group
== NULL
) {
353 STAILQ_FOREACH_SAFE(group_impl
, &(*group
)->group_impls
, link
, tmp
) {
354 if (!TAILQ_EMPTY(&group_impl
->socks
)) {
360 STAILQ_FOREACH_SAFE(group_impl
, &(*group
)->group_impls
, link
, tmp
) {
361 rc
= group_impl
->net_impl
->group_impl_close(group_impl
);
363 SPDK_ERRLOG("group_impl_close for net(%s) failed\n",
364 group_impl
->net_impl
->name
);
376 spdk_net_impl_register(struct spdk_net_impl
*impl
)
378 if (!strcmp("posix", impl
->name
)) {
379 STAILQ_INSERT_TAIL(&g_net_impls
, impl
, link
);
381 STAILQ_INSERT_HEAD(&g_net_impls
, impl
, link
);