]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-tcp: Use path_rundir_append() to construct lock_path
authorMartin Schwenke <mschwenke@ddn.com>
Fri, 9 Aug 2024 01:20:06 +0000 (11:20 +1000)
committerVolker Lendecke <vl@samba.org>
Tue, 20 Aug 2024 13:06:33 +0000 (13:06 +0000)
The current constant value doesn't respect CTDB_TEST_MODE/CTDB_BASE.
Instead use the path module to allow automatic listening in test mode
with local daemons.

A single node can be tested with local daemons, using something like:

  $ tests/local_daemons.sh foo setup -n 1 -C "node address"
  $ grep "node address" foo/node.0/ctdb.conf
      # node address = 127.0.0.1
  $ tests/local_daemons.sh foo start all
  $ tests/local_daemons.sh foo print-log 0 | grep -i chose
  ... node.0 ctdbd[24546]: ctdb chose network address 127.0.0.1:4379

The trick is that commenting out the node address in ctdb.conf means
the chosen node address is the first one from the nodes file that
allows bind/listen.  In this case it is the only line.

The following ensures that automatic listening works for a node that
isn't the first:

  $ cat >mynodes
  192.168.1.1
  127.0.0.1
  $ tests/local_daemons.sh foo setup -n 2 -N mynodes -C "node address"
  $ grep "node address" foo/node.1/ctdb.conf
      # node address = 127.0.0.1
  $ tests/local_daemons.sh foo start 1
  $ tests/local_daemons.sh foo print-log 1 | grep -i chose
  [...] node.1 ctdbd[22787]: ctdb chose network address 127.0.0.1:4379

Note that the first address isn't local on this host, so will always
fail.

So, doing the above and starting both nodes yields...

  ...
  $ tests/local_daemons.sh foo start 1
  $ sleep 3; tests/local_daemons.sh foo start 0
  $ tests/local_daemons.sh foo print-log all | grep -i 'chose\|bind'
  [...] node.1 ctdbd[26351]: ctdb chose network address 127.0.0.1:4379
  [...] node.0 ctdbd[26438]: ctdb_tcp_listen_addr: Failed to bind() to socket - Address already in use (98)
  [...] node.0 ctdbd[26438]: Unable to bind to any node address - giving up

... as expected.

It would be nice to add tests for this, but we don't really have
infrastructure for that.  At least manual testing shows, for the
obvious cases, the previous commits didn't break anything.  :-)

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
ctdb/tcp/tcp_connect.c

index 61f7918e3b5735e50956c3c34aae6d84dc8f1492..8fb041e08e69085fd08ffbe564ea31d0460eaef4 100644 (file)
@@ -34,6 +34,7 @@
 #include "common/system.h"
 #include "common/common.h"
 #include "common/logging.h"
+#include "common/path.h"
 
 #include "ctdb_tcp.h"
 
@@ -479,7 +480,7 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
 {
        int lock_fd;
        unsigned int i;
-       const char *lock_path = CTDB_RUNDIR "/.socket_lock";
+       char *lock_path = NULL;
        struct flock lock;
        int ret;
 
@@ -499,9 +500,15 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
         * atomic. The SO_REUSEADDR setsockopt only prevents double
         * binds if the first socket is in LISTEN state.
         */
+       lock_path = path_rundir_append(ctdb, ".socket_lock");
+       if (lock_path == NULL) {
+               DBG_ERR("Memory allocation error\n");
+               return -1;
+       }
        lock_fd = open(lock_path, O_RDWR|O_CREAT, 0666);
        if (lock_fd == -1) {
                DBG_ERR("Unable to open %s\n", lock_path);
+               talloc_free(lock_path);
                return -1;
        }
 
@@ -514,8 +521,10 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
        if (fcntl(lock_fd, F_SETLKW, &lock) != 0) {
                DBG_ERR("Unable to lock %s\n", lock_path);
                close(lock_fd);
+               talloc_free(lock_path);
                return -1;
        }
+       talloc_free(lock_path);
 
        for (i=0; i < ctdb->num_nodes; i++) {
                if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {