Add a new command 'ctdb checktcpport <port>'
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 17 Aug 2011 00:16:35 +0000 (10:16 +1000)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 17 Aug 2011 00:16:35 +0000 (10:16 +1000)
that tries to bind to the specified port on INADDR_ANY.

This can be used for testing if a service is listening to that port or not.

Errors are printed to stdout and the returned status code is either 0 : if we managed to bind to the port (in which case the service is NOT listening on that bort) or the value of errno that stopped us from binding to a port.

errno for EADDRINUSE is 98 so a script using this command should check the status code against the value 98.
If this command returns 98 it means the service is listening to the specified port.

tools/ctdb.c

index ec9481e96b9813f657ed8364cc9725c574c69d68..6cada94ebd54c5c7a7826de1f2dc6e803ccd40c4 100644 (file)
@@ -3296,6 +3296,47 @@ static int control_pstore(struct ctdb_context *ctdb, int argc, const char **argv
        return 0;
 }
 
+/*
+  check if a service is bound to a port or not
+ */
+static int control_chktcpport(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       int s, ret;
+       unsigned v;
+       int port;
+        struct sockaddr_in sin;
+
+       if (argc != 1) {
+               printf("Use: ctdb chktcport <port>\n");
+               return EINVAL;
+       }
+
+       port = atoi(argv[0]);
+
+       s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+       if (s == -1) {
+               printf("Failed to open local socket\n");
+               return errno;
+       }
+
+       v = fcntl(s, F_GETFL, 0);
+        fcntl(s, F_SETFL, v | O_NONBLOCK);
+
+       bzero(&sin, sizeof(sin));
+       sin.sin_family = PF_INET;
+       sin.sin_port   = htons(port);
+       ret = bind(s, (struct sockaddr *)&sin, sizeof(sin));
+       close(s);
+       if (ret == -1) {
+               printf("Failed to bind to local socket: %d %s\n", errno, strerror(errno));
+               return errno;
+       }
+
+       return 0;
+}
+
+
+
 static void log_handler(struct ctdb_context *ctdb, uint64_t srvid, 
                             TDB_DATA data, void *private_data)
 {
@@ -4912,6 +4953,7 @@ static const struct {
        { "tfetch",          control_tfetch,            false,  true,  "fetch a record from a [c]tdb-file", "<tdb-file> <key> [<file>]" },
        { "readkey",         control_readkey,           true,   false,  "read the content off a database key", "<tdb-file> <key>" },
        { "writekey",        control_writekey,          true,   false,  "write to a database key", "<tdb-file> <key> <value>" },
+       { "checktcpport",    control_chktcpport,        false,  true,  "check if a service is bound to a specific tcp port or not", "<port>" },
 };
 
 /*