22761186 Error: Couldn't open a master agentx socket to listen on s11u3-sru
authorVishwas Shekarappa Gudiyavar <vishwas.shekarappa.gudiyavar@oracle.com>
Wed, 07 Sep 2016 00:15:35 -0700
branchs11u3-sru
changeset 6733 0901797054b4
parent 6729 541ae3f2f1b4
child 6734 ea93ede4968e
22761186 Error: Couldn't open a master agentx socket to listen on
components/net-snmp/patches/058.22761186.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/net-snmp/patches/058.22761186.patch	Wed Sep 07 00:15:35 2016 -0700
@@ -0,0 +1,274 @@
+The patch has been taken from community and modifies directory creation code to happen after the domain selection code so that the directory creation code knows what directory to create.
+
+The details can be found in the following location
+https://sourceforge.net/p/net-snmp/code/ci/b066a45975a505545b064c5492f7d7fe0a7623dd/
+
+--- net-snmp-5.4.1/agent/mibgroup/agentx/master.c	2007-01-22 08:19:47.000000000 -0800
++++ copy_net-snmp-5.4.1/agent/mibgroup/agentx/master.c	2016-01-30 01:41:53.175843516 -0800
+@@ -60,13 +60,6 @@
+     char *agentx_sockets;
+     char *cp1;
+ 
+-#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
+-    int agentx_dir_perm;
+-    int agentx_sock_perm;
+-    int agentx_sock_user;
+-    int agentx_sock_group;
+-#endif
+-
+     if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE) != MASTER_AGENT)
+         return;
+ 
+@@ -89,7 +82,6 @@
+         agentx_sockets = strdup("");
+     }
+ 
+-
+     DEBUGMSGTL(("agentx/master", "initializing...\n"));
+     snmp_sess_init(&sess);
+     sess.version = AGENTX_VERSION_1;
+@@ -98,6 +90,18 @@
+                                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT);
+     sess.retries = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+                                       NETSNMP_DS_AGENT_AGENTX_RETRIES);
++
++#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
++    {
++       int agentx_dir_perm =
++           netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
++                              NETSNMP_DS_AGENT_X_DIR_PERM);
++       if (agentx_dir_perm == 0)
++           agentx_dir_perm = NETSNMP_AGENT_DIRECTORY_MODE;
++       netsnmp_unix_create_path_with_mode(agentx_dir_perm);
++    }
++#endif
++
+     cp1 = agentx_sockets;
+     while (cp1) {
+         netsnmp_transport *t;
+@@ -111,44 +115,15 @@
+         if (cp1 != NULL) {
+             *cp1++ = '\0';
+ 	}
+-    
+-        if (sess.peername[0] == '/') {
+-#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
+-            /*
+-             *  If this is a Unix pathname,
+-             *  try and create the directory first.
+-             */
+-            agentx_dir_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
+-                                                 NETSNMP_DS_AGENT_X_DIR_PERM);
+-            if (agentx_dir_perm == 0)
+-                agentx_dir_perm = NETSNMP_AGENT_DIRECTORY_MODE;
+-            if (mkdirhier(sess.peername, (mode_t)agentx_dir_perm, 1)) {
+-                snmp_log(LOG_ERR,
+-                         "Failed to create the directory for the agentX socket: %s\n",
+-                         sess.peername);
+-            }
+-#else
+-            netsnmp_sess_log_error(LOG_WARNING,
+-                                   "unix domain support not available\n",
+-                                   &sess);
+-#endif
+-        }
+-    
+-        /*
+-         *  Otherwise, let 'snmp_open' interpret the string.
+-         */
++
++       /*
++        *  Let 'snmp_open' interpret the descriptor.
++        */
+         sess.local_port = AGENTX_PORT;      /* Indicate server & set default port */
+         sess.remote_port = 0;
+         sess.callback = handle_master_agentx_packet;
+         errno = 0;
+         t = netsnmp_transport_open_server("agentx", sess.peername);
+-        if (t == NULL && errno == EADDRINUSE) {
+-            /*
+-             * Could be a left-over socket (now deleted)
+-             * Try again
+-             */
+-            t = netsnmp_transport_open_server("agentx", sess.peername);
+-        }
+         if (t == NULL) {
+             /*
+              * diagnose snmp_open errors with the input netsnmp_session
+@@ -169,41 +144,52 @@
+                 netsnmp_sess_log_error(LOG_WARNING, buf, &sess);
+             }
+         } else {
+-            session =
+-                snmp_add_full(&sess, t, NULL, agentx_parse, NULL, NULL,
+-                              agentx_realloc_build, agentx_check_packet, NULL);
+-        }
+-        if (session == NULL) {
+-            netsnmp_transport_free(t);
+-        }
+-
+ #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
++        if (t->domain == netsnmp_UnixDomain && t->local != NULL) {
+         /*
+          * Apply any settings to the ownership/permissions of the AgentX socket
+          */
+-        agentx_sock_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+-                                              NETSNMP_DS_AGENT_X_SOCK_PERM);
+-        agentx_sock_user = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+-                                              NETSNMP_DS_AGENT_X_SOCK_USER);
+-        agentx_sock_group = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+-                                               NETSNMP_DS_AGENT_X_SOCK_GROUP);
+-
+-        if (agentx_sock_perm != 0)
+-            chmod(sess.peername, agentx_sock_perm);
+-        if (agentx_sock_user || agentx_sock_group) {
+-            /*
+-             * If either of user or group haven't been set,
+-             *  then leave them unchanged.
+-             */
+-            if (agentx_sock_user == 0 )
+-                agentx_sock_user = -1;
+-            if (agentx_sock_group == 0 )
+-                agentx_sock_group = -1;
+-            chown(sess.peername, agentx_sock_user, agentx_sock_group);
++            int agentx_sock_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
++                                                  NETSNMP_DS_AGENT_X_SOCK_PERM);
++            int agentx_sock_user = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
++                                                  NETSNMP_DS_AGENT_X_SOCK_USER);
++            int agentx_sock_group = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
++                                                  NETSNMP_DS_AGENT_X_SOCK_GROUP);
++
++            char name[sizeof(struct sockaddr_un) + 1];
++            memcpy(name, t->local, t->local_length);
++            name[t->local_length] = '\0';
++
++            if (agentx_sock_perm != 0)
++                chmod(name, agentx_sock_perm);
++
++            if (agentx_sock_user || agentx_sock_group) {
++                /*
++                 * If either of user or group haven't been set,
++                 *  then leave them unchanged.
++                 */
++                if (agentx_sock_user == 0 )
++                    agentx_sock_user = -1;
++                if (agentx_sock_group == 0 )
++                    agentx_sock_group = -1;
++                chown(name, agentx_sock_user, agentx_sock_group);
++            }
+         }
+ #endif
++        session =
++            snmp_add_full(&sess, t, NULL, agentx_parse, NULL, NULL,
++                          agentx_realloc_build, agentx_check_packet, NULL);
++         }
++
++        if (session == NULL) {
++            netsnmp_transport_free(t);
++        }
+     }
+ 
++#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
++    netsnmp_unix_dont_create_path();
++#endif
++
+     SNMP_FREE(agentx_sockets);
+     DEBUGMSGTL(("agentx/master", "initializing...   DONE\n"));
+ }
+--- net-snmp-5.4.1/include/net-snmp/library/snmpUnixDomain.h	2006-10-27 13:19:44.000000000 -0700
++++ copy_net-snmp-5.4.1/include/net-snmp/library/snmpUnixDomain.h	2016-01-29 03:24:45.623926107 -0800
+@@ -41,9 +41,20 @@
+ 
+ void            netsnmp_unix_ctor(void);
+ 
++/*
++ * Support functions
++ */
++void            netsnmp_unix_create_path_with_mode(int mode);
++void            netsnmp_unix_dont_create_path(void);
++
+ #ifdef __cplusplus
+ }
+ #endif
++#else
++
++#define netsnmp_unix_create_path_with_mode(x)
++#define netsnmp_unix_dont_create_path()
++
+ #endif                          /*NETSNMP_TRANSPORT_UNIX_DOMAIN */
+ 
+ #endif/*_SNMPUNIXDOMAIN_H*/
+--- net-snmp-5.4.1/snmplib/snmpUnixDomain.c	2007-04-30 03:07:13.000000000 -0700
++++ copy_net-snmp-5.4.1/snmplib/snmpUnixDomain.c	2016-01-29 03:30:08.333575786 -0800
+@@ -252,7 +252,25 @@
+     }
+ }
+ 
++static int create_path = 0;
++static mode_t create_mode;
+ 
++/** If trying to create unix sockets in nonexisting directories then
++ *  try to create the directory with mask mode.
++ */
++void netsnmp_unix_create_path_with_mode(int mode)
++{
++    create_path = 1;
++    create_mode = mode;
++}
++
++/** If trying to create unix sockets in nonexisting directories then
++ *  fail.
++ */
++void netsnmp_unix_dont_create_path(void)
++{
++    create_path = 0;
++}
+ 
+ /*
+  * Open a Unix-domain transport for SNMP.  Local is TRUE if addr is the local
+@@ -308,7 +326,7 @@
+     t->flags = NETSNMP_TRANSPORT_FLAG_STREAM;
+ 
+     if (local) {
+-      t->local = (u_char *)malloc(strlen(addr->sun_path));
++        t->local = (u_char *)malloc(strlen(addr->sun_path));
+         if (t->local == NULL) {
+             netsnmp_transport_free(t);
+             return NULL;
+@@ -325,6 +343,16 @@
+ 
+         unlink(addr->sun_path);
+         rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
++
++        if (rc != 0 && errno == ENOENT && create_path) {
++            rc = mkdirhier(addr->sun_path, create_mode, 1);
++            if (rc != 0) {
++                netsnmp_unix_close(t);
++                netsnmp_transport_free(t);
++                return NULL;
++            }
++            rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
++        }
+         if (rc != 0) {
+             DEBUGMSGTL(("netsnmp_unix_transport",
+                         "couldn't bind \"%s\", errno %d (%s)\n",
+@@ -358,7 +386,7 @@
+         }
+ 
+     } else {
+-      t->remote = (u_char *)malloc(strlen(addr->sun_path));
++        t->remote = (u_char *)malloc(strlen(addr->sun_path));
+         if (t->remote == NULL) {
+             netsnmp_transport_free(t);
+             return NULL;
+@@ -385,8 +413,8 @@
+         sup->server.sun_family = AF_UNIX;
+         strcpy(sup->server.sun_path, addr->sun_path);
+         sup->local = 0;
+-       netsnmp_sock_buffer_set(t->sock, SO_SNDBUF, local, 0);
+-       netsnmp_sock_buffer_set(t->sock, SO_RCVBUF, local, 0);
++        netsnmp_sock_buffer_set(t->sock, SO_SNDBUF, local, 0);
++        netsnmp_sock_buffer_set(t->sock, SO_RCVBUF, local, 0);
+     }
+ 
+     /*