diff options
Diffstat (limited to '')
-rw-r--r-- | src/msg/xio/XioPortal.cc | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/msg/xio/XioPortal.cc b/src/msg/xio/XioPortal.cc new file mode 100644 index 00000000..e2379fb3 --- /dev/null +++ b/src/msg/xio/XioPortal.cc @@ -0,0 +1,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; +} |