Whamcloud - gitweb
1. Add ioctl OBD_IOC_GETDEVICE to get device list, because Darwin user
authorliangzhen <liangzhen>
Fri, 24 Feb 2006 10:17:14 +0000 (10:17 +0000)
committerliangzhen <liangzhen>
Fri, 24 Feb 2006 10:17:14 +0000 (10:17 +0000)
   can't get device list from /proc filesystem.
2. Smallfix for version command of lctl
3. Return value to Darwin should be positive value.
4. Add basic features for Darwin in lconf (load and unload echo).

lustre/include/lustre_lib.h
lustre/obdclass/class_obd.c
lustre/obdclass/darwin/darwin-module.c
lustre/utils/lconf
lustre/utils/obd.c

index d2def9b..70b6d04 100644 (file)
@@ -424,6 +424,7 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 #define OBD_IOC_LOV_GET_CONFIG         _IOWR('f', 132, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_CLIENT_RECOVER         _IOW ('f', 133, OBD_IOC_DATA_TYPE)
 
+
 #define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 139      )
 #define OBD_IOC_NO_TRANSNO             _IOW ('f', 140, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_SET_READONLY           _IOW ('f', 141, OBD_IOC_DATA_TYPE)
@@ -433,6 +434,8 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 
 #define OBD_IOC_CLOSE_UUID             _IOWR ('f', 147, OBD_IOC_DATA_TYPE)
 
+#define OBD_IOC_GETDEVICE              _IOWR ('f', 149, OBD_IOC_DATA_TYPE)
+
 #define OBD_IOC_LOV_SETSTRIPE          _IOW ('f', 154, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_LOV_GETSTRIPE          _IOW ('f', 155, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_LOV_SETEA              _IOW ('f', 156, OBD_IOC_DATA_TYPE)
index ff6b41d..391c339 100644 (file)
@@ -262,13 +262,49 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
                 GOTO(out, err);
         }
 
-
         case OBD_IOC_CLOSE_UUID: {
                 CDEBUG(D_IOCTL, "closing all connections to uuid %s (NOOP)\n",
                        data->ioc_inlbuf1);
                 GOTO(out, err = 0);
         }
 
+        case OBD_IOC_GETDEVICE: {
+                int     index = data->ioc_count;
+                char    *status, *str;
+
+                if (!data->ioc_inlbuf1) {
+                        CERROR("No buffer passed in ioctl\n");
+                        GOTO(out, err = -EINVAL);
+                } 
+                if (data->ioc_inllen1 < 128) {
+                        CERROR("ioctl buffer too small to hold version\n");
+                        GOTO(out, err = -EINVAL);
+                }
+                                
+                if (index >= MAX_OBD_DEVICES)
+                        GOTO(out, err = -ENOENT);
+                obd = &obd_dev[index];
+                if (!obd->obd_type)
+                        GOTO(out, err = -ENOENT);
+                
+                if (obd->obd_stopping)
+                        status = "ST";
+                else if (obd->obd_set_up)
+                        status = "UP";
+                else if (obd->obd_attached)
+                        status = "AT";
+                else
+                        status = "--"; 
+                str = (char *)data->ioc_bulk;
+                snprintf(str, len - sizeof(*data), "%3d %s %s %s %s %d",
+                         (int)index, status, obd->obd_type->typ_name,
+                         obd->obd_name, obd->obd_uuid.uuid,
+                         atomic_read(&obd->obd_refcount));
+                err = obd_ioctl_popdata((void *)arg, data, len);
+
+                GOTO(out, err = 0);
+        }
+
         }
 
         if (data->ioc_dev >= MAX_OBD_DEVICES) {
index 336fe2e..8b97261 100644 (file)
@@ -115,8 +115,8 @@ static int
 obd_class_open(dev_t dev, int flags, int devtype, struct proc *p)
 {
        if (obd_psdev_ops.p_open != NULL)
-               return obd_psdev_ops.p_open(0, NULL);
-       return -EPERM;
+               return -obd_psdev_ops.p_open(0, NULL);
+       return EPERM;
 }
 
 /*  closing /dev/obd */
@@ -124,8 +124,8 @@ static int
 obd_class_release(dev_t dev, int flags, int mode, struct proc *p)
 {
        if (obd_psdev_ops.p_close != NULL)
-               return obd_psdev_ops.p_close(0, NULL);
-       return -EPERM;
+               return -obd_psdev_ops.p_close(0, NULL);
+       return EPERM;
 }
 
 static int
@@ -135,11 +135,11 @@ obd_class_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
        ENTRY;
 
        if (!is_suser())
-               RETURN (-EPERM);
+               RETURN (EPERM);
        if (obd_psdev_ops.p_ioctl != NULL)
-               err = obd_psdev_ops.p_ioctl(NULL, cmd, (void *)arg);
+               err = -obd_psdev_ops.p_ioctl(NULL, cmd, (void *)arg);
        else
-               err = -EPERM;
+               err = EPERM;
 
        RETURN(err);
 }
index 398d463..cfea7da 100755 (executable)
@@ -38,6 +38,15 @@ else:
     from fcntl import F_GETFL, F_SETFL
 
 PYMOD_DIR = ["/usr/lib64/lustre/python", "/usr/lib/lustre/python"]
+PLATFORM = ''
+KEXTPATH = ''
+if string.find(sys.platform, 'linux') != -1:
+    PLATFORM='LINUX'
+elif string.find(sys.platform, 'darwin') != -1:
+    PLATFORM='DARWIN'
+    KEXTPATH='/System/Library/Extensions/'
+else:
+    PLATFORM='Unsupported'
 
 def development_mode():
     base = os.path.dirname(sys.argv[0])
@@ -456,15 +465,25 @@ class LCTLInterface:
 
     # get list of devices
     def device_list(self):
-        devices = '/proc/fs/lustre/devices'
         ret = []
-        if os.access(devices, os.R_OK):
-            try:
-                fp = open(devices, 'r')
-                ret =  fp.readlines()
-                fp.close()
-            except IOError, e:
-                log(e)
+        if PLATFORM == 'LINUX':
+            devices = '/proc/fs/lustre/devices'
+            if os.access(devices, os.R_OK):
+                try:
+                    fp = open(devices, 'r')
+                    ret =  fp.readlines()
+                    fp.close()
+                except IOError, e:
+                    log(e)
+        elif PLATFORM == 'DARWIN':
+            rc, out = self.run("device_list")
+            ret = out.split("\n")
+            if len(ret) == 0:
+                return ret
+            tail = ret[-1]
+            if not tail:
+                # remove the last empty line
+                ret = ret[:-1]
         return ret
 
     # get lustre version
@@ -791,15 +810,24 @@ def sys_get_branch():
 
 def mod_loaded(modname):
     """Check if a module is already loaded. Look in /proc/modules for it."""
-    try:
-        fp = open('/proc/modules')
-        lines = fp.readlines()
-        fp.close()
-        # please forgive my tired fingers for this one
-        ret = filter(lambda word, mod=modname: word == mod,
-                     map(lambda line: string.split(line)[0], lines))
-        return ret
-    except Exception, e:
+    if PLATFORM == 'LINUX':
+        try:
+            fp = open('/proc/modules')
+            lines = fp.readlines()
+            fp.close()
+            # please forgive my tired fingers for this one
+            ret = filter(lambda word, mod=modname: word == mod,
+                         map(lambda line: string.split(line)[0], lines))
+            return ret
+        except Exception, e:
+            return 0
+    elif PLATFORM == 'DARWIN':
+        ret, out = run('/usr/sbin/kextstat | /usr/bin/grep', modname)
+        if ret == 0:
+                return 1
+        else:
+                return 0
+    else:
         return 0
 
 # XXX: instead of device_list, ask for $name and see what we get
@@ -861,26 +889,28 @@ class kmod:
             if mod_loaded(mod) and not config.noexec:
                 continue
             log ('loading module:', mod, 'srcdir', src_dir, 'devdir', dev_dir)
-            if mod == 'lnet':
-                #For LNET we really need modprobe to load defined LNDs
-                run('/sbin/modprobe lnet')
-                #But if that fails, try insmod anyhow
-            if src_dir:
-                module = find_module(src_dir, dev_dir, mod)
-                if not module:
-                    panic('module not found:', mod)
-                (rc, out) = run('/sbin/insmod', module)
-                if rc and not mod_loaded(mod):
-                    if rc == 1:
-                        print("Bad module options? Check dmesg.") 
-                    raise CommandError('insmod', out, rc)
-            else:
-                (rc, out) = run('/sbin/modprobe', mod)
-                if rc and not mod_loaded(mod):
-                    if rc == 1:
-                        print("Bad module options? Check dmesg.") 
-                    raise CommandError('modprobe', out, rc)
-
+            if PLATFORM == 'LINUX':
+                if mod == 'lnet':
+                    #For LNET we really need modprobe to load defined LNDs
+                    run('/sbin/modprobe lnet')
+                    #But if that fails, try insmod anyhow
+                if src_dir:
+                    module = find_module(src_dir, dev_dir, mod)
+                    if not module:
+                        panic('module not found:', mod)
+                    (rc, out) = run('/sbin/insmod', module)
+                    if rc and not mod_loaded(mod):
+                        if rc == 1:
+                            print("Bad module options? Check dmesg.") 
+                        raise CommandError('insmod', out, rc)
+                else:
+                    (rc, out) = run('/sbin/modprobe', mod)
+                    if rc and not mod_loaded(mod):
+                        if rc == 1:
+                            print("Bad module options? Check dmesg.") 
+                        raise CommandError('modprobe', out, rc)
+            elif PLATFORM == 'DARWIN':
+                run('/sbin/kextload', KEXTPATH + mod + '.kext');
     def cleanup_module(self):
         """Unload the modules in the list in reverse order."""
 
@@ -902,7 +932,10 @@ class kmod:
                 log('unloading the network')
                 lctl.unconfigure_network()
                 if mod_loaded("ksocklnd"):
-                    run('/sbin/rmmod ksocklnd')
+                    if PLATFORM == 'LINUX':
+                        run('/sbin/rmmod ksocklnd')
+                    elif PLATFORM == 'DARWIN':
+                        run('/sbin/kextunload', KEXTPATH+'ksocklnd.kext')
                 if mod_loaded("kqswlnd"):
                     run('/sbin/rmmod kqswlnd')
                 if mod_loaded("kgmlnd"):
@@ -917,7 +950,10 @@ class kmod:
                     run('/sbin/rmmod kralnd')
                 if mod_loaded("kptllnd"):
                     run('/sbin/rmmod kptllnd')
-            (rc, out) = run('/sbin/rmmod', mod)
+            if PLATFORM == 'LINUX':
+                (rc, out) = run('/sbin/rmmod', mod)
+            elif PLATFORM == 'DARWIN':
+                (rc, out) = run('/sbin/kextunload', KEXTPATH+mod+'.kext');
             if rc:
                 log('! unable to unload module:', mod)
                 logall(out)
@@ -999,7 +1035,12 @@ class Network(Module):
             sys_optimize_elan()
 
     def safe_to_clean(self):
-        return not is_network_prepared()
+        if PLATFORM == 'LINUX':
+            return not is_network_prepared()
+        elif PLATFORM == 'DARWIN':
+            # XXX always assume it's safe to clean 
+            return 1    
+        return 1
 
     def cleanup(self):
         self.info(self.net_type, self.nid)
@@ -2171,14 +2212,17 @@ def doHost(lustreDB, hosts):
             for_each_profile(node_db, prof_list, doSetup)
             return
 
-        sys_set_netmem_max('/proc/sys/net/core/rmem_max', MAXTCPBUF)
-        sys_set_netmem_max('/proc/sys/net/core/wmem_max', MAXTCPBUF)
+        if PLATFORM == 'LINUX':
+            sys_set_netmem_max('/proc/sys/net/core/rmem_max', MAXTCPBUF)
+            sys_set_netmem_max('/proc/sys/net/core/wmem_max', MAXTCPBUF)
 
         for_each_profile(node_db, prof_list, doModules)
 
-        sys_set_debug_path()
-        sys_set_ptldebug(ptldebug)
-        sys_set_subsystem(subsystem)
+        if PLATFORM == 'LINUX':
+            # XXX need to be fixed for Darwin
+            sys_set_debug_path()
+            sys_set_ptldebug(ptldebug)
+            sys_set_subsystem(subsystem)
         script = config.gdb_script
         run(lctl.lctl, ' modules >', script)
         if config.gdb:
index 891b6c8..3072e1d 100644 (file)
@@ -850,6 +850,7 @@ int jt_get_version(int argc, char **argv)
         memset(buf, 0, sizeof(buf));
         data->ioc_version = OBD_IOCTL_VERSION;
         data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
+        data->ioc_inlbuf1 = buf + size_round(sizeof(*data));
         data->ioc_len = obd_ioctl_packlen(data);
 
         rc = l2_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf);
@@ -867,6 +868,7 @@ int jt_get_version(int argc, char **argv)
 int jt_obd_list(int argc, char **argv)
 {
         int rc;
+#if HAVE_PROC_FS
         char buf[MAX_STRING_SIZE];
         FILE *fp = fopen(DEVICES_LIST, "r");
 
@@ -883,8 +885,40 @@ int jt_obd_list(int argc, char **argv)
                 printf("%s", buf);
 
         fclose(fp);
-
         return 0;
+#else
+        /* No /proc filesystem, get device list by ioctl */
+        int index;
+        char buf[8192];
+        struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
+
+        if (argc != 1)
+                return CMD_HELP;
+
+        for (index = 0;; index++) {
+                memset(buf, 0, sizeof(buf));
+                data->ioc_version = OBD_IOCTL_VERSION;
+                data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
+                data->ioc_inlbuf1 = buf + size_round(sizeof(*data));
+                data->ioc_len = obd_ioctl_packlen(data);
+                data->ioc_count = index;
+
+                rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETDEVICE, buf);
+                if (rc != 0)
+                        break;
+                printf("%s\n", (char *)data->ioc_bulk);
+        }
+        if (rc != 0) {
+                if (errno == ENOENT) 
+                        /* no device or the last device */
+                        rc = 0;
+                else 
+                        fprintf(stderr, "Error getting device list: %s: "
+                                        "check dmesg.\n",
+                                        strerror(errno));
+        }
+        return rc;
+#endif
 }
 
 /* Get echo client's stripe meta-data for the given object