Skip to content

Commit b247306

Browse files
committed
rgw/frontend: Allow multiple rgw's to run on same port on same host.
The idea here is to leverage the `SO_REUSEPORT` param supported by kernel 3.9 and above, which allows the multiple services to run on the same port. Signed-off-by: kchheda3 <[email protected]>
1 parent b3a6c35 commit b247306

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

PendingReleaseNotes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* RGW: Adding missing quotes to the ETag values returned by S3 CopyPart,
2222
PostObject and CompleteMultipartUpload responses.
2323
* RGW: Added support for S3 GetObjectAttributes.
24+
* RGW: Added BEAST frontend option 'so_reuseport' which facilitates running multiple
25+
RGW instances on the same host by sharing a single TCP port.
2426

2527
* RBD: All Python APIs that produce timestamps now return "aware" `datetime`
2628
objects instead of "naive" ones (i.e. those including time zone information

doc/radosgw/frontends.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ Options
135135
:Default: ``16384``
136136
:Maximum: ``65536``
137137

138+
``so_reuseport``
139+
140+
:Description: If set allows multiple RGW instances on a host to listen on the same TCP port.
141+
142+
``1`` Enable running multiple RGW on same port.
143+
144+
``0`` Disallow running multiple RGW on same port.
145+
146+
:Type: Integer (0 or 1)
147+
:Default: 0
148+
138149

139150
Generic Options
140151
===============

src/rgw/rgw_asio_frontend.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,12 @@ int AsioFrontend::init()
696696
l.use_nodelay = (nodelay->second == "1");
697697
}
698698
}
699-
700699

700+
bool reuse_port = false;
701+
auto reuse_port_it = config.find("so_reuseport");
702+
if (reuse_port_it != config.end()) {
703+
reuse_port = (reuse_port_it->second == "1");
704+
}
701705
bool socket_bound = false;
702706
// start listeners
703707
for (auto& l : listeners) {
@@ -722,7 +726,21 @@ int AsioFrontend::init()
722726
}
723727
}
724728

725-
l.acceptor.set_option(tcp::acceptor::reuse_address(true));
729+
if (reuse_port) {
730+
// setting option |SO_REUSEPORT| allows running of multiple rgw processes on
731+
// the same port. Can read more about the implementation here.
732+
// https://web.git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=c617f398edd4db2b8567a28e899a88f8f574798d
733+
int one = 1;
734+
if (setsockopt(l.acceptor.native_handle(), SOL_SOCKET,
735+
SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one)) == -1) {
736+
lderr(ctx()) << "setsockopt SO_REUSEADDR | SO_REUSEPORT failed:" <<
737+
dendl;
738+
return -1;
739+
}
740+
} else {
741+
l.acceptor.set_option(tcp::acceptor::reuse_address(true));
742+
}
743+
726744
l.acceptor.bind(l.endpoint, ec);
727745
if (ec) {
728746
lderr(ctx()) << "failed to bind address " << l.endpoint

0 commit comments

Comments
 (0)