Whamcloud - gitweb
* portals auto-loads required NALs (taken from 'networks=')
authoreeb <eeb>
Thu, 5 May 2005 17:12:51 +0000 (17:12 +0000)
committereeb <eeb>
Thu, 5 May 2005 17:12:51 +0000 (17:12 +0000)
lnet/include/libcfs/kp30.h
lnet/include/lnet/lib-lnet.h
lnet/include/lnet/lib-p30.h
lnet/include/lnet/lib-types.h
lnet/libcfs/nidstrings.c
lnet/lnet/api-ni.c
lnet/lnet/config.c
lnet/lnet/module.c
lnet/utils/portals.c

index 50ab197..d99a977 100644 (file)
@@ -421,6 +421,7 @@ extern int portal_ioctl_getdata(char *buf, char *end, void *arg);
 #define IOC_PORTAL_DEL_ROUTE               _IOWR('e', 53, IOCTL_PORTAL_TYPE)
 #define IOC_PORTAL_GET_ROUTE               _IOWR('e', 54, IOCTL_PORTAL_TYPE)
 #define IOC_PORTAL_NOTIFY_ROUTER           _IOWR('e', 55, IOCTL_PORTAL_TYPE)
+#define IOC_PORTAL_UNCONFIGURE             _IOWR('e', 56, IOCTL_PORTAL_TYPE)
 /* nal ioctls */
 #define IOC_PORTAL_REGISTER_MYNID          _IOWR('e', 70, IOCTL_PORTAL_TYPE)
 #define IOC_PORTAL_CLOSE_CONNECTION        _IOWR('e', 71, IOCTL_PORTAL_TYPE)
index d02bcdd..79d5c7f 100644 (file)
@@ -411,6 +411,8 @@ ptl_ni_decref(ptl_ni_t *ni)
                 ptl_queue_zombie_ni(ni);
 }
 
+extern ptl_err_t ptl_get_apinih (ptl_handle_ni_t *nih);
+
 extern ptl_ni_t *ptl_net2ni (__u32 net);
 extern void ptl_enq_event_locked (void *private,
                                   ptl_eq_t *eq, ptl_event_t *ev);
index d02bcdd..79d5c7f 100644 (file)
@@ -411,6 +411,8 @@ ptl_ni_decref(ptl_ni_t *ni)
                 ptl_queue_zombie_ni(ni);
 }
 
+extern ptl_err_t ptl_get_apinih (ptl_handle_ni_t *nih);
+
 extern ptl_ni_t *ptl_net2ni (__u32 net);
 extern void ptl_enq_event_locked (void *private,
                                   ptl_eq_t *eq, ptl_event_t *ev);
index cc91093..a6e9ca7 100644 (file)
@@ -345,6 +345,7 @@ typedef struct
         /* Stuff initialised at PtlInit() */
         int               apini_init;           /* PtlInit() called? */
         int               apini_refcount;       /* PtlNIInit/PtlNIFini counter */
+        int               apini_niinit_self;    /* Have I called PtlNIInit myself? */
         
         struct list_head  apini_nals;           /* registered NALs */
 
index c3e4b81..1d2be09 100644 (file)
@@ -520,6 +520,7 @@ libcfs_str2anynid(ptl_nid_t *nidp, char *str)
 
 #ifdef __KERNEL__
 EXPORT_SYMBOL(libcfs_isknown_nal);
+EXPORT_SYMBOL(libcfs_nal2modname);
 EXPORT_SYMBOL(libcfs_nal2str);
 EXPORT_SYMBOL(libcfs_str2nal);
 EXPORT_SYMBOL(libcfs_net2str);
index f31f2ca..3460d29 100644 (file)
@@ -27,6 +27,10 @@ static char *networks = DEFAULT_NETWORKS;
 CFS_MODULE_PARM(networks, "s", charp, 0444,
                 "local networks (default='"DEFAULT_NETWORKS"')");
 
+static int nal_load_timeout = 10;
+CFS_MODULE_PARM(nal_load_timeout, "i", int, 0444,
+                "seconds to wait for a NAL to load");
+
 ptl_apini_t       ptl_apini;                    /* THE network interface (at the API) */
 
 void ptl_assert_wire_constants (void)
@@ -638,9 +642,50 @@ ptl_shutdown_nalnis (void)
 ptl_err_t
 ptl_load_nal (int type)
 {
-        CERROR("Automatic NAL loading not implemented (%s)\n",
-               libcfs_nal2str(type));
-        return PTL_FAIL;
+        /* Called holding api_mutex */
+        static char cmd[256];
+
+        char *envp[] = {
+                "HOME=/",
+                "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
+                NULL};
+        char *argv[] = {
+                "/bin/sh",
+                "-c",
+                cmd,
+                NULL};
+        int timeout = nal_load_timeout;
+        int rc;
+
+        snprintf(cmd, sizeof(cmd), "modprobe %s > /dev/console",
+                 libcfs_nal2modname(type));
+        
+        rc = USERMODEHELPER(argv[0], argv, envp);
+        if (rc < 0) {
+                CERROR("Error %d trying '%s' '%s' '%s'\n",
+                       rc, argv[0], argv[1], argv[2]);
+                return PTL_FAIL;
+        }
+
+        do {
+                set_current_state(TASK_UNINTERRUPTIBLE);
+                schedule_timeout(cfs_time_seconds(1));
+                timeout--;
+
+                PTL_MUTEX_DOWN(&ptl_apini.apini_nal_mutex);
+                rc = (ptl_find_nal_by_type(type) == NULL) ? PTL_FAIL : PTL_OK;
+                PTL_MUTEX_UP(&ptl_apini.apini_nal_mutex);
+                
+        } while (rc != PTL_OK && timeout > 0);
+
+        if (rc != PTL_OK) {
+                LCONSOLE_ERROR("Timeout waiting for NAL %s to load\n",
+                               libcfs_nal2str(type));
+                LCONSOLE_ERROR("cmd: \"%s %s '%s'\"\n",
+                               argv[0], argv[1], argv[2]);
+        }
+
+        return rc;
 }
 
 ptl_err_t
