Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / msg / xio / XioPortal.cc
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 }