]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/frontend: Allow multiple rgw's to run on same port on same host. 62011/head
authorkchheda3 <kchheda3@bloomberg.net>
Wed, 26 Feb 2025 15:36:15 +0000 (10:36 -0500)
committerkchheda3 <kchheda3@bloomberg.net>
Wed, 30 Apr 2025 15:12:24 +0000 (11:12 -0400)
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 <kchheda3@bloomberg.net>
PendingReleaseNotes
doc/radosgw/frontends.rst
src/rgw/rgw_asio_frontend.cc

index 404d2d7f8cdec4edda8ba446f18c2ebacbcaa923..4e1b7f2711a9967baf407ba648a0ac19dd395663 100644 (file)
@@ -21,6 +21,8 @@
 * RGW: Adding missing quotes to the ETag values returned by S3 CopyPart,
   PostObject and CompleteMultipartUpload responses.
 * RGW: Added support for S3 GetObjectAttributes.
+* RGW: Added BEAST frontend option 'so_reuseport' which facilitates running multiple
+        RGW instances on the same host by sharing a single TCP port.
 
 * RBD: All Python APIs that produce timestamps now return "aware" `datetime`
   objects instead of "naive" ones (i.e. those including time zone information
index 5c6900f54489df1a3f3db8f368f9101eba0c61d9..bf46e3cc15a112833d3e30ab93338ec27e70d9fa 100644 (file)
@@ -135,6 +135,17 @@ Options
 :Default: ``16384``
 :Maximum: ``65536``
 
+``so_reuseport``
+
+:Description:  If set allows multiple RGW instances on a host to listen on the same TCP port.
+
+              ``1`` Enable running multiple RGW on same port.
+
+              ``0`` Disallow running multiple RGW on same port.
+
+:Type: Integer (0 or 1)
+:Default: 0
+
 
 Generic Options
 ===============
index a76aebccfd06e12681c9241c35593576127dd67d..e33e5b3bf789f4dd26670897a19eb1a9d1badc6d 100644 (file)
@@ -696,8 +696,12 @@ int AsioFrontend::init()
       l.use_nodelay = (nodelay->second == "1");
     }
   }
-  
 
+  bool reuse_port = false;
+  auto reuse_port_it = config.find("so_reuseport");
+  if (reuse_port_it != config.end()) {
+    reuse_port = (reuse_port_it->second == "1");
+  }
   bool socket_bound = false;
   // start listeners
   for (auto& l : listeners) {
@@ -722,7 +726,21 @@ int AsioFrontend::init()
       }
     }
 
-    l.acceptor.set_option(tcp::acceptor::reuse_address(true));
+    if (reuse_port) {
+      // setting option |SO_REUSEPORT| allows running of multiple rgw processes on
+      // the same port. Can read more about the implementation here.
+      // https://web.git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=c617f398edd4db2b8567a28e899a88f8f574798d
+      int one = 1;
+      if (setsockopt(l.acceptor.native_handle(), SOL_SOCKET,
+                     SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one)) == -1) {
+        lderr(ctx()) << "setsockopt SO_REUSEADDR | SO_REUSEPORT failed:" <<
+ dendl;
+        return -1;
+      }
+    } else {
+      l.acceptor.set_option(tcp::acceptor::reuse_address(true));
+    }
+
     l.acceptor.bind(l.endpoint, ec);
     if (ec) {
       lderr(ctx()) << "failed to bind address " << l.endpoint