]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2013 CohortFS, LLC | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #include "XioPortal.h" | |
16 | #include <stdio.h> | |
17 | ||
18 | #define dout_subsys ceph_subsys_xio | |
19 | ||
20 | int XioPortal::bind(struct xio_session_ops *ops, const string &base_uri, | |
21 | uint16_t port, uint16_t *assigned_port) | |
22 | { | |
23 | // format uri | |
24 | char buf[40]; | |
25 | xio_uri = base_uri; | |
26 | xio_uri += ":"; | |
27 | sprintf(buf, "%d", port); | |
28 | xio_uri += buf; | |
29 | ||
30 | uint16_t assigned; | |
31 | server = xio_bind(ctx, ops, xio_uri.c_str(), &assigned, 0, msgr); | |
32 | if (server == NULL) | |
33 | return xio_errno(); | |
34 | ||
35 | // update uri if port changed | |
36 | if (port != assigned) { | |
37 | xio_uri = base_uri; | |
38 | xio_uri += ":"; | |
39 | sprintf(buf, "%d", assigned); | |
40 | xio_uri += buf; | |
41 | } | |
42 | ||
43 | portal_id = const_cast<char*>(xio_uri.c_str()); | |
44 | if (assigned_port) | |
45 | *assigned_port = assigned; | |
46 | ldout(msgr->cct,20) << "xio_bind: portal " << xio_uri | |
47 | << " returned server " << server << dendl; | |
48 | return 0; | |
49 | } | |
50 | ||
51 | int XioPortals::bind(struct xio_session_ops *ops, const string& base_uri, | |
52 | uint16_t port, uint16_t *port0) | |
53 | { | |
54 | /* a server needs at least 1 portal */ | |
55 | if (n < 1) | |
56 | return EINVAL; | |
57 | Messenger *msgr = portals[0]->msgr; | |
58 | portals.resize(n); | |
59 | ||
60 | uint16_t port_min = msgr->cct->_conf->ms_bind_port_min; | |
61 | const uint16_t port_max = msgr->cct->_conf->ms_bind_port_max; | |
62 | ||
63 | /* bind the portals */ | |
64 | for (size_t i = 0; i < portals.size(); i++) { | |
65 | uint16_t result_port; | |
66 | if (port != 0) { | |
67 | // bind directly to the given port | |
68 | int r = portals[i]->bind(ops, base_uri, port, &result_port); | |
69 | if (r != 0) | |
70 | return -r; | |
71 | } else { | |
72 | int r = EADDRINUSE; | |
73 | // try ports within the configured range | |
74 | for (; port_min <= port_max; port_min++) { | |
75 | r = portals[i]->bind(ops, base_uri, port_min, &result_port); | |
76 | if (r == 0) { | |
77 | port_min++; | |
78 | break; | |
79 | } | |
80 | } | |
81 | if (r != 0) { | |
82 | lderr(msgr->cct) << "portal.bind unable to bind to " << base_uri | |
83 | << " on any port in range " << msgr->cct->_conf->ms_bind_port_min | |
84 | << "-" << port_max << ": " << xio_strerror(r) << dendl; | |
85 | return -r; | |
86 | } | |
87 | } | |
88 | ||
89 | ldout(msgr->cct,5) << "xp::bind: portal " << i << " bind OK: " | |
90 | << portals[i]->xio_uri << dendl; | |
91 | ||
92 | if (i == 0 && port0 != NULL) | |
93 | *port0 = result_port; | |
94 | port = 0; // use port 0 for all subsequent portals | |
95 | } | |
96 | ||
97 | return 0; | |
98 | } |