@@ -670,7 +715,7 @@ ptl_startup_nalnis (void)
 
                 for (retry = 0;; retry = 1) {
                         nal = ptl_find_nal_by_type(nal_type);
-                        if (nal != NULL)
+                        if (nal != NULL) 
                                 break;
                         
                         PTL_MUTEX_UP(&ptl_apini.apini_nal_mutex);
@@ -873,35 +918,31 @@ PtlNICtl(ptl_handle_ni_t nih, unsigned int cmd, void *arg)
                         break;
                 }
                 PTL_UNLOCK(flags);
-                break;
+                return rc;
 
         case IOC_PORTAL_FAIL_NID:
-                rc = ptl_fail_nid(data->ioc_nid, data->ioc_count);
-                break;
+                return ptl_fail_nid(data->ioc_nid, data->ioc_count);
                 
         case IOC_PORTAL_ADD_ROUTE:
         case IOC_PORTAL_DEL_ROUTE:
         case IOC_PORTAL_GET_ROUTE:
         case IOC_PORTAL_NOTIFY_ROUTER:
-                rc = kpr_ctl(cmd, arg);
-                break;
+                return kpr_ctl(cmd, arg);
 
         default:
                 ni = ptl_net2ni(data->ioc_net);
-                if (ni == NULL) {
+                if (ni == NULL)
+                        return -EINVAL;
+
+                if (ni->ni_nal->nal_ctl == NULL)
                         rc = -EINVAL;
-                } else {
-                        if (ni->ni_nal->nal_ctl == NULL)
-                                rc = -EINVAL;
-                        else
-                                rc = ni->ni_nal->nal_ctl(ni, cmd, arg);
+                else
+                        rc = ni->ni_nal->nal_ctl(ni, cmd, arg);
 
-                        ptl_ni_decref(ni);
-                }
-                break;
+                ptl_ni_decref(ni);
+                return rc;
         }
-        
-        return rc;
+        /* not reached */
 }
 
 ptl_err_t
index 3359f68..6873cce 100644 (file)
@@ -53,7 +53,7 @@ ptl_syntax(char *name, char *str, int offset, int width)
         
        LCONSOLE_ERROR("Error parsing '%s=\"%s\"'\n", name, str);
        LCONSOLE_ERROR("here...........%.*s..%.*s|%.*s|\n", 
-                       strlen(name), dots, offset, dots,
+                       (int)strlen(name), dots, offset, dots,
                        (width < 1) ? 0 : width - 1, dashes);
 }
 
index 6ec216e..9943b3e 100644 (file)
 
 static int kportal_ioctl(unsigned int cmd, struct portal_ioctl_data *data)
 {
+        ptl_err_t          initrc;
         int                rc;
         ptl_handle_ni_t    nih;
 
-        rc = PtlNIInit(PTL_IFACE_DEFAULT, LUSTRE_SRV_PTL_PID, 
-                       NULL, NULL, &nih);
-        if (!(rc == PTL_OK || rc == PTL_IFACE_DUP))
+        if (cmd == IOC_PORTAL_UNCONFIGURE) {
+                /* ghastly hack to prevent repeated net config */
+                PTL_MUTEX_DOWN(&ptl_apini.apini_api_mutex);
+                initrc = ptl_apini.apini_niinit_self;
+                ptl_apini.apini_niinit_self = 0;
+                rc = ptl_apini.apini_refcount;
+                PTL_MUTEX_UP(&ptl_apini.apini_api_mutex);
+
+                if (initrc) {
+                        rc--;
+                        PtlNIFini((ptl_handle_ni_t){0});
+                }
+                
+                return rc == 0 ? 0 : -EBUSY;
+        }
+        
+        initrc = PtlNIInit(PTL_IFACE_DEFAULT, LUSTRE_SRV_PTL_PID, 
+                           NULL, NULL, &nih);
+        if (!(initrc == PTL_OK || initrc == PTL_IFACE_DUP))
                 RETURN (-EINVAL);
 
         rc = PtlNICtl(nih, cmd, data);
 
-        PtlNIFini(nih);
+        if (initrc == PTL_OK) {
+                PTL_MUTEX_DOWN(&ptl_apini.apini_api_mutex);
+                /* I instantiated the network */
+                ptl_apini.apini_niinit_self = 1;
+                PTL_MUTEX_UP(&ptl_apini.apini_api_mutex);
+        } else {
+                PtlNIFini(nih);
+        }
+        
         return rc;
 }
 
index df8efd9..6c60eab 100644 (file)
@@ -310,6 +310,23 @@ int jt_ptl_network(int argc, char **argv)
         int                      set = argc >= 2;
         int                      count;
         int                      rc;
+
+        if (set && !strcmp(argv[1], "unconfigure")) {
+                PORTAL_IOC_INIT(data);
+                rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_UNCONFIGURE, &data);
+                
+                if (rc == 0) {
+                        printf ("portals ready to unload\n");
+                        return 0;
+                }
+                
+                if (errno == EBUSY)
+                        fprintf(stderr, "Portals still in use\n");
+                else
+                        fprintf(stderr, "Unconfigure error %d: %s\n",
+                                errno, strerror(errno));
+                return -1;
+        }
         
         if (set) {
                 net = libcfs_str2net(argv[1]);