]> git.proxmox.com Git - mirror_kronosnet.git/commitdiff
[handle] API change warning: add support for knet_handle_new to create proper sockpairs
authorFabio M. Di Nitto <fdinitto@redhat.com>
Sun, 13 Sep 2015 06:26:01 +0000 (08:26 +0200)
committerFabio M. Di Nitto <fdinitto@redhat.com>
Tue, 15 Sep 2015 17:42:44 +0000 (19:42 +0200)
this is a small facility for applications that don't want/need to create
socketpairs to read/write data to/from knet and avoids lots of duplicated
socket management on the client side.

Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
kronosnetd/vty_cli_cmds.c
libknet/handle.c
libknet/internals.h
libknet/khandle_test.c
libknet/libknet.h
libknet/ping_test.c

index ec9ad3b65872881ef8e93c8e41dd5b66816d3753..c7220f2a694da166c95a1410bd6d853d4527ced9 100644 (file)
@@ -1559,7 +1559,7 @@ static int knet_cmd_no_interface(struct knet_vty *vty)
 
 static int knet_cmd_interface(struct knet_vty *vty)
 {
-       int err = 0, paramlen = 0, paramoffset = 0, found = 0, requested_id;
+       int err = 0, paramlen = 0, paramoffset = 0, found = 0, requested_id, tapfd;
        uint16_t baseport;
        uint8_t *bport = (uint8_t *)&baseport;
        char *param = NULL;
@@ -1611,7 +1611,9 @@ tap_found:
 
        knet_iface->cfg_ring.base_port = baseport;
 
-       knet_iface->cfg_ring.knet_h = knet_handle_new(requested_id, tap_get_fd(knet_iface->cfg_eth.tap), vty->logfd, vty->loglevel);
+       tapfd = tap_get_fd(knet_iface->cfg_eth.tap);
+
+       knet_iface->cfg_ring.knet_h = knet_handle_new(requested_id, &tapfd, vty->logfd, vty->loglevel);
        if (!knet_iface->cfg_ring.knet_h) {
                knet_vty_write(vty, "Error: Unable to create ring handle for device %s%s",
                                device, telnet_newline);
index 0ee9cd2133dd0f26df5022eba480e48ac6d8b3b2..04f659e183d2efb0591e217f888354433fcbb4e0 100644 (file)
 
 static pthread_mutex_t handle_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static int _init_socketpair(knet_handle_t knet_h)
+{
+       if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, knet_h->sockpair) != 0) {
+               return -1;
+       }
+
+       if (_fdset_cloexec(knet_h->sockpair[0])) {
+               return -1;
+       }
+
+       if (_fdset_nonblock(knet_h->sockpair[0])) {
+               return -1;
+       }
+
+       if (_fdset_cloexec(knet_h->sockpair[1])) {
+               return -1;
+       }
+
+       if (_fdset_nonblock(knet_h->sockpair[1])) {
+               return -1;
+       }
+
+       return 0;
+}
+
+static void _close_socketpair(knet_handle_t knet_h)
+{
+       if (knet_h->sockpair[0]) {
+               close(knet_h->sockpair[0]);
+               knet_h->sockpair[0] = 0;
+       }
+       if (knet_h->sockpair[1]) {
+               close(knet_h->sockpair[1]);
+               knet_h->sockpair[1] = 0;
+       }
+}
+
 static int _init_locks(knet_handle_t knet_h)
 {
        int savederrno = 0;
@@ -486,7 +523,7 @@ static void _stop_threads(knet_handle_t knet_h)
 }
 
 knet_handle_t knet_handle_new(uint16_t host_id,
-                             int      datafd,
+                             int      *datafd,
                              int      log_fd,
                              uint8_t  default_log_level)
 {
@@ -497,7 +534,12 @@ knet_handle_t knet_handle_new(uint16_t host_id,
         * validate incoming request
         */
 
-       if (datafd <= 0) {
+       if (datafd == NULL) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if (*datafd < 0) {
                errno = EINVAL;
                return NULL;
        }
@@ -523,7 +565,18 @@ knet_handle_t knet_handle_new(uint16_t host_id,
         */
 
        knet_h->host_id = host_id;
-       knet_h->sockfd = datafd;
+
+       if (*datafd == 0) {
+               if (_init_socketpair(knet_h)) {
+                       savederrno = errno;
+                       goto exit_fail;
+               }
+               knet_h->sockfd = knet_h->sockpair[0];
+               *datafd = knet_h->sockpair[1];
+       } else {
+               knet_h->sockfd = *datafd;
+       }
+
        knet_h->logfd = log_fd;
        if (knet_h->logfd > 0) {
                memset(&knet_h->log_levels, default_log_level, KNET_MAX_SUBSYSTEMS);
@@ -650,6 +703,7 @@ int knet_handle_free(knet_handle_t knet_h)
        crypto_fini(knet_h);
 
        _destroy_locks(knet_h);
+       _close_socketpair(knet_h);
 
 exit_nolock:
        free(knet_h);
index 1649f6714979f395e7ce5a54a21f0664f14c5a54..c4c233d9ff82d8c0977fdbc6c158ef9ab3c5475c 100644 (file)
@@ -81,6 +81,7 @@ struct knet_handle {
        uint16_t host_id;
        unsigned int enabled:1;
        int sockfd;
+       int sockpair[2];
        int logfd;
        uint8_t log_levels[KNET_MAX_SUBSYSTEMS];
        int hostpipefd[2];
index 075566c0af720436ebbcb0ace4f60ee83bec8bbe..35a5cad06fec82c84fb8643570e459352932a508 100644 (file)
 
 int main(int argc, char *argv[])
 {
-       int sock, i;
+       int sock = 0, i;
        knet_handle_t knet_h;
 
-       sock = socket(AF_UNIX, SOCK_STREAM, 0);
+       knet_h = knet_handle_new(1, &sock, 0, 0);
 
-       if (sock < 0) {
-               printf("Unable to create new socket\n");
-               exit(EXIT_FAILURE);
-       }
-
-       knet_h = knet_handle_new(1, sock, 0, 0);
-
-       for (i = 0; i < KNET_MAX_HOST; i++)
+       for (i = 0; i < KNET_MAX_HOST; i++) {
+               printf("add host: %d\n", i);
                knet_host_add(knet_h, i);
+       }
 
-       for (i = 0; i < KNET_MAX_HOST; i++)
+       for (i = 0; i < KNET_MAX_HOST; i++) {
+               printf("del host: %d\n", i);
                knet_host_remove(knet_h, i);
+       }
 
        if (knet_handle_free(knet_h) != 0) {
                printf("Unable to free knet_handle\n");
index 667c7d2fafe7ff99b7a174c692cb408acc1df190..d329d34a342cc4a0c0ce019a0f04da52d925251f 100644 (file)
@@ -59,13 +59,19 @@ typedef struct knet_handle *knet_handle_t;
  *            It is user responsibility to check that the value
  *            is unique, or bad might happen.
  *
- * datafd   - read/write file descriptor (must be > 0).
+ * datafd   - read/write file descriptor.
  *            knet will read data here to send to the other hosts
  *            and will write data received from the network.
  *            Each data packet can be of max size KNET_MAX_PACKET_SIZE!
  *            Applications might be able to write more data at a time
  *            but they will be delivered in KNET_MAX_PACKET_SIZE chunks.
  *            Please refer to ping_test.c on how to setup socketpair.
+ *            datafd can be 0, and knet_handle_new will create a properly
+ *            populated socket pair the same way as ping_test, or a value
+ *            higher than 0. Negative number will return error.
+ *            knet_handle_new will take care to cleanup the socketpair
+ *            only if it's been created by knet_handle_new, when calling
+ *            knet_handle_free.
  *
  * log_fd   - write file descriptor. If set to a value > 0, it will be used
  *            to write log packets (see below) from libknet to the application.
@@ -85,7 +91,7 @@ typedef struct knet_handle *knet_handle_t;
  */
 
 knet_handle_t knet_handle_new(uint16_t host_id,
-                             int      datafd,
+                             int      *datafd,
                              int      log_fd,
                              uint8_t  default_log_level);
 
index e040a3a8c260dbe0469ff1933b78d612a0b99320..b4fc4ec329151f814775d8cf24a4e848ac700f35 100644 (file)
@@ -24,7 +24,7 @@
 
 #define KNET_RING_DEFPORT 50000
 
-static int knet_sock[2];
+static int knet_sock = 0;
 static knet_handle_t knet_h;
 static struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
 static uint8_t loglevel = KNET_LOG_INFO;
@@ -292,11 +292,6 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, knet_sock) != 0) {
-               printf("Unable to create socket\n");
-               exit(EXIT_FAILURE);
-       }
-
        if (pipe(logpipefd)) {
                printf("Unable to create log pipe\n");
                exit(EXIT_FAILURE);
@@ -318,7 +313,7 @@ int main(int argc, char *argv[])
 
        set_debug(argc, argv);
 
-       if ((knet_h = knet_handle_new(1, knet_sock[0], logfd, loglevel)) == NULL) {
+       if ((knet_h = knet_handle_new(1, &knet_sock, logfd, loglevel)) == NULL) {
                printf("Unable to create new knet_handle_t\n");
                exit(EXIT_FAILURE);
        }
@@ -373,7 +368,6 @@ int main(int argc, char *argv[])
 
                snprintf(hello_world, sizeof(hello_world), "Hello world!");
 
-
                switch(big) {
                        case 0: /* hello world */
                                iov_out[0].iov_base = (void *)hello_world;
@@ -396,7 +390,7 @@ int main(int argc, char *argv[])
                                break;
                }
 
-               wlen = writev(knet_sock[1], iov_out, 1);
+               wlen = writev(knet_sock, iov_out, 1);
                if (wlen != iov_out[0].iov_len) {
                        printf("Unable to send messages to socket\n");
                        exit(1);
@@ -407,7 +401,7 @@ int main(int argc, char *argv[])
 
  select_loop:
                FD_ZERO(&rfds);
-               FD_SET(knet_sock[1], &rfds);
+               FD_SET(knet_sock, &rfds);
                FD_SET(logpipefd[0], &rfds);
 
                len = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
@@ -418,7 +412,7 @@ int main(int argc, char *argv[])
                if (len < 0) {
                        printf("Unable select over knet_handle_t\n");
                        exit(EXIT_FAILURE);
-               } else if (FD_ISSET(knet_sock[1], &rfds)) {
+               } else if (FD_ISSET(knet_sock, &rfds)) {
                        struct iovec iov_in;
                        ssize_t rlen = 0;
 
@@ -427,7 +421,7 @@ int main(int argc, char *argv[])
                        iov_in.iov_base = (void *)recvbuff;
                        iov_in.iov_len = sizeof(recvbuff);
 
-                       rlen = readv(knet_sock[1], &iov_in, 1);
+                       rlen = readv(knet_sock, &iov_in, 1);
 
                        if (!rlen) {
                                printf("EOF\n");