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