Add retry mechanism for netlink socket creation
[platform/core/connectivity/stc-manager.git] / src / helper / helper-nl.c
old mode 100644 (file)
new mode 100755 (executable)
index 2c3c8f9..6d54e8f
 #include <linux/rtnetlink.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
-/**
- * create_netlink(): Create netlink socket and returns it.
- * Returns: Created socket on success and -1 on failure.
- */
-API int create_netlink(int protocol, uint32_t groups)
+#define NETLINK_SOCK_RETRY_COUNT 3
+
+int __create_netlink(int protocol, uint32_t groups, int retry)
 {
        /**
         * TODO it's one socket, in future make set of sockets
         * unique for protocol and groups
         */
        int sock;
-       sock = socket(PF_NETLINK, SOCK_RAW, protocol);
-       if (sock < 0)
+
+       if (retry <= 0)
                return -EINVAL; //LCOV_EXCL_LINE
 
+       errno = 0;
+       sock = socket(PF_NETLINK, SOCK_RAW, protocol);
+       if (sock < 0) {
+               STC_LOGE("failed to open socket errno [%d], retry [%d]",
+                               errno, NETLINK_SOCK_RETRY_COUNT - retry); //LCOV_EXCL_LINE
+               return __create_netlink(protocol, groups, --retry); //LCOV_EXCL_LINE
+       }
+
        struct sockaddr_nl src_addr = { 0, };
 
        src_addr.nl_family = AF_NETLINK;
        src_addr.nl_groups = groups;
 
+       errno = 0;
        if (bind(sock, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
+               STC_LOGE("failed to bind socket errno [%d], retry [%d]",
+                               errno, NETLINK_SOCK_RETRY_COUNT - retry); //LCOV_EXCL_LINE
                close(sock); //LCOV_EXCL_LINE
-               return -1; //LCOV_EXCL_LINE
+               return __create_netlink(protocol, groups, --retry); //LCOV_EXCL_LINE
        }
 
        return sock;
 }
 
+/**
+ * create_netlink(): Create netlink socket and returns it.
+ * Returns: Created socket on success and -1 on failure.
+ */
+API int create_netlink(int protocol, uint32_t groups)
+{
+       return __create_netlink(protocol, groups, NETLINK_SOCK_RETRY_COUNT);
+}
+
 void fill_attribute_list(struct rtattr **atb, const int max_len,
                         struct rtattr *rt_na, int rt_len)
 {
@@ -67,7 +86,7 @@ void fill_attribute_list(struct rtattr **atb, const int max_len,
 /* read netlink message from socket
  * return opaque pointer to genl structure
  */
-int read_netlink(int sock, void *buf, size_t len)
+API int read_netlink(int sock, void *buf, size_t len)
 {
        ssize_t ret;
        struct sockaddr_nl addr